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 DPB size for a given level, and number of luma samples
167 *
168 * @par Description:
169 * For given width, height and level number of max_dpb_size is computed as per
170 * Annex A.4.1
171 *
172 * @param[in] level
173 * Level of the stream
174 *
175 * @param[in] pic_size
176 * Width * Height
177 *
178 * @returns Number of buffers in DPB
179 *
180 * @remarks
181 *
182 *
183 *******************************************************************************
184 */
ihevcd_get_dpb_size(WORD32 level,WORD32 pic_size)185 WORD32 ihevcd_get_dpb_size(WORD32 level, WORD32 pic_size)
186 {
187
188 WORD32 max_luma_samples;
189
190 WORD32 max_dpb_size;
191 WORD32 lvl_idx = ihevcd_get_lvl_idx(level);
192 max_luma_samples = gai4_ihevc_max_luma_pic_size[lvl_idx];
193
194
195
196 if(pic_size <= (max_luma_samples >> 2))
197 {
198 max_dpb_size = MIN(4 * MAX_DPB_PIC_BUF, 16);
199 }
200 else if(pic_size <= (max_luma_samples >> 1))
201 {
202 max_dpb_size = MIN(2 * MAX_DPB_PIC_BUF, 16);
203 }
204 else if(pic_size <= ((3 * max_luma_samples) >> 2))
205 {
206 max_dpb_size = MIN((4 * MAX_DPB_PIC_BUF) / 3, 16);
207 }
208 else
209 {
210 max_dpb_size = MAX_DPB_PIC_BUF;
211 }
212
213 return max_dpb_size;
214 }
215 /**
216 *******************************************************************************
217 *
218 * @brief
219 * Used to get reference picture buffer size for a given level and
220 * and padding used
221 *
222 * @par Description:
223 * Used to get reference picture buffer size for a given level and padding used
224 * Each picture is padded on all four sides
225 *
226 * @param[in] pic_size
227 * Mumber of luma samples (Width * Height)
228 *
229 * @param[in] level
230 * Level
231 *
232 * @param[in] horz_pad
233 * Total padding used in horizontal direction
234 *
235 * @param[in] vert_pad
236 * Total padding used in vertical direction
237 *
238 * @returns Total picture buffer size
239 *
240 * @remarks
241 *
242 *
243 *******************************************************************************
244 */
ihevcd_get_total_pic_buf_size(WORD32 pic_size,WORD32 level,WORD32 horz_pad,WORD32 vert_pad,WORD32 init_num_bufs,WORD32 init_extra_bufs,WORD32 chroma_only)245 WORD32 ihevcd_get_total_pic_buf_size(WORD32 pic_size,
246 WORD32 level,
247 WORD32 horz_pad,
248 WORD32 vert_pad,
249 WORD32 init_num_bufs,
250 WORD32 init_extra_bufs,
251 WORD32 chroma_only)
252 {
253 WORD32 size;
254 WORD32 num_luma_samples;
255 WORD32 lvl_idx;
256 WORD32 max_wd, min_ht;
257 WORD32 max_dpb_size;
258 WORD32 num_samples;
259 WORD32 max_num_bufs;
260 WORD32 pad = MAX(horz_pad, vert_pad);
261
262
263 /* Get maximum number of buffers for the current picture size */
264 max_dpb_size = ihevcd_get_dpb_size(level, pic_size);
265
266
267 max_num_bufs = (2 * max_dpb_size + 1);
268 /* If num_ref_frames and num_reorder_frmaes is specified
269 * Use minimum value
270 */
271 max_num_bufs = MIN(max_num_bufs, init_num_bufs);
272
273 /*
274 * Add extra buffers if required
275 */
276 max_num_bufs += init_extra_bufs;
277 max_num_bufs = MIN(max_num_bufs, BUF_MGR_MAX_CNT);
278
279 /* Get level index */
280 lvl_idx = ihevcd_get_lvl_idx(level);
281
282
283 /* Maximum width of luma samples in a picture at given level */
284 max_wd = ALIGN64(gai4_ihevc_max_wd_ht[lvl_idx]);
285
286 /* Minimum height of luma samples in a picture at given level */
287 min_ht = ALIGN64(gai4_ihevc_min_wd_ht[lvl_idx]);
288
289 /* Use max_wd and min_ht to get maximum number of luma samples for given level */
290 /* Because max_wd and min_ht are aligned to 64, product will be higher than the
291 * value given by the spec for a given level
292 */
293 num_luma_samples = max_wd * min_ht;
294
295 /* Allocation is required for
296 * (Wd + horz_pad) * (Ht + vert_pad) * (2 * max_dpb_size + 1)
297 *
298 * Above expanded as
299 * ((Wd * Ht) + (horz_pad * vert_pad) + Wd * vert_pad + Ht * horz_pad) * (2 * max_dpb_size + 1)
300 * (Wd * Ht) * (2 * max_dpb_size + 1) + ((horz_pad * vert_pad) + Wd * vert_pad + Ht * horz_pad) * (2 * max_dpb_size + 1)
301 * Now max_dpb_size increases with smaller Wd and Ht, but Wd * ht * max_dpb_size will still be lesser or equal to max_wd * max_ht * dpb_size
302 *
303 * In the above equation (Wd * Ht) * (2 * max_dpb_size + 1) is accounted by using num_samples * (2 * max_dpb_size + 1) below
304 *
305 * For the padded area use MAX(horz_pad, vert_pad) as pad
306 * ((pad * pad) + pad * (Wd + Ht)) * (2 * max_dpb_size + 1) has to accounted from the above for padding
307 *
308 * Since Width and Height can change worst Wd + Ht is when One of the dimensions is max and other is min
309 * So use max_wd and min_ht
310 */
311
312 /* Account for padding area */
313
314 num_luma_samples += (pad * pad) + pad * (max_wd + min_ht);
315
316 /* Account for chroma */
317 if(0 == chroma_only)
318 num_samples = num_luma_samples * 3 / 2;
319 else
320 num_samples = num_luma_samples / 2;
321
322 /* Number of bytes in reference pictures */
323 size = num_samples * max_num_bufs;
324
325
326 return size;
327 }
328 /**
329 *******************************************************************************
330 *
331 * @brief
332 * Used to get MV bank size for a given number of luma samples
333 *
334 * @par Description:
335 * For given number of luma samples one MV bank size is computed
336 * Each MV bank includes pu_map and pu_t for all the min PUs(4x4) in a picture
337 *
338 * @param[in] num_luma_samples
339 * Max number of luma pixels in the frame
340 *
341 * @returns Total MV Bank size
342 *
343 * @remarks
344 *
345 *
346 *******************************************************************************
347 */
ihevcd_get_pic_mv_bank_size(WORD32 num_luma_samples)348 WORD32 ihevcd_get_pic_mv_bank_size(WORD32 num_luma_samples)
349 {
350 WORD32 size;
351
352 WORD32 pic_size;
353
354 WORD32 mv_bank_size;
355 WORD32 num_pu;
356 WORD32 num_ctb;
357 pic_size = num_luma_samples;
358
359
360 num_pu = pic_size / (MIN_PU_SIZE * MIN_PU_SIZE);
361 num_ctb = pic_size / (MIN_CTB_SIZE * MIN_CTB_SIZE);
362
363 mv_bank_size = 0;
364
365 /* Size for storing pu_t start index each CTB */
366 /* One extra entry is needed to compute number of PUs in the last CTB */
367 mv_bank_size += (num_ctb + 1) * sizeof(WORD32);
368
369 /* Size for pu_map */
370 mv_bank_size += num_pu;
371
372 /* Size for storing pu_t for each PU */
373 mv_bank_size += num_pu * sizeof(pu_t);
374
375 size = mv_bank_size;
376 return size;
377 }
378 /**
379 *******************************************************************************
380 *
381 * @brief
382 * Used to get TU data size for a given number luma samples
383 *
384 * @par Description:
385 * For a given number of luma samples TU data size is computed
386 * Each TU data includes tu_map and tu_t and coeff data for all
387 * the min TUs(4x4) in given CTB
388 *
389 * @param[in] num_luma_samples
390 * Number of 64 x 64 CTBs for which TU data has to be allocated.
391 *
392 * @returns Total TU data size
393 *
394 * @remarks Assumption is num_luma_samples will be at least
395 * 64 x 64 to handle CTB of size 64 x 64. Can be frame size as well
396 *
397 *******************************************************************************
398 */
ihevcd_get_tu_data_size(WORD32 num_luma_samples)399 WORD32 ihevcd_get_tu_data_size(WORD32 num_luma_samples)
400 {
401
402
403 WORD32 tu_data_size;
404 WORD32 num_ctb;
405 WORD32 num_luma_tu, num_chroma_tu, num_tu;
406 num_ctb = num_luma_samples / (MIN_CTB_SIZE * MIN_CTB_SIZE);
407
408 num_luma_tu = num_luma_samples / (MIN_TU_SIZE * MIN_TU_SIZE);
409 num_chroma_tu = num_luma_tu >> 1;
410
411 num_tu = num_luma_tu + num_chroma_tu;
412 tu_data_size = 0;
413
414 /* Size for storing tu_t start index each CTB */
415 /* One extra entry is needed to compute number of TUs in the last CTB */
416 tu_data_size += (num_ctb + 1) * sizeof(WORD32);
417
418 /* Size for storing tu map */
419 tu_data_size += num_luma_tu * sizeof(UWORD8);
420
421 /* Size for storing tu_t for each TU */
422 tu_data_size += num_tu * sizeof(tu_t);
423
424 /* Size for storing number of coded subblocks and scan_idx for each TU */
425 tu_data_size += num_tu * (sizeof(WORD8) + sizeof(WORD8));
426
427 /* Size for storing coeff data for each TU */
428 tu_data_size += num_tu * sizeof(tu_sblk_coeff_data_t);
429
430
431 return tu_data_size;
432 }
433
434
ihevcd_nctb_cnt(codec_t * ps_codec,sps_t * ps_sps)435 WORD32 ihevcd_nctb_cnt(codec_t *ps_codec, sps_t *ps_sps)
436 {
437 WORD32 nctb = 1;
438 UNUSED(ps_codec);
439 //TODO: Currently set to 1
440 /* If CTB size is less than 32 x 32 then set nCTB as 4 */
441 if(ps_sps->i1_log2_ctb_size < 5)
442 nctb = 1;
443
444 return nctb;
445 }
446
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)447 IHEVCD_ERROR_T ihevcd_get_tile_pos(pps_t *ps_pps,
448 sps_t *ps_sps,
449 WORD32 ctb_x,
450 WORD32 ctb_y,
451 WORD32 *pi4_ctb_tile_x,
452 WORD32 *pi4_ctb_tile_y,
453 WORD32 *pi4_tile_idx)
454 {
455
456 tile_t *ps_tile_tmp;
457 WORD32 i;
458 WORD32 tile_row, tile_col;
459
460 if(ctb_x < 0 || ctb_y < 0)
461 {
462 *pi4_ctb_tile_x = 0;
463 *pi4_ctb_tile_y = 0;
464 *pi4_tile_idx = 0;
465
466 return (IHEVCD_ERROR_T)IHEVCD_SUCCESS;
467 }
468
469 tile_row = 0;
470 tile_col = 0;
471 ps_tile_tmp = ps_pps->ps_tile;
472 if(0 == ps_pps->i1_tiles_enabled_flag)
473 {
474 *pi4_ctb_tile_x = ctb_x;
475 *pi4_ctb_tile_y = ctb_y;
476 *pi4_tile_idx = 0;
477 }
478 else
479 {
480 for(i = 0; i < ps_pps->i1_num_tile_columns; i++)
481 {
482 WORD16 next_tile_ctb_x;
483 ps_tile_tmp = ps_pps->ps_tile + i; //* ps_pps->i1_num_tile_rows;
484 if((ps_pps->i1_num_tile_columns - 1) == i)
485 {
486 next_tile_ctb_x = ps_sps->i2_pic_wd_in_ctb;
487 }
488 else
489 {
490 tile_t *ps_tile_next_tmp;
491 ps_tile_next_tmp = ps_pps->ps_tile + i + 1;
492 next_tile_ctb_x = ps_tile_next_tmp->u1_pos_x;
493 }
494 if((ctb_x >= ps_tile_tmp->u1_pos_x) && (ctb_x < next_tile_ctb_x))
495 {
496 tile_col = i;
497 break;
498 }
499 }
500 *pi4_ctb_tile_x = ctb_x - ps_tile_tmp->u1_pos_x;
501
502 for(i = 0; i < ps_pps->i1_num_tile_rows; i++)
503 {
504 WORD16 next_tile_ctb_y;
505 ps_tile_tmp = ps_pps->ps_tile + i * ps_pps->i1_num_tile_columns;
506 if((ps_pps->i1_num_tile_rows - 1) == i)
507 {
508 next_tile_ctb_y = ps_sps->i2_pic_ht_in_ctb;
509 }
510 else
511 {
512 tile_t *ps_tile_next_tmp;
513 ps_tile_next_tmp = ps_pps->ps_tile + ((i + 1) * ps_pps->i1_num_tile_columns);
514 next_tile_ctb_y = ps_tile_next_tmp->u1_pos_y;
515 }
516 if((ctb_y >= ps_tile_tmp->u1_pos_y) && (ctb_y < next_tile_ctb_y))
517 {
518 tile_row = i;
519 break;
520 }
521
522 }
523 *pi4_ctb_tile_y = ctb_y - ps_tile_tmp->u1_pos_y;
524 *pi4_tile_idx = tile_row * ps_pps->i1_num_tile_columns
525 + tile_col;
526 }
527 return (IHEVCD_ERROR_T)IHEVCD_SUCCESS;
528 }
529 /**
530 *******************************************************************************
531 *
532 * @brief
533 * Function to initialize ps_pic_buf structs add pic buffers to
534 * buffer manager in case of non-shared mode
535 *
536 * @par Description:
537 * Function to initialize ps_pic_buf structs add pic buffers to
538 * buffer manager in case of non-shared mode
539 * To be called once per stream or for every reset
540 *
541 * @param[in] ps_codec
542 * Pointer to codec context
543 *
544 * @returns Error from IHEVCD_ERROR_T
545 *
546 * @remarks
547 *
548 *
549 *******************************************************************************
550 */
ihevcd_pic_buf_mgr_add_bufs(codec_t * ps_codec)551 IHEVCD_ERROR_T ihevcd_pic_buf_mgr_add_bufs(codec_t *ps_codec)
552 {
553 IHEVCD_ERROR_T ret = (IHEVCD_ERROR_T)IHEVCD_SUCCESS;
554 WORD32 i;
555 WORD32 max_dpb_size;
556 sps_t *ps_sps;
557 UWORD8 *pu1_buf;
558 pic_buf_t *ps_pic_buf;
559 WORD32 pic_buf_size_allocated;
560
561 WORD32 max_num_bufs;
562 WORD32 pic_size;
563 WORD32 level;
564
565
566 /* Initialize MV Bank buffer manager */
567 ps_sps = ps_codec->s_parse.ps_sps;
568
569 pic_size = ps_sps->i2_pic_width_in_luma_samples *
570 ps_sps->i2_pic_height_in_luma_samples;
571
572
573 /* Compute the number of MB Bank buffers needed */
574 level = ps_codec->i4_init_level;
575 max_dpb_size = ihevcd_get_dpb_size(level, pic_size);
576 /* Allocate twice dpb size to handle worst case reorder without returning more
577 * than one output per call
578 */
579 max_dpb_size *= 2;
580 /* Allocate one extra picture to handle current frame
581 * In case of asynchronous parsing and processing, number of buffers should increase here
582 * based on when parsing and processing threads are synchronized
583 */
584 max_dpb_size++;
585
586 /* If num_ref_frames and num_reorder_frmaes is specified
587 * Use minimum value
588 */
589 max_num_bufs = MIN(max_dpb_size, (ps_codec->i4_init_num_ref + ps_codec->i4_init_num_reorder + 1));
590
591
592 pu1_buf = (UWORD8 *)ps_codec->ps_pic_buf;
593
594 ps_pic_buf = (pic_buf_t *)ps_codec->ps_pic_buf;
595
596 pu1_buf += BUF_MGR_MAX_CNT * sizeof(pic_buf_t);
597
598 /* In case of non-shared mode, add picture buffers to buffer manager
599 * In case of shared mode buffers are added in the run-time
600 */
601 if(0 == ps_codec->i4_share_disp_buf)
602 {
603 WORD32 buf_ret;
604 WORD32 luma_samples;
605 WORD32 chroma_samples;
606 pic_buf_size_allocated = ps_codec->i4_total_pic_buf_size -
607 BUF_MGR_MAX_CNT * sizeof(pic_buf_t);
608
609 luma_samples = (ps_codec->i4_strd) *
610 (ps_sps->i2_pic_height_in_luma_samples + PAD_HT);
611
612 chroma_samples = luma_samples / 2;
613
614 /* Try to add as many buffers as possible since memory is already allocated */
615 /* If the number of buffers that can be added is less than max_num_bufs
616 * return with an error.
617 */
618 for(i = 0; i < (2 * MAX_DPB_SIZE) + 1; i++)
619 {
620 pic_buf_size_allocated -= (luma_samples + chroma_samples);
621
622 if(pic_buf_size_allocated < 0)
623 {
624 if(i < max_num_bufs)
625 {
626 ps_codec->s_parse.i4_error_code = IHEVCD_INSUFFICIENT_MEM_PICBUF;
627 return IHEVCD_INSUFFICIENT_MEM_PICBUF;
628 }
629 break;
630 }
631
632 ps_pic_buf->pu1_luma = pu1_buf + ps_codec->i4_strd * PAD_TOP + PAD_LEFT;
633 pu1_buf += luma_samples;
634
635 ps_pic_buf->pu1_chroma = pu1_buf + ps_codec->i4_strd * (PAD_TOP / 2) + PAD_LEFT;
636 pu1_buf += chroma_samples;
637
638 buf_ret = ihevc_buf_mgr_add((buf_mgr_t *)ps_codec->pv_pic_buf_mgr, ps_pic_buf, i);
639
640 if(0 != buf_ret)
641 {
642 ps_codec->s_parse.i4_error_code = IHEVCD_BUF_MGR_ERROR;
643 return IHEVCD_BUF_MGR_ERROR;
644 }
645 ps_pic_buf++;
646 }
647 }
648
649 return ret;
650 }
651 /**
652 *******************************************************************************
653 *
654 * @brief
655 * Function to add buffers to MV Bank buffer manager
656 *
657 * @par Description:
658 * Function to add buffers to MV Bank buffer manager
659 * To be called once per stream or for every reset
660 *
661 * @param[in] ps_codec
662 * Pointer to codec context
663 *
664 * @returns Error from IHEVCD_ERROR_T
665 *
666 * @remarks
667 *
668 *
669 *******************************************************************************
670 */
ihevcd_mv_buf_mgr_add_bufs(codec_t * ps_codec)671 IHEVCD_ERROR_T ihevcd_mv_buf_mgr_add_bufs(codec_t *ps_codec)
672 {
673 IHEVCD_ERROR_T ret = (IHEVCD_ERROR_T)IHEVCD_SUCCESS;
674 WORD32 i;
675 WORD32 max_dpb_size;
676 WORD32 mv_bank_size_allocated;
677 WORD32 pic_mv_bank_size;
678 WORD32 level;
679 sps_t *ps_sps;
680 UWORD8 *pu1_buf;
681 mv_buf_t *ps_mv_buf;
682
683
684 /* Initialize MV Bank buffer manager */
685 ps_sps = ps_codec->s_parse.ps_sps;
686
687
688 /* Compute the number of MB Bank buffers needed */
689 level = ps_codec->i4_init_level;
690 max_dpb_size = ihevcd_get_dpb_size(level,
691 ps_sps->i2_pic_width_in_luma_samples *
692 ps_sps->i2_pic_height_in_luma_samples);
693
694 /* Allocate one extra MV Bank to handle current frame
695 * In case of asynchronous parsing and processing, number of buffers should increase here
696 * based on when parsing and processing threads are synchronized
697 */
698 max_dpb_size++;
699
700 pu1_buf = (UWORD8 *)ps_codec->pv_mv_bank_buf_base;
701
702 ps_mv_buf = (mv_buf_t *)pu1_buf;
703 pu1_buf += (MAX_DPB_SIZE + 1) * sizeof(mv_buf_t);
704 ps_codec->ps_mv_buf = ps_mv_buf;
705 mv_bank_size_allocated = ps_codec->i4_total_mv_bank_size - (MAX_DPB_SIZE + 1) * sizeof(mv_buf_t);
706
707 /* Compute MV bank size per picture */
708 pic_mv_bank_size = ihevcd_get_pic_mv_bank_size(ps_sps->i2_pic_width_in_luma_samples *
709 ps_sps->i2_pic_height_in_luma_samples);
710
711 for(i = 0; i < max_dpb_size; i++)
712 {
713 WORD32 buf_ret;
714 WORD32 num_pu;
715 WORD32 num_ctb;
716 WORD32 pic_size;
717 pic_size = ALIGN64(ps_sps->i2_pic_width_in_luma_samples) *
718 ALIGN64(ps_sps->i2_pic_height_in_luma_samples);
719
720
721 num_pu = pic_size / (MIN_PU_SIZE * MIN_PU_SIZE);
722 num_ctb = pic_size / (MIN_CTB_SIZE * MIN_CTB_SIZE);
723
724
725 mv_bank_size_allocated -= pic_mv_bank_size;
726
727 if(mv_bank_size_allocated < 0)
728 {
729 ps_codec->s_parse.i4_error_code = IHEVCD_INSUFFICIENT_MEM_MVBANK;
730 return IHEVCD_INSUFFICIENT_MEM_MVBANK;
731 }
732
733 ps_mv_buf->pu4_pic_pu_idx = (UWORD32 *)pu1_buf;
734 pu1_buf += (num_ctb + 1) * sizeof(WORD32);
735
736 ps_mv_buf->pu1_pic_pu_map = pu1_buf;
737 pu1_buf += num_pu;
738
739 ps_mv_buf->pu1_pic_slice_map = (UWORD16 *)pu1_buf;
740 pu1_buf += num_ctb * sizeof(UWORD16);
741
742 ps_mv_buf->ps_pic_pu = (pu_t *)pu1_buf;
743
744 buf_ret = ihevc_buf_mgr_add((buf_mgr_t *)ps_codec->pv_mv_buf_mgr, ps_mv_buf, i);
745
746 if(0 != buf_ret)
747 {
748 ps_codec->s_parse.i4_error_code = IHEVCD_BUF_MGR_ERROR;
749 return IHEVCD_BUF_MGR_ERROR;
750 }
751 pu1_buf += pic_mv_bank_size;
752 ps_mv_buf++;
753
754 }
755 return ret;
756 }
757 /**
758 *******************************************************************************
759 *
760 * @brief
761 * Picture level initializations required during parsing
762 *
763 * @par Description:
764 * Initialize picture level context variables during parsing Initialize mv
765 * bank buffer manager in the first init call
766 *
767 * @param[in] ps_codec
768 * Pointer to codec context
769 *
770 * @returns Error from IHEVCD_ERROR_T
771 *
772 * @remarks
773 *
774 *
775 *******************************************************************************
776 */
ihevcd_parse_pic_init(codec_t * ps_codec)777 IHEVCD_ERROR_T ihevcd_parse_pic_init(codec_t *ps_codec)
778 {
779 IHEVCD_ERROR_T ret = (IHEVCD_ERROR_T)IHEVCD_SUCCESS;
780 mv_buf_t *ps_mv_buf;
781 sps_t *ps_sps;
782 WORD32 num_min_cu;
783 WORD32 cur_pic_buf_id;
784 WORD32 cur_mv_bank_buf_id;
785 pic_buf_t *ps_cur_pic;
786 slice_header_t *ps_slice_hdr;
787 UWORD8 *pu1_cur_pic_luma, *pu1_cur_pic_chroma;
788 WORD32 i;
789
790 ps_codec->s_parse.i4_error_code = IHEVCD_SUCCESS;
791 ps_sps = ps_codec->s_parse.ps_sps;
792 ps_slice_hdr = ps_codec->s_parse.ps_slice_hdr;
793 /* If parse_pic_init is called, then slice data is present in the input bitstrea stream */
794 ps_codec->i4_pic_present = 1;
795
796 /* Memset picture level intra map and transquant bypass map to zero */
797 num_min_cu = ((ps_sps->i2_pic_height_in_luma_samples + 7) / 8) * ((ps_sps->i2_pic_width_in_luma_samples + 63) / 64);
798 memset(ps_codec->s_parse.pu1_pic_intra_flag, 0, num_min_cu);
799 memset(ps_codec->s_parse.pu1_pic_no_loop_filter_flag, 0, num_min_cu);
800
801
802
803 if(0 == ps_codec->s_parse.i4_first_pic_init)
804 {
805 ret = ihevcd_mv_buf_mgr_add_bufs(ps_codec);
806 RETURN_IF((ret != (IHEVCD_ERROR_T)IHEVCD_SUCCESS), ret);
807
808 ret = ihevcd_pic_buf_mgr_add_bufs(ps_codec);
809 RETURN_IF((ret != (IHEVCD_ERROR_T)IHEVCD_SUCCESS), ret);
810
811 ps_codec->s_parse.i4_first_pic_init = 1;
812 }
813
814 /* Initialize all the slice headers' slice addresses to zero */
815 {
816 WORD32 slice_idx;
817 WORD32 slice_start_idx;
818
819 slice_start_idx = ps_codec->i4_slice_error ? 2 : 1;
820
821 for(slice_idx = slice_start_idx; slice_idx < MAX_SLICE_HDR_CNT; slice_idx++)
822 {
823 slice_header_t *ps_slice_hdr_tmp = ps_codec->ps_slice_hdr_base + slice_idx;
824 ps_slice_hdr_tmp->i2_ctb_x = -1;
825 ps_slice_hdr_tmp->i2_ctb_y = -1;
826
827 }
828 }
829
830 /* Get free MV Bank to hold current picture's motion vector data */
831 {
832 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);
833
834 /* If there are no free buffers then return with an error code.
835 * If the buffer is to be freed by another thread , change the
836 * following to call thread yield and wait for buffer to be freed
837 */
838 if(NULL == ps_mv_buf)
839 {
840 ps_codec->s_parse.i4_error_code = IHEVCD_NO_FREE_MVBANK;
841 ps_codec->i4_error_code = IHEVCD_NO_FREE_MVBANK;
842 return IHEVCD_NO_FREE_MVBANK;
843 }
844
845 ps_codec->s_parse.ps_cur_mv_buf = ps_mv_buf;
846 /* Set current ABS poc to ps_mv_buf, so that while freeing a reference buffer
847 * corresponding mv buffer can be found by looping through ps_codec->ps_mv_buf array
848 * and getting a buffer id to free
849 */
850 ps_mv_buf->i4_abs_poc = ps_slice_hdr->i4_abs_pic_order_cnt;
851 }
852
853 /* Get free picture buffer to hold current picture recon data */
854 /* TODO: For asynchronous api the following initializations related to picture
855 * buffer should be moved to processing side
856 */
857 {
858
859 UWORD8 *pu1_buf;
860 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);
861
862 /* If there are no free buffers then return with an error code.
863 * TODO: If the buffer is to be freed by another thread , change the
864 * following to call thread yield and wait for buffer to be freed
865 */
866 if(NULL == ps_cur_pic)
867 {
868 ps_codec->s_parse.i4_error_code = IHEVCD_NO_FREE_PICBUF;
869 ps_codec->i4_error_code = IHEVCD_NO_FREE_PICBUF;
870 return IHEVCD_NO_FREE_PICBUF;
871 }
872
873 /* Store input timestamp sent with input buffer */
874 ps_cur_pic->u4_ts = ps_codec->u4_ts;
875 ps_cur_pic->i4_abs_poc = ps_slice_hdr->i4_abs_pic_order_cnt;
876 ps_cur_pic->i4_poc_lsb = ps_slice_hdr->i4_pic_order_cnt_lsb;
877 pu1_buf = ps_cur_pic->pu1_luma;
878 pu1_cur_pic_luma = pu1_buf;
879
880 pu1_buf = ps_cur_pic->pu1_chroma;
881
882 pu1_cur_pic_chroma = pu1_buf;
883 }
884
885 if(0 == ps_codec->u4_pic_cnt)
886 {
887 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);
888 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);
889 }
890
891 /* Fill the remaining entries of the reference lists with the nearest POC
892 * This is done to handle cases where there is a corruption in the reference index */
893 {
894 pic_buf_t *ps_pic_buf_ref;
895 mv_buf_t *ps_mv_buf_ref;
896 WORD32 r_idx;
897 dpb_mgr_t *ps_dpb_mgr = (dpb_mgr_t *)ps_codec->pv_dpb_mgr;
898 buf_mgr_t *ps_mv_buf_mgr = (buf_mgr_t *)ps_codec->pv_mv_buf_mgr;
899
900 ps_pic_buf_ref = ihevc_dpb_mgr_get_ref_by_nearest_poc(ps_dpb_mgr, ps_slice_hdr->i4_abs_pic_order_cnt);
901 if(NULL == ps_pic_buf_ref)
902 {
903 ps_pic_buf_ref = ps_cur_pic;
904 ps_mv_buf_ref = ps_mv_buf;
905 }
906 else
907 {
908 ps_mv_buf_ref = ihevcd_mv_mgr_get_poc(ps_mv_buf_mgr, ps_pic_buf_ref->i4_abs_poc);
909 }
910
911 for(r_idx = 0; r_idx < ps_slice_hdr->i1_num_ref_idx_l0_active; r_idx++)
912 {
913 if(NULL == ps_slice_hdr->as_ref_pic_list0[r_idx].pv_pic_buf)
914 {
915 ps_slice_hdr->as_ref_pic_list0[r_idx].pv_pic_buf = (void *)ps_pic_buf_ref;
916 ps_slice_hdr->as_ref_pic_list0[r_idx].pv_mv_buf = (void *)ps_mv_buf_ref;
917 }
918 }
919
920 for(r_idx = ps_slice_hdr->i1_num_ref_idx_l0_active; r_idx < MAX_DPB_SIZE; r_idx++)
921 {
922 ps_slice_hdr->as_ref_pic_list0[r_idx].pv_pic_buf = (void *)ps_pic_buf_ref;
923 ps_slice_hdr->as_ref_pic_list0[r_idx].pv_mv_buf = (void *)ps_mv_buf_ref;
924 }
925
926 for(r_idx = 0; r_idx < ps_slice_hdr->i1_num_ref_idx_l1_active; r_idx++)
927 {
928 if(NULL == ps_slice_hdr->as_ref_pic_list1[r_idx].pv_pic_buf)
929 {
930 ps_slice_hdr->as_ref_pic_list1[r_idx].pv_pic_buf = (void *)ps_pic_buf_ref;
931 ps_slice_hdr->as_ref_pic_list1[r_idx].pv_mv_buf = (void *)ps_mv_buf_ref;
932 }
933 }
934
935 for(r_idx = ps_slice_hdr->i1_num_ref_idx_l1_active; r_idx < MAX_DPB_SIZE; r_idx++)
936 {
937 ps_slice_hdr->as_ref_pic_list1[r_idx].pv_pic_buf = (void *)ps_pic_buf_ref;
938 ps_slice_hdr->as_ref_pic_list1[r_idx].pv_mv_buf = (void *)ps_mv_buf_ref;
939 }
940 }
941
942
943 /* Reset the jobq to start of the jobq buffer */
944 ihevcd_jobq_reset((jobq_t *)ps_codec->pv_proc_jobq);
945
946 ps_codec->s_parse.i4_pic_pu_idx = 0;
947 ps_codec->s_parse.i4_pic_tu_idx = 0;
948
949 ps_codec->s_parse.pu1_pic_pu_map = ps_mv_buf->pu1_pic_pu_map;
950 ps_codec->s_parse.ps_pic_pu = ps_mv_buf->ps_pic_pu;
951 ps_codec->s_parse.pu4_pic_pu_idx = ps_mv_buf->pu4_pic_pu_idx;
952 ps_codec->s_parse.pu1_slice_idx = (UWORD16 *)ps_mv_buf->pu1_pic_slice_map;
953 for(i = 0; i < MAX_PROCESS_THREADS; i++)
954 {
955 ps_codec->as_process[i].pu1_slice_idx = (UWORD16 *)ps_mv_buf->pu1_pic_slice_map;
956 }
957 ps_codec->s_parse.pu1_pu_map = ps_codec->s_parse.pu1_pic_pu_map;
958 ps_codec->s_parse.ps_pu = ps_codec->s_parse.ps_pic_pu;
959
960 {
961 UWORD8 *pu1_buf;
962 WORD32 ctb_luma_min_tu_cnt, ctb_chroma_min_tu_cnt, ctb_min_tu_cnt;
963 WORD32 pic_size;
964 WORD32 num_ctb;
965
966 pic_size = ps_sps->i2_pic_width_in_luma_samples *
967 ps_sps->i2_pic_height_in_luma_samples;
968
969 ctb_luma_min_tu_cnt = pic_size / (MIN_TU_SIZE * MIN_TU_SIZE);
970
971 ctb_chroma_min_tu_cnt = ctb_luma_min_tu_cnt >> 1;
972
973 ctb_min_tu_cnt = ctb_luma_min_tu_cnt + ctb_chroma_min_tu_cnt;
974
975 num_ctb = pic_size / (MIN_CTB_SIZE * MIN_CTB_SIZE);
976 pu1_buf = (UWORD8 *)ps_codec->pv_tu_data;
977 ps_codec->s_parse.pu4_pic_tu_idx = (UWORD32 *)pu1_buf;
978 pu1_buf += (num_ctb + 1) * sizeof(WORD32);
979
980 ps_codec->s_parse.pu1_pic_tu_map = pu1_buf;
981 pu1_buf += ctb_min_tu_cnt;
982
983 ps_codec->s_parse.ps_pic_tu = (tu_t *)pu1_buf;
984 pu1_buf += ctb_min_tu_cnt * sizeof(tu_t);
985
986 ps_codec->s_parse.pv_pic_tu_coeff_data = pu1_buf;
987
988 ps_codec->s_parse.pu1_tu_map = ps_codec->s_parse.pu1_pic_tu_map;
989 ps_codec->s_parse.ps_tu = ps_codec->s_parse.ps_pic_tu;
990 ps_codec->s_parse.pv_tu_coeff_data = ps_codec->s_parse.pv_pic_tu_coeff_data;
991 }
992
993 ps_codec->s_parse.s_bs_ctxt.ps_pic_pu = ps_codec->s_parse.ps_pic_pu;
994 ps_codec->s_parse.s_bs_ctxt.pu4_pic_pu_idx = ps_codec->s_parse.pu4_pic_pu_idx;
995 ps_codec->s_parse.s_bs_ctxt.pu4_pic_tu_idx = ps_codec->s_parse.pu4_pic_tu_idx;
996
997
998 /* Set number of CTBs to be processed simultaneously */
999 ps_codec->i4_proc_nctb = ihevcd_nctb_cnt(ps_codec, ps_sps);
1000
1001 /* Memset Parse Map and process map at the start of frame */
1002 //TODO: In case of asynchronous API proc_map can not be set to zero here
1003 {
1004 WORD32 num_ctb;
1005
1006 num_ctb = ps_sps->i4_pic_size_in_ctb;
1007
1008 memset(ps_codec->pu1_parse_map, 0, num_ctb);
1009
1010 memset(ps_codec->pu1_proc_map, 0, num_ctb);
1011 }
1012
1013
1014
1015 /* Initialize disp buf id to -1, this will be updated at the end of frame if there is
1016 * buffer to be displayed
1017 */
1018 ps_codec->i4_disp_buf_id = -1;
1019 ps_codec->ps_disp_buf = NULL;
1020
1021 ps_codec->i4_disable_deblk_pic = 0;
1022 ps_codec->i4_disable_sao_pic = 0;
1023 ps_codec->i4_fullpel_inter_pred = 0;
1024 ps_codec->i4_mv_frac_mask = 0x7FFFFFFF;
1025
1026 /* If degrade is enabled, set the degrade flags appropriately */
1027 if(ps_codec->i4_degrade_type && ps_codec->i4_degrade_pics)
1028 {
1029 WORD32 degrade_pic;
1030 ps_codec->i4_degrade_pic_cnt++;
1031 degrade_pic = 0;
1032
1033 /* If degrade is to be done in all frames, then do not check further */
1034 switch(ps_codec->i4_degrade_pics)
1035 {
1036 case 4:
1037 {
1038 degrade_pic = 1;
1039 break;
1040 }
1041 case 3:
1042 {
1043 if(ps_slice_hdr->i1_slice_type != ISLICE)
1044 degrade_pic = 1;
1045
1046 break;
1047 }
1048 case 2:
1049 {
1050
1051 /* If pic count hits non-degrade interval or it is an islice, then do not degrade */
1052 if((ps_slice_hdr->i1_slice_type != ISLICE) &&
1053 (ps_codec->i4_degrade_pic_cnt != ps_codec->i4_nondegrade_interval))
1054 degrade_pic = 1;
1055
1056 break;
1057 }
1058 case 1:
1059 {
1060 /* Check if the current picture is non-ref */
1061 if((ps_slice_hdr->i1_nal_unit_type < NAL_BLA_W_LP) &&
1062 (ps_slice_hdr->i1_nal_unit_type % 2 == 0))
1063 {
1064 degrade_pic = 1;
1065 }
1066 break;
1067 }
1068
1069
1070 }
1071 if(degrade_pic)
1072 {
1073 if(ps_codec->i4_degrade_type & 0x1)
1074 ps_codec->i4_disable_sao_pic = 1;
1075
1076 if(ps_codec->i4_degrade_type & 0x2)
1077 ps_codec->i4_disable_deblk_pic = 1;
1078
1079 /* MC degrading is done only for non-ref pictures */
1080 if((ps_slice_hdr->i1_nal_unit_type < NAL_BLA_W_LP) &&
1081 (ps_slice_hdr->i1_nal_unit_type % 2 == 0))
1082 {
1083 if(ps_codec->i4_degrade_type & 0x4)
1084 ps_codec->i4_mv_frac_mask = 0;
1085
1086 if(ps_codec->i4_degrade_type & 0x8)
1087 ps_codec->i4_mv_frac_mask = 0;
1088 }
1089 }
1090 else
1091 ps_codec->i4_degrade_pic_cnt = 0;
1092 }
1093
1094
1095 {
1096 WORD32 i;
1097 for(i = 0; i < MAX_PROCESS_THREADS; i++)
1098 {
1099 ps_codec->as_process[i].pu4_pic_pu_idx = ps_codec->s_parse.pu4_pic_pu_idx;
1100 ps_codec->as_process[i].ps_pic_pu = ps_codec->s_parse.ps_pic_pu;
1101 ps_codec->as_process[i].pu1_pic_pu_map = ps_codec->s_parse.pu1_pic_pu_map;
1102 ps_codec->as_process[i].pu4_pic_tu_idx = ps_codec->s_parse.pu4_pic_tu_idx;
1103 ps_codec->as_process[i].ps_pic_tu = ps_codec->s_parse.ps_pic_tu;
1104 ps_codec->as_process[i].pu1_pic_tu_map = ps_codec->s_parse.pu1_pic_tu_map;
1105 ps_codec->as_process[i].pv_pic_tu_coeff_data = ps_codec->s_parse.pv_pic_tu_coeff_data;
1106 ps_codec->as_process[i].i4_cur_mv_bank_buf_id = cur_mv_bank_buf_id;
1107 ps_codec->as_process[i].s_sao_ctxt.pu1_slice_idx = ps_codec->as_process[i].pu1_slice_idx;
1108 ps_codec->as_process[i].s_sao_ctxt.pu1_tile_idx = ps_codec->as_process[i].pu1_tile_idx;
1109
1110 /* TODO: For asynchronous api the following initializations related to picture
1111 * buffer should be moved to processing side
1112 */
1113 ps_codec->as_process[i].pu1_cur_pic_luma = pu1_cur_pic_luma;
1114 ps_codec->as_process[i].pu1_cur_pic_chroma = pu1_cur_pic_chroma;
1115 ps_codec->as_process[i].ps_cur_pic = ps_cur_pic;
1116 ps_codec->as_process[i].i4_cur_pic_buf_id = cur_pic_buf_id;
1117
1118 ps_codec->as_process[i].ps_out_buffer = ps_codec->ps_out_buffer;
1119 if(1 < ps_codec->i4_num_cores)
1120 {
1121 ps_codec->as_process[i].i4_check_parse_status = 1;
1122 ps_codec->as_process[i].i4_check_proc_status = 1;
1123 }
1124 else
1125 {
1126 ps_codec->as_process[i].i4_check_parse_status = 0;
1127 ps_codec->as_process[i].i4_check_proc_status = 0;
1128 }
1129 ps_codec->as_process[i].pu1_pic_intra_flag = ps_codec->s_parse.pu1_pic_intra_flag;
1130 ps_codec->as_process[i].pu1_pic_no_loop_filter_flag = ps_codec->s_parse.pu1_pic_no_loop_filter_flag;
1131 ps_codec->as_process[i].i4_init_done = 0;
1132
1133 ps_codec->as_process[i].s_bs_ctxt.pu4_pic_tu_idx = ps_codec->as_process[i].pu4_pic_tu_idx;
1134 ps_codec->as_process[i].s_bs_ctxt.pu4_pic_pu_idx = ps_codec->as_process[i].pu4_pic_pu_idx;
1135 ps_codec->as_process[i].s_bs_ctxt.ps_pic_pu = ps_codec->as_process[i].ps_pic_pu;
1136 ps_codec->as_process[i].s_deblk_ctxt.pu1_pic_no_loop_filter_flag = ps_codec->s_parse.pu1_pic_no_loop_filter_flag;
1137 ps_codec->as_process[i].s_deblk_ctxt.pu1_cur_pic_luma = pu1_cur_pic_luma;
1138 ps_codec->as_process[i].s_deblk_ctxt.pu1_cur_pic_chroma = pu1_cur_pic_chroma;
1139 ps_codec->as_process[i].s_sao_ctxt.pu1_pic_no_loop_filter_flag = ps_codec->s_parse.pu1_pic_no_loop_filter_flag;
1140 ps_codec->as_process[i].s_sao_ctxt.pu1_cur_pic_luma = pu1_cur_pic_luma;
1141 ps_codec->as_process[i].s_sao_ctxt.pu1_cur_pic_chroma = pu1_cur_pic_chroma;
1142 if(i < (ps_codec->i4_num_cores - 1))
1143 {
1144 ithread_create(ps_codec->apv_process_thread_handle[i], NULL,
1145 (void *)ihevcd_process_thread,
1146 (void *)&ps_codec->as_process[i]);
1147 ps_codec->ai4_process_thread_created[i] = 1;
1148 }
1149 else
1150 {
1151 ps_codec->ai4_process_thread_created[i] = 0;
1152 }
1153
1154 }
1155 ps_codec->s_parse.s_deblk_ctxt.pu1_cur_pic_luma = pu1_cur_pic_luma;
1156 ps_codec->s_parse.s_deblk_ctxt.pu1_cur_pic_chroma = pu1_cur_pic_chroma;
1157
1158 ps_codec->s_parse.s_sao_ctxt.pu1_cur_pic_luma = pu1_cur_pic_luma;
1159 ps_codec->s_parse.s_sao_ctxt.pu1_cur_pic_chroma = pu1_cur_pic_chroma;
1160 }
1161 /* Since any input bitstream buffer that contains slice data will be sent to output(even in
1162 * case of error, this buffer is added to display queue and next buffer in the display queue
1163 * will be returned as the display buffer.
1164 * Note: If format conversion (or frame copy) is used and is scheduled
1165 * in a different thread then it has to check if the processing for the current row is complete before
1166 * it copies/converts a given row. In case of low delay or in case of B pictures, current frame being decoded has to be
1167 * returned, which requires a status check to ensure that the current row is reconstructed before copying.
1168 */
1169 /* Add current picture to display manager */
1170 {
1171 WORD32 abs_poc;
1172 slice_header_t *ps_slice_hdr;
1173 ps_slice_hdr = ps_codec->s_parse.ps_slice_hdr;
1174 abs_poc = ps_slice_hdr->i4_abs_pic_order_cnt;
1175 ihevc_disp_mgr_add((disp_mgr_t *)ps_codec->pv_disp_buf_mgr,
1176 ps_codec->as_process[0].i4_cur_pic_buf_id,
1177 abs_poc,
1178 ps_codec->as_process[0].ps_cur_pic);
1179 }
1180 ps_codec->ps_disp_buf = NULL;
1181 /* Get picture to be displayed if number of pictures decoded is more than max allowed reorder */
1182 /* Since the current will be decoded, check is fore >= instead of > */
1183 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]) ||
1184 ((WORD32)(ps_codec->u4_pic_cnt - ps_codec->u4_disp_cnt) >= ps_codec->i4_init_num_reorder))
1185
1186 {
1187 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);
1188 ps_codec->u4_disp_cnt++;
1189 }
1190
1191 ps_codec->s_fmt_conv.i4_cur_row = 0;
1192 /* Set number of rows to be processed at a time */
1193 ps_codec->s_fmt_conv.i4_num_rows = 4;
1194
1195 if(ps_codec->u4_enable_fmt_conv_ahead && (ps_codec->i4_num_cores > 1))
1196 {
1197 process_ctxt_t *ps_proc;
1198
1199 /* i4_num_cores - 1 contexts are currently being used by other threads */
1200 ps_proc = &ps_codec->as_process[ps_codec->i4_num_cores - 1];
1201
1202 /* If the frame being decoded and displayed are different, schedule format conversion jobs
1203 * this will keep the proc threads busy and lets parse thread decode few CTBs ahead
1204 * If the frame being decoded and displayed are same, then format conversion is scheduled later.
1205 */
1206 if((ps_codec->ps_disp_buf) && (ps_codec->i4_disp_buf_id != ps_proc->i4_cur_pic_buf_id) &&
1207 ((0 == ps_codec->i4_share_disp_buf) || (IV_YUV_420P == ps_codec->e_chroma_fmt)))
1208 {
1209
1210 for(i = 0; i < ps_sps->i2_pic_ht_in_ctb; i++)
1211 {
1212 proc_job_t s_job;
1213 IHEVCD_ERROR_T ret;
1214 s_job.i4_cmd = CMD_FMTCONV;
1215 s_job.i2_ctb_cnt = 0;
1216 s_job.i2_ctb_x = 0;
1217 s_job.i2_ctb_y = i;
1218 s_job.i2_slice_idx = 0;
1219 s_job.i4_tu_coeff_data_ofst = 0;
1220 ret = ihevcd_jobq_queue((jobq_t *)ps_codec->s_parse.pv_proc_jobq,
1221 &s_job, sizeof(proc_job_t), 1);
1222 if(ret != (IHEVCD_ERROR_T)IHEVCD_SUCCESS)
1223 return ret;
1224 }
1225 }
1226 }
1227
1228
1229 return ret;
1230 }
1231
1232
1233