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_decode.c
22 *
23 * @brief
24 *  Contains codecs main decode function
25 *
26 * @author
27 *  Harish
28 *
29 * @par List of Functions:
30 * - fill_outargs()
31 * - ihevcd_decode
32 * @remarks
33 *  None
34 *
35 *******************************************************************************
36 */
37/*****************************************************************************/
38/* File Includes                                                             */
39/*****************************************************************************/
40#include <stdio.h>
41#include <stddef.h>
42#include <stdlib.h>
43#include <string.h>
44#include <assert.h>
45
46#include "ihevc_typedefs.h"
47#include "iv.h"
48#include "ivd.h"
49#include "ihevcd_cxa.h"
50#include "ithread.h"
51
52#include "ihevc_defs.h"
53#include "ihevc_debug.h"
54#include "ihevc_structs.h"
55#include "ihevc_macros.h"
56#include "ihevc_platform_macros.h"
57#include "ihevc_cabac_tables.h"
58#include "ihevc_disp_mgr.h"
59#include "ihevc_buf_mgr.h"
60#include "ihevc_dpb_mgr.h"
61#include "ihevc_error.h"
62
63#include "ihevcd_defs.h"
64#include "ihevcd_function_selector.h"
65#include "ihevcd_structs.h"
66#include "ihevcd_error.h"
67#include "ihevcd_nal.h"
68#include "ihevcd_bitstream.h"
69#include "ihevcd_fmt_conv.h"
70#include "ihevcd_job_queue.h"
71#include "ihevcd_debug.h"
72#include "ihevcd_process_slice.h"
73#include "ihevcd_ittiam_logo.h"
74#include "ihevcd_profile.h"
75
76#define NUM_FRAMES_LIMIT_ENABLED 0
77
78#if NUM_FRAMES_LIMIT_ENABLED
79#define NUM_FRAMES_LIMIT 10000
80#else
81#define NUM_FRAMES_LIMIT 0x7FFFFFFF
82#endif
83
84IHEVCD_ERROR_T ihevcd_check_out_buf_size(codec_t *ps_codec);
85IHEVCD_ERROR_T ihevcd_fmt_conv(codec_t *ps_codec,
86                               process_ctxt_t *ps_proc,
87                               UWORD8 *pu1_y_dst,
88                               UWORD8 *pu1_u_dst,
89                               UWORD8 *pu1_v_dst,
90                               WORD32 cur_row,
91                               WORD32 num_rows);
92WORD32 ihevcd_init(codec_t *ps_codec);
93
94WORD32 ihevcd_allocate_dynamic_bufs(codec_t *ps_codec);
95WORD32 ihevcd_free_dynamic_bufs(codec_t *ps_codec);
96/*****************************************************************************/
97/* Function Prototypes                                                       */
98/*****************************************************************************/
99
100
101/**
102 *******************************************************************************
103 *
104 * @brief Fills output arguments for decode process
105 *
106 * @par   Description
107 * Fills elements in the output structure based on the current state
108 *
109 * @param[in] ps_codec
110 * Codec context
111 *
112 * @param[in] ps_dec_ip
113 * Pointer to input structure
114 *
115 * @param[in] ps_dec_op
116 * Pointer to output structure
117 *
118 * @returns none
119 *
120 * @remarks
121 *
122 *******************************************************************************
123 */
124static UWORD32 ihevcd_map_error(IHEVCD_ERROR_T e_error)
125{
126    UWORD32 error_code = 0;
127    error_code = e_error;
128    switch(error_code)
129    {
130        case IHEVCD_SUCCESS :
131            break;
132        case IHEVCD_INIT_NOT_DONE:
133        case IHEVCD_LEVEL_UNSUPPORTED:
134        case IHEVCD_NUM_REF_UNSUPPORTED:
135        case IHEVCD_NUM_REORDER_UNSUPPORTED:
136        case IHEVCD_NUM_EXTRA_DISP_UNSUPPORTED:
137        case IHEVCD_INSUFFICIENT_MEM_MVBANK:
138        case IHEVCD_INSUFFICIENT_MEM_PICBUF:
139            error_code |= 1 << IVD_FATALERROR;
140            break;
141        case IHEVCD_INVALID_DISP_STRD:
142        case IHEVCD_CXA_VERS_BUF_INSUFFICIENT:
143        case IHEVCD_UNSUPPORTED_VPS_ID:
144        case IHEVCD_UNSUPPORTED_SPS_ID:
145        case IHEVCD_UNSUPPORTED_PPS_ID:
146        case IHEVCD_UNSUPPORTED_CHROMA_FMT_IDC:
147        case IHEVCD_UNSUPPORTED_BIT_DEPTH:
148        case IHEVCD_BUF_MGR_ERROR:
149        case IHEVCD_NO_FREE_MVBANK:
150        case IHEVCD_NO_FREE_PICBUF:
151        case IHEVCD_SLICE_IN_HEADER_MODE:
152        case IHEVCD_END_OF_SEQUENCE:
153            break;
154        default:
155            break;
156    }
157    return error_code;
158}
159/**
160 *******************************************************************************
161 *
162 * @brief Fills output arguments for decode process
163 *
164 * @par   Description
165 * Fills elements in the output structure based on the current state
166 *
167 * @param[in] ps_codec
168 * Codec context
169 *
170 * @param[in] ps_dec_ip
171 * Pointer to input structure
172 *
173 * @param[in] ps_dec_op
174 * Pointer to output structure
175 *
176 * @returns none
177 *
178 * @remarks
179 *
180 *******************************************************************************
181 */
182static void ihevcd_fill_outargs(codec_t *ps_codec,
183                                ivd_video_decode_ip_t *ps_dec_ip,
184                                ivd_video_decode_op_t *ps_dec_op)
185{
186
187    ps_dec_op->u4_error_code = ihevcd_map_error((IHEVCD_ERROR_T)ps_codec->i4_error_code);
188    ps_dec_op->u4_num_bytes_consumed = ps_dec_ip->u4_num_Bytes
189                    - ps_codec->i4_bytes_remaining;
190    if(ps_codec->i4_sps_done)
191    {
192        ps_dec_op->u4_pic_wd = ps_codec->i4_disp_wd;
193        ps_dec_op->u4_pic_ht = ps_codec->i4_disp_ht;
194    }
195    else
196    {
197        ps_dec_op->u4_pic_wd = 0;
198        ps_dec_op->u4_pic_ht = 0;
199    }
200
201    ps_dec_op->e_pic_type = ps_codec->e_dec_pic_type;
202    ps_dec_op->u4_frame_decoded_flag = ps_codec->i4_pic_present;
203    ps_dec_op->u4_new_seq = 0;
204
205    ps_dec_op->u4_output_present = 0;
206    ps_dec_op->u4_progressive_frame_flag = 1;
207    if(ps_codec->i4_sps_done)
208    {
209        sps_t *ps_sps = (ps_codec->s_parse.ps_sps_base + ps_codec->i4_sps_id);
210        profile_tier_lvl_info_t *ps_ptl;
211        ps_ptl = &ps_sps->s_ptl;
212        if((0 == ps_ptl->s_ptl_gen.i1_general_progressive_source_flag) &&
213           (1 == ps_ptl->s_ptl_gen.i1_general_interlaced_source_flag))
214        {
215            ps_dec_op->u4_progressive_frame_flag = 0;
216        }
217    }
218
219    ps_dec_op->u4_is_ref_flag = 1;
220    ps_dec_op->e_output_format = ps_codec->e_chroma_fmt;
221    ps_dec_op->u4_is_ref_flag = 1;
222
223    ps_dec_op->e4_fld_type = IV_FLD_TYPE_DEFAULT;
224
225    ps_dec_op->u4_ts = (UWORD32)(-1);
226    ps_dec_op->u4_disp_buf_id = ps_codec->i4_disp_buf_id;
227    if(ps_codec->i4_flush_mode)
228    {
229        ps_dec_op->u4_num_bytes_consumed = 0;
230        /*In the case of flush ,since no frame is decoded set pic type as invalid*/
231        ps_dec_op->u4_is_ref_flag = 0;
232        ps_dec_op->e_pic_type = IV_NA_FRAME;
233        ps_dec_op->u4_frame_decoded_flag = 0;
234
235    }
236    /* If there is a display buffer */
237    if(ps_codec->ps_disp_buf)
238    {
239        pic_buf_t *ps_disp_buf = ps_codec->ps_disp_buf;
240        sei_params_t *ps_sei = &ps_disp_buf->s_sei_params;
241
242        if(ps_sei->i1_sei_parameters_present_flag &&
243           ps_sei->i1_pic_timing_params_present_flag)
244        {
245            UWORD32 u4_pic_struct;
246            u4_pic_struct = ps_sei->s_pic_timing_sei_params.u4_pic_struct;
247            switch(u4_pic_struct)
248            {
249                case 1:
250                    ps_dec_op->e4_fld_type = IV_TOP_FLD;
251                    ps_dec_op->u4_progressive_frame_flag = 0;
252                    break;
253                case 2:
254                    ps_dec_op->e4_fld_type = IV_BOT_FLD;
255                    ps_dec_op->u4_progressive_frame_flag = 0;
256                    break;
257                case 0:
258                default:
259                    ps_dec_op->e4_fld_type = IV_FLD_TYPE_DEFAULT;
260                    ps_dec_op->u4_progressive_frame_flag = 1;
261                    break;
262            }
263        }
264        ps_dec_op->u4_output_present = 1;
265        ps_dec_op->u4_ts = ps_disp_buf->u4_ts;
266        if((ps_codec->i4_flush_mode == 0) && (ps_codec->s_parse.i4_end_of_frame == 0))
267            ps_dec_op->u4_output_present = 0;
268        ps_dec_op->s_disp_frm_buf.u4_y_wd = ps_codec->i4_disp_wd;
269        ps_dec_op->s_disp_frm_buf.u4_y_ht = ps_codec->i4_disp_ht;
270
271        if(ps_codec->i4_share_disp_buf)
272        {
273            ps_dec_op->s_disp_frm_buf.pv_y_buf = ps_disp_buf->pu1_luma;
274            if(ps_codec->e_chroma_fmt != IV_YUV_420P)
275            {
276                ps_dec_op->s_disp_frm_buf.pv_u_buf = ps_disp_buf->pu1_chroma;
277                ps_dec_op->s_disp_frm_buf.pv_v_buf = NULL;
278            }
279            else
280            {
281                WORD32 i;
282                UWORD8 *pu1_u_dst = NULL, *pu1_v_dst = NULL;
283                for(i = 0; i < ps_codec->i4_share_disp_buf_cnt; i++)
284                {
285                    WORD32 diff = ps_disp_buf->pu1_luma - ps_codec->s_disp_buffer[i].pu1_bufs[0];
286                    if(diff == (ps_codec->i4_strd * PAD_TOP + PAD_LEFT))
287                    {
288                        pu1_u_dst = ps_codec->s_disp_buffer[i].pu1_bufs[1];
289                        pu1_u_dst += (ps_codec->i4_strd * PAD_TOP) / 4 + (PAD_LEFT / 2);
290
291                        pu1_v_dst = ps_codec->s_disp_buffer[i].pu1_bufs[2];
292                        pu1_v_dst += (ps_codec->i4_strd * PAD_TOP) / 4 + (PAD_LEFT / 2);
293                        break;
294                    }
295                }
296                ps_dec_op->s_disp_frm_buf.pv_u_buf = pu1_u_dst;
297                ps_dec_op->s_disp_frm_buf.pv_v_buf = pu1_v_dst;
298            }
299            ps_dec_op->s_disp_frm_buf.u4_y_strd = ps_codec->i4_strd;
300        }
301        else
302        {
303            ps_dec_op->s_disp_frm_buf.pv_y_buf =
304                            ps_dec_ip->s_out_buffer.pu1_bufs[0];
305            ps_dec_op->s_disp_frm_buf.pv_u_buf =
306                            ps_dec_ip->s_out_buffer.pu1_bufs[1];
307            ps_dec_op->s_disp_frm_buf.pv_v_buf =
308                            ps_dec_ip->s_out_buffer.pu1_bufs[2];
309            ps_dec_op->s_disp_frm_buf.u4_y_strd = ps_codec->i4_disp_strd;
310        }
311
312        if((IV_YUV_420SP_VU == ps_codec->e_chroma_fmt)
313                        || (IV_YUV_420SP_UV == ps_codec->e_chroma_fmt))
314        {
315            ps_dec_op->s_disp_frm_buf.u4_u_strd =
316                            ps_dec_op->s_disp_frm_buf.u4_y_strd;
317            ps_dec_op->s_disp_frm_buf.u4_v_strd = 0;
318            ps_dec_op->s_disp_frm_buf.u4_u_wd =
319                            ps_dec_op->s_disp_frm_buf.u4_y_wd;
320            ps_dec_op->s_disp_frm_buf.u4_v_wd = 0;
321            ps_dec_op->s_disp_frm_buf.u4_u_ht =
322                            ps_dec_op->s_disp_frm_buf.u4_y_ht / 2;
323            ps_dec_op->s_disp_frm_buf.u4_v_ht = 0;
324        }
325        else if(IV_YUV_420P == ps_codec->e_chroma_fmt)
326        {
327            ps_dec_op->s_disp_frm_buf.u4_u_strd =
328                            ps_dec_op->s_disp_frm_buf.u4_y_strd / 2;
329            ps_dec_op->s_disp_frm_buf.u4_v_strd =
330                            ps_dec_op->s_disp_frm_buf.u4_y_strd / 2;
331            ps_dec_op->s_disp_frm_buf.u4_u_wd =
332                            ps_dec_op->s_disp_frm_buf.u4_y_wd / 2;
333            ps_dec_op->s_disp_frm_buf.u4_v_wd =
334                            ps_dec_op->s_disp_frm_buf.u4_y_wd / 2;
335            ps_dec_op->s_disp_frm_buf.u4_u_ht =
336                            ps_dec_op->s_disp_frm_buf.u4_y_ht / 2;
337            ps_dec_op->s_disp_frm_buf.u4_v_ht =
338                            ps_dec_op->s_disp_frm_buf.u4_y_ht / 2;
339        }
340
341    }
342    else if(ps_codec->i4_flush_mode)
343    {
344        ps_dec_op->u4_error_code = IHEVCD_END_OF_SEQUENCE;
345        /* Come out of flush mode */
346        ps_codec->i4_flush_mode = 0;
347    }
348
349}
350
351/**
352 *******************************************************************************
353 *
354 * @brief
355 *  Codec process call
356 *
357 * @par Description:
358 *  Codec process call  Tests for few error checks  Handle flush and decode
359 * header related code  Parse bitstream for start codes  For each NAL unit
360 * call decode NAL function  Once a complete frame is decoded (in frame
361 * decode mode)  Fill output arguments and return
362 *
363 * @param[in] ps_codec_obj
364 *  Pointer to codec object at API level
365 *
366 * @param[in] pv_api_ip
367 *  Pointer to input argument structure
368 *
369 * @param[in] pv_api_op
370 *  Pointer to output argument structure
371 *
372 * @returns  Status
373 *
374 * @remarks
375 *
376 *
377 *******************************************************************************
378 */
379WORD32 ihevcd_decode(iv_obj_t *ps_codec_obj, void *pv_api_ip, void *pv_api_op)
380{
381    WORD32 ret = IV_SUCCESS;
382    codec_t *ps_codec = (codec_t *)(ps_codec_obj->pv_codec_handle);
383    ivd_video_decode_ip_t *ps_dec_ip;
384    ivd_video_decode_op_t *ps_dec_op;
385
386    WORD32 proc_idx = 0;
387    WORD32 prev_proc_idx = 0;
388
389    /* Initialize error code */
390    ps_codec->i4_error_code = 0;
391
392    ps_dec_ip = (ivd_video_decode_ip_t *)pv_api_ip;
393    ps_dec_op = (ivd_video_decode_op_t *)pv_api_op;
394
395    {
396        UWORD32 u4_size = ps_dec_op->u4_size;
397        memset(ps_dec_op, 0, sizeof(ivd_video_decode_op_t));
398        ps_dec_op->u4_size = u4_size; //Restore size field
399    }
400    if(ps_codec->i4_init_done != 1)
401    {
402        ps_dec_op->u4_error_code |= 1 << IVD_FATALERROR;
403        ps_dec_op->u4_error_code |= IHEVCD_INIT_NOT_DONE;
404        return IV_FAIL;
405    }
406
407    if(ps_codec->u4_pic_cnt >= NUM_FRAMES_LIMIT)
408    {
409        ps_dec_op->u4_error_code |= 1 << IVD_FATALERROR;
410        ps_dec_op->u4_error_code |= IHEVCD_NUM_FRAMES_LIMIT_REACHED;
411        return IV_FAIL;
412    }
413
414    /* If reset flag is set, flush the existing buffers */
415    if(ps_codec->i4_reset_flag)
416    {
417        ps_codec->i4_flush_mode = 1;
418    }
419
420    /*Data memory barries instruction,so that bitstream write by the application is complete*/
421    //arm_dsb();
422    /* In case the decoder is not in flush mode check for input buffer validity */
423    if(0 == ps_codec->i4_flush_mode)
424    {
425        if(ps_dec_ip->pv_stream_buffer == NULL)
426        {
427            ps_dec_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM;
428            ps_dec_op->u4_error_code |= IVD_DEC_FRM_BS_BUF_NULL;
429            return IV_FAIL;
430        }
431        if(ps_dec_ip->u4_num_Bytes <= MIN_START_CODE_LEN)
432        {
433            if((WORD32)ps_dec_ip->u4_num_Bytes > 0)
434                ps_dec_op->u4_num_bytes_consumed = ps_dec_ip->u4_num_Bytes;
435            else
436                ps_dec_op->u4_num_bytes_consumed = 0;
437
438            ps_dec_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM;
439            ps_dec_op->u4_error_code |= IVD_DEC_NUMBYTES_INV;
440            return IV_FAIL;
441
442        }
443    }
444
445#ifdef APPLY_CONCEALMENT
446    {
447        WORD32 num_mbs;
448
449        num_mbs = (ps_codec->i4_wd * ps_codec->i4_ht + 255) >> 8;
450        /* Reset MB Count at the beginning of every process call */
451        ps_codec->mb_count = 0;
452        memset(ps_codec->mb_map, 0, ((num_mbs + 7) >> 3));
453    }
454#endif
455
456    if(0 == ps_codec->i4_share_disp_buf && ps_codec->i4_header_mode == 0)
457    {
458        UWORD32 i;
459        if(ps_dec_ip->s_out_buffer.u4_num_bufs == 0)
460        {
461            ps_dec_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM;
462            ps_dec_op->u4_error_code |= IVD_DISP_FRM_ZERO_OP_BUFS;
463            return IV_FAIL;
464        }
465
466        for(i = 0; i < ps_dec_ip->s_out_buffer.u4_num_bufs; i++)
467        {
468            if(ps_dec_ip->s_out_buffer.pu1_bufs[i] == NULL)
469            {
470                ps_dec_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM;
471                ps_dec_op->u4_error_code |= IVD_DISP_FRM_OP_BUF_NULL;
472                return IV_FAIL;
473            }
474
475            if(ps_dec_ip->s_out_buffer.u4_min_out_buf_size[i] == 0)
476            {
477                ps_dec_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM;
478                ps_dec_op->u4_error_code |= IVD_DISP_FRM_ZERO_OP_BUF_SIZE;
479                return IV_FAIL;
480            }
481        }
482    }
483
484    ps_codec->ps_out_buffer = &ps_dec_ip->s_out_buffer;
485    ps_codec->u4_ts = ps_dec_ip->u4_ts;
486    if(ps_codec->i4_flush_mode)
487    {
488
489        ps_dec_op->u4_pic_wd = ps_codec->i4_disp_wd;
490        ps_dec_op->u4_pic_ht = ps_codec->i4_disp_ht;
491
492        ps_dec_op->u4_new_seq = 0;
493
494        ps_codec->ps_disp_buf = (pic_buf_t *)ihevc_disp_mgr_get(
495                        (disp_mgr_t *)ps_codec->pv_disp_buf_mgr, &ps_codec->i4_disp_buf_id);
496        /* In case of non-shared mode, then convert/copy the frame to output buffer */
497        /* Only if the codec is in non-shared mode or in shared mode but needs 420P output */
498        if((ps_codec->ps_disp_buf)
499                        && ((0 == ps_codec->i4_share_disp_buf)
500                                        || (IV_YUV_420P
501                                                        == ps_codec->e_chroma_fmt)))
502        {
503
504            process_ctxt_t *ps_proc = &ps_codec->as_process[prev_proc_idx];
505            if(0 == ps_proc->i4_init_done)
506            {
507                ihevcd_init_proc_ctxt(ps_proc, 0);
508            }
509
510            /* Output buffer check */
511            ret = ihevcd_check_out_buf_size(ps_codec);
512            RETURN_IF((ret != (IHEVCD_ERROR_T)IHEVCD_SUCCESS), ret);
513
514            /* Set remaining number of rows to be processed */
515            ret = ihevcd_fmt_conv(ps_codec, &ps_codec->as_process[prev_proc_idx],
516                                  ps_dec_ip->s_out_buffer.pu1_bufs[0],
517                                  ps_dec_ip->s_out_buffer.pu1_bufs[1],
518                                  ps_dec_ip->s_out_buffer.pu1_bufs[2], 0,
519                                  ps_codec->i4_disp_ht);
520
521            ihevc_buf_mgr_release((buf_mgr_t *)ps_codec->pv_pic_buf_mgr,
522                                  ps_codec->i4_disp_buf_id, BUF_MGR_DISP);
523        }
524
525        ihevcd_fill_outargs(ps_codec, ps_dec_ip, ps_dec_op);
526
527        if(1 == ps_dec_op->u4_output_present)
528        {
529            WORD32 xpos = ps_codec->i4_disp_wd - 32 - LOGO_WD;
530            WORD32 ypos = ps_codec->i4_disp_ht - 32 - LOGO_HT;
531
532            if(ypos < 0)
533                ypos = 0;
534
535            if(xpos < 0)
536                xpos = 0;
537
538            INSERT_LOGO(ps_dec_ip->s_out_buffer.pu1_bufs[0],
539                        ps_dec_ip->s_out_buffer.pu1_bufs[1],
540                        ps_dec_ip->s_out_buffer.pu1_bufs[2], ps_codec->i4_disp_strd,
541                        xpos,
542                        ypos,
543                        ps_codec->e_chroma_fmt,
544                        ps_codec->i4_disp_wd,
545                        ps_codec->i4_disp_ht);
546        }
547
548
549        if(NULL == ps_codec->ps_disp_buf)
550        {
551            /* If in flush mode and there are no more buffers to flush,
552             * check for the reset flag and reset the decoder */
553            if(ps_codec->i4_reset_flag)
554            {
555                ihevcd_init(ps_codec);
556            }
557            return (IV_FAIL);
558        }
559
560        return (IV_SUCCESS);
561
562    }
563    /* In case of shared mode, check if there is a free buffer for reconstruction */
564    if((0 == ps_codec->i4_header_mode) && (1 == ps_codec->i4_share_disp_buf))
565    {
566        WORD32 buf_status;
567        buf_status = 1;
568        if(ps_codec->pv_pic_buf_mgr)
569            buf_status = ihevc_buf_mgr_check_free((buf_mgr_t *)ps_codec->pv_pic_buf_mgr);
570
571        /* If there is no free buffer, then return with an error code */
572        if(0 == buf_status)
573        {
574            ps_dec_op->u4_error_code = IVD_DEC_REF_BUF_NULL;
575            ps_dec_op->u4_error_code |= (1 << IVD_UNSUPPORTEDPARAM);
576            return IV_FAIL;
577        }
578    }
579    ps_codec->i4_bytes_remaining = ps_dec_ip->u4_num_Bytes;
580    ps_codec->pu1_inp_bitsbuf = (UWORD8 *)ps_dec_ip->pv_stream_buffer;
581    ps_codec->s_parse.i4_end_of_frame = 0;
582
583    ps_codec->i4_pic_present = 0;
584    ps_codec->i4_slice_error = 0;
585    ps_codec->ps_disp_buf = NULL;
586
587    if(ps_codec->i4_num_cores > 1)
588    {
589        ithread_set_affinity(0);
590    }
591    while(MIN_START_CODE_LEN < ps_codec->i4_bytes_remaining)
592    {
593        WORD32 nal_len;
594        WORD32 nal_ofst;
595        WORD32 bits_len;
596
597        if(ps_codec->i4_slice_error)
598        {
599            slice_header_t *ps_slice_hdr_next = ps_codec->s_parse.ps_slice_hdr_base + (ps_codec->s_parse.i4_cur_slice_idx & (MAX_SLICE_HDR_CNT - 1));
600            WORD32 next_slice_addr = ps_slice_hdr_next->i2_ctb_x +
601                            ps_slice_hdr_next->i2_ctb_y * ps_codec->s_parse.ps_sps->i2_pic_wd_in_ctb;
602            if(ps_codec->s_parse.i4_next_ctb_indx == next_slice_addr)
603                ps_codec->i4_slice_error = 0;
604        }
605
606        if(ps_codec->pu1_bitsbuf_dynamic)
607        {
608            ps_codec->pu1_bitsbuf = ps_codec->pu1_bitsbuf_dynamic;
609            ps_codec->u4_bitsbuf_size = ps_codec->u4_bitsbuf_size_dynamic;
610        }
611        else
612        {
613            ps_codec->pu1_bitsbuf = ps_codec->pu1_bitsbuf_static;
614            ps_codec->u4_bitsbuf_size = ps_codec->u4_bitsbuf_size_static;
615        }
616
617        nal_ofst = ihevcd_nal_search_start_code(ps_codec->pu1_inp_bitsbuf,
618                                                ps_codec->i4_bytes_remaining);
619
620        ps_codec->i4_nal_ofst = nal_ofst;
621        {
622            WORD32 bytes_remaining = ps_codec->i4_bytes_remaining - nal_ofst;
623
624            bytes_remaining = MIN((UWORD32)bytes_remaining, ps_codec->u4_bitsbuf_size);
625            ihevcd_nal_remv_emuln_bytes(ps_codec->pu1_inp_bitsbuf + nal_ofst,
626                                        ps_codec->pu1_bitsbuf,
627                                        bytes_remaining,
628                                        &nal_len, &bits_len);
629
630            /* Decoder may read upto 8 extra bytes at the end of frame */
631            /* These are not used, but still set them to zero to avoid uninitialized reads */
632            if(bits_len < (WORD32)(ps_codec->u4_bitsbuf_size - 8))
633            {
634                memset(ps_codec->pu1_bitsbuf + bits_len, 0, 2 * sizeof(UWORD32));
635            }
636        }
637        /* This may be used to update the offsets for tiles and entropy sync row offsets */
638        ps_codec->i4_num_emln_bytes = nal_len - bits_len;
639        ps_codec->i4_nal_len = nal_len;
640
641        ihevcd_bits_init(&ps_codec->s_parse.s_bitstrm, ps_codec->pu1_bitsbuf,
642                         bits_len);
643
644        ret = ihevcd_nal_unit(ps_codec);
645
646        /* If the frame is incomplete and
647         * the bytes remaining is zero or a header is received,
648         * complete the frame treating it to be in error */
649        if(ps_codec->i4_pic_present &&
650                        (ps_codec->s_parse.i4_next_ctb_indx != ps_codec->s_parse.ps_sps->i4_pic_size_in_ctb))
651        {
652            if((ps_codec->i4_bytes_remaining - (nal_len + nal_ofst) <= MIN_START_CODE_LEN) ||
653                            (ps_codec->i4_header_in_slice_mode))
654            {
655                slice_header_t *ps_slice_hdr_next;
656
657                ps_codec->s_parse.i4_cur_slice_idx--;
658                if(ps_codec->s_parse.i4_cur_slice_idx < 0)
659                    ps_codec->s_parse.i4_cur_slice_idx = 0;
660
661                ps_slice_hdr_next = ps_codec->s_parse.ps_slice_hdr_base + ((ps_codec->s_parse.i4_cur_slice_idx + 1) & (MAX_SLICE_HDR_CNT - 1));
662                ps_slice_hdr_next->i2_ctb_x = 0;
663                ps_slice_hdr_next->i2_ctb_y = ps_codec->s_parse.ps_sps->i2_pic_ht_in_ctb;
664                ps_codec->i4_slice_error = 1;
665                continue;
666            }
667        }
668
669        if(IHEVCD_IGNORE_SLICE == ret)
670        {
671            ps_codec->s_parse.i4_cur_slice_idx = MAX(0, (ps_codec->s_parse.i4_cur_slice_idx - 1));
672            ps_codec->pu1_inp_bitsbuf += (nal_ofst + nal_len);
673            ps_codec->i4_bytes_remaining -= (nal_ofst + nal_len);
674
675            continue;
676        }
677
678        if((IVD_RES_CHANGED == ret) ||
679           (IVD_STREAM_WIDTH_HEIGHT_NOT_SUPPORTED == ret))
680        {
681            break;
682        }
683
684        /* Update bytes remaining and bytes consumed and input bitstream pointer */
685        /* Do not consume the NAL in the following cases */
686        /* Slice header reached during header decode mode */
687        /* TODO: Next picture's slice reached */
688        if(ret != IHEVCD_SLICE_IN_HEADER_MODE)
689        {
690            if((0 == ps_codec->i4_slice_error) ||
691                            (ps_codec->i4_bytes_remaining - (nal_len + nal_ofst) <= MIN_START_CODE_LEN))
692            {
693                ps_codec->pu1_inp_bitsbuf += (nal_ofst + nal_len);
694                ps_codec->i4_bytes_remaining -= (nal_ofst + nal_len);
695            }
696            if(ret != IHEVCD_SUCCESS)
697                break;
698
699            if(ps_codec->s_parse.i4_end_of_frame)
700                break;
701        }
702        else
703        {
704            ret = IHEVCD_SUCCESS;
705            break;
706        }
707
708        /* Allocate dynamic bitstream buffer once SPS is decoded */
709        if((ps_codec->u4_allocate_dynamic_done == 0) && ps_codec->i4_sps_done)
710        {
711            WORD32 ret;
712            ret = ihevcd_allocate_dynamic_bufs(ps_codec);
713            if(ret != IV_SUCCESS)
714            {
715                /* Free any dynamic buffers that are allocated */
716                ihevcd_free_dynamic_bufs(ps_codec);
717                ps_codec->i4_error_code = IVD_MEM_ALLOC_FAILED;
718                ps_dec_op->u4_error_code |= 1 << IVD_FATALERROR;
719                ps_dec_op->u4_error_code |= IVD_MEM_ALLOC_FAILED;
720
721                return IV_FAIL;
722            }
723        }
724
725        BREAK_AFTER_SLICE_NAL();
726    }
727
728    if((ps_codec->u4_pic_cnt == 0) && (ret != IHEVCD_SUCCESS))
729    {
730        ps_codec->i4_error_code = ret;
731
732        ihevcd_fill_outargs(ps_codec, ps_dec_ip, ps_dec_op);
733        return IV_FAIL;
734    }
735
736    if(1 == ps_codec->i4_pic_present)
737    {
738        WORD32 i;
739        sps_t *ps_sps = ps_codec->s_parse.ps_sps;
740        ps_codec->i4_first_pic_done = 1;
741
742        /*TODO temporary fix: end_of_frame is checked before adding format conversion to job queue         */
743        if(ps_codec->i4_num_cores > 1 && ps_codec->s_parse.i4_end_of_frame)
744        {
745
746            /* Add job queue for format conversion / frame copy for each ctb row */
747            /* Only if the codec is in non-shared mode or in shared mode but needs 420P output */
748            process_ctxt_t *ps_proc;
749
750            /* i4_num_cores - 1 contexts are currently being used by other threads */
751            ps_proc = &ps_codec->as_process[ps_codec->i4_num_cores - 1];
752
753            if((ps_codec->ps_disp_buf) &&
754               ((0 == ps_codec->i4_share_disp_buf) || (IV_YUV_420P == ps_codec->e_chroma_fmt)))
755            {
756                /* If format conversion jobs were not issued in pic_init() add them here */
757                if((0 == ps_codec->u4_enable_fmt_conv_ahead) ||
758                                (ps_codec->i4_disp_buf_id == ps_proc->i4_cur_pic_buf_id))
759                    for(i = 0; i < ps_sps->i2_pic_ht_in_ctb; i++)
760                    {
761                        proc_job_t s_job;
762                        IHEVCD_ERROR_T ret;
763                        s_job.i4_cmd = CMD_FMTCONV;
764                        s_job.i2_ctb_cnt = 0;
765                        s_job.i2_ctb_x = 0;
766                        s_job.i2_ctb_y = i;
767                        s_job.i2_slice_idx = 0;
768                        s_job.i4_tu_coeff_data_ofst = 0;
769                        ret = ihevcd_jobq_queue((jobq_t *)ps_codec->s_parse.pv_proc_jobq,
770                                                &s_job, sizeof(proc_job_t), 1);
771                        if(ret != (IHEVCD_ERROR_T)IHEVCD_SUCCESS)
772                            return (WORD32)ret;
773                    }
774            }
775            /* Reached end of frame : Signal terminate */
776            /* The terminate flag is checked only after all the jobs are dequeued */
777            ret = ihevcd_jobq_terminate((jobq_t *)ps_codec->s_parse.pv_proc_jobq);
778
779            while(1)
780            {
781                IHEVCD_ERROR_T ret;
782                proc_job_t s_job;
783                process_ctxt_t *ps_proc;
784
785                /* i4_num_cores - 1 contexts are currently being used by other threads */
786                ps_proc = &ps_codec->as_process[ps_codec->i4_num_cores - 1];
787
788                ret = ihevcd_jobq_dequeue((jobq_t *)ps_proc->pv_proc_jobq, &s_job,
789                                          sizeof(proc_job_t), 1);
790                if((IHEVCD_ERROR_T)IHEVCD_SUCCESS != ret)
791                    break;
792
793                ps_proc->i4_ctb_cnt = s_job.i2_ctb_cnt;
794                ps_proc->i4_ctb_x = s_job.i2_ctb_x;
795                ps_proc->i4_ctb_y = s_job.i2_ctb_y;
796                ps_proc->i4_cur_slice_idx = s_job.i2_slice_idx;
797
798                if(CMD_PROCESS == s_job.i4_cmd)
799                {
800                    ihevcd_init_proc_ctxt(ps_proc, s_job.i4_tu_coeff_data_ofst);
801
802                    ihevcd_process(ps_proc);
803                }
804                else if(CMD_FMTCONV == s_job.i4_cmd)
805                {
806                    sps_t *ps_sps = ps_codec->s_parse.ps_sps;
807                    WORD32 num_rows = 1 << ps_sps->i1_log2_ctb_size;
808                    if(0 == ps_proc->i4_init_done)
809                    {
810                        ihevcd_init_proc_ctxt(ps_proc, 0);
811                    }
812
813                    num_rows = MIN(num_rows, (ps_codec->i4_disp_ht - (s_job.i2_ctb_y << ps_sps->i1_log2_ctb_size)));
814                    if(num_rows < 0)
815                        num_rows = 0;
816
817                    ihevcd_fmt_conv(ps_codec, ps_proc,
818                                    ps_dec_ip->s_out_buffer.pu1_bufs[0],
819                                    ps_dec_ip->s_out_buffer.pu1_bufs[1],
820                                    ps_dec_ip->s_out_buffer.pu1_bufs[2],
821                                    s_job.i2_ctb_y << ps_sps->i1_log2_ctb_size,
822                                    num_rows);
823                }
824            }
825        }
826        /* In case of non-shared mode and while running in single core mode, then convert/copy the frame to output buffer */
827        /* Only if the codec is in non-shared mode or in shared mode but needs 420P output */
828        else if((ps_codec->ps_disp_buf) && ((0 == ps_codec->i4_share_disp_buf) ||
829                                            (IV_YUV_420P == ps_codec->e_chroma_fmt)) &&
830                        (ps_codec->s_parse.i4_end_of_frame))
831        {
832            process_ctxt_t *ps_proc = &ps_codec->as_process[proc_idx];
833            /* Set remaining number of rows to be processed */
834            ps_codec->s_fmt_conv.i4_num_rows = ps_codec->i4_disp_ht
835                            - ps_codec->s_fmt_conv.i4_cur_row;
836            if(0 == ps_proc->i4_init_done)
837            {
838                ihevcd_init_proc_ctxt(ps_proc, 0);
839            }
840
841            if(ps_codec->s_fmt_conv.i4_num_rows < 0)
842                ps_codec->s_fmt_conv.i4_num_rows = 0;
843
844            ret = ihevcd_fmt_conv(ps_codec, ps_proc,
845                                  ps_dec_ip->s_out_buffer.pu1_bufs[0],
846                                  ps_dec_ip->s_out_buffer.pu1_bufs[1],
847                                  ps_dec_ip->s_out_buffer.pu1_bufs[2],
848                                  ps_codec->s_fmt_conv.i4_cur_row,
849                                  ps_codec->s_fmt_conv.i4_num_rows);
850            ps_codec->s_fmt_conv.i4_cur_row += ps_codec->s_fmt_conv.i4_num_rows;
851
852        }
853
854
855        DEBUG_DUMP_MV_MAP(ps_codec);
856
857        /* Mark MV Buf as needed for reference */
858        ihevc_buf_mgr_set_status((buf_mgr_t *)ps_codec->pv_mv_buf_mgr,
859                                 ps_codec->as_process[proc_idx].i4_cur_mv_bank_buf_id,
860                                 BUF_MGR_REF);
861
862        /* Mark pic buf as needed for reference */
863        ihevc_buf_mgr_set_status((buf_mgr_t *)ps_codec->pv_pic_buf_mgr,
864                                 ps_codec->as_process[proc_idx].i4_cur_pic_buf_id,
865                                 BUF_MGR_REF);
866
867        /* Mark pic buf as needed for display */
868        ihevc_buf_mgr_set_status((buf_mgr_t *)ps_codec->pv_pic_buf_mgr,
869                                 ps_codec->as_process[proc_idx].i4_cur_pic_buf_id,
870                                 BUF_MGR_DISP);
871
872        /* Insert the current picture as short term reference */
873        ihevc_dpb_mgr_insert_ref((dpb_mgr_t *)ps_codec->pv_dpb_mgr,
874                                 ps_codec->as_process[proc_idx].ps_cur_pic,
875                                 ps_codec->as_process[proc_idx].i4_cur_pic_buf_id);
876
877        /* If a frame was displayed (in non-shared mode), then release it from display manager */
878        if((0 == ps_codec->i4_share_disp_buf) && (ps_codec->ps_disp_buf))
879            ihevc_buf_mgr_release((buf_mgr_t *)ps_codec->pv_pic_buf_mgr,
880                                  ps_codec->i4_disp_buf_id, BUF_MGR_DISP);
881
882        /* Wait for threads */
883        for(i = 0; i < (ps_codec->i4_num_cores - 1); i++)
884        {
885            if(ps_codec->ai4_process_thread_created[i])
886            {
887                ithread_join(ps_codec->apv_process_thread_handle[i], NULL);
888                ps_codec->ai4_process_thread_created[i] = 0;
889            }
890        }
891
892        DEBUG_VALIDATE_PADDED_REGION(&ps_codec->as_process[proc_idx]);
893        if(ps_codec->u4_pic_cnt > 0)
894        {
895            DEBUG_DUMP_PIC_PU(ps_codec);
896        }
897        DEBUG_DUMP_PIC_BUFFERS(ps_codec);
898
899        /* Increment the number of pictures decoded */
900        ps_codec->u4_pic_cnt++;
901    }
902    ihevcd_fill_outargs(ps_codec, ps_dec_ip, ps_dec_op);
903
904    if(1 == ps_dec_op->u4_output_present)
905    {
906        WORD32 xpos = ps_codec->i4_disp_wd - 32 - LOGO_WD;
907        WORD32 ypos = ps_codec->i4_disp_ht - 32 - LOGO_HT;
908
909        if(ypos < 0)
910            ypos = 0;
911
912        if(xpos < 0)
913            xpos = 0;
914
915        INSERT_LOGO(ps_dec_ip->s_out_buffer.pu1_bufs[0],
916                    ps_dec_ip->s_out_buffer.pu1_bufs[1],
917                    ps_dec_ip->s_out_buffer.pu1_bufs[2], ps_codec->i4_disp_strd,
918                    xpos,
919                    ypos,
920                    ps_codec->e_chroma_fmt,
921                    ps_codec->i4_disp_wd,
922                    ps_codec->i4_disp_ht);
923    }
924
925
926    return ret;
927}
928
929