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