1bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee#include "viddec_fw_debug.h"
2bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee#include "viddec_parser_ops.h"
3bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee#include "viddec_mp4_parse.h"
4bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee#include "viddec_mp4_decodevideoobjectplane.h"
5bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee#include "viddec_mp4_shortheader.h"
6bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee#include "viddec_mp4_videoobjectlayer.h"
7bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee#include "viddec_mp4_videoobjectplane.h"
8bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee#include "viddec_mp4_visualobject.h"
9bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
10bd8388b4555645b3d29abc6a94c303638064d69awonjong.leeextern uint32_t viddec_parse_sc_mp4(void *in, void *pcxt, void *sc_state);
11bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
12bd8388b4555645b3d29abc6a94c303638064d69awonjong.leevoid viddec_mp4_get_context_size(viddec_parser_memory_sizes_t *size)
13bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee{
14bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    /* Should return size of my structure */
15bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    size->context_size = sizeof(viddec_mp4_parser_t);
16bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    size->persist_size = 0;
17bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    return;
18bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee} // viddec_mp4_get_context_size
19bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
20bd8388b4555645b3d29abc6a94c303638064d69awonjong.leeuint32_t viddec_mp4_wkld_done(void *parent, void *ctxt, uint32_t next_sc, uint32_t *codec_specific_errors)
21bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee{
22bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    viddec_mp4_parser_t *parser = (viddec_mp4_parser_t *) ctxt;
23bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    int result = VIDDEC_PARSE_SUCESS;
24bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    uint8_t frame_boundary = false;
25bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    uint8_t force_frame_complete = false;
26bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
27bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    //DEB("entering is_wkld_done: next_sc: 0x%x, sc_seen: %d\n", next_sc, parser->sc_seen);
28bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
29bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    parent = parent;
30bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
31bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    // VS, VO, VOL, VOP or GVOP start codes indicate frame boundary.
32bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    frame_boundary = (  (MP4_SC_VISUAL_OBJECT_SEQUENCE == next_sc) ||
33bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee                        (MP4_SC_VISUAL_OBJECT == next_sc) ||
34bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee                        ((MP4_SC_VIDEO_OBJECT_LAYER_MIN <= next_sc) && (next_sc <= MP4_SC_VIDEO_OBJECT_LAYER_MAX)) ||
35bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee                        (next_sc <= MP4_SC_VIDEO_OBJECT_MAX) ||
36bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee                        (MP4_SC_VIDEO_OBJECT_PLANE == next_sc) ||
37bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee                        ((SHORT_THIRD_STARTCODE_BYTE & 0xFC) == (next_sc & 0xFC)) ||
38bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee                        (MP4_SC_GROUP_OF_VOP == next_sc)    );
39bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
40bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    // EOS and discontinuity should force workload completion.
41bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    force_frame_complete = ((VIDDEC_PARSE_EOS == next_sc) || (VIDDEC_PARSE_DISCONTINUITY == next_sc));
42bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
43bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    if(frame_boundary | force_frame_complete)
44bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    {
45bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee        *codec_specific_errors = 0;
46bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
47bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee        // Frame is considered complete and without errors, if a VOL was received since startup and
48bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee        // if a VOP was received for this workload.
49bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee        if (!((parser->sc_seen & MP4_SC_SEEN_VOL) && (parser->sc_seen & MP4_SC_SEEN_VOP)) && !(parser->sc_seen & MP4_SC_SEEN_SVH))
50bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee            *codec_specific_errors |= VIDDEC_FW_WORKLOAD_ERR_NOTDECODABLE;
51bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
52bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee        /*
53bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee        This is the strategy for error detection.
54bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee        Errors in any field needed by the firmware (parser/decoder) are treated as non-decodable.
55bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee        Errors in other fields will be considered decodable.
56bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee        Defaults/alternate strategies will be considered on a case-by-case basis as customer content is seen.
57bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
58bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee        ERROR_TYPE      |       PARSING         |   INVALID/UNSUPPORTED |       BS = Bitstream error
59bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee        -----------------------------------------------------------------       UNSUP = Un-supported
60bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee        DFLT_PRESENT    |       YES |   NO      |       YES |   NO      |       ND = Non-decodable
61bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee        COMPONENT USED  |           |           |           |           |       DFLT = Populate defaults
62bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee        -----------------------------------------------------------------
63bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee        FIRMWARE        | BS+ND     | BS+ND     | UNSUP+ND  | UNSUP+ND  |
64bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee        DRIVER/USER     | BS+DFLT   | BS        | UNSUP     | UNSUP     |
65bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee        NONE            | BS        | BS        | UNSUP     | UNSUP     |
66bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee                        |           |           | Continue Parsing      |
67bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee        */
68bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee        if((parser->bitstream_error & MP4_BS_ERROR_HDR_NONDEC) || (parser->bitstream_error & MP4_BS_ERROR_FRM_NONDEC))
69bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee            *codec_specific_errors |= (VIDDEC_FW_WORKLOAD_ERR_NOTDECODABLE | VIDDEC_FW_WORKLOAD_ERR_MISSING_DMEM);
70bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
71bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee        if((parser->bitstream_error & MP4_BS_ERROR_HDR_UNSUP) || (parser->bitstream_error & MP4_BS_ERROR_FRM_UNSUP))
72bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee            *codec_specific_errors |= VIDDEC_FW_WORKLOAD_ERR_UNSUPPORTED;
73bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
74bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee        if((parser->bitstream_error & MP4_BS_ERROR_HDR_PARSE) || (parser->bitstream_error & MP4_BS_ERROR_FRM_PARSE))
75bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee            *codec_specific_errors |= VIDDEC_FW_WORKLOAD_ERR_BITSTREAM_ERROR;
76bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
77bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee        parser->bitstream_error &= MP4_HDR_ERROR_MASK;
78bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee        parser->sc_seen &= MP4_SC_SEEN_VOL;
79bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee        result = VIDDEC_PARSE_FRMDONE;
80bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    }
81bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    //DEB("exiting is_wkld_done: next_sc: 0x%x, sc_seen: %d, err: %d, fr_bnd:%d, force:%d\n",
82bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    //        next_sc, parser->sc_seen, *codec_specific_errors, frame_boundary, force_frame_complete);
83bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
84bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    return result;
85bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee} // viddec_mp4_wkld_done
86bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
87bd8388b4555645b3d29abc6a94c303638064d69awonjong.leevoid viddec_mp4_init(void *ctxt, uint32_t *persist_mem, uint32_t preserve)
88bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee{
89bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    viddec_mp4_parser_t *parser = (viddec_mp4_parser_t *) ctxt;
90bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
91bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    persist_mem = persist_mem;
92bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    parser->is_frame_start = false;
93bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    parser->prev_sc = MP4_SC_INVALID;
94bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    parser->current_sc = MP4_SC_INVALID;
95bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    parser->cur_sc_prefix = false;
96bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    parser->next_sc_prefix = false;
97bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    parser->ignore_scs = false;
98bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
99bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    if(preserve)
100bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    {
101bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee        // Need to maintain information till VOL
102bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee        parser->sc_seen &= MP4_SC_SEEN_VOL;
103bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee        parser->bitstream_error &= MP4_HDR_ERROR_MASK;
104bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
105bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee        // Reset only frame related data
106bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee        memset(&(parser->info.VisualObject.VideoObject.VideoObjectPlane), 0, sizeof(mp4_VideoObjectPlane_t));
107bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee        memset(&(parser->info.VisualObject.VideoObject.VideoObjectPlaneH263), 0, sizeof(mp4_VideoObjectPlaneH263));
108bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    }
109bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    else
110bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    {
111bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee        parser->sc_seen = MP4_SC_SEEN_INVALID;
112bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee        parser->bitstream_error = MP4_BS_ERROR_NONE;
113bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee        memset(&(parser->info), 0, sizeof(mp4_Info_t));
114bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    }
115bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
116bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    return;
117bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee} // viddec_mp4_init
118bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
119bd8388b4555645b3d29abc6a94c303638064d69awonjong.leestatic uint32_t viddec_mp4_decodevop_and_emitwkld(void *parent, void *ctxt)
120bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee{
121bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    int status = MP4_STATUS_OK;
122bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    viddec_mp4_parser_t *cxt = (viddec_mp4_parser_t *)ctxt;
123bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
124bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    status = mp4_DecodeVideoObjectPlane(&(cxt->info));
125bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
126bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee#ifndef VBP
127bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    status = viddec_fw_mp4_emit_workload(parent, ctxt);
128bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee#endif
129bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
130bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    return status;
131bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee} // viddec_mp4_decodevop_and_emitwkld
132bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
133bd8388b4555645b3d29abc6a94c303638064d69awonjong.leeuint32_t viddec_mp4_parse(void *parent, void *ctxt)
134bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee{
135bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    uint32_t sc=0;
136bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    viddec_mp4_parser_t *cxt;
137bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    uint8_t is_svh=0;
138bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    int32_t getbits=0;
139bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    int32_t status = 0;
140bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
141bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    cxt = (viddec_mp4_parser_t *)ctxt;
142bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    is_svh = (cxt->cur_sc_prefix) ? false: true;
143bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    if((getbits = viddec_pm_peek_bits(parent, &sc, 32)) == -1)
144bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    {
145bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee        DEB("Start code not found\n");
146bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee        return VIDDEC_PARSE_ERROR;
147bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    }
148bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
149bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    if(!is_svh)
150bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    {
151bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee        viddec_pm_get_bits(parent, &sc, 32);
152bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee        sc = sc & 0xFF;
153bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee        cxt->current_sc = sc;
154bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee        cxt->current_sc |= 0x100;
155bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee        DEB("current_sc=0x%.8X, prev_sc=0x%x\n", sc, cxt->prev_sc);
156bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
157bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee        switch(sc)
158bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee        {
159bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee            case MP4_SC_VISUAL_OBJECT_SEQUENCE:
160bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee            {
161bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee                status = mp4_Parse_VisualSequence(parent, cxt);
162bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee                cxt->prev_sc = MP4_SC_VISUAL_OBJECT_SEQUENCE;
163bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee                DEB("MP4_VISUAL_OBJECT_SEQUENCE_SC: \n");
164bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee                break;
165bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee            }
166bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee            case MP4_SC_VISUAL_OBJECT_SEQUENCE_EC:
167bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee            {/* Not required to do anything */
168bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee                break;
169bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee            }
170bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee            case MP4_SC_USER_DATA:
171bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee            {   /* Copy userdata to user-visible buffer (EMIT) */
172bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee                status = mp4_Parse_UserData(parent, cxt);
173bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee                DEB("MP4_USER_DATA_SC: \n");
174bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee                break;
175bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee            }
176bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee            case MP4_SC_GROUP_OF_VOP:
177bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee            {
178bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee                status = mp4_Parse_GroupOfVideoObjectPlane(parent, cxt);
179bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee                cxt->prev_sc = MP4_SC_GROUP_OF_VOP;
180bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee                DEB("MP4_GROUP_OF_VOP_SC:0x%.8X\n", status);
181bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee                break;
182bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee            }
183bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee            case MP4_SC_VIDEO_SESSION_ERROR:
184bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee            {/* Not required to do anything?? */
185bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee                break;
186bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee            }
187bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee            case MP4_SC_VISUAL_OBJECT:
188bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee            {
189bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee                status = mp4_Parse_VisualObject(parent, cxt);
190bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee                cxt->prev_sc = MP4_SC_VISUAL_OBJECT;
191bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee                DEB("MP4_VISUAL_OBJECT_SC: status=%.8X\n", status);
192bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee                break;
193bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee            }
194bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee            case MP4_SC_VIDEO_OBJECT_PLANE:
195bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee            {
196bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee                /* We must decode the VOP Header information, it does not end  on a byte boundary, so we need to emit
197bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee                   a starting bit offset after parsing the header. */
198bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee                status = mp4_Parse_VideoObjectPlane(parent, cxt);
199bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee                status = viddec_mp4_decodevop_and_emitwkld(parent, cxt);
200bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee                // TODO: Fix this for interlaced
201bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee                cxt->is_frame_start = true;
202bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee                cxt->sc_seen |= MP4_SC_SEEN_VOP;
203bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
204bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee                DEB("MP4_VIDEO_OBJECT_PLANE_SC: status=0x%.8X\n", status);
205bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee                break;
206bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee            }
207bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee            case MP4_SC_STUFFING:
208bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee            {
209bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee                break;
210bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee            }
211bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee            default:
212bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee            {
213bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee                if( (sc >=  MP4_SC_VIDEO_OBJECT_LAYER_MIN) && (sc <=  MP4_SC_VIDEO_OBJECT_LAYER_MAX) )
214bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee                {
215bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee                    status = mp4_Parse_VideoObjectLayer(parent, cxt);
216bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee                    cxt->sc_seen = MP4_SC_SEEN_VOL;
217bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee                    cxt->prev_sc = MP4_SC_VIDEO_OBJECT_LAYER_MIN;
218bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee                    DEB("MP4_VIDEO_OBJECT_LAYER_MIN_SC:status=0x%.8X\n", status);
219bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee                    sc = MP4_SC_VIDEO_OBJECT_LAYER_MIN;
220bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee                }
221bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee                // sc is unsigned and will be >= 0, so no check needed for sc >= MP4_SC_VIDEO_OBJECT_MIN
222bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee                else if(sc <= MP4_SC_VIDEO_OBJECT_MAX)
223bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee                {
224bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee                     // If there is more data, it is short video header, else the next start code is expected to be VideoObjectLayer
225bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee                     getbits = viddec_pm_get_bits(parent, &sc, 22);
226bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee                     if(getbits != -1)
227bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee                     {
228bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee                        cxt->current_sc = sc;
229bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee                        status = mp4_Parse_VideoObject_svh(parent, cxt);
230bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee                        status = viddec_mp4_decodevop_and_emitwkld(parent, cxt);
231bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee                        cxt->sc_seen = MP4_SC_SEEN_SVH;
232bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee                        cxt->is_frame_start = true;
233bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee                        DEB("MP4_SCS_SVH: status=0x%.8X 0x%.8X %.8X\n", status, cxt->current_sc, sc);
234bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee                        DEB("MP4_VIDEO_OBJECT_MIN_SC:status=0x%.8X\n", status);
235bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee                     }
236bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee                }
237bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee                else
238bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee                {
239bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee                    DEB("UNKWON Cod:0x%08X\n", sc);
240bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee                }
241bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee            }
242bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee            break;
243bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee        }
244bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    }
245bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    else
246bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    {
247bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee        viddec_pm_get_bits(parent, &sc, 22);
248bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee        cxt->current_sc = sc;
249bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee        DEB("current_sc=0x%.8X, prev_sc=0x%x\n", sc, cxt->prev_sc);
250bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee        status = mp4_Parse_VideoObject_svh(parent, cxt);
251bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee        status = viddec_mp4_decodevop_and_emitwkld(parent, cxt);
252bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee        cxt->sc_seen = MP4_SC_SEEN_SVH;
253bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee        cxt->is_frame_start = true;
254bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee        DEB("SVH: MP4_SCS_SVH: status=0x%.8X 0x%.8X %.8X\n", status, cxt->current_sc, sc);
255bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    }
256bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
257bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    // Current sc becomes the previous sc
258bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    cxt->prev_sc = sc;
259bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
260bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    return VIDDEC_PARSE_SUCESS;
261bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee} // viddec_mp4_parse
262bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
263bd8388b4555645b3d29abc6a94c303638064d69awonjong.leeuint32_t viddec_mp4_is_frame_start(void *ctxt)
264bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee{
265bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    viddec_mp4_parser_t *parser = (viddec_mp4_parser_t *)ctxt;
266bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    return parser->is_frame_start;
267bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee} // viddec_mp4_is_frame_start
268bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
269bd8388b4555645b3d29abc6a94c303638064d69awonjong.leevoid viddec_mp4_get_ops(viddec_parser_ops_t *ops)
270bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee{
271bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    ops->parse_syntax = viddec_mp4_parse;
272bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    ops->get_cxt_size = viddec_mp4_get_context_size;
273bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    ops->is_wkld_done = viddec_mp4_wkld_done;
274bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    ops->parse_sc = viddec_parse_sc_mp4;
275bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    ops->is_frame_start = viddec_mp4_is_frame_start;
276bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    ops->init = viddec_mp4_init;
277bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    return;
278bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee} // viddec_mp4_get_ops
279