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