1/******************************************************************************
2 *
3 * Copyright (C) 2015 The Android Open Source Project
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 * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
19*/
20#include <string.h>
21
22#include "iv_datatypedef.h"
23#include "iv.h"
24#include "ivd.h"
25#include "impeg2_macros.h"
26#include "impeg2_buf_mgr.h"
27#include "impeg2_disp_mgr.h"
28#include "impeg2_defs.h"
29#include "impeg2_inter_pred.h"
30#include "impeg2_idct.h"
31#include "impeg2_format_conv.h"
32#include "impeg2_mem_func.h"
33#include "impeg2_platform_macros.h"
34#include "ithread.h"
35#include "impeg2_job_queue.h"
36
37#include "impeg2d.h"
38#include "impeg2d_bitstream.h"
39#include "impeg2d_api.h"
40#include "impeg2d_structs.h"
41#include "impeg2_globals.h"
42#include "impeg2d_pic_proc.h"
43
44
45
46/******************************************************************************
47*  Function Name   : impeg2d_next_start_code
48*
49*  Description     : Peek for next_start_code from the stream_t.
50*
51*  Arguments       :
52*  dec             : Decoder Context
53*
54*  Values Returned : None
55******************************************************************************/
56void impeg2d_next_start_code(dec_state_t *ps_dec)
57{
58    stream_t *ps_stream;
59    ps_stream = &ps_dec->s_bit_stream;
60    impeg2d_bit_stream_flush_to_byte_boundary(ps_stream);
61
62    while ((impeg2d_bit_stream_nxt(ps_stream,START_CODE_PREFIX_LEN) != START_CODE_PREFIX)
63        && (ps_dec->s_bit_stream.u4_offset < ps_dec->s_bit_stream.u4_max_offset))
64    {
65        impeg2d_bit_stream_get(ps_stream,8);
66    }
67    return;
68}
69/******************************************************************************
70*  Function Name   : impeg2d_next_code
71*
72*  Description     : Peek for next_start_code from the stream_t.
73*
74*  Arguments       :
75*  dec             : Decoder Context
76*
77*  Values Returned : None
78******************************************************************************/
79void impeg2d_next_code(dec_state_t *ps_dec, UWORD32 u4_start_code_val)
80{
81    stream_t *ps_stream;
82    ps_stream = &ps_dec->s_bit_stream;
83    impeg2d_bit_stream_flush_to_byte_boundary(ps_stream);
84
85    while ((impeg2d_bit_stream_nxt(ps_stream,START_CODE_LEN) != u4_start_code_val)
86        && (ps_dec->s_bit_stream.u4_offset <= ps_dec->s_bit_stream.u4_max_offset))
87    {
88
89        if (impeg2d_bit_stream_get(ps_stream,8) != 0)
90        {
91            /* Ignore stuffing bit errors. */
92        }
93
94    }
95    return;
96}
97/******************************************************************************
98*  Function Name   : impeg2d_peek_next_start_code
99*
100*  Description     : Peek for next_start_code from the stream_t.
101*
102*  Arguments       :
103*  dec             : Decoder Context
104*
105*  Values Returned : None
106******************************************************************************/
107void impeg2d_peek_next_start_code(dec_state_t *ps_dec)
108{
109    stream_t *ps_stream;
110    ps_stream = &ps_dec->s_bit_stream;
111    impeg2d_bit_stream_flush_to_byte_boundary(ps_stream);
112
113    while ((impeg2d_bit_stream_nxt(ps_stream,START_CODE_PREFIX_LEN) != START_CODE_PREFIX)
114        && (ps_dec->s_bit_stream.u4_offset <= ps_dec->s_bit_stream.u4_max_offset))
115    {
116        impeg2d_bit_stream_get(ps_stream,8);
117    }
118    return;
119}
120/******************************************************************************
121*
122*  Function Name   : impeg2d_dec_seq_hdr
123*
124*  Description     : Decodes Sequence header information
125*
126*  Arguments       :
127*  dec             : Decoder Context
128*
129*  Values Returned : None
130******************************************************************************/
131IMPEG2D_ERROR_CODES_T impeg2d_dec_seq_hdr(dec_state_t *ps_dec)
132{
133    stream_t *ps_stream;
134    ps_stream = &ps_dec->s_bit_stream;
135    UWORD16 u2_height;
136    UWORD16 u2_width;
137
138    if (impeg2d_bit_stream_nxt(ps_stream,START_CODE_LEN) != SEQUENCE_HEADER_CODE)
139    {
140        impeg2d_bit_stream_flush(ps_stream,START_CODE_LEN);
141        return IMPEG2D_FRM_HDR_START_CODE_NOT_FOUND;
142
143    }
144    impeg2d_bit_stream_flush(ps_stream,START_CODE_LEN);
145
146    u2_width    = impeg2d_bit_stream_get(ps_stream,12);
147    u2_height   = impeg2d_bit_stream_get(ps_stream,12);
148
149    if ((u2_width != ps_dec->u2_horizontal_size)
150                    || (u2_height != ps_dec->u2_vertical_size))
151    {
152        if (0 == ps_dec->u2_header_done)
153        {
154            /* This is the first time we are reading the resolution */
155            ps_dec->u2_horizontal_size = u2_width;
156            ps_dec->u2_vertical_size = u2_height;
157            if (0 == ps_dec->u4_frm_buf_stride)
158            {
159                ps_dec->u4_frm_buf_stride  = (UWORD32) ALIGN16(u2_width);
160            }
161        }
162        else
163        {
164            if((u2_width > ps_dec->u2_create_max_width)
165                            || (u2_height > ps_dec->u2_create_max_height))
166            {
167                IMPEG2D_ERROR_CODES_T e_error = IMPEG2D_UNSUPPORTED_DIMENSIONS;
168
169                ps_dec->u2_reinit_max_height   = u2_height;
170                ps_dec->u2_reinit_max_width    = u2_width;
171
172                return e_error;
173            }
174            else
175            {
176                /* The resolution has changed */
177                return (IMPEG2D_ERROR_CODES_T)IVD_RES_CHANGED;
178            }
179        }
180    }
181
182    if((ps_dec->u2_horizontal_size > ps_dec->u2_create_max_width)
183                    || (ps_dec->u2_vertical_size > ps_dec->u2_create_max_height))
184    {
185        IMPEG2D_ERROR_CODES_T e_error = IMPEG2D_UNSUPPORTED_DIMENSIONS;
186        return SET_IVD_FATAL_ERROR(e_error);
187    }
188
189
190    /*------------------------------------------------------------------------*/
191    /* Flush the following as they are not being used                         */
192    /* aspect_ratio_info (4 bits)                                             */
193    /*------------------------------------------------------------------------*/
194    ps_dec->u2_aspect_ratio_info = impeg2d_bit_stream_get(ps_stream,4);
195
196    /*------------------------------------------------------------------------*/
197    /* Frame rate code(4 bits)                                                */
198    /*------------------------------------------------------------------------*/
199    ps_dec->u2_frame_rate_code = impeg2d_bit_stream_get(ps_stream,4);
200    /*------------------------------------------------------------------------*/
201    /* Flush the following as they are not being used                         */
202    /* bit_rate_value (18 bits)                                               */
203    /*------------------------------------------------------------------------*/
204    impeg2d_bit_stream_flush(ps_stream,18);
205    GET_MARKER_BIT(ps_dec,ps_stream);
206    /*------------------------------------------------------------------------*/
207    /* Flush the following as they are not being used                         */
208    /* vbv_buffer_size_value(10 bits), constrained_parameter_flag (1 bit)     */
209    /*------------------------------------------------------------------------*/
210    impeg2d_bit_stream_flush(ps_stream,11);
211
212    /*------------------------------------------------------------------------*/
213    /* Quantization matrix for the intra blocks                               */
214    /*------------------------------------------------------------------------*/
215    if(impeg2d_bit_stream_get_bit(ps_stream) == 1)
216    {
217        UWORD16 i;
218        for(i = 0; i < NUM_PELS_IN_BLOCK; i++)
219        {
220            ps_dec->au1_intra_quant_matrix[gau1_impeg2_inv_scan_zig_zag[i]] =  (UWORD8)impeg2d_bit_stream_get(ps_stream,8);
221        }
222
223    }
224    else
225    {
226        memcpy(ps_dec->au1_intra_quant_matrix,gau1_impeg2_intra_quant_matrix_default,
227                NUM_PELS_IN_BLOCK);
228    }
229
230    /*------------------------------------------------------------------------*/
231    /* Quantization matrix for the inter blocks                               */
232    /*------------------------------------------------------------------------*/
233    if(impeg2d_bit_stream_get_bit(ps_stream) == 1)
234    {
235        UWORD16 i;
236        for(i = 0; i < NUM_PELS_IN_BLOCK; i++)
237        {
238            ps_dec->au1_inter_quant_matrix[gau1_impeg2_inv_scan_zig_zag[i]] =   (UWORD8)impeg2d_bit_stream_get(ps_stream,8);
239        }
240    }
241    else
242    {
243        memcpy(ps_dec->au1_inter_quant_matrix,gau1_impeg2_inter_quant_matrix_default,
244            NUM_PELS_IN_BLOCK);
245    }
246    impeg2d_next_start_code(ps_dec);
247
248    return (IMPEG2D_ERROR_CODES_T)IVD_ERROR_NONE;
249}
250
251/******************************************************************************
252*
253*  Function Name   : impeg2d_dec_seq_ext
254*
255*  Description     : Gets additional sequence data.
256*
257*  Arguments       :
258*  dec             : Decoder Context
259*
260*  Values Returned : None
261******************************************************************************/
262IMPEG2D_ERROR_CODES_T impeg2d_dec_seq_ext(dec_state_t *ps_dec)
263{
264    stream_t *ps_stream;
265
266    ps_stream = &ps_dec->s_bit_stream;
267
268    if (impeg2d_bit_stream_nxt(ps_stream,START_CODE_LEN) != EXTENSION_START_CODE)
269    {
270        impeg2d_bit_stream_flush(ps_stream,START_CODE_LEN);
271        return IMPEG2D_FRM_HDR_START_CODE_NOT_FOUND;
272
273    }
274    /* Flush the extension start code */
275    impeg2d_bit_stream_flush(ps_stream,START_CODE_LEN);
276
277    /* Flush extension start code identifier */
278    impeg2d_bit_stream_flush(ps_stream,4);
279
280    /*----------------------------------------------------------------------*/
281    /* Profile and Level information                                        */
282    /*----------------------------------------------------------------------*/
283    {
284        UWORD32   u4_esc_bit, u4_profile, u4_level;
285
286        /* Read the profile and level information */
287        /* check_profile_and_level: Table 8-1     */
288        /* [7:7] 1 Escape bit                     */
289        /* [6:4] 3 Profile identification         */
290        /* [3:0] 4 Level identification           */
291
292        u4_esc_bit   = impeg2d_bit_stream_get_bit(ps_stream);
293        u4_profile   = impeg2d_bit_stream_get(ps_stream,3);
294        u4_level     = impeg2d_bit_stream_get(ps_stream,4);
295        UNUSED(u4_profile);
296        UNUSED(u4_level);
297        /*
298        if( escBit == 1                   ||
299            profile < MPEG2_MAIN_PROFILE  ||
300            level < MPEG2_MAIN_LEVEL)
301            */
302        if (1 == u4_esc_bit)
303        {
304            return IMPEG2D_PROF_LEVEL_NOT_SUPPORTED;
305        }
306    }
307
308    ps_dec->u2_progressive_sequence = impeg2d_bit_stream_get_bit(ps_stream);
309
310    /* Read the chrominance format */
311    if(impeg2d_bit_stream_get(ps_stream,2) != 0x1)
312        return IMPEG2D_CHROMA_FMT_NOT_SUP;
313
314    /* Read the 2 most significant bits from horizontal_size */
315    ps_dec->u2_horizontal_size    += (impeg2d_bit_stream_get(ps_stream,2) << 12);
316
317    /* Read the 2 most significant bits from vertical_size */
318    ps_dec->u2_vertical_size      += (impeg2d_bit_stream_get(ps_stream,2) << 12);
319
320    /*-----------------------------------------------------------------------*/
321    /* Flush the following as they are not used now                          */
322    /* bit_rate_extension          12                                        */
323    /* marker_bit                   1                                        */
324    /* vbv_buffer_size_extension    8                                        */
325    /* low_delay                    1                                        */
326    /*-----------------------------------------------------------------------*/
327    impeg2d_bit_stream_flush(ps_stream,12);
328    GET_MARKER_BIT(ps_dec,ps_stream);
329    impeg2d_bit_stream_flush(ps_stream,9);
330    /*-----------------------------------------------------------------------*/
331    /* frame_rate_extension_n       2                                        */
332    /* frame_rate_extension_d       5                                        */
333    /*-----------------------------------------------------------------------*/
334    ps_dec->u2_frame_rate_extension_n = impeg2d_bit_stream_get(ps_stream,2);
335    ps_dec->u2_frame_rate_extension_d = impeg2d_bit_stream_get(ps_stream,5);
336
337    return (IMPEG2D_ERROR_CODES_T)IVD_ERROR_NONE;
338}
339
340/*******************************************************************************
341*
342*  Function Name   : impeg2d_dec_seq_disp_ext
343*
344*  Description     : This function is eqvt to sequence_display_extension() of
345*                    standard. It flushes data present as it is not being used
346*
347*  Arguments       :
348*  dec             : Decoder Context
349*
350*  Values Returned : None
351******************************************************************************/
352void impeg2d_dec_seq_disp_ext(dec_state_t *ps_dec)
353{
354    stream_t *ps_stream;
355    ps_stream = &ps_dec->s_bit_stream;
356
357    /*
358    sequence_display_extension()
359    {
360        extension_start_code_identifier 4
361        video_format                    3
362        colour_description              1
363        if (colour_description)
364        {
365            colour_primaries            8
366            transfer_characteristics    8
367            matrix_coefficients         8
368        }
369        display_horizontal_size         14
370        marker_bit                      1
371        display_vertical_size           14
372        next_start_code()
373    }
374    */
375
376    impeg2d_bit_stream_get(ps_stream,7);
377    if (impeg2d_bit_stream_get_bit(ps_stream) == 1)
378    {
379        impeg2d_bit_stream_get(ps_stream,24);
380    }
381
382    /* display_horizontal_size and display_vertical_size */
383    ps_dec->u2_display_horizontal_size = impeg2d_bit_stream_get(ps_stream,14);;
384    GET_MARKER_BIT(ps_dec,ps_stream);
385    ps_dec->u2_display_vertical_size   = impeg2d_bit_stream_get(ps_stream,14);
386
387    impeg2d_next_start_code(ps_dec);
388}
389
390
391/*******************************************************************************
392*
393*  Function Name   : impeg2d_dec_seq_scale_ext
394*
395*  Description     : This function is eqvt to sequence_scalable_extension() of
396*                    standard.
397*
398*  Arguments       : Decoder context
399*
400*  Values Returned : None
401*******************************************************************************/
402IMPEG2D_ERROR_CODES_T impeg2d_dec_seq_scale_ext(dec_state_t *ps_dec)
403{
404    UNUSED(ps_dec);
405    return IMPEG2D_SCALABILITIY_NOT_SUPPORTED;
406}
407
408/*******************************************************************************
409*
410*  Function Name   : impeg2d_dec_quant_matrix_ext
411*
412*  Description     : Gets Intra and NonIntra quantizer matrix from the stream.
413*
414*  Arguments       : Decoder context
415*
416*  Values Returned : None
417*******************************************************************************/
418void impeg2d_dec_quant_matrix_ext(dec_state_t *ps_dec)
419{
420    stream_t *ps_stream;
421
422    ps_stream = &ps_dec->s_bit_stream;
423    /* Flush extension_start_code_identifier */
424    impeg2d_bit_stream_flush(ps_stream,4);
425
426    /*------------------------------------------------------------------------*/
427    /* Quantization matrix for the intra blocks                               */
428    /*------------------------------------------------------------------------*/
429    if(impeg2d_bit_stream_get(ps_stream,1) == 1)
430    {
431        UWORD16 i;
432        for(i = 0; i < NUM_PELS_IN_BLOCK; i++)
433        {
434            ps_dec->au1_intra_quant_matrix[gau1_impeg2_inv_scan_zig_zag[i]] =  (UWORD8)impeg2d_bit_stream_get(ps_stream,8);
435        }
436
437    }
438
439
440    /*------------------------------------------------------------------------*/
441    /* Quantization matrix for the inter blocks                               */
442    /*------------------------------------------------------------------------*/
443    if(impeg2d_bit_stream_get(ps_stream,1) == 1)
444    {
445        UWORD16 i;
446        for(i = 0; i < NUM_PELS_IN_BLOCK; i++)
447        {
448            ps_dec->au1_inter_quant_matrix[gau1_impeg2_inv_scan_zig_zag[i]] =   (UWORD8)impeg2d_bit_stream_get(ps_stream,8);
449        }
450    }
451
452    /* Note : chroma intra quantizer matrix and chroma non
453    intra quantizer matrix are not needed for 4:2:0 format */
454    impeg2d_next_start_code(ps_dec);
455}
456/*******************************************************************************
457*
458*  Function Name   : impeg2d_dec_pic_disp_ext
459*
460*  Description     : This function is eqvt to picture_display_extension() of
461*                    standard.The parameters are not used by decoder
462*
463*  Arguments       : Pointer to dec_state_t
464*
465*  Values Returned : Decoder context
466*
467*  Values Returned : None
468*******************************************************************************/
469void impeg2d_dec_pic_disp_ext(dec_state_t *ps_dec)
470{
471    WORD16 i2_number_of_frame_centre_offsets ;
472    stream_t *ps_stream;
473
474    ps_stream = &ps_dec->s_bit_stream;
475    impeg2d_bit_stream_flush(ps_stream,4);
476
477    if (ps_dec->u2_progressive_sequence)
478    {
479        i2_number_of_frame_centre_offsets = (ps_dec->u2_repeat_first_field) ?
480            2 + ps_dec->u2_top_field_first : 1;
481    }
482    else
483    {
484        i2_number_of_frame_centre_offsets =
485            (ps_dec->u2_picture_structure != FRAME_PICTURE) ?
486            1 : 2 + ps_dec->u2_repeat_first_field;
487    }
488    while(i2_number_of_frame_centre_offsets--)
489    {
490        /* frame_centre_horizontal_offset */
491        impeg2d_bit_stream_get(ps_stream,16);
492        GET_MARKER_BIT(ps_dec,ps_stream);
493        /* frame_centre_vertical_offset */
494        impeg2d_bit_stream_get(ps_stream,16);
495        GET_MARKER_BIT(ps_dec,ps_stream);
496    }
497    impeg2d_next_start_code(ps_dec);
498}
499
500/*******************************************************************************
501*
502*  Function Name   : impeg2d_dec_itu_t_ext
503*
504*  Description     : This function is eqvt to ITU-T_extension() of
505*                    standard.The parameters are not used by decoder
506*
507*  Arguments       : Decoder context
508*
509*  Values Returned : None
510*******************************************************************************/
511void impeg2d_dec_itu_t_ext(dec_state_t *ps_dec)
512{
513  impeg2d_bit_stream_flush(&ps_dec->s_bit_stream,EXT_ID_LEN);
514  impeg2d_next_start_code(ps_dec);
515}
516
517/*******************************************************************************
518*  Function Name   : impeg2d_dec_copyright_ext
519*
520*  Description     : This function is eqvt to copyright_extension() of
521*                    standard. The parameters are not used by decoder
522*
523*  Arguments       : Decoder context
524*
525*  Values Returned : None
526*******************************************************************************/
527
528
529void impeg2d_dec_copyright_ext(dec_state_t *ps_dec)
530{
531    UWORD32 u4_bits_to_flush;
532
533    u4_bits_to_flush = COPYRIGHT_EXTENSION_LEN;
534
535    while(u4_bits_to_flush >= 32 )
536    {
537        impeg2d_bit_stream_flush(&ps_dec->s_bit_stream,32);
538        u4_bits_to_flush = u4_bits_to_flush - 32;
539    }
540
541    if(u4_bits_to_flush > 0)
542    {
543        impeg2d_bit_stream_flush(&ps_dec->s_bit_stream,u4_bits_to_flush);
544    }
545
546
547  impeg2d_next_start_code(ps_dec);
548}
549/*******************************************************************************
550*  Function Name   : impeg2d_dec_cam_param_ext
551*
552*  Description     : This function is eqvt to camera_parameters_extension() of
553*                    standard. The parameters are not used by decoder
554*
555*  Arguments       : Decoder context
556*
557*  Values Returned : None
558*******************************************************************************/
559
560
561void impeg2d_dec_cam_param_ext(dec_state_t *ps_dec)
562{
563
564    UWORD32 u4_bits_to_flush;
565
566    u4_bits_to_flush = CAMERA_PARAMETER_EXTENSION_LEN;
567
568    while(u4_bits_to_flush >= 32 )
569    {
570        impeg2d_bit_stream_flush(&ps_dec->s_bit_stream,32);
571        u4_bits_to_flush = u4_bits_to_flush - 32;
572    }
573
574    if(u4_bits_to_flush > 0)
575    {
576        impeg2d_bit_stream_flush(&ps_dec->s_bit_stream,u4_bits_to_flush);
577    }
578
579  impeg2d_next_start_code(ps_dec);
580}
581
582/*******************************************************************************
583*
584*  Function Name   : impeg2d_dec_grp_of_pic_hdr
585*
586*  Description     : Gets information at the GOP level.
587*
588*  Arguments       : Decoder context
589*
590*  Values Returned : None
591*******************************************************************************/
592
593
594void impeg2d_dec_grp_of_pic_hdr(dec_state_t *ps_dec)
595{
596
597    UWORD32 u4_bits_to_flush;
598
599    u4_bits_to_flush = GROUP_OF_PICTURE_LEN;
600
601    while(u4_bits_to_flush >= 32 )
602    {
603        impeg2d_bit_stream_flush(&ps_dec->s_bit_stream,32);
604        u4_bits_to_flush = u4_bits_to_flush - 32;
605    }
606
607    if(u4_bits_to_flush > 0)
608    {
609        impeg2d_bit_stream_flush(&ps_dec->s_bit_stream,u4_bits_to_flush);
610    }
611
612}
613
614
615/*******************************************************************************
616*
617*  Function Name   : impeg2d_dec_pic_hdr
618*
619*  Description     : Gets the picture header information.
620*
621*  Arguments       : Decoder context
622*
623*  Values Returned : None
624*******************************************************************************/
625IMPEG2D_ERROR_CODES_T impeg2d_dec_pic_hdr(dec_state_t *ps_dec)
626{
627    stream_t *ps_stream;
628    ps_stream = &ps_dec->s_bit_stream;
629
630    impeg2d_bit_stream_flush(ps_stream,START_CODE_LEN);
631    /* Flush temporal reference */
632    impeg2d_bit_stream_get(ps_stream,10);
633
634    /* Picture type */
635    ps_dec->e_pic_type = (e_pic_type_t)impeg2d_bit_stream_get(ps_stream,3);
636    if((ps_dec->e_pic_type < I_PIC) || (ps_dec->e_pic_type > D_PIC))
637    {
638        impeg2d_next_code(ps_dec, PICTURE_START_CODE);
639        return IMPEG2D_INVALID_PIC_TYPE;
640    }
641
642    /* Flush vbv_delay */
643    impeg2d_bit_stream_get(ps_stream,16);
644
645    if(ps_dec->e_pic_type == P_PIC || ps_dec->e_pic_type == B_PIC)
646    {
647        ps_dec->u2_full_pel_forw_vector = impeg2d_bit_stream_get_bit(ps_stream);
648        ps_dec->u2_forw_f_code          = impeg2d_bit_stream_get(ps_stream,3);
649    }
650    if(ps_dec->e_pic_type == B_PIC)
651    {
652        ps_dec->u2_full_pel_back_vector = impeg2d_bit_stream_get_bit(ps_stream);
653        ps_dec->u2_back_f_code          = impeg2d_bit_stream_get(ps_stream,3);
654    }
655
656    if(ps_dec->u2_is_mpeg2 == 0)
657    {
658        ps_dec->au2_f_code[0][0] = ps_dec->au2_f_code[0][1] = ps_dec->u2_forw_f_code;
659        ps_dec->au2_f_code[1][0] = ps_dec->au2_f_code[1][1] = ps_dec->u2_back_f_code;
660    }
661
662    /*-----------------------------------------------------------------------*/
663    /*  Flush the extra bit value                                            */
664    /*                                                                       */
665    /*  while(impeg2d_bit_stream_nxt() == '1')                                  */
666    /*  {                                                                    */
667    /*      extra_bit_picture         1                                      */
668    /*      extra_information_picture 8                                      */
669    /*  }                                                                    */
670    /*  extra_bit_picture             1                                      */
671    /*-----------------------------------------------------------------------*/
672    while (impeg2d_bit_stream_nxt(ps_stream,1) == 1)
673    {
674        impeg2d_bit_stream_get(ps_stream,9);
675    }
676    impeg2d_bit_stream_get_bit(ps_stream);
677    impeg2d_next_start_code(ps_dec);
678
679    return (IMPEG2D_ERROR_CODES_T)IVD_ERROR_NONE;
680}
681
682
683/*******************************************************************************
684*
685*  Function Name   : impeg2d_dec_pic_coding_ext
686*
687*  Description     : Reads more picture level parameters
688*
689*  Arguments       :
690*  dec             : Decoder context
691*
692*  Values Returned : None
693*******************************************************************************/
694void impeg2d_dec_pic_coding_ext(dec_state_t *ps_dec)
695{
696    stream_t *ps_stream;
697
698    ps_stream = &ps_dec->s_bit_stream;
699    impeg2d_bit_stream_flush(ps_stream,START_CODE_LEN);
700    /* extension code identifier */
701    impeg2d_bit_stream_get(ps_stream,4);
702
703    ps_dec->au2_f_code[0][0]             = impeg2d_bit_stream_get(ps_stream,4);
704    ps_dec->au2_f_code[0][1]             = impeg2d_bit_stream_get(ps_stream,4);
705    ps_dec->au2_f_code[1][0]             = impeg2d_bit_stream_get(ps_stream,4);
706    ps_dec->au2_f_code[1][1]             = impeg2d_bit_stream_get(ps_stream,4);
707    ps_dec->u2_intra_dc_precision        = impeg2d_bit_stream_get(ps_stream,2);
708    ps_dec->u2_picture_structure            = impeg2d_bit_stream_get(ps_stream,2);
709    ps_dec->u2_top_field_first              = impeg2d_bit_stream_get_bit(ps_stream);
710    ps_dec->u2_frame_pred_frame_dct         = impeg2d_bit_stream_get_bit(ps_stream);
711    ps_dec->u2_concealment_motion_vectors   = impeg2d_bit_stream_get_bit(ps_stream);
712    ps_dec->u2_q_scale_type                 = impeg2d_bit_stream_get_bit(ps_stream);
713    ps_dec->u2_intra_vlc_format             = impeg2d_bit_stream_get_bit(ps_stream);
714    ps_dec->u2_alternate_scan               = impeg2d_bit_stream_get_bit(ps_stream);
715    ps_dec->u2_repeat_first_field           = impeg2d_bit_stream_get_bit(ps_stream);
716    /* Flush chroma_420_type */
717    impeg2d_bit_stream_get_bit(ps_stream);
718
719    ps_dec->u2_progressive_frame            = impeg2d_bit_stream_get_bit(ps_stream);
720    if (impeg2d_bit_stream_get_bit(ps_stream))
721    {
722        /* Flush v_axis, field_sequence, burst_amplitude, sub_carrier_phase */
723        impeg2d_bit_stream_flush(ps_stream,20);
724    }
725    impeg2d_next_start_code(ps_dec);
726
727
728    if(VERTICAL_SCAN == ps_dec->u2_alternate_scan)
729    {
730        ps_dec->pu1_inv_scan_matrix = (UWORD8 *)gau1_impeg2_inv_scan_vertical;
731    }
732    else
733    {
734        ps_dec->pu1_inv_scan_matrix = (UWORD8 *)gau1_impeg2_inv_scan_zig_zag;
735    }
736}
737
738/*******************************************************************************
739*
740*  Function Name   : impeg2d_dec_slice
741*
742*  Description     : Reads Slice level parameters and calls functions that
743*                    decode individual MBs of slice
744*
745*  Arguments       :
746*  dec             : Decoder context
747*
748*  Values Returned : None
749*******************************************************************************/
750IMPEG2D_ERROR_CODES_T impeg2d_dec_slice(dec_state_t *ps_dec)
751{
752    stream_t *ps_stream;
753    UWORD32 u4_slice_vertical_position;
754    UWORD32 u4_slice_vertical_position_extension;
755    IMPEG2D_ERROR_CODES_T e_error;
756
757    ps_stream = &ps_dec->s_bit_stream;
758
759    /*------------------------------------------------------------------------*/
760    /* All the profiles supported require restricted slice structure. Hence   */
761    /* there is no need to store slice_vertical_position. Note that max       */
762    /* height supported does not exceed 2800 and scalablity is not supported  */
763    /*------------------------------------------------------------------------*/
764
765    /* Remove the slice start code */
766    impeg2d_bit_stream_flush(ps_stream,START_CODE_PREFIX_LEN);
767    u4_slice_vertical_position = impeg2d_bit_stream_get(ps_stream, 8);
768    if(u4_slice_vertical_position > 2800)
769    {
770        u4_slice_vertical_position_extension = impeg2d_bit_stream_get(ps_stream, 3);
771        u4_slice_vertical_position += (u4_slice_vertical_position_extension << 7);
772    }
773
774    if((u4_slice_vertical_position > ps_dec->u2_num_vert_mb) ||
775       (u4_slice_vertical_position == 0))
776    {
777        return IMPEG2D_INVALID_VERT_SIZE;
778    }
779
780    // change the mb_y to point to slice_vertical_position
781    u4_slice_vertical_position--;
782    if (ps_dec->u2_mb_y != u4_slice_vertical_position)
783    {
784        ps_dec->u2_mb_y    = u4_slice_vertical_position;
785        ps_dec->u2_mb_x    = 0;
786    }
787    ps_dec->u2_first_mb = 1;
788
789    /*------------------------------------------------------------------------*/
790    /* Quant scale code decoding                                              */
791    /*------------------------------------------------------------------------*/
792    {
793        UWORD16 u2_quant_scale_code;
794        u2_quant_scale_code = impeg2d_bit_stream_get(ps_stream,5);
795        ps_dec->u1_quant_scale = (ps_dec->u2_q_scale_type) ?
796            gau1_impeg2_non_linear_quant_scale[u2_quant_scale_code] : (u2_quant_scale_code << 1);
797    }
798
799    if (impeg2d_bit_stream_nxt(ps_stream,1) == 1)
800    {
801        impeg2d_bit_stream_flush(ps_stream,9);
802        /* Flush extra bit information */
803        while (impeg2d_bit_stream_nxt(ps_stream,1) == 1)
804        {
805            impeg2d_bit_stream_flush(ps_stream,9);
806        }
807    }
808    impeg2d_bit_stream_get_bit(ps_stream);
809
810    /* Reset the DC predictors to reset values given in Table 7.2 at the start*/
811    /* of slice data */
812    ps_dec->u2_def_dc_pred[Y_LUMA]   = 128 << ps_dec->u2_intra_dc_precision;
813    ps_dec->u2_def_dc_pred[U_CHROMA]   = 128 << ps_dec->u2_intra_dc_precision;
814    ps_dec->u2_def_dc_pred[V_CHROMA]   = 128 << ps_dec->u2_intra_dc_precision;
815    /*------------------------------------------------------------------------*/
816    /* dec->DecMBsinSlice() implements the following psuedo code from standard*/
817    /* do                                                                     */
818    /* {                                                                      */
819    /*      macroblock()                                                      */
820    /* } while (impeg2d_bit_stream_nxt() != '000 0000 0000 0000 0000 0000')      */
821    /*------------------------------------------------------------------------*/
822
823    e_error = ps_dec->pf_decode_slice(ps_dec);
824    if ((IMPEG2D_ERROR_CODES_T)IVD_ERROR_NONE != e_error)
825    {
826        return e_error;
827    }
828
829    /* Check for the MBy index instead of number of MBs left, because the
830     * number of MBs left in case of multi-thread decode is the number of MBs
831     * in that row only
832     */
833    if(ps_dec->u2_mb_y < ps_dec->u2_num_vert_mb)
834        impeg2d_next_start_code(ps_dec);
835
836    return (IMPEG2D_ERROR_CODES_T)IVD_ERROR_NONE;
837}
838
839void impeg2d_dec_pic_data_thread(dec_state_t *ps_dec)
840{
841    WORD32 i4_continue_decode;
842
843    WORD32 i4_cur_row, temp;
844    UWORD32 u4_bits_read;
845    WORD32 i4_dequeue_job;
846    IMPEG2D_ERROR_CODES_T e_error;
847
848    i4_cur_row = ps_dec->u2_mb_y + 1;
849
850    i4_continue_decode = 1;
851
852    i4_dequeue_job = 1;
853    do
854    {
855        if(i4_cur_row > ps_dec->u2_num_vert_mb)
856        {
857            i4_continue_decode = 0;
858            break;
859        }
860
861        {
862            if((ps_dec->i4_num_cores> 1) && (i4_dequeue_job))
863            {
864                job_t s_job;
865                IV_API_CALL_STATUS_T e_ret;
866                UWORD8 *pu1_buf;
867
868                e_ret = impeg2_jobq_dequeue(ps_dec->pv_jobq, &s_job, sizeof(s_job), 1, 1);
869                if(e_ret != IV_SUCCESS)
870                    break;
871
872                if(CMD_PROCESS == s_job.i4_cmd)
873                {
874                    pu1_buf = ps_dec->pu1_inp_bits_buf + s_job.i4_bistream_ofst;
875                    impeg2d_bit_stream_init(&(ps_dec->s_bit_stream), pu1_buf,
876                            (ps_dec->u4_num_inp_bytes - s_job.i4_bistream_ofst) + 8);
877                    i4_cur_row      = s_job.i2_start_mb_y;
878                    ps_dec->i4_start_mb_y = s_job.i2_start_mb_y;
879                    ps_dec->i4_end_mb_y = s_job.i2_end_mb_y;
880                    ps_dec->u2_mb_x = 0;
881                    ps_dec->u2_mb_y = ps_dec->i4_start_mb_y;
882                    ps_dec->u2_num_mbs_left = (ps_dec->i4_end_mb_y - ps_dec->i4_start_mb_y) * ps_dec->u2_num_horiz_mb;
883
884                }
885                else
886                {
887                    WORD32 start_row;
888                    WORD32 num_rows;
889                    start_row = s_job.i2_start_mb_y << 4;
890                    num_rows = MIN((s_job.i2_end_mb_y << 4), ps_dec->u2_vertical_size);
891                    num_rows -= start_row;
892                    impeg2d_format_convert(ps_dec, ps_dec->ps_disp_pic,
893                                        ps_dec->ps_disp_frm_buf,
894                                        start_row, num_rows);
895                    break;
896
897                }
898
899            }
900            e_error = impeg2d_dec_slice(ps_dec);
901
902            if ((IMPEG2D_ERROR_CODES_T)IVD_ERROR_NONE != e_error)
903            {
904                impeg2d_next_start_code(ps_dec);
905            }
906        }
907
908        /* Detecting next slice start code */
909        while(1)
910        {
911            // skip (dec->u4_num_cores-1) rows
912            u4_bits_read = impeg2d_bit_stream_nxt(&ps_dec->s_bit_stream,START_CODE_LEN);
913            temp = u4_bits_read & 0xFF;
914            i4_continue_decode = (((u4_bits_read >> 8) == 0x01) && (temp) && (temp <= 0xAF));
915
916            if(i4_continue_decode)
917            {
918                /* If the slice is from the same row, then continue decoding without dequeue */
919                if((temp - 1) == i4_cur_row)
920                {
921                    i4_dequeue_job = 0;
922                    break;
923                }
924
925                if(temp < ps_dec->i4_end_mb_y)
926                {
927                    i4_cur_row = ps_dec->u2_mb_y;
928                }
929                else
930                {
931                    i4_dequeue_job = 1;
932                }
933                break;
934
935            }
936            else
937                break;
938        }
939
940    }while(i4_continue_decode);
941    if(ps_dec->i4_num_cores > 1)
942    {
943        while(1)
944        {
945            job_t s_job;
946            IV_API_CALL_STATUS_T e_ret;
947
948            e_ret = impeg2_jobq_dequeue(ps_dec->pv_jobq, &s_job, sizeof(s_job), 1, 1);
949            if(e_ret != IV_SUCCESS)
950                break;
951            if(CMD_FMTCONV == s_job.i4_cmd)
952            {
953                WORD32 start_row;
954                WORD32 num_rows;
955                start_row = s_job.i2_start_mb_y << 4;
956                num_rows = MIN((s_job.i2_end_mb_y << 4), ps_dec->u2_vertical_size);
957                num_rows -= start_row;
958                impeg2d_format_convert(ps_dec, ps_dec->ps_disp_pic,
959                                    ps_dec->ps_disp_frm_buf,
960                                    start_row, num_rows);
961            }
962        }
963    }
964    else
965    {
966        if((NULL != ps_dec->ps_disp_pic) && ((0 == ps_dec->u4_share_disp_buf) || (IV_YUV_420P != ps_dec->i4_chromaFormat)))
967            impeg2d_format_convert(ps_dec, ps_dec->ps_disp_pic,
968                            ps_dec->ps_disp_frm_buf,
969                            0, ps_dec->u2_vertical_size);
970    }
971}
972
973static WORD32 impeg2d_init_thread_dec_ctxt(dec_state_t *ps_dec,
974                                           dec_state_t *ps_dec_thd,
975                                           WORD32 i4_min_mb_y)
976{
977    UNUSED(i4_min_mb_y);
978    ps_dec_thd->i4_start_mb_y = 0;
979    ps_dec_thd->i4_end_mb_y = ps_dec->u2_num_vert_mb;
980    ps_dec_thd->u2_mb_x = 0;
981    ps_dec_thd->u2_mb_y = 0;
982    ps_dec_thd->u2_is_mpeg2 = ps_dec->u2_is_mpeg2;
983    ps_dec_thd->u2_frame_width = ps_dec->u2_frame_width;
984    ps_dec_thd->u2_frame_height = ps_dec->u2_frame_height;
985    ps_dec_thd->u2_picture_width = ps_dec->u2_picture_width;
986    ps_dec_thd->u2_horizontal_size = ps_dec->u2_horizontal_size;
987    ps_dec_thd->u2_vertical_size = ps_dec->u2_vertical_size;
988    ps_dec_thd->u2_create_max_width = ps_dec->u2_create_max_width;
989    ps_dec_thd->u2_create_max_height = ps_dec->u2_create_max_height;
990    ps_dec_thd->u2_header_done = ps_dec->u2_header_done;
991    ps_dec_thd->u2_decode_header = ps_dec->u2_decode_header;
992
993    ps_dec_thd->u2_num_horiz_mb = ps_dec->u2_num_horiz_mb;
994    ps_dec_thd->u2_num_vert_mb = ps_dec->u2_num_vert_mb;
995    ps_dec_thd->u2_num_flds_decoded = ps_dec->u2_num_flds_decoded;
996
997    ps_dec_thd->u4_frm_buf_stride = ps_dec->u4_frm_buf_stride;
998
999    ps_dec_thd->u2_field_dct = ps_dec->u2_field_dct;
1000    ps_dec_thd->u2_read_dct_type = ps_dec->u2_read_dct_type;
1001
1002    ps_dec_thd->u2_read_motion_type = ps_dec->u2_read_motion_type;
1003    ps_dec_thd->u2_motion_type = ps_dec->u2_motion_type;
1004
1005    ps_dec_thd->pu2_mb_type = ps_dec->pu2_mb_type;
1006    ps_dec_thd->u2_fld_pic = ps_dec->u2_fld_pic;
1007    ps_dec_thd->u2_frm_pic = ps_dec->u2_frm_pic;
1008
1009    ps_dec_thd->u2_fld_parity = ps_dec->u2_fld_parity;
1010
1011    ps_dec_thd->au2_fcode_data[0] = ps_dec->au2_fcode_data[0];
1012    ps_dec_thd->au2_fcode_data[1] = ps_dec->au2_fcode_data[1];
1013
1014    ps_dec_thd->u1_quant_scale = ps_dec->u1_quant_scale;
1015
1016    ps_dec_thd->u2_num_mbs_left = ps_dec->u2_num_mbs_left;
1017    ps_dec_thd->u2_first_mb = ps_dec->u2_first_mb;
1018    ps_dec_thd->u2_num_skipped_mbs = ps_dec->u2_num_skipped_mbs;
1019
1020    memcpy(&ps_dec_thd->s_cur_frm_buf, &ps_dec->s_cur_frm_buf, sizeof(yuv_buf_t));
1021    memcpy(&ps_dec_thd->as_recent_fld[0][0], &ps_dec->as_recent_fld[0][0], sizeof(yuv_buf_t));
1022    memcpy(&ps_dec_thd->as_recent_fld[0][1], &ps_dec->as_recent_fld[0][1], sizeof(yuv_buf_t));
1023    memcpy(&ps_dec_thd->as_recent_fld[1][0], &ps_dec->as_recent_fld[1][0], sizeof(yuv_buf_t));
1024    memcpy(&ps_dec_thd->as_recent_fld[1][1], &ps_dec->as_recent_fld[1][1], sizeof(yuv_buf_t));
1025    memcpy(&ps_dec_thd->as_ref_buf, &ps_dec->as_ref_buf, sizeof(yuv_buf_t) * 2 * 2);
1026
1027
1028    ps_dec_thd->pf_decode_slice = ps_dec->pf_decode_slice;
1029
1030    ps_dec_thd->pf_vld_inv_quant = ps_dec->pf_vld_inv_quant;
1031
1032    memcpy(ps_dec_thd->pf_idct_recon, ps_dec->pf_idct_recon, sizeof(ps_dec->pf_idct_recon));
1033
1034    memcpy(ps_dec_thd->pf_mc, ps_dec->pf_mc, sizeof(ps_dec->pf_mc));
1035    ps_dec_thd->pf_interpolate = ps_dec->pf_interpolate;
1036    ps_dec_thd->pf_copy_mb = ps_dec->pf_copy_mb;
1037    ps_dec_thd->pf_fullx_halfy_8x8              =  ps_dec->pf_fullx_halfy_8x8;
1038    ps_dec_thd->pf_halfx_fully_8x8              =  ps_dec->pf_halfx_fully_8x8;
1039    ps_dec_thd->pf_halfx_halfy_8x8              =  ps_dec->pf_halfx_halfy_8x8;
1040    ps_dec_thd->pf_fullx_fully_8x8              =  ps_dec->pf_fullx_fully_8x8;
1041
1042    ps_dec_thd->pf_memset_8bit_8x8_block        =  ps_dec->pf_memset_8bit_8x8_block;
1043    ps_dec_thd->pf_memset_16bit_8x8_linear_block        =  ps_dec->pf_memset_16bit_8x8_linear_block;
1044    ps_dec_thd->pf_copy_yuv420p_buf             =   ps_dec->pf_copy_yuv420p_buf;
1045    ps_dec_thd->pf_fmt_conv_yuv420p_to_yuv422ile    =   ps_dec->pf_fmt_conv_yuv420p_to_yuv422ile;
1046    ps_dec_thd->pf_fmt_conv_yuv420p_to_yuv420sp_uv  =   ps_dec->pf_fmt_conv_yuv420p_to_yuv420sp_uv;
1047    ps_dec_thd->pf_fmt_conv_yuv420p_to_yuv420sp_vu  =   ps_dec->pf_fmt_conv_yuv420p_to_yuv420sp_vu;
1048
1049
1050    memcpy(ps_dec_thd->au1_intra_quant_matrix, ps_dec->au1_intra_quant_matrix, NUM_PELS_IN_BLOCK * sizeof(UWORD8));
1051    memcpy(ps_dec_thd->au1_inter_quant_matrix, ps_dec->au1_inter_quant_matrix, NUM_PELS_IN_BLOCK * sizeof(UWORD8));
1052    ps_dec_thd->pu1_inv_scan_matrix = ps_dec->pu1_inv_scan_matrix;
1053
1054
1055    ps_dec_thd->u2_progressive_sequence = ps_dec->u2_progressive_sequence;
1056    ps_dec_thd->e_pic_type =  ps_dec->e_pic_type;
1057    ps_dec_thd->u2_full_pel_forw_vector = ps_dec->u2_full_pel_forw_vector;
1058    ps_dec_thd->u2_forw_f_code =   ps_dec->u2_forw_f_code;
1059    ps_dec_thd->u2_full_pel_back_vector = ps_dec->u2_full_pel_back_vector;
1060    ps_dec_thd->u2_back_f_code = ps_dec->u2_back_f_code;
1061
1062    memcpy(ps_dec_thd->ai2_mv, ps_dec->ai2_mv, (2*2*2)*sizeof(WORD16));
1063    memcpy(ps_dec_thd->au2_f_code, ps_dec->au2_f_code, (2*2)*sizeof(UWORD16));
1064    ps_dec_thd->u2_intra_dc_precision = ps_dec->u2_intra_dc_precision;
1065    ps_dec_thd->u2_picture_structure = ps_dec->u2_picture_structure;
1066    ps_dec_thd->u2_top_field_first = ps_dec->u2_top_field_first;
1067    ps_dec_thd->u2_frame_pred_frame_dct = ps_dec->u2_frame_pred_frame_dct;
1068    ps_dec_thd->u2_concealment_motion_vectors = ps_dec->u2_concealment_motion_vectors;
1069    ps_dec_thd->u2_q_scale_type =  ps_dec->u2_q_scale_type;
1070    ps_dec_thd->u2_intra_vlc_format = ps_dec->u2_intra_vlc_format;
1071    ps_dec_thd->u2_alternate_scan = ps_dec->u2_alternate_scan;
1072    ps_dec_thd->u2_repeat_first_field = ps_dec->u2_repeat_first_field;
1073    ps_dec_thd->u2_progressive_frame = ps_dec->u2_progressive_frame;
1074    ps_dec_thd->pu1_inp_bits_buf = ps_dec->pu1_inp_bits_buf;
1075    ps_dec_thd->u4_num_inp_bytes = ps_dec->u4_num_inp_bytes;
1076    ps_dec_thd->pv_jobq = ps_dec->pv_jobq;
1077    ps_dec_thd->pv_jobq_buf = ps_dec->pv_jobq_buf;
1078    ps_dec_thd->i4_jobq_buf_size = ps_dec->i4_jobq_buf_size;
1079
1080
1081    ps_dec_thd->u2_frame_rate_code = ps_dec->u2_frame_rate_code;
1082    ps_dec_thd->u2_frame_rate_extension_n = ps_dec->u2_frame_rate_extension_n;
1083    ps_dec_thd->u2_frame_rate_extension_d = ps_dec->u2_frame_rate_extension_d;
1084    ps_dec_thd->u2_framePeriod =   ps_dec->u2_framePeriod;
1085    ps_dec_thd->u2_display_horizontal_size = ps_dec->u2_display_horizontal_size;
1086    ps_dec_thd->u2_display_vertical_size = ps_dec->u2_display_vertical_size;
1087    ps_dec_thd->u2_aspect_ratio_info = ps_dec->u2_aspect_ratio_info;
1088
1089    ps_dec_thd->ps_func_bi_direct = ps_dec->ps_func_bi_direct;
1090    ps_dec_thd->ps_func_forw_or_back = ps_dec->ps_func_forw_or_back;
1091
1092    return 0;
1093
1094}
1095
1096
1097WORD32 impeg2d_get_slice_pos(dec_state_multi_core_t *ps_dec_state_multi_core)
1098{
1099    WORD32 u4_bits;
1100    WORD32 i4_row;
1101
1102
1103    dec_state_t *ps_dec = ps_dec_state_multi_core->ps_dec_state[0];
1104    WORD32 i4_prev_row;
1105    stream_t s_bitstrm;
1106    WORD32 i4_start_row;
1107    WORD32 i4_slice_bistream_ofst;
1108    WORD32 i;
1109    s_bitstrm = ps_dec->s_bit_stream;
1110    i4_prev_row = -1;
1111
1112    ps_dec_state_multi_core->ps_dec_state[0]->i4_start_mb_y = 0;
1113    ps_dec_state_multi_core->ps_dec_state[1]->i4_start_mb_y = -1;
1114    ps_dec_state_multi_core->ps_dec_state[2]->i4_start_mb_y = -1;
1115    ps_dec_state_multi_core->ps_dec_state[3]->i4_start_mb_y = -1;
1116
1117    ps_dec_state_multi_core->ps_dec_state[0]->i4_end_mb_y = ps_dec->u2_num_vert_mb;
1118    ps_dec_state_multi_core->ps_dec_state[1]->i4_end_mb_y = -1;
1119    ps_dec_state_multi_core->ps_dec_state[2]->i4_end_mb_y = -1;
1120    ps_dec_state_multi_core->ps_dec_state[3]->i4_end_mb_y = -1;
1121
1122    if(ps_dec->i4_num_cores == 1)
1123        return 0;
1124    /* Reset the jobq to start of the jobq buffer */
1125    impeg2_jobq_reset((jobq_t *)ps_dec->pv_jobq);
1126
1127    i4_start_row = -1;
1128    i4_slice_bistream_ofst = 0;
1129    while(1)
1130    {
1131        WORD32 i4_is_slice;
1132
1133        if(s_bitstrm.u4_offset + START_CODE_LEN >= s_bitstrm.u4_max_offset)
1134        {
1135            break;
1136        }
1137        u4_bits = impeg2d_bit_stream_nxt(&s_bitstrm,START_CODE_LEN);
1138
1139        i4_row = u4_bits & 0xFF;
1140
1141        /* Detect end of frame */
1142        i4_is_slice = (((u4_bits >> 8) == 0x01) && (i4_row) && (i4_row <= ps_dec->u2_num_vert_mb));
1143        if(!i4_is_slice)
1144            break;
1145
1146        i4_row -= 1;
1147
1148
1149        if(i4_prev_row != i4_row)
1150        {
1151            /* Create a job for previous slice row */
1152            if(i4_start_row != -1)
1153            {
1154                job_t s_job;
1155                IV_API_CALL_STATUS_T ret;
1156                s_job.i2_start_mb_y = i4_start_row;
1157                s_job.i2_end_mb_y = i4_row;
1158                s_job.i4_cmd = CMD_PROCESS;
1159                s_job.i4_bistream_ofst = i4_slice_bistream_ofst;
1160                ret = impeg2_jobq_queue(ps_dec->pv_jobq, &s_job, sizeof(s_job), 1, 0);
1161                if(ret != IV_SUCCESS)
1162                    return ret;
1163
1164            }
1165            /* Store current slice's bitstream offset */
1166            i4_slice_bistream_ofst = s_bitstrm.u4_offset >> 3;
1167            i4_slice_bistream_ofst -= (size_t)s_bitstrm.pv_bs_buf & 3;
1168            i4_prev_row = i4_row;
1169
1170            /* Store current slice's row position */
1171            i4_start_row = i4_row;
1172
1173        }
1174
1175
1176        impeg2d_bit_stream_flush(&s_bitstrm, START_CODE_LEN);
1177
1178        // flush bytes till next start code
1179        /* Flush the bytes till a  start code is encountered  */
1180        while(impeg2d_bit_stream_nxt(&s_bitstrm, 24) != START_CODE_PREFIX)
1181        {
1182            impeg2d_bit_stream_get(&s_bitstrm, 8);
1183
1184            if(s_bitstrm.u4_offset >= s_bitstrm.u4_max_offset)
1185            {
1186                break;
1187            }
1188        }
1189    }
1190
1191    /* Create job for the last slice row */
1192    {
1193        job_t s_job;
1194        IV_API_CALL_STATUS_T e_ret;
1195        s_job.i2_start_mb_y = i4_start_row;
1196        s_job.i2_end_mb_y = ps_dec->u2_num_vert_mb;
1197        s_job.i4_cmd = CMD_PROCESS;
1198        s_job.i4_bistream_ofst = i4_slice_bistream_ofst;
1199        e_ret = impeg2_jobq_queue(ps_dec->pv_jobq, &s_job, sizeof(s_job), 1, 0);
1200        if(e_ret != IV_SUCCESS)
1201            return e_ret;
1202
1203    }
1204    if((NULL != ps_dec->ps_disp_pic) && ((0 == ps_dec->u4_share_disp_buf) || (IV_YUV_420P != ps_dec->i4_chromaFormat)))
1205    {
1206        for(i = 0; i < ps_dec->u2_vertical_size; i+=64)
1207        {
1208            job_t s_job;
1209            IV_API_CALL_STATUS_T ret;
1210            s_job.i2_start_mb_y = i;
1211            s_job.i2_start_mb_y >>= 4;
1212            s_job.i2_end_mb_y = (i + 64);
1213            s_job.i2_end_mb_y >>= 4;
1214            s_job.i4_cmd = CMD_FMTCONV;
1215            s_job.i4_bistream_ofst = 0;
1216            ret = impeg2_jobq_queue(ps_dec->pv_jobq, &s_job, sizeof(s_job), 1, 0);
1217            if(ret != IV_SUCCESS)
1218                return ret;
1219
1220        }
1221    }
1222
1223    impeg2_jobq_terminate(ps_dec->pv_jobq);
1224    ps_dec->i4_bytes_consumed = s_bitstrm.u4_offset >> 3;
1225    ps_dec->i4_bytes_consumed -= ((size_t)s_bitstrm.pv_bs_buf & 3);
1226
1227    return 0;
1228}
1229
1230/*******************************************************************************
1231*
1232*  Function Name   : impeg2d_dec_pic_data
1233*
1234*  Description     : It intializes several parameters and decodes a Picture
1235*                    till any slice is left.
1236*
1237*  Arguments       :
1238*  dec             : Decoder context
1239*
1240*  Values Returned : None
1241*******************************************************************************/
1242
1243void impeg2d_dec_pic_data(dec_state_t *ps_dec)
1244{
1245
1246    WORD32 i;
1247    dec_state_multi_core_t *ps_dec_state_multi_core;
1248
1249    UWORD32  u4_error_code;
1250
1251    dec_state_t *ps_dec_thd;
1252    WORD32 i4_status;
1253    WORD32 i4_min_mb_y;
1254
1255
1256    /* Resetting the MB address and MB coordinates at the start of the Frame */
1257    ps_dec->u2_mb_x = ps_dec->u2_mb_y = 0;
1258    u4_error_code = 0;
1259
1260    ps_dec_state_multi_core = ps_dec->ps_dec_state_multi_core;
1261    impeg2d_get_slice_pos(ps_dec_state_multi_core);
1262
1263    i4_min_mb_y = 1;
1264    for(i=0; i < ps_dec->i4_num_cores - 1; i++)
1265    {
1266        // initialize decoder context for thread
1267        // launch dec->u4_num_cores-1 threads
1268
1269        ps_dec_thd = ps_dec_state_multi_core->ps_dec_state[i+1];
1270
1271        ps_dec_thd->ps_disp_pic = ps_dec->ps_disp_pic;
1272        ps_dec_thd->ps_disp_frm_buf = ps_dec->ps_disp_frm_buf;
1273
1274        i4_status = impeg2d_init_thread_dec_ctxt(ps_dec, ps_dec_thd, i4_min_mb_y);
1275        //impeg2d_dec_pic_data_thread(ps_dec_thd);
1276
1277        if(i4_status == 0)
1278        {
1279            ithread_create(ps_dec_thd->pv_codec_thread_handle, NULL, (void *)impeg2d_dec_pic_data_thread, ps_dec_thd);
1280            ps_dec_state_multi_core->au4_thread_launched[i + 1] = 1;
1281            i4_min_mb_y = ps_dec_thd->u2_mb_y + 1;
1282        }
1283        else
1284        {
1285            ps_dec_state_multi_core->au4_thread_launched[i + 1] = 0;
1286            break;
1287        }
1288    }
1289
1290    impeg2d_dec_pic_data_thread(ps_dec);
1291
1292    // wait for threads to complete
1293    for(i=0; i < (ps_dec->i4_num_cores - 1); i++)
1294    {
1295        if(ps_dec_state_multi_core->au4_thread_launched[i + 1] == 1)
1296        {
1297            ps_dec_thd = ps_dec_state_multi_core->ps_dec_state[i+1];
1298            ithread_join(ps_dec_thd->pv_codec_thread_handle, NULL);
1299        }
1300    }
1301
1302    ps_dec->u4_error_code = u4_error_code;
1303
1304}
1305/*******************************************************************************
1306*
1307*  Function Name   : impeg2d_flush_ext_and_user_data
1308*
1309*  Description     : Flushes the extension and user data present in the
1310*                    stream_t
1311*
1312*  Arguments       :
1313*  dec             : Decoder context
1314*
1315*  Values Returned : None
1316*******************************************************************************/
1317void impeg2d_flush_ext_and_user_data(dec_state_t *ps_dec)
1318{
1319    UWORD32 u4_start_code;
1320    stream_t *ps_stream;
1321
1322    ps_stream    = &ps_dec->s_bit_stream;
1323    u4_start_code = impeg2d_bit_stream_nxt(ps_stream,START_CODE_LEN);
1324
1325    while(u4_start_code == EXTENSION_START_CODE || u4_start_code == USER_DATA_START_CODE)
1326    {
1327        impeg2d_bit_stream_flush(ps_stream,START_CODE_LEN);
1328        while(impeg2d_bit_stream_nxt(ps_stream,START_CODE_PREFIX_LEN) != START_CODE_PREFIX)
1329        {
1330            impeg2d_bit_stream_flush(ps_stream,8);
1331        }
1332        u4_start_code = impeg2d_bit_stream_nxt(ps_stream,START_CODE_LEN);
1333    }
1334}
1335/*******************************************************************************
1336*
1337*  Function Name   : impeg2d_dec_user_data
1338*
1339*  Description     : Flushes the user data present in the stream_t
1340*
1341*  Arguments       :
1342*  dec             : Decoder context
1343*
1344*  Values Returned : None
1345*******************************************************************************/
1346void impeg2d_dec_user_data(dec_state_t *ps_dec)
1347{
1348    UWORD32 u4_start_code;
1349    stream_t *ps_stream;
1350
1351    ps_stream    = &ps_dec->s_bit_stream;
1352    u4_start_code = impeg2d_bit_stream_nxt(ps_stream,START_CODE_LEN);
1353
1354    while(u4_start_code == USER_DATA_START_CODE)
1355    {
1356        impeg2d_bit_stream_flush(ps_stream,START_CODE_LEN);
1357        while(impeg2d_bit_stream_nxt(ps_stream,START_CODE_PREFIX_LEN) != START_CODE_PREFIX)
1358        {
1359            impeg2d_bit_stream_flush(ps_stream,8);
1360        }
1361        u4_start_code = impeg2d_bit_stream_nxt(ps_stream,START_CODE_LEN);
1362    }
1363}
1364/*******************************************************************************
1365*  Function Name   : impeg2d_dec_seq_ext_data
1366*
1367*  Description     : Decodes the extension data following Sequence
1368*                    Extension. It flushes any user data if present
1369*
1370*  Arguments       :
1371*  dec             : Decoder context
1372*
1373*  Values Returned : None
1374*******************************************************************************/
1375IMPEG2D_ERROR_CODES_T impeg2d_dec_seq_ext_data(dec_state_t *ps_dec)
1376{
1377    stream_t   *ps_stream;
1378    UWORD32     u4_start_code;
1379    IMPEG2D_ERROR_CODES_T e_error;
1380
1381    e_error = (IMPEG2D_ERROR_CODES_T) IVD_ERROR_NONE;
1382
1383    ps_stream      = &ps_dec->s_bit_stream;
1384    u4_start_code = impeg2d_bit_stream_nxt(ps_stream,START_CODE_LEN);
1385    while( (u4_start_code == EXTENSION_START_CODE ||
1386            u4_start_code == USER_DATA_START_CODE) &&
1387            (IMPEG2D_ERROR_CODES_T)IVD_ERROR_NONE == e_error)
1388    {
1389        if(u4_start_code == USER_DATA_START_CODE)
1390        {
1391            impeg2d_dec_user_data(ps_dec);
1392        }
1393        else
1394        {
1395            impeg2d_bit_stream_flush(ps_stream,START_CODE_LEN);
1396            u4_start_code   = impeg2d_bit_stream_nxt(ps_stream,EXT_ID_LEN);
1397            switch(u4_start_code)
1398            {
1399            case SEQ_DISPLAY_EXT_ID:
1400                impeg2d_dec_seq_disp_ext(ps_dec);
1401                break;
1402            case SEQ_SCALABLE_EXT_ID:
1403                e_error = IMPEG2D_SCALABILITIY_NOT_SUPPORTED;
1404                break;
1405            default:
1406                /* In case its a reserved extension code */
1407                impeg2d_bit_stream_flush(ps_stream,EXT_ID_LEN);
1408                impeg2d_peek_next_start_code(ps_dec);
1409                break;
1410            }
1411        }
1412        u4_start_code = impeg2d_bit_stream_nxt(ps_stream,START_CODE_LEN);
1413    }
1414    return e_error;
1415}
1416/*******************************************************************************
1417*  Function Name   : impeg2d_dec_pic_ext_data
1418*
1419*  Description     : Decodes the extension data following Picture Coding
1420*                    Extension. It flushes any user data if present
1421*
1422*  Arguments       :
1423*  dec             : Decoder context
1424*
1425*  Values Returned : None
1426*******************************************************************************/
1427IMPEG2D_ERROR_CODES_T impeg2d_dec_pic_ext_data(dec_state_t *ps_dec)
1428{
1429    stream_t   *ps_stream;
1430    UWORD32     u4_start_code;
1431    IMPEG2D_ERROR_CODES_T e_error;
1432
1433    e_error = (IMPEG2D_ERROR_CODES_T)IVD_ERROR_NONE;
1434
1435    ps_stream      = &ps_dec->s_bit_stream;
1436    u4_start_code   = impeg2d_bit_stream_nxt(ps_stream,START_CODE_LEN);
1437    while ( (u4_start_code == EXTENSION_START_CODE ||
1438            u4_start_code == USER_DATA_START_CODE) &&
1439            (IMPEG2D_ERROR_CODES_T)IVD_ERROR_NONE == e_error)
1440    {
1441        if(u4_start_code == USER_DATA_START_CODE)
1442        {
1443            impeg2d_dec_user_data(ps_dec);
1444        }
1445        else
1446        {
1447            impeg2d_bit_stream_flush(ps_stream,START_CODE_LEN);
1448            u4_start_code   = impeg2d_bit_stream_nxt(ps_stream,EXT_ID_LEN);
1449            switch(u4_start_code)
1450            {
1451            case QUANT_MATRIX_EXT_ID:
1452                impeg2d_dec_quant_matrix_ext(ps_dec);
1453                break;
1454            case COPYRIGHT_EXT_ID:
1455                impeg2d_dec_copyright_ext(ps_dec);
1456                break;
1457            case PIC_DISPLAY_EXT_ID:
1458                impeg2d_dec_pic_disp_ext(ps_dec);
1459                break;
1460            case CAMERA_PARAM_EXT_ID:
1461                impeg2d_dec_cam_param_ext(ps_dec);
1462                break;
1463            case ITU_T_EXT_ID:
1464                impeg2d_dec_itu_t_ext(ps_dec);
1465                break;
1466            case PIC_SPATIAL_SCALABLE_EXT_ID:
1467            case PIC_TEMPORAL_SCALABLE_EXT_ID:
1468                e_error = IMPEG2D_SCALABLITY_NOT_SUP;
1469                break;
1470            default:
1471                /* In case its a reserved extension code */
1472                impeg2d_bit_stream_flush(ps_stream,EXT_ID_LEN);
1473                impeg2d_next_start_code(ps_dec);
1474                break;
1475            }
1476        }
1477        u4_start_code = impeg2d_bit_stream_nxt(ps_stream,START_CODE_LEN);
1478    }
1479    return e_error;
1480}
1481
1482/*******************************************************************************
1483*
1484*  Function Name   : impeg2d_process_video_header
1485*
1486*  Description     : Processes video sequence header information
1487*
1488*  Arguments       :
1489*  dec             : Decoder context
1490*
1491*  Values Returned : None
1492*******************************************************************************/
1493IMPEG2D_ERROR_CODES_T impeg2d_process_video_header(dec_state_t *ps_dec)
1494{
1495    stream_t *ps_stream;
1496    ps_stream = &ps_dec->s_bit_stream;
1497    IMPEG2D_ERROR_CODES_T e_error;
1498
1499    impeg2d_next_code(ps_dec, SEQUENCE_HEADER_CODE);
1500    if(ps_dec->s_bit_stream.u4_offset < ps_dec->s_bit_stream.u4_max_offset)
1501    {
1502        e_error = impeg2d_dec_seq_hdr(ps_dec);
1503        if ((IMPEG2D_ERROR_CODES_T)IVD_ERROR_NONE != e_error)
1504        {
1505            return e_error;
1506        }
1507    }
1508    else
1509    {
1510      return IMPEG2D_BITSTREAM_BUFF_EXCEEDED_ERR;
1511    }
1512    if (impeg2d_bit_stream_nxt(ps_stream,START_CODE_LEN) == EXTENSION_START_CODE)
1513    {
1514        /* MPEG2 Decoder */
1515        if(ps_dec->s_bit_stream.u4_offset < ps_dec->s_bit_stream.u4_max_offset)
1516        {
1517            e_error = impeg2d_dec_seq_ext(ps_dec);
1518            if ((IMPEG2D_ERROR_CODES_T)IVD_ERROR_NONE != e_error)
1519            {
1520                return e_error;
1521            }
1522        }
1523        else
1524        {
1525          return IMPEG2D_BITSTREAM_BUFF_EXCEEDED_ERR;
1526        }
1527        if(ps_dec->s_bit_stream.u4_offset < ps_dec->s_bit_stream.u4_max_offset)
1528        {
1529            e_error = impeg2d_dec_seq_ext_data(ps_dec);
1530            if ((IMPEG2D_ERROR_CODES_T)IVD_ERROR_NONE != e_error)
1531            {
1532                return e_error;
1533            }
1534        }
1535        return impeg2d_init_video_state(ps_dec,MPEG_2_VIDEO);
1536    }
1537    else
1538    {
1539         /* MPEG1 Decoder */
1540        if(ps_dec->s_bit_stream.u4_offset < ps_dec->s_bit_stream.u4_max_offset)
1541        {
1542            impeg2d_flush_ext_and_user_data(ps_dec);
1543        }
1544        return impeg2d_init_video_state(ps_dec,MPEG_1_VIDEO);
1545    }
1546}
1547/*******************************************************************************
1548*
1549*  Function Name   : impeg2d_process_video_bit_stream
1550*
1551*  Description     : Processes video sequence header information
1552*
1553*  Arguments       :
1554*  dec             : Decoder context
1555*
1556*  Values Returned : None
1557*******************************************************************************/
1558IMPEG2D_ERROR_CODES_T impeg2d_process_video_bit_stream(dec_state_t *ps_dec)
1559{
1560    stream_t *ps_stream;
1561    UWORD32 u4_next_bits, u4_start_code_found;
1562    IMPEG2D_ERROR_CODES_T e_error;
1563
1564    ps_stream = &ps_dec->s_bit_stream;
1565    impeg2d_next_start_code(ps_dec);
1566    /* If the stream is MPEG-2 compliant stream */
1567    u4_start_code_found = 0;
1568
1569    if(ps_dec->u2_is_mpeg2)
1570    {
1571        /* MPEG2 decoding starts */
1572        while((u4_start_code_found == 0) && (ps_dec->s_bit_stream.u4_offset < ps_dec->s_bit_stream.u4_max_offset))
1573        {
1574            u4_next_bits = impeg2d_bit_stream_nxt(ps_stream,START_CODE_LEN);
1575
1576            if(u4_next_bits == SEQUENCE_HEADER_CODE)
1577            {
1578                if(ps_dec->s_bit_stream.u4_offset < ps_dec->s_bit_stream.u4_max_offset)
1579                {
1580                    e_error = impeg2d_dec_seq_hdr(ps_dec);
1581                    if ((IMPEG2D_ERROR_CODES_T)IVD_ERROR_NONE != e_error)
1582                    {
1583                        return e_error;
1584                    }
1585
1586                    u4_start_code_found = 0;
1587
1588                }
1589                else
1590                {
1591                    return IMPEG2D_BITSTREAM_BUFF_EXCEEDED_ERR;
1592                }
1593
1594
1595                if(ps_dec->s_bit_stream.u4_offset < ps_dec->s_bit_stream.u4_max_offset)
1596                {
1597                    IMPEG2D_ERROR_CODES_T e_error;
1598                    e_error = impeg2d_dec_seq_ext(ps_dec);
1599                    if ((IMPEG2D_ERROR_CODES_T)IVD_ERROR_NONE != e_error)
1600                    {
1601                        return e_error;
1602                    }
1603                    u4_start_code_found = 0;
1604
1605                }
1606                else
1607                {
1608                    return IMPEG2D_BITSTREAM_BUFF_EXCEEDED_ERR;
1609                }
1610            }
1611            else if((u4_next_bits == USER_DATA_START_CODE) || (u4_next_bits == EXTENSION_START_CODE))
1612            {
1613                if(ps_dec->s_bit_stream.u4_offset < ps_dec->s_bit_stream.u4_max_offset)
1614                {
1615                    impeg2d_dec_seq_ext_data(ps_dec);
1616                    u4_start_code_found = 0;
1617
1618                }
1619
1620            }
1621            else if((ps_dec->s_bit_stream.u4_offset < ps_dec->s_bit_stream.u4_max_offset)
1622                    && (u4_next_bits == GOP_START_CODE))
1623            {
1624                impeg2d_dec_grp_of_pic_hdr(ps_dec);
1625                impeg2d_dec_user_data(ps_dec);
1626                u4_start_code_found = 0;
1627
1628            }
1629            else if((ps_dec->s_bit_stream.u4_offset < ps_dec->s_bit_stream.u4_max_offset)
1630                    && (u4_next_bits == PICTURE_START_CODE))
1631            {
1632
1633                e_error = impeg2d_dec_pic_hdr(ps_dec);
1634                if ((IMPEG2D_ERROR_CODES_T)IVD_ERROR_NONE != e_error)
1635                {
1636                    return e_error;
1637                }
1638                impeg2d_dec_pic_coding_ext(ps_dec);
1639                e_error = impeg2d_dec_pic_ext_data(ps_dec);
1640                if ((IMPEG2D_ERROR_CODES_T)IVD_ERROR_NONE != e_error)
1641                {
1642                    return e_error;
1643                }
1644                impeg2d_pre_pic_dec_proc(ps_dec);
1645                impeg2d_dec_pic_data(ps_dec);
1646                impeg2d_post_pic_dec_proc(ps_dec);
1647                u4_start_code_found = 1;
1648            }
1649            else
1650
1651            {
1652                FLUSH_BITS(ps_dec->s_bit_stream.u4_offset, ps_dec->s_bit_stream.u4_buf, ps_dec->s_bit_stream.u4_buf_nxt, 8, ps_dec->s_bit_stream.pu4_buf_aligned);
1653
1654            }
1655            if(u4_start_code_found == 0)
1656            {
1657                impeg2d_next_start_code(ps_dec);
1658            }
1659        }
1660        if((u4_start_code_found == 0) && (ps_dec->s_bit_stream.u4_offset > ps_dec->s_bit_stream.u4_max_offset))
1661        {
1662            return IMPEG2D_FRM_HDR_START_CODE_NOT_FOUND;
1663        }
1664
1665    }
1666        /* If the stream is MPEG-1 compliant stream */
1667    else
1668    {
1669        while((u4_start_code_found == 0) && (ps_dec->s_bit_stream.u4_offset < ps_dec->s_bit_stream.u4_max_offset))
1670        {
1671            u4_next_bits = impeg2d_bit_stream_nxt(ps_stream,START_CODE_LEN);
1672
1673            if(impeg2d_bit_stream_nxt(ps_stream,START_CODE_LEN) == SEQUENCE_HEADER_CODE)
1674            {
1675                if(ps_dec->s_bit_stream.u4_offset < ps_dec->s_bit_stream.u4_max_offset)
1676                {
1677                    e_error = impeg2d_dec_seq_hdr(ps_dec);
1678                    if ((IMPEG2D_ERROR_CODES_T)IVD_ERROR_NONE != e_error)
1679                    {
1680                        return e_error;
1681                    }
1682
1683                    u4_start_code_found = 0;
1684                }
1685                else
1686                {
1687                    return IMPEG2D_BITSTREAM_BUFF_EXCEEDED_ERR;
1688                }
1689            }
1690            else if((ps_dec->s_bit_stream.u4_offset < ps_dec->s_bit_stream.u4_max_offset) && (u4_next_bits == EXTENSION_START_CODE || u4_next_bits == USER_DATA_START_CODE))
1691            {
1692                impeg2d_flush_ext_and_user_data(ps_dec);
1693                u4_start_code_found = 0;
1694            }
1695
1696
1697            else if ((impeg2d_bit_stream_nxt(ps_stream,START_CODE_LEN) == GOP_START_CODE)
1698                    && (ps_dec->s_bit_stream.u4_offset < ps_dec->s_bit_stream.u4_max_offset))
1699            {
1700                impeg2d_dec_grp_of_pic_hdr(ps_dec);
1701                impeg2d_flush_ext_and_user_data(ps_dec);
1702                u4_start_code_found = 0;
1703            }
1704            else if ((impeg2d_bit_stream_nxt(ps_stream,START_CODE_LEN) == PICTURE_START_CODE)
1705                    && (ps_dec->s_bit_stream.u4_offset < ps_dec->s_bit_stream.u4_max_offset))
1706            {
1707
1708                e_error = impeg2d_dec_pic_hdr(ps_dec);
1709                if ((IMPEG2D_ERROR_CODES_T)IVD_ERROR_NONE != e_error)
1710                {
1711                    return e_error;
1712                }
1713                impeg2d_flush_ext_and_user_data(ps_dec);
1714                impeg2d_pre_pic_dec_proc(ps_dec);
1715                impeg2d_dec_pic_data(ps_dec);
1716                impeg2d_post_pic_dec_proc(ps_dec);
1717                u4_start_code_found = 1;
1718            }
1719            else
1720            {
1721                FLUSH_BITS(ps_dec->s_bit_stream.u4_offset, ps_dec->s_bit_stream.u4_buf, ps_dec->s_bit_stream.u4_buf_nxt, 8, ps_dec->s_bit_stream.pu4_buf_aligned);
1722            }
1723            impeg2d_next_start_code(ps_dec);
1724
1725        }
1726        if((u4_start_code_found == 0) && (ps_dec->s_bit_stream.u4_offset > ps_dec->s_bit_stream.u4_max_offset))
1727        {
1728           return IMPEG2D_FRM_HDR_START_CODE_NOT_FOUND;
1729        }
1730    }
1731
1732    return (IMPEG2D_ERROR_CODES_T)IVD_ERROR_NONE;
1733}
1734