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