1 /******************************************************************************
2 *
3 * Copyright (C) 2012 Ittiam Systems Pvt Ltd, Bangalore
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at:
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
17 ******************************************************************************/
18 /**
19 *******************************************************************************
20 * @file
21 * ihevcd_utils.c
22 *
23 * @brief
24 * Contains miscellaneous utility functions such as init() etc
25 *
26 * @author
27 * Harish
28 *
29 * @par List of Functions:
30 *
31 * @remarks
32 * None
33 *
34 *******************************************************************************
35 */
36 /*****************************************************************************/
37 /* File Includes */
38 /*****************************************************************************/
39 #include <stdio.h>
40 #include <stddef.h>
41 #include <stdlib.h>
42 #include <string.h>
43 #include <assert.h>
44
45 #include "ihevc_typedefs.h"
46 #include "iv.h"
47 #include "ivd.h"
48 #include "ihevcd_cxa.h"
49 #include "ithread.h"
50
51 #include "ihevc_defs.h"
52 #include "ihevc_debug.h"
53 #include "ihevc_defs.h"
54 #include "ihevc_error.h"
55 #include "ihevc_structs.h"
56 #include "ihevc_buf_mgr.h"
57 #include "ihevc_dpb_mgr.h"
58 #include "ihevc_macros.h"
59 #include "ihevc_platform_macros.h"
60
61 #include "ihevc_common_tables.h"
62 #include "ihevc_buf_mgr.h"
63 #include "ihevc_disp_mgr.h"
64 #include "ihevc_cabac_tables.h"
65
66 #include "ihevcd_defs.h"
67
68 #include "ihevcd_function_selector.h"
69 #include "ihevcd_structs.h"
70 #include "ihevcd_error.h"
71 #include "ihevcd_nal.h"
72 #include "ihevcd_bitstream.h"
73 #include "ihevcd_utils.h"
74 #include "ihevcd_trace.h"
75 #include "ihevcd_process_slice.h"
76 #include "ihevcd_job_queue.h"
77 #define MAX_DPB_PIC_BUF 6
78
79 /* Function declarations */
80 mv_buf_t* ihevcd_mv_mgr_get_poc(buf_mgr_t *ps_mv_buf_mgr, UWORD32 abs_poc);
81
82 /**
83 *******************************************************************************
84 *
85 * @brief
86 * Used to get level index for a given level
87 *
88 * @par Description:
89 * Converts from level_idc (which is multiplied by 30) to an index that can be
90 * used as a lookup. Also used to ignore invalid levels like 2.2 , 3.2 etc
91 *
92 * @param[in] level
93 * Level of the stream
94 *
95 * @returns Level index for a given level
96 *
97 * @remarks
98 *
99 *
100 *******************************************************************************
101 */
ihevcd_get_lvl_idx(WORD32 level)102 WORD32 ihevcd_get_lvl_idx(WORD32 level)
103 {
104 WORD32 lvl_idx = 0;
105
106 if(level < IHEVC_LEVEL_20)
107 {
108 lvl_idx = 0;
109 }
110 else if(level >= IHEVC_LEVEL_20 && level < IHEVC_LEVEL_21)
111 {
112 lvl_idx = 1;
113 }
114 else if(level >= IHEVC_LEVEL_21 && level < IHEVC_LEVEL_30)
115 {
116 lvl_idx = 2;
117 }
118 else if(level >= IHEVC_LEVEL_30 && level < IHEVC_LEVEL_31)
119 {
120 lvl_idx = 3;
121 }
122 else if(level >= IHEVC_LEVEL_31 && level < IHEVC_LEVEL_40)
123 {
124 lvl_idx = 4;
125 }
126 else if(level >= IHEVC_LEVEL_40 && level < IHEVC_LEVEL_41)
127 {
128 lvl_idx = 5;
129 }
130 else if(level >= IHEVC_LEVEL_41 && level < IHEVC_LEVEL_50)
131 {
132 lvl_idx = 6;
133 }
134 else if(level >= IHEVC_LEVEL_50 && level < IHEVC_LEVEL_51)
135 {
136 lvl_idx = 7;
137 }
138 else if(level >= IHEVC_LEVEL_51 && level < IHEVC_LEVEL_52)
139 {
140 lvl_idx = 8;
141 }
142 else if(level >= IHEVC_LEVEL_52 && level < IHEVC_LEVEL_60)
143 {
144 lvl_idx = 9;
145 }
146 else if(level >= IHEVC_LEVEL_60 && level < IHEVC_LEVEL_61)
147 {
148 lvl_idx = 10;
149 }
150 else if(level >= IHEVC_LEVEL_61 && level < IHEVC_LEVEL_62)
151 {
152 lvl_idx = 11;
153 }
154 else if(level >= IHEVC_LEVEL_62)
155 {
156 lvl_idx = 12;
157 }
158
159 return (lvl_idx);
160 }
161
162 /**
163 *******************************************************************************
164 *
165 * @brief
166 * Used to get reference picture buffer size for a given level and
167 * and padding used
168 *
169 * @par Description:
170 * Used to get reference picture buffer size for a given level and padding used
171 * Each picture is padded on all four sides
172 *
173 * @param[in] pic_size
174 * Mumber of luma samples (Width * Height)
175 *
176 * @param[in] level
177 * Level
178 *
179 * @param[in] horz_pad
180 * Total padding used in horizontal direction
181 *
182 * @param[in] vert_pad
183 * Total padding used in vertical direction
184 *
185 * @returns Total picture buffer size
186 *
187 * @remarks
188 *
189 *
190 *******************************************************************************
191 */
ihevcd_get_total_pic_buf_size(codec_t * ps_codec,WORD32 wd,WORD32 ht)192 WORD32 ihevcd_get_total_pic_buf_size(codec_t *ps_codec,
193 WORD32 wd,
194 WORD32 ht)
195 {
196 WORD32 size;
197 WORD32 num_luma_samples;
198 WORD32 max_dpb_size;
199 WORD32 num_samples;
200
201
202 sps_t *ps_sps = (ps_codec->s_parse.ps_sps_base + ps_codec->i4_sps_id);
203
204 /* Get maximum number of buffers for the current picture size */
205 max_dpb_size = ps_sps->ai1_sps_max_dec_pic_buffering[ps_sps->i1_sps_max_sub_layers - 1];
206
207 if(ps_codec->e_frm_out_mode != IVD_DECODE_FRAME_OUT)
208 max_dpb_size += ps_sps->ai1_sps_max_num_reorder_pics[ps_sps->i1_sps_max_sub_layers - 1];
209
210 max_dpb_size++;
211 /* Allocation is required for
212 * (Wd + horz_pad) * (Ht + vert_pad) * (2 * max_dpb_size + 1)
213 */
214
215 /* Account for padding area */
216 num_luma_samples = (wd + PAD_WD) * (ht + PAD_HT);
217
218 /* Account for chroma */
219 num_samples = num_luma_samples * 3 / 2;
220
221 /* Number of bytes in reference pictures */
222 size = num_samples * max_dpb_size;
223
224
225 return size;
226 }
227 /**
228 *******************************************************************************
229 *
230 * @brief
231 * Used to get MV bank size for a given number of luma samples
232 *
233 * @par Description:
234 * For given number of luma samples one MV bank size is computed
235 * Each MV bank includes pu_map and pu_t for all the min PUs(4x4) in a picture
236 *
237 * @param[in] num_luma_samples
238 * Max number of luma pixels in the frame
239 *
240 * @returns Total MV Bank size
241 *
242 * @remarks
243 *
244 *
245 *******************************************************************************
246 */
ihevcd_get_pic_mv_bank_size(WORD32 num_luma_samples)247 WORD32 ihevcd_get_pic_mv_bank_size(WORD32 num_luma_samples)
248 {
249 WORD32 size;
250
251 WORD32 pic_size;
252
253 WORD32 mv_bank_size;
254 WORD32 num_pu;
255 WORD32 num_ctb;
256 pic_size = num_luma_samples;
257
258
259 num_pu = pic_size / (MIN_PU_SIZE * MIN_PU_SIZE);
260 num_ctb = pic_size / (MIN_CTB_SIZE * MIN_CTB_SIZE);
261
262 mv_bank_size = 0;
263
264 /* Size for storing pu_t start index each CTB */
265 /* One extra entry is needed to compute number of PUs in the last CTB */
266 mv_bank_size += (num_ctb + 1) * sizeof(WORD32);
267
268 /* Size for pu_map */
269 mv_bank_size += num_pu;
270
271 /* Size for storing pu_t for each PU */
272 mv_bank_size += num_pu * sizeof(pu_t);
273
274 /* Size for storing slice_idx for each CTB */
275 mv_bank_size += ALIGN4(num_ctb * sizeof(UWORD16));
276
277 size = mv_bank_size;
278 return size;
279 }
280 /**
281 *******************************************************************************
282 *
283 * @brief
284 * Used to get TU data size for a given number luma samples
285 *
286 * @par Description:
287 * For a given number of luma samples TU data size is computed
288 * Each TU data includes tu_map and tu_t and coeff data for all
289 * the min TUs(4x4) in given CTB
290 *
291 * @param[in] num_luma_samples
292 * Number of 64 x 64 CTBs for which TU data has to be allocated.
293 *
294 * @returns Total TU data size
295 *
296 * @remarks Assumption is num_luma_samples will be at least
297 * 64 x 64 to handle CTB of size 64 x 64. Can be frame size as well
298 *
299 *******************************************************************************
300 */
ihevcd_get_tu_data_size(WORD32 num_luma_samples)301 WORD32 ihevcd_get_tu_data_size(WORD32 num_luma_samples)
302 {
303
304
305 WORD32 tu_data_size;
306 WORD32 num_ctb;
307 WORD32 num_luma_tu, num_chroma_tu, num_tu;
308 num_ctb = num_luma_samples / (MIN_CTB_SIZE * MIN_CTB_SIZE);
309
310 num_luma_tu = num_luma_samples / (MIN_TU_SIZE * MIN_TU_SIZE);
311 num_chroma_tu = num_luma_tu >> 1;
312
313 num_tu = num_luma_tu + num_chroma_tu;
314 tu_data_size = 0;
315
316 /* Size for storing tu_t start index each CTB */
317 /* One extra entry is needed to compute number of TUs in the last CTB */
318 tu_data_size += (num_ctb + 1) * sizeof(WORD32);
319
320 /* Size for storing tu map */
321 tu_data_size += num_luma_tu * sizeof(UWORD8);
322
323 /* Size for storing tu_t for each TU */
324 tu_data_size += num_tu * sizeof(tu_t);
325
326 /* Size for storing number of coded subblocks and scan_idx for each TU */
327 tu_data_size += num_tu * (sizeof(WORD8) + sizeof(WORD8));
328
329 /* Size for storing coeff data for each TU */
330 tu_data_size += num_tu * sizeof(tu_sblk_coeff_data_t);
331
332
333 return tu_data_size;
334 }
335
336
ihevcd_nctb_cnt(codec_t * ps_codec,sps_t * ps_sps)337 WORD32 ihevcd_nctb_cnt(codec_t *ps_codec, sps_t *ps_sps)
338 {
339 WORD32 nctb = 1;
340 UNUSED(ps_codec);
341 //TODO: Currently set to 1
342 /* If CTB size is less than 32 x 32 then set nCTB as 4 */
343 if(ps_sps->i1_log2_ctb_size < 5)
344 nctb = 1;
345
346 return nctb;
347 }
348
ihevcd_get_tile_pos(pps_t * ps_pps,sps_t * ps_sps,WORD32 ctb_x,WORD32 ctb_y,WORD32 * pi4_ctb_tile_x,WORD32 * pi4_ctb_tile_y,WORD32 * pi4_tile_idx)349 IHEVCD_ERROR_T ihevcd_get_tile_pos(pps_t *ps_pps,
350 sps_t *ps_sps,
351 WORD32 ctb_x,
352 WORD32 ctb_y,
353 WORD32 *pi4_ctb_tile_x,
354 WORD32 *pi4_ctb_tile_y,
355 WORD32 *pi4_tile_idx)
356 {
357
358 tile_t *ps_tile_tmp;
359 WORD32 i;
360 WORD32 tile_row, tile_col;
361
362 if(ctb_x < 0 || ctb_y < 0)
363 {
364 *pi4_ctb_tile_x = 0;
365 *pi4_ctb_tile_y = 0;
366 *pi4_tile_idx = 0;
367
368 return (IHEVCD_ERROR_T)IHEVCD_SUCCESS;
369 }
370
371 tile_row = 0;
372 tile_col = 0;
373 ps_tile_tmp = ps_pps->ps_tile;
374 if(0 == ps_pps->i1_tiles_enabled_flag)
375 {
376 *pi4_ctb_tile_x = ctb_x;
377 *pi4_ctb_tile_y = ctb_y;
378 *pi4_tile_idx = 0;
379 }
380 else
381 {
382 for(i = 0; i < ps_pps->i1_num_tile_columns; i++)
383 {
384 WORD16 next_tile_ctb_x;
385 ps_tile_tmp = ps_pps->ps_tile + i; //* ps_pps->i1_num_tile_rows;
386 if((ps_pps->i1_num_tile_columns - 1) == i)
387 {
388 next_tile_ctb_x = ps_sps->i2_pic_wd_in_ctb;
389 }
390 else
391 {
392 tile_t *ps_tile_next_tmp;
393 ps_tile_next_tmp = ps_pps->ps_tile + i + 1;
394 next_tile_ctb_x = ps_tile_next_tmp->u1_pos_x;
395 }
396 if((ctb_x >= ps_tile_tmp->u1_pos_x) && (ctb_x < next_tile_ctb_x))
397 {
398 tile_col = i;
399 break;
400 }
401 }
402 *pi4_ctb_tile_x = ctb_x - ps_tile_tmp->u1_pos_x;
403
404 for(i = 0; i < ps_pps->i1_num_tile_rows; i++)
405 {
406 WORD16 next_tile_ctb_y;
407 ps_tile_tmp = ps_pps->ps_tile + i * ps_pps->i1_num_tile_columns;
408 if((ps_pps->i1_num_tile_rows - 1) == i)
409 {
410 next_tile_ctb_y = ps_sps->i2_pic_ht_in_ctb;
411 }
412 else
413 {
414 tile_t *ps_tile_next_tmp;
415 ps_tile_next_tmp = ps_pps->ps_tile + ((i + 1) * ps_pps->i1_num_tile_columns);
416 next_tile_ctb_y = ps_tile_next_tmp->u1_pos_y;
417 }
418 if((ctb_y >= ps_tile_tmp->u1_pos_y) && (ctb_y < next_tile_ctb_y))
419 {
420 tile_row = i;
421 break;
422 }
423
424 }
425 *pi4_ctb_tile_y = ctb_y - ps_tile_tmp->u1_pos_y;
426 *pi4_tile_idx = tile_row * ps_pps->i1_num_tile_columns
427 + tile_col;
428 }
429 return (IHEVCD_ERROR_T)IHEVCD_SUCCESS;
430 }
431 /**
432 *******************************************************************************
433 *
434 * @brief
435 * Function to initialize ps_pic_buf structs add pic buffers to
436 * buffer manager in case of non-shared mode
437 *
438 * @par Description:
439 * Function to initialize ps_pic_buf structs add pic buffers to
440 * buffer manager in case of non-shared mode
441 * To be called once per stream or for every reset
442 *
443 * @param[in] ps_codec
444 * Pointer to codec context
445 *
446 * @returns Error from IHEVCD_ERROR_T
447 *
448 * @remarks
449 *
450 *
451 *******************************************************************************
452 */
ihevcd_pic_buf_mgr_add_bufs(codec_t * ps_codec)453 IHEVCD_ERROR_T ihevcd_pic_buf_mgr_add_bufs(codec_t *ps_codec)
454 {
455 IHEVCD_ERROR_T ret = (IHEVCD_ERROR_T)IHEVCD_SUCCESS;
456 WORD32 i;
457 WORD32 max_dpb_size;
458 sps_t *ps_sps;
459 UWORD8 *pu1_buf;
460 pic_buf_t *ps_pic_buf;
461 WORD32 pic_buf_size_allocated;
462
463
464
465
466 /* Initialize Pic buffer manager */
467 ps_sps = ps_codec->s_parse.ps_sps;
468
469 /* Compute the number of Pic buffers needed */
470 max_dpb_size = ps_sps->ai1_sps_max_dec_pic_buffering[ps_sps->i1_sps_max_sub_layers - 1];
471
472 if(ps_codec->e_frm_out_mode != IVD_DECODE_FRAME_OUT)
473 max_dpb_size += ps_sps->ai1_sps_max_num_reorder_pics[ps_sps->i1_sps_max_sub_layers - 1];
474
475 /* Allocate one extra picture to handle current frame
476 * In case of asynchronous parsing and processing, number of buffers should increase here
477 * based on when parsing and processing threads are synchronized
478 */
479 max_dpb_size++;
480
481
482 pu1_buf = (UWORD8 *)ps_codec->pu1_ref_pic_buf_base;
483
484 ps_pic_buf = (pic_buf_t *)ps_codec->ps_pic_buf;
485
486 /* In case of non-shared mode, add picture buffers to buffer manager
487 * In case of shared mode buffers are added in the run-time
488 */
489 if(0 == ps_codec->i4_share_disp_buf)
490 {
491 WORD32 buf_ret;
492 WORD32 luma_samples;
493 WORD32 chroma_samples;
494 pic_buf_size_allocated = ps_codec->i4_total_pic_buf_size;
495
496 luma_samples = (ps_codec->i4_strd) *
497 (ps_sps->i2_pic_height_in_luma_samples + PAD_HT);
498
499 chroma_samples = luma_samples / 2;
500
501 /* Try to add as many buffers as possible since memory is already allocated */
502 /* If the number of buffers that can be added is less than max_num_bufs
503 * return with an error.
504 */
505 for(i = 0; i < max_dpb_size; i++)
506 {
507 pic_buf_size_allocated -= (luma_samples + chroma_samples);
508
509 if(pic_buf_size_allocated < 0)
510 {
511 ps_codec->s_parse.i4_error_code = IHEVCD_INSUFFICIENT_MEM_PICBUF;
512 return IHEVCD_INSUFFICIENT_MEM_PICBUF;
513 }
514
515 ps_pic_buf->pu1_luma = pu1_buf + ps_codec->i4_strd * PAD_TOP + PAD_LEFT;
516 pu1_buf += luma_samples;
517
518 ps_pic_buf->pu1_chroma = pu1_buf + ps_codec->i4_strd * (PAD_TOP / 2) + PAD_LEFT;
519 pu1_buf += chroma_samples;
520
521 /* Pad boundary pixels (one pixel on all sides) */
522 /* This ensures SAO does not read uninitialized pixels */
523 /* Note these are not used in actual processing */
524 {
525 UWORD8 *pu1_buf;
526 WORD32 strd, wd, ht;
527 WORD32 i;
528 strd = ps_codec->i4_strd;
529 wd = ps_codec->i4_wd;
530 ht = ps_codec->i4_ht;
531
532 pu1_buf = ps_pic_buf->pu1_luma;
533 for(i = 0; i < ht; i++)
534 {
535 pu1_buf[-1] = 0;
536 pu1_buf[wd] = 0;
537 pu1_buf += strd;
538 }
539 pu1_buf = ps_pic_buf->pu1_luma;
540 memset(pu1_buf - strd - 1, 0, wd + 2);
541
542 pu1_buf += strd * ht;
543 memset(pu1_buf - 1, 0, wd + 2);
544
545 pu1_buf = ps_pic_buf->pu1_chroma;
546 ht >>= 1;
547 for(i = 0; i < ht; i++)
548 {
549 pu1_buf[-1] = 0;
550 pu1_buf[-2] = 0;
551 pu1_buf[wd] = 0;
552 pu1_buf[wd + 1] = 0;
553 pu1_buf += strd;
554 }
555 pu1_buf = ps_pic_buf->pu1_chroma;
556 memset(pu1_buf - strd - 2, 0, wd + 4);
557
558 pu1_buf += strd * ht;
559 memset(pu1_buf - 2, 0, wd + 4);
560 }
561
562 buf_ret = ihevc_buf_mgr_add((buf_mgr_t *)ps_codec->pv_pic_buf_mgr, ps_pic_buf, i);
563
564
565 if(0 != buf_ret)
566 {
567 ps_codec->s_parse.i4_error_code = IHEVCD_BUF_MGR_ERROR;
568 return IHEVCD_BUF_MGR_ERROR;
569 }
570 ps_pic_buf++;
571 }
572 }
573 else
574 {
575 /* In case of shared mode, buffers are added without adjusting for padding.
576 Update luma and chroma pointers here to account for padding as per stride.
577 In some cases stride might not be available when set_display_frame is called.
578 Hence updated luma and chroma pointers here */
579
580 for(i = 0; i < BUF_MGR_MAX_CNT; i++)
581 {
582 ps_pic_buf = ihevc_buf_mgr_get_buf((buf_mgr_t *)ps_codec->pv_pic_buf_mgr, i);
583 if((NULL == ps_pic_buf) ||
584 (NULL == ps_pic_buf->pu1_luma) ||
585 (NULL == ps_pic_buf->pu1_chroma))
586 {
587 break;
588 }
589 ps_pic_buf->pu1_luma += ps_codec->i4_strd * PAD_TOP + PAD_LEFT;
590 ps_pic_buf->pu1_chroma += ps_codec->i4_strd * (PAD_TOP / 2) + PAD_LEFT;
591 }
592 }
593
594 return ret;
595 }
596 /**
597 *******************************************************************************
598 *
599 * @brief
600 * Function to add buffers to MV Bank buffer manager
601 *
602 * @par Description:
603 * Function to add buffers to MV Bank buffer manager
604 * To be called once per stream or for every reset
605 *
606 * @param[in] ps_codec
607 * Pointer to codec context
608 *
609 * @returns Error from IHEVCD_ERROR_T
610 *
611 * @remarks
612 *
613 *
614 *******************************************************************************
615 */
ihevcd_mv_buf_mgr_add_bufs(codec_t * ps_codec)616 IHEVCD_ERROR_T ihevcd_mv_buf_mgr_add_bufs(codec_t *ps_codec)
617 {
618 IHEVCD_ERROR_T ret = (IHEVCD_ERROR_T)IHEVCD_SUCCESS;
619 WORD32 i;
620 WORD32 max_dpb_size;
621 WORD32 mv_bank_size_allocated;
622 WORD32 pic_mv_bank_size;
623
624 sps_t *ps_sps;
625 UWORD8 *pu1_buf;
626 mv_buf_t *ps_mv_buf;
627
628
629 /* Initialize MV Bank buffer manager */
630 ps_sps = ps_codec->s_parse.ps_sps;
631
632
633 /* Compute the number of MV Bank buffers needed */
634 max_dpb_size = ps_sps->ai1_sps_max_dec_pic_buffering[ps_sps->i1_sps_max_sub_layers - 1];
635
636 /* Allocate one extra MV Bank to handle current frame
637 * In case of asynchronous parsing and processing, number of buffers should increase here
638 * based on when parsing and processing threads are synchronized
639 */
640 max_dpb_size++;
641
642 ps_codec->i4_max_dpb_size = max_dpb_size;
643
644 pu1_buf = (UWORD8 *)ps_codec->pv_mv_bank_buf_base;
645
646 ps_mv_buf = (mv_buf_t *)pu1_buf;
647 pu1_buf += max_dpb_size * sizeof(mv_buf_t);
648 ps_codec->ps_mv_buf = ps_mv_buf;
649 mv_bank_size_allocated = ps_codec->i4_total_mv_bank_size - max_dpb_size * sizeof(mv_buf_t);
650
651 /* Compute MV bank size per picture */
652 pic_mv_bank_size = ihevcd_get_pic_mv_bank_size(ALIGN64(ps_sps->i2_pic_width_in_luma_samples) *
653 ALIGN64(ps_sps->i2_pic_height_in_luma_samples));
654
655 for(i = 0; i < max_dpb_size; i++)
656 {
657 WORD32 buf_ret;
658 WORD32 num_pu;
659 WORD32 num_ctb;
660 WORD32 pic_size;
661 pic_size = ALIGN64(ps_sps->i2_pic_width_in_luma_samples) *
662 ALIGN64(ps_sps->i2_pic_height_in_luma_samples);
663
664
665 num_pu = pic_size / (MIN_PU_SIZE * MIN_PU_SIZE);
666 num_ctb = pic_size / (MIN_CTB_SIZE * MIN_CTB_SIZE);
667
668
669 mv_bank_size_allocated -= pic_mv_bank_size;
670
671 if(mv_bank_size_allocated < 0)
672 {
673 ps_codec->s_parse.i4_error_code = IHEVCD_INSUFFICIENT_MEM_MVBANK;
674 return IHEVCD_INSUFFICIENT_MEM_MVBANK;
675 }
676
677 ps_mv_buf->pu4_pic_pu_idx = (UWORD32 *)pu1_buf;
678 pu1_buf += (num_ctb + 1) * sizeof(WORD32);
679
680 ps_mv_buf->pu1_pic_pu_map = pu1_buf;
681 pu1_buf += num_pu;
682
683 ps_mv_buf->pu1_pic_slice_map = (UWORD16 *)pu1_buf;
684 pu1_buf += ALIGN4(num_ctb * sizeof(UWORD16));
685
686 ps_mv_buf->ps_pic_pu = (pu_t *)pu1_buf;
687 pu1_buf += num_pu * sizeof(pu_t);
688
689 buf_ret = ihevc_buf_mgr_add((buf_mgr_t *)ps_codec->pv_mv_buf_mgr, ps_mv_buf, i);
690
691 if(0 != buf_ret)
692 {
693 ps_codec->s_parse.i4_error_code = IHEVCD_BUF_MGR_ERROR;
694 return IHEVCD_BUF_MGR_ERROR;
695 }
696
697 ps_mv_buf++;
698
699 }
700 return ret;
701 }
702 /**
703 *******************************************************************************
704 *
705 * @brief
706 * Output buffer check
707 *
708 * @par Description:
709 * Check for the number of buffers and buffer sizes of output buffer
710 *
711 * @param[in] ps_codec
712 * Pointer to codec context
713 *
714 * @returns Error from IHEVCD_ERROR_T
715 *
716 * @remarks
717 *
718 *
719 *******************************************************************************
720 */
ihevcd_check_out_buf_size(codec_t * ps_codec)721 IHEVCD_ERROR_T ihevcd_check_out_buf_size(codec_t *ps_codec)
722 {
723 ivd_out_bufdesc_t *ps_out_buffer = ps_codec->ps_out_buffer;
724 UWORD32 au4_min_out_buf_size[IVD_VIDDEC_MAX_IO_BUFFERS];
725 UWORD32 u4_min_num_out_bufs = 0, i;
726 UWORD32 wd, ht;
727
728 if(0 == ps_codec->i4_share_disp_buf)
729 {
730 wd = ps_codec->i4_disp_wd;
731 ht = ps_codec->i4_disp_ht;
732 }
733 else
734 {
735 /* In case of shared mode, do not check validity of ps_codec->ps_out_buffer */
736 return (IHEVCD_ERROR_T)IHEVCD_SUCCESS;
737 }
738
739 if(ps_codec->i4_disp_strd > (WORD32)wd)
740 wd = ps_codec->i4_disp_strd;
741
742 if(ps_codec->e_chroma_fmt == IV_YUV_420P)
743 u4_min_num_out_bufs = MIN_OUT_BUFS_420;
744 else if(ps_codec->e_chroma_fmt == IV_YUV_422ILE)
745 u4_min_num_out_bufs = MIN_OUT_BUFS_422ILE;
746 else if(ps_codec->e_chroma_fmt == IV_RGB_565)
747 u4_min_num_out_bufs = MIN_OUT_BUFS_RGB565;
748 else if(ps_codec->e_chroma_fmt == IV_RGBA_8888)
749 u4_min_num_out_bufs = MIN_OUT_BUFS_RGBA8888;
750 else if((ps_codec->e_chroma_fmt == IV_YUV_420SP_UV)
751 || (ps_codec->e_chroma_fmt == IV_YUV_420SP_VU))
752 u4_min_num_out_bufs = MIN_OUT_BUFS_420SP;
753
754 if(ps_codec->e_chroma_fmt == IV_YUV_420P)
755 {
756 au4_min_out_buf_size[0] = (wd * ht);
757 au4_min_out_buf_size[1] = (wd * ht) >> 2;
758 au4_min_out_buf_size[2] = (wd * ht) >> 2;
759 }
760 else if(ps_codec->e_chroma_fmt == IV_YUV_422ILE)
761 {
762 au4_min_out_buf_size[0] = (wd * ht) * 2;
763 au4_min_out_buf_size[1] =
764 au4_min_out_buf_size[2] = 0;
765 }
766 else if(ps_codec->e_chroma_fmt == IV_RGB_565)
767 {
768 au4_min_out_buf_size[0] = (wd * ht) * 2;
769 au4_min_out_buf_size[1] =
770 au4_min_out_buf_size[2] = 0;
771 }
772 else if(ps_codec->e_chroma_fmt == IV_RGBA_8888)
773 {
774 au4_min_out_buf_size[0] = (wd * ht) * 4;
775 au4_min_out_buf_size[1] =
776 au4_min_out_buf_size[2] = 0;
777 }
778 else if((ps_codec->e_chroma_fmt == IV_YUV_420SP_UV)
779 || (ps_codec->e_chroma_fmt == IV_YUV_420SP_VU))
780 {
781 au4_min_out_buf_size[0] = (wd * ht);
782 au4_min_out_buf_size[1] = (wd * ht) >> 1;
783 au4_min_out_buf_size[2] = 0;
784 }
785
786 if(ps_out_buffer->u4_num_bufs < u4_min_num_out_bufs)
787 {
788 return (IHEVCD_ERROR_T)IV_FAIL;
789 }
790
791 for (i = 0 ; i < u4_min_num_out_bufs; i++)
792 {
793 if(ps_out_buffer->u4_min_out_buf_size[i] < au4_min_out_buf_size[i])
794 {
795 return (IHEVCD_ERROR_T)IV_FAIL;
796 }
797 }
798
799 return (IHEVCD_ERROR_T)IHEVCD_SUCCESS;
800 }
801
802 /**
803 *******************************************************************************
804 *
805 * @brief
806 * Picture level initializations required during parsing
807 *
808 * @par Description:
809 * Initialize picture level context variables during parsing Initialize mv
810 * bank buffer manager in the first init call
811 *
812 * @param[in] ps_codec
813 * Pointer to codec context
814 *
815 * @returns Error from IHEVCD_ERROR_T
816 *
817 * @remarks
818 *
819 *
820 *******************************************************************************
821 */
ihevcd_parse_pic_init(codec_t * ps_codec)822 IHEVCD_ERROR_T ihevcd_parse_pic_init(codec_t *ps_codec)
823 {
824 IHEVCD_ERROR_T ret = (IHEVCD_ERROR_T)IHEVCD_SUCCESS;
825 mv_buf_t *ps_mv_buf;
826 sps_t *ps_sps;
827 WORD32 num_min_cu;
828 WORD32 cur_pic_buf_id;
829 WORD32 cur_mv_bank_buf_id;
830 pic_buf_t *ps_cur_pic;
831 slice_header_t *ps_slice_hdr;
832 UWORD8 *pu1_cur_pic_luma, *pu1_cur_pic_chroma;
833 WORD32 i;
834
835 ps_codec->s_parse.i4_error_code = IHEVCD_SUCCESS;
836 ps_sps = ps_codec->s_parse.ps_sps;
837 ps_slice_hdr = ps_codec->s_parse.ps_slice_hdr;
838
839 /* Memset picture level intra map and transquant bypass map to zero */
840 num_min_cu = ((ps_sps->i2_pic_height_in_luma_samples + 7) / 8) * ((ps_sps->i2_pic_width_in_luma_samples + 63) / 64);
841 memset(ps_codec->s_parse.pu1_pic_intra_flag, 0, num_min_cu);
842 memset(ps_codec->s_parse.pu1_pic_no_loop_filter_flag, 0, num_min_cu);
843
844
845
846 if(0 == ps_codec->s_parse.i4_first_pic_init)
847 {
848 ret = ihevcd_mv_buf_mgr_add_bufs(ps_codec);
849 RETURN_IF((ret != (IHEVCD_ERROR_T)IHEVCD_SUCCESS), ret);
850
851 ret = ihevcd_pic_buf_mgr_add_bufs(ps_codec);
852 RETURN_IF((ret != (IHEVCD_ERROR_T)IHEVCD_SUCCESS), ret);
853
854 ps_codec->s_parse.i4_first_pic_init = 1;
855 }
856
857 /* Output buffer check */
858 ret = ihevcd_check_out_buf_size(ps_codec);
859 RETURN_IF((ret != (IHEVCD_ERROR_T)IHEVCD_SUCCESS), ret);
860
861 /* Initialize all the slice headers' slice addresses to zero */
862 {
863 WORD32 slice_idx;
864 WORD32 slice_start_idx;
865
866 slice_start_idx = ps_codec->i4_slice_error ? 2 : 1;
867
868 for(slice_idx = slice_start_idx; slice_idx < MAX_SLICE_HDR_CNT; slice_idx++)
869 {
870 slice_header_t *ps_slice_hdr_tmp = ps_codec->ps_slice_hdr_base + slice_idx;
871 ps_slice_hdr_tmp->i2_ctb_x = -1;
872 ps_slice_hdr_tmp->i2_ctb_y = -1;
873
874 }
875 }
876
877 /* Get free MV Bank to hold current picture's motion vector data */
878 {
879 ps_mv_buf = (mv_buf_t *)ihevc_buf_mgr_get_next_free((buf_mgr_t *)ps_codec->pv_mv_buf_mgr, &cur_mv_bank_buf_id);
880
881 /* If there are no free buffers then return with an error code.
882 * If the buffer is to be freed by another thread , change the
883 * following to call thread yield and wait for buffer to be freed
884 */
885 if(NULL == ps_mv_buf)
886 {
887 ps_codec->s_parse.i4_error_code = IHEVCD_NO_FREE_MVBANK;
888 ps_codec->i4_error_code = IHEVCD_NO_FREE_MVBANK;
889 return IHEVCD_NO_FREE_MVBANK;
890 }
891
892 ps_codec->s_parse.ps_cur_mv_buf = ps_mv_buf;
893 /* Set current ABS poc to ps_mv_buf, so that while freeing a reference buffer
894 * corresponding mv buffer can be found by looping through ps_codec->ps_mv_buf array
895 * and getting a buffer id to free
896 */
897 ps_mv_buf->i4_abs_poc = ps_slice_hdr->i4_abs_pic_order_cnt;
898 }
899
900 /* Get free picture buffer to hold current picture recon data */
901 /* TODO: For asynchronous api the following initializations related to picture
902 * buffer should be moved to processing side
903 */
904 {
905
906 UWORD8 *pu1_buf;
907 ps_cur_pic = (pic_buf_t *)ihevc_buf_mgr_get_next_free((buf_mgr_t *)ps_codec->pv_pic_buf_mgr, &cur_pic_buf_id);
908
909 /* If there are no free buffers then return with an error code.
910 * TODO: If the buffer is to be freed by another thread , change the
911 * following to call thread yield and wait for buffer to be freed
912 */
913 if(NULL == ps_cur_pic)
914 {
915 ps_codec->s_parse.i4_error_code = IHEVCD_NO_FREE_PICBUF;
916 ps_codec->i4_error_code = IHEVCD_NO_FREE_PICBUF;
917 return IHEVCD_NO_FREE_PICBUF;
918 }
919
920 /* Store input timestamp sent with input buffer */
921 ps_cur_pic->u4_ts = ps_codec->u4_ts;
922 ps_cur_pic->i4_abs_poc = ps_slice_hdr->i4_abs_pic_order_cnt;
923 ps_cur_pic->i4_poc_lsb = ps_slice_hdr->i4_pic_order_cnt_lsb;
924 pu1_buf = ps_cur_pic->pu1_luma;
925 pu1_cur_pic_luma = pu1_buf;
926
927 pu1_buf = ps_cur_pic->pu1_chroma;
928
929 pu1_cur_pic_chroma = pu1_buf;
930
931 ps_cur_pic->s_sei_params.i1_sei_parameters_present_flag = 0;
932 if(ps_codec->s_parse.s_sei_params.i1_sei_parameters_present_flag)
933 {
934 sei_params_t *ps_sei = &ps_codec->s_parse.s_sei_params;
935 ps_cur_pic->s_sei_params = ps_codec->s_parse.s_sei_params;
936
937 /* Once sei_params is copied to pic_buf,
938 * mark sei_params in s_parse as not present,
939 * this ensures that future frames do not use this data again.
940 */
941 ps_sei->i1_sei_parameters_present_flag = 0;
942 ps_sei->i1_user_data_registered_present_flag = 0;
943 ps_sei->i1_aud_present_flag = 0;
944 ps_sei->i1_time_code_present_flag = 0;
945 ps_sei->i1_buf_period_params_present_flag = 0;
946 ps_sei->i1_pic_timing_params_present_flag = 0;
947 ps_sei->i1_recovery_point_params_present_flag = 0;
948 ps_sei->i1_active_parameter_set = 0;
949 ps_sei->i4_sei_mastering_disp_colour_vol_params_present_flags = 0;
950 }
951 }
952
953 if(0 == ps_codec->u4_pic_cnt)
954 {
955 memset(ps_cur_pic->pu1_luma, 128, (ps_sps->i2_pic_width_in_luma_samples + PAD_WD) * ps_sps->i2_pic_height_in_luma_samples);
956 memset(ps_cur_pic->pu1_chroma, 128, (ps_sps->i2_pic_width_in_luma_samples + PAD_WD) * ps_sps->i2_pic_height_in_luma_samples / 2);
957 }
958
959 /* Fill the remaining entries of the reference lists with the nearest POC
960 * This is done to handle cases where there is a corruption in the reference index */
961 {
962 pic_buf_t *ps_pic_buf_ref;
963 mv_buf_t *ps_mv_buf_ref;
964 WORD32 r_idx;
965 dpb_mgr_t *ps_dpb_mgr = (dpb_mgr_t *)ps_codec->pv_dpb_mgr;
966 buf_mgr_t *ps_mv_buf_mgr = (buf_mgr_t *)ps_codec->pv_mv_buf_mgr;
967
968 ps_pic_buf_ref = ihevc_dpb_mgr_get_ref_by_nearest_poc(ps_dpb_mgr, ps_slice_hdr->i4_abs_pic_order_cnt);
969 if(NULL == ps_pic_buf_ref)
970 {
971 WORD32 size;
972
973 WORD32 num_pu;
974 WORD32 num_ctb;
975 WORD32 pic_size;
976 /* In case current mv buffer itself is being used as reference mv buffer for colocated
977 * calculations, then memset all the buffers to zero.
978 */
979 pic_size = ALIGN64(ps_sps->i2_pic_width_in_luma_samples) *
980 ALIGN64(ps_sps->i2_pic_height_in_luma_samples);
981
982 num_pu = pic_size / (MIN_PU_SIZE * MIN_PU_SIZE);
983 num_ctb = pic_size / (MIN_CTB_SIZE * MIN_CTB_SIZE);
984
985 memset(ps_mv_buf->ai4_l0_collocated_poc, 0, sizeof(ps_mv_buf->ai4_l0_collocated_poc));
986 memset(ps_mv_buf->ai1_l0_collocated_poc_lt, 0, sizeof(ps_mv_buf->ai1_l0_collocated_poc_lt));
987 memset(ps_mv_buf->ai4_l1_collocated_poc, 0, sizeof(ps_mv_buf->ai4_l1_collocated_poc));
988 memset(ps_mv_buf->ai1_l1_collocated_poc_lt, 0, sizeof(ps_mv_buf->ai1_l1_collocated_poc_lt));
989
990 size = (num_ctb + 1) * sizeof(WORD32);
991 memset(ps_mv_buf->pu4_pic_pu_idx, 0, size);
992
993 size = num_pu;
994 memset(ps_mv_buf->pu1_pic_pu_map, 0, size);
995 size = ALIGN4(num_ctb * sizeof(UWORD16));
996 memset(ps_mv_buf->pu1_pic_slice_map, 0, size);
997 size = num_pu * sizeof(pu_t);
998 memset(ps_mv_buf->ps_pic_pu, 0, size);
999
1000 ps_pic_buf_ref = ps_cur_pic;
1001 ps_mv_buf_ref = ps_mv_buf;
1002 }
1003 else
1004 {
1005 ps_mv_buf_ref = ihevcd_mv_mgr_get_poc(ps_mv_buf_mgr, ps_pic_buf_ref->i4_abs_poc);
1006 }
1007
1008 for(r_idx = 0; r_idx < ps_slice_hdr->i1_num_ref_idx_l0_active; r_idx++)
1009 {
1010 if(NULL == ps_slice_hdr->as_ref_pic_list0[r_idx].pv_pic_buf)
1011 {
1012 ps_slice_hdr->as_ref_pic_list0[r_idx].pv_pic_buf = (void *)ps_pic_buf_ref;
1013 ps_slice_hdr->as_ref_pic_list0[r_idx].pv_mv_buf = (void *)ps_mv_buf_ref;
1014 }
1015 }
1016
1017 for(r_idx = ps_slice_hdr->i1_num_ref_idx_l0_active; r_idx < MAX_DPB_SIZE; r_idx++)
1018 {
1019 ps_slice_hdr->as_ref_pic_list0[r_idx].pv_pic_buf = (void *)ps_pic_buf_ref;
1020 ps_slice_hdr->as_ref_pic_list0[r_idx].pv_mv_buf = (void *)ps_mv_buf_ref;
1021 }
1022
1023 for(r_idx = 0; r_idx < ps_slice_hdr->i1_num_ref_idx_l1_active; r_idx++)
1024 {
1025 if(NULL == ps_slice_hdr->as_ref_pic_list1[r_idx].pv_pic_buf)
1026 {
1027 ps_slice_hdr->as_ref_pic_list1[r_idx].pv_pic_buf = (void *)ps_pic_buf_ref;
1028 ps_slice_hdr->as_ref_pic_list1[r_idx].pv_mv_buf = (void *)ps_mv_buf_ref;
1029 }
1030 }
1031
1032 for(r_idx = ps_slice_hdr->i1_num_ref_idx_l1_active; r_idx < MAX_DPB_SIZE; r_idx++)
1033 {
1034 ps_slice_hdr->as_ref_pic_list1[r_idx].pv_pic_buf = (void *)ps_pic_buf_ref;
1035 ps_slice_hdr->as_ref_pic_list1[r_idx].pv_mv_buf = (void *)ps_mv_buf_ref;
1036 }
1037 }
1038
1039
1040 /* Reset the jobq to start of the jobq buffer */
1041 ihevcd_jobq_reset((jobq_t *)ps_codec->pv_proc_jobq);
1042
1043 ps_codec->s_parse.i4_pic_pu_idx = 0;
1044 ps_codec->s_parse.i4_pic_tu_idx = 0;
1045
1046 ps_codec->s_parse.pu1_pic_pu_map = ps_mv_buf->pu1_pic_pu_map;
1047 ps_codec->s_parse.ps_pic_pu = ps_mv_buf->ps_pic_pu;
1048 ps_codec->s_parse.pu4_pic_pu_idx = ps_mv_buf->pu4_pic_pu_idx;
1049 ps_codec->s_parse.pu1_slice_idx = (UWORD16 *)ps_mv_buf->pu1_pic_slice_map;
1050 for(i = 0; i < MAX_PROCESS_THREADS; i++)
1051 {
1052 ps_codec->as_process[i].pu1_slice_idx = (UWORD16 *)ps_mv_buf->pu1_pic_slice_map;
1053 }
1054 ps_codec->s_parse.pu1_pu_map = ps_codec->s_parse.pu1_pic_pu_map;
1055 ps_codec->s_parse.ps_pu = ps_codec->s_parse.ps_pic_pu;
1056
1057 {
1058 UWORD8 *pu1_buf;
1059 WORD32 ctb_luma_min_tu_cnt, ctb_chroma_min_tu_cnt, ctb_min_tu_cnt;
1060 WORD32 pic_size;
1061 WORD32 num_ctb;
1062
1063 pic_size = ALIGN64(ps_sps->i2_pic_width_in_luma_samples) *
1064 ALIGN64(ps_sps->i2_pic_height_in_luma_samples);
1065
1066 ctb_luma_min_tu_cnt = pic_size / (MIN_TU_SIZE * MIN_TU_SIZE);
1067
1068 ctb_chroma_min_tu_cnt = ctb_luma_min_tu_cnt >> 1;
1069
1070 ctb_min_tu_cnt = ctb_luma_min_tu_cnt + ctb_chroma_min_tu_cnt;
1071
1072 num_ctb = pic_size / (MIN_CTB_SIZE * MIN_CTB_SIZE);
1073 pu1_buf = (UWORD8 *)ps_codec->pv_tu_data;
1074 ps_codec->s_parse.pu4_pic_tu_idx = (UWORD32 *)pu1_buf;
1075 pu1_buf += (num_ctb + 1) * sizeof(WORD32);
1076
1077 ps_codec->s_parse.pu1_pic_tu_map = pu1_buf;
1078 pu1_buf += ctb_min_tu_cnt;
1079
1080 ps_codec->s_parse.ps_pic_tu = (tu_t *)pu1_buf;
1081 pu1_buf += ctb_min_tu_cnt * sizeof(tu_t);
1082
1083 ps_codec->s_parse.pv_pic_tu_coeff_data = pu1_buf;
1084
1085 ps_codec->s_parse.pu1_tu_map = ps_codec->s_parse.pu1_pic_tu_map;
1086 ps_codec->s_parse.ps_tu = ps_codec->s_parse.ps_pic_tu;
1087 ps_codec->s_parse.pv_tu_coeff_data = ps_codec->s_parse.pv_pic_tu_coeff_data;
1088 }
1089
1090 ps_codec->s_parse.s_bs_ctxt.ps_pic_pu = ps_codec->s_parse.ps_pic_pu;
1091 ps_codec->s_parse.s_bs_ctxt.pu4_pic_pu_idx = ps_codec->s_parse.pu4_pic_pu_idx;
1092 ps_codec->s_parse.s_bs_ctxt.pu4_pic_tu_idx = ps_codec->s_parse.pu4_pic_tu_idx;
1093
1094
1095 /* Set number of CTBs to be processed simultaneously */
1096 ps_codec->i4_proc_nctb = ihevcd_nctb_cnt(ps_codec, ps_sps);
1097
1098 /* Memset Parse Map and process map at the start of frame */
1099 //TODO: In case of asynchronous API proc_map can not be set to zero here
1100 {
1101 WORD32 num_ctb;
1102
1103 num_ctb = ps_sps->i4_pic_size_in_ctb;
1104
1105 memset(ps_codec->pu1_parse_map, 0, num_ctb);
1106
1107 memset(ps_codec->pu1_proc_map, 0, num_ctb);
1108 }
1109
1110
1111
1112 /* Initialize disp buf id to -1, this will be updated at the end of frame if there is
1113 * buffer to be displayed
1114 */
1115 ps_codec->i4_disp_buf_id = -1;
1116 ps_codec->ps_disp_buf = NULL;
1117
1118 ps_codec->i4_disable_deblk_pic = 0;
1119 ps_codec->i4_disable_sao_pic = 0;
1120 ps_codec->i4_fullpel_inter_pred = 0;
1121 ps_codec->i4_mv_frac_mask = 0x7FFFFFFF;
1122
1123 /* If degrade is enabled, set the degrade flags appropriately */
1124 if(ps_codec->i4_degrade_type && ps_codec->i4_degrade_pics)
1125 {
1126 WORD32 degrade_pic;
1127 ps_codec->i4_degrade_pic_cnt++;
1128 degrade_pic = 0;
1129
1130 /* If degrade is to be done in all frames, then do not check further */
1131 switch(ps_codec->i4_degrade_pics)
1132 {
1133 case 4:
1134 {
1135 degrade_pic = 1;
1136 break;
1137 }
1138 case 3:
1139 {
1140 if(ps_slice_hdr->i1_slice_type != ISLICE)
1141 degrade_pic = 1;
1142
1143 break;
1144 }
1145 case 2:
1146 {
1147
1148 /* If pic count hits non-degrade interval or it is an islice, then do not degrade */
1149 if((ps_slice_hdr->i1_slice_type != ISLICE) &&
1150 (ps_codec->i4_degrade_pic_cnt != ps_codec->i4_nondegrade_interval))
1151 degrade_pic = 1;
1152
1153 break;
1154 }
1155 case 1:
1156 {
1157 /* Check if the current picture is non-ref */
1158 if((ps_slice_hdr->i1_nal_unit_type < NAL_BLA_W_LP) &&
1159 (ps_slice_hdr->i1_nal_unit_type % 2 == 0))
1160 {
1161 degrade_pic = 1;
1162 }
1163 break;
1164 }
1165
1166
1167 }
1168 if(degrade_pic)
1169 {
1170 if(ps_codec->i4_degrade_type & 0x1)
1171 ps_codec->i4_disable_sao_pic = 1;
1172
1173 if(ps_codec->i4_degrade_type & 0x2)
1174 ps_codec->i4_disable_deblk_pic = 1;
1175
1176 /* MC degrading is done only for non-ref pictures */
1177 if((ps_slice_hdr->i1_nal_unit_type < NAL_BLA_W_LP) &&
1178 (ps_slice_hdr->i1_nal_unit_type % 2 == 0))
1179 {
1180 if(ps_codec->i4_degrade_type & 0x4)
1181 ps_codec->i4_mv_frac_mask = 0;
1182
1183 if(ps_codec->i4_degrade_type & 0x8)
1184 ps_codec->i4_mv_frac_mask = 0;
1185 }
1186 }
1187 else
1188 ps_codec->i4_degrade_pic_cnt = 0;
1189 }
1190
1191
1192 {
1193 WORD32 i;
1194 for(i = 0; i < MAX_PROCESS_THREADS; i++)
1195 {
1196 ps_codec->as_process[i].pu4_pic_pu_idx = ps_codec->s_parse.pu4_pic_pu_idx;
1197 ps_codec->as_process[i].ps_pic_pu = ps_codec->s_parse.ps_pic_pu;
1198 ps_codec->as_process[i].pu1_pic_pu_map = ps_codec->s_parse.pu1_pic_pu_map;
1199 ps_codec->as_process[i].pu4_pic_tu_idx = ps_codec->s_parse.pu4_pic_tu_idx;
1200 ps_codec->as_process[i].ps_pic_tu = ps_codec->s_parse.ps_pic_tu;
1201 ps_codec->as_process[i].pu1_pic_tu_map = ps_codec->s_parse.pu1_pic_tu_map;
1202 ps_codec->as_process[i].pv_pic_tu_coeff_data = ps_codec->s_parse.pv_pic_tu_coeff_data;
1203 ps_codec->as_process[i].i4_cur_mv_bank_buf_id = cur_mv_bank_buf_id;
1204 ps_codec->as_process[i].s_sao_ctxt.pu1_slice_idx = ps_codec->as_process[i].pu1_slice_idx;
1205 ps_codec->as_process[i].s_sao_ctxt.pu1_tile_idx = ps_codec->as_process[i].pu1_tile_idx;
1206
1207 /* TODO: For asynchronous api the following initializations related to picture
1208 * buffer should be moved to processing side
1209 */
1210 ps_codec->as_process[i].pu1_cur_pic_luma = pu1_cur_pic_luma;
1211 ps_codec->as_process[i].pu1_cur_pic_chroma = pu1_cur_pic_chroma;
1212 ps_codec->as_process[i].ps_cur_pic = ps_cur_pic;
1213 ps_codec->as_process[i].i4_cur_pic_buf_id = cur_pic_buf_id;
1214
1215 ps_codec->as_process[i].ps_out_buffer = ps_codec->ps_out_buffer;
1216 if(1 < ps_codec->i4_num_cores)
1217 {
1218 ps_codec->as_process[i].i4_check_parse_status = 1;
1219 ps_codec->as_process[i].i4_check_proc_status = 1;
1220 }
1221 else
1222 {
1223 ps_codec->as_process[i].i4_check_parse_status = 0;
1224 ps_codec->as_process[i].i4_check_proc_status = 0;
1225 }
1226 ps_codec->as_process[i].pu1_pic_intra_flag = ps_codec->s_parse.pu1_pic_intra_flag;
1227 ps_codec->as_process[i].pu1_pic_no_loop_filter_flag = ps_codec->s_parse.pu1_pic_no_loop_filter_flag;
1228 ps_codec->as_process[i].i4_init_done = 0;
1229
1230 ps_codec->as_process[i].s_bs_ctxt.pu4_pic_tu_idx = ps_codec->as_process[i].pu4_pic_tu_idx;
1231 ps_codec->as_process[i].s_bs_ctxt.pu4_pic_pu_idx = ps_codec->as_process[i].pu4_pic_pu_idx;
1232 ps_codec->as_process[i].s_bs_ctxt.ps_pic_pu = ps_codec->as_process[i].ps_pic_pu;
1233 ps_codec->as_process[i].s_deblk_ctxt.pu1_pic_no_loop_filter_flag = ps_codec->s_parse.pu1_pic_no_loop_filter_flag;
1234 ps_codec->as_process[i].s_deblk_ctxt.pu1_cur_pic_luma = pu1_cur_pic_luma;
1235 ps_codec->as_process[i].s_deblk_ctxt.pu1_cur_pic_chroma = pu1_cur_pic_chroma;
1236 ps_codec->as_process[i].s_sao_ctxt.pu1_pic_no_loop_filter_flag = ps_codec->s_parse.pu1_pic_no_loop_filter_flag;
1237 ps_codec->as_process[i].s_sao_ctxt.pu1_cur_pic_luma = pu1_cur_pic_luma;
1238 ps_codec->as_process[i].s_sao_ctxt.pu1_cur_pic_chroma = pu1_cur_pic_chroma;
1239 if(i < (ps_codec->i4_num_cores - 1))
1240 {
1241 ithread_create(ps_codec->apv_process_thread_handle[i], NULL,
1242 (void *)ihevcd_process_thread,
1243 (void *)&ps_codec->as_process[i]);
1244 ps_codec->ai4_process_thread_created[i] = 1;
1245 }
1246 else
1247 {
1248 ps_codec->ai4_process_thread_created[i] = 0;
1249 }
1250
1251 }
1252 ps_codec->s_parse.s_deblk_ctxt.pu1_cur_pic_luma = pu1_cur_pic_luma;
1253 ps_codec->s_parse.s_deblk_ctxt.pu1_cur_pic_chroma = pu1_cur_pic_chroma;
1254
1255 ps_codec->s_parse.s_sao_ctxt.pu1_cur_pic_luma = pu1_cur_pic_luma;
1256 ps_codec->s_parse.s_sao_ctxt.pu1_cur_pic_chroma = pu1_cur_pic_chroma;
1257 }
1258 /* Since any input bitstream buffer that contains slice data will be sent to output(even in
1259 * case of error, this buffer is added to display queue and next buffer in the display queue
1260 * will be returned as the display buffer.
1261 * Note: If format conversion (or frame copy) is used and is scheduled
1262 * in a different thread then it has to check if the processing for the current row is complete before
1263 * it copies/converts a given row. In case of low delay or in case of B pictures, current frame being decoded has to be
1264 * returned, which requires a status check to ensure that the current row is reconstructed before copying.
1265 */
1266 /* Add current picture to display manager */
1267 {
1268 WORD32 abs_poc;
1269 slice_header_t *ps_slice_hdr;
1270 ps_slice_hdr = ps_codec->s_parse.ps_slice_hdr;
1271 abs_poc = ps_slice_hdr->i4_abs_pic_order_cnt;
1272 ihevc_disp_mgr_add((disp_mgr_t *)ps_codec->pv_disp_buf_mgr,
1273 ps_codec->as_process[0].i4_cur_pic_buf_id,
1274 abs_poc,
1275 ps_codec->as_process[0].ps_cur_pic);
1276 }
1277 ps_codec->ps_disp_buf = NULL;
1278 /* Get picture to be displayed if number of pictures decoded is more than max allowed reorder */
1279 /* Since the current will be decoded, check is fore >= instead of > */
1280 if(((WORD32)(ps_codec->u4_pic_cnt - ps_codec->u4_disp_cnt) >= ps_sps->ai1_sps_max_num_reorder_pics[ps_sps->i1_sps_max_sub_layers - 1]) ||
1281 (ps_codec->e_frm_out_mode == IVD_DECODE_FRAME_OUT))
1282
1283 {
1284 ps_codec->ps_disp_buf = (pic_buf_t *)ihevc_disp_mgr_get((disp_mgr_t *)ps_codec->pv_disp_buf_mgr, &ps_codec->i4_disp_buf_id);
1285 ps_codec->u4_disp_cnt++;
1286 }
1287
1288 ps_codec->s_fmt_conv.i4_cur_row = 0;
1289 /* Set number of rows to be processed at a time */
1290 ps_codec->s_fmt_conv.i4_num_rows = 4;
1291
1292 if(ps_codec->u4_enable_fmt_conv_ahead && (ps_codec->i4_num_cores > 1))
1293 {
1294 process_ctxt_t *ps_proc;
1295
1296 /* i4_num_cores - 1 contexts are currently being used by other threads */
1297 ps_proc = &ps_codec->as_process[ps_codec->i4_num_cores - 1];
1298
1299 /* If the frame being decoded and displayed are different, schedule format conversion jobs
1300 * this will keep the proc threads busy and lets parse thread decode few CTBs ahead
1301 * If the frame being decoded and displayed are same, then format conversion is scheduled later.
1302 */
1303 if((ps_codec->ps_disp_buf) && (ps_codec->i4_disp_buf_id != ps_proc->i4_cur_pic_buf_id) &&
1304 ((0 == ps_codec->i4_share_disp_buf) || (IV_YUV_420P == ps_codec->e_chroma_fmt)))
1305 {
1306
1307 for(i = 0; i < ps_sps->i2_pic_ht_in_ctb; i++)
1308 {
1309 proc_job_t s_job;
1310 IHEVCD_ERROR_T ret;
1311 s_job.i4_cmd = CMD_FMTCONV;
1312 s_job.i2_ctb_cnt = 0;
1313 s_job.i2_ctb_x = 0;
1314 s_job.i2_ctb_y = i;
1315 s_job.i2_slice_idx = 0;
1316 s_job.i4_tu_coeff_data_ofst = 0;
1317 ret = ihevcd_jobq_queue((jobq_t *)ps_codec->s_parse.pv_proc_jobq,
1318 &s_job, sizeof(proc_job_t), 1);
1319 if(ret != (IHEVCD_ERROR_T)IHEVCD_SUCCESS)
1320 return ret;
1321 }
1322 }
1323 }
1324
1325 /* If parse_pic_init is called, then slice data is present in the input bitstrea stream */
1326 ps_codec->i4_pic_present = 1;
1327
1328 return ret;
1329 }
1330
1331
1332