1bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee/**
2bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee * viddec_mpeg2_parse.c
3bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee * --------------------
4bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee * This file acts as the main interface between the parser manager and MPEG2
5bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee * parser. All the operations done by the MPEG2 parser are defined here and
6bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee * functions pointers for each operation is returned to the parser manager.
7bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee */
8bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
9bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee#include "viddec_mpeg2.h"
10bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
11bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee/* viddec_mpeg2_parser_init() - Initializes parser context. */
12bd8388b4555645b3d29abc6a94c303638064d69awonjong.leestatic void viddec_mpeg2_parser_init
13bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee(
14bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    void        *ctxt,
15bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    uint32_t    *persist_mem,
16bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    uint32_t     preserve
17bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee)
18bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee{
19bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    struct viddec_mpeg2_parser *parser = (struct viddec_mpeg2_parser *) ctxt;
20bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
21bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    /* Avoid compiler warning */
22bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    persist_mem = persist_mem;
23bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
24bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    /* Initialize state variables */
25bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    parser->mpeg2_pic_metadata_complete         =  false;
26bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    parser->mpeg2_picture_interlaced            =  false;
27bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    parser->mpeg2_first_field                   =  false;
28bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    parser->mpeg2_frame_start                   =  false;
29bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    parser->mpeg2_ref_table_updated             =  false;
30bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    parser->mpeg2_use_next_workload             =  false;
31bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    parser->mpeg2_first_slice_flag              =  false;
32bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    parser->mpeg2_curr_frame_headers            =  MPEG2_HEADER_NONE;
33bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    parser->mpeg2_last_parsed_sc                =  MPEG2_SC_ALL;
34bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    parser->mpeg2_last_parsed_slice_sc          =  MPEG2_SC_SLICE_MAX;
35bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    parser->mpeg2_wl_status                     =  MPEG2_WL_EMPTY;
36bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    parser->mpeg2_prev_picture_structure        =  MPEG2_PIC_STRUCT_FRAME;
37bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    parser->mpeg2_prev_temp_ref                 =  0;
38bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    parser->mpeg2_num_pan_scan_offsets          =  0;
39bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
40bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    if(preserve)
41bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    {
42bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    	/* Init all picture level header info */
43bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    	memset(&parser->info.pic_hdr, 0, sizeof(struct mpeg2_picture_hdr_info));
44bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    	memset(&parser->info.pic_cod_ext, 0, sizeof(struct mpeg2_picture_coding_ext_info));
45bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    	memset(&parser->info.pic_disp_ext, 0, sizeof(struct mpeg2_picture_disp_ext_info));
46bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    }
47bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    else
48bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    {
49bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    	/* Init all header info */
50bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    	memset(&parser->info, 0, sizeof(struct mpeg2_info));
51bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
52bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    	parser->mpeg2_stream                        =  false;
53bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    	parser->mpeg2_custom_qmat_parsed            =  false;
54bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    	parser->mpeg2_valid_seq_hdr_parsed          =  false;
55bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    	parser->mpeg2_curr_seq_headers              =  MPEG2_HEADER_NONE;
56bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	}
57bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
58bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    MPEG2_DEB("MPEG2 Parser: Context Initialized.\n");
59bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
60bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    return;
61bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee}
62bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
63bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee/* viddec_mpeg2_get_context_size() - Returns the memory size required by the */
64bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee/* MPEG2 parser. */
65bd8388b4555645b3d29abc6a94c303638064d69awonjong.leestatic void viddec_mpeg2_get_context_size
66bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee(
67bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    viddec_parser_memory_sizes_t    *size
68bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee)
69bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee{
70bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    /* Should return size of my structure */
71bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    size->context_size = sizeof(struct viddec_mpeg2_parser);
72bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    size->persist_size = 0;
73bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee}
74bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
75bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee/* viddec_mpeg2_get_error_code() - Returns the error code for the current */
76bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee/* workload. */
77bd8388b4555645b3d29abc6a94c303638064d69awonjong.leestatic void viddec_mpeg2_get_error_code
78bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee(
79bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    struct viddec_mpeg2_parser  *parser,
80bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    viddec_workload_t           *wl,
81bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    uint32_t                    *error_code
82bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee)
83bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee{
84bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    *error_code = 0;
85bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
86bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    /* Dangling field error */
87bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    if (parser->mpeg2_wl_status & MPEG2_WL_DANGLING_FIELD)
88bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    {
89bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee        *error_code |= VIDDEC_FW_WORKLOAD_ERR_DANGLING_FLD;
90bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee        if (parser->mpeg2_wl_status & MPEG2_WL_DANGLING_FIELD_TOP)
91bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee        {
92bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee            *error_code |= VIDDEC_FW_WORKLOAD_ERR_TOPFIELD;
93bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee        }
94bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee        else
95bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee        {
96bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee            *error_code |= VIDDEC_FW_WORKLOAD_ERR_BOTTOMFIELD;
97bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee        }
98bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    }
99bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
100bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    /* Repeated same field */
101bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    if (parser->mpeg2_wl_status & MPEG2_WL_REPEAT_FIELD)
102bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    {
103bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee        *error_code |= (VIDDEC_FW_WORKLOAD_ERR_DANGLING_FLD
104bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee                        | VIDDEC_FW_WORKLOAD_ERR_NOTDECODABLE);
105bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    }
106bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
107bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    /* If workload is not complete, set non-decodeable flag */
108bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    if (!(parser->mpeg2_wl_status & MPEG2_WL_COMPLETE))
109bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    {
110bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee        *error_code |= VIDDEC_FW_WORKLOAD_ERR_NOTDECODABLE;
111bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    }
112bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
113bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    /* If reference info is not updated, set missing reference flag */
114bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    if (!(parser->mpeg2_wl_status & MPEG2_WL_REF_INFO))
115bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    {
116bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee        *error_code |= VIDDEC_FW_WORKLOAD_ERR_MISSING_REFERENCE;
117bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    }
118bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
119bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    /* Missing DMEM data flag and irrecoverable flag is set */
120bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    if (!(parser->mpeg2_wl_status & MPEG2_WL_DMEM_DATA))
121bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    {
122bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee        *error_code |= ( VIDDEC_FW_WORKLOAD_ERR_MISSING_DMEM
123bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee                         | VIDDEC_FW_WORKLOAD_ERR_NOTDECODABLE ) ;
124bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    }
125bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
126bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    /* Missing sequence header and irrecoverable flag is set */
127bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    if ((!(parser->mpeg2_curr_seq_headers & MPEG2_HEADER_SEQ))
128bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    		&& (!parser->mpeg2_valid_seq_hdr_parsed))
129bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    {
130bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee        *error_code |= ( VIDDEC_FW_WORKLOAD_ERR_MISSING_SEQ_INFO
131bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee                         | VIDDEC_FW_WORKLOAD_ERR_NOTDECODABLE ) ;
132bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    }
133bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
134bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    /* Unsupported features found in stream */
135bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    if (parser->mpeg2_wl_status & MPEG2_WL_UNSUPPORTED)
136bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    {
137bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee        *error_code |= ( VIDDEC_FW_WORKLOAD_ERR_UNSUPPORTED
138bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee                         | VIDDEC_FW_WORKLOAD_ERR_NOTDECODABLE ) ;
139bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    }
140bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
141bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    /* If frame type is unknown, default to I frame. */
142bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    if ((wl->attrs.frame_type != VIDDEC_FRAME_TYPE_I)
143bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee            && (wl->attrs.frame_type != VIDDEC_FRAME_TYPE_P)
144bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee            && (wl->attrs.frame_type != VIDDEC_FRAME_TYPE_B))
145bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    {
146bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee        wl->attrs.frame_type = VIDDEC_FRAME_TYPE_I;
147bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    }
148bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
149bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    /* If there is a mismatch between the frame type and reference information */
150bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    /* then mark the workload as not decodable */
151bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    if (wl->attrs.frame_type == VIDDEC_FRAME_TYPE_B)
152bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    {
153bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee        if (wl->is_reference_frame != 0) *error_code |= VIDDEC_FW_WORKLOAD_ERR_NOTDECODABLE;
154bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    }
155bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    else
156bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    {
157bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee        if (wl->is_reference_frame == 0) *error_code |= VIDDEC_FW_WORKLOAD_ERR_NOTDECODABLE;
158bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    }
159bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
160bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    /* For non-decodable frames, do not set reference info so that the workload */
161bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    /* manager does not increment ref count. */
162bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    if (*error_code & VIDDEC_FW_WORKLOAD_ERR_NOTDECODABLE)
163bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    {
164bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee        wl->is_reference_frame = 0;
165bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    }
166bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
167bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    /* Corrupted header notification */
168bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    if (parser->mpeg2_wl_status & MPEG2_WL_CORRUPTED_SEQ_HDR)
169bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee        *error_code |= VIDDEC_FW_MPEG2_ERR_CORRUPTED_SEQ_HDR;
170bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    if (parser->mpeg2_wl_status & MPEG2_WL_CORRUPTED_SEQ_EXT)
171bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee        *error_code |= VIDDEC_FW_MPEG2_ERR_CORRUPTED_SEQ_EXT;
172bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    if (parser->mpeg2_wl_status & MPEG2_WL_CORRUPTED_SEQ_DISP_EXT)
173bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee        *error_code |= VIDDEC_FW_MPEG2_ERR_CORRUPTED_SEQ_DISP_EXT;
174bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    if (parser->mpeg2_wl_status & MPEG2_WL_CORRUPTED_GOP_HDR)
175bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee        *error_code |= VIDDEC_FW_MPEG2_ERR_CORRUPTED_GOP_HDR;
176bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    if (parser->mpeg2_wl_status & MPEG2_WL_CORRUPTED_PIC_HDR)
177bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee        *error_code |= VIDDEC_FW_MPEG2_ERR_CORRUPTED_PIC_HDR;
178bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    if (parser->mpeg2_wl_status & MPEG2_WL_CORRUPTED_PIC_COD_EXT)
179bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee        *error_code |= VIDDEC_FW_MPEG2_ERR_CORRUPTED_PIC_COD_EXT;
180bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    if (parser->mpeg2_wl_status & MPEG2_WL_CORRUPTED_PIC_DISP_EXT)
181bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee        *error_code |= VIDDEC_FW_MPEG2_ERR_CORRUPTED_PIC_DISP_EXT;
182bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    if (parser->mpeg2_wl_status & MPEG2_WL_CORRUPTED_QMAT_EXT)
183bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee        *error_code |= VIDDEC_FW_MPEG2_ERR_CORRUPTED_QMAT_EXT;
184bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
185bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    MPEG2_DEB("Workload error code: 0x%8X.\n", *error_code);
186bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    return;
187bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee}
188bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
189bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee/* viddec_mpeg2_is_start_frame() - Returns if the current chunk of parsed */
190bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee/* data has start of a frame. */
191bd8388b4555645b3d29abc6a94c303638064d69awonjong.leestatic uint32_t viddec_mpeg2_is_start_frame
192bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee(
193bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    void    *ctxt
194bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee)
195bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee{
196bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    struct viddec_mpeg2_parser *parser = (struct viddec_mpeg2_parser *) ctxt;
197bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    return (parser->mpeg2_frame_start);
198bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee}
199bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
200bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee/* viddec_mpeg2_is_workload_done() - Returns current frame parsing status */
201bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee/* to the parser manager. */
202bd8388b4555645b3d29abc6a94c303638064d69awonjong.leestatic uint32_t viddec_mpeg2_is_workload_done
203bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee(
204bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    void            *parent,
205bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    void            *ctxt,
206bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    unsigned int    next_sc,
207bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    uint32_t        *codec_specific_errors
208bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee)
209bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee{
210bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    struct viddec_mpeg2_parser *parser = (struct viddec_mpeg2_parser *) ctxt;
211bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    viddec_workload_t *wl = viddec_pm_get_header(parent);
212bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    uint32_t ret = VIDDEC_PARSE_SUCESS;
213bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    uint32_t frame_boundary = 0;
214bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	uint8_t force_frame_complete = 0;
215bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    parent = parent;
216bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
217bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    /* Detect Frame Boundary */
218bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    frame_boundary = ((MPEG2_SC_PICTURE == next_sc) || (MPEG2_SC_SEQ_HDR == next_sc) || (MPEG2_SC_GROUP == next_sc));
219bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    if (frame_boundary)
220bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    {
221bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee        parser->mpeg2_first_slice_flag = false;
222bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    }
223bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
224bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	force_frame_complete = ((VIDDEC_PARSE_EOS == next_sc) || (VIDDEC_PARSE_DISCONTINUITY == next_sc));
225bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
226bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    if (force_frame_complete || (frame_boundary && (parser->mpeg2_pic_metadata_complete)))
227bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    {
228bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		if(!force_frame_complete)
229bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee        {
230bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee            parser->mpeg2_wl_status            |= MPEG2_WL_COMPLETE;
231bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee            parser->mpeg2_last_parsed_slice_sc  =  MPEG2_SC_SLICE_MAX;
232bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee            parser->mpeg2_pic_metadata_complete = false;
233bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee            parser->mpeg2_first_slice_flag = false;
234bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee        }
235bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
236bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee        viddec_mpeg2_get_error_code(parser, wl, codec_specific_errors);
237bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee        parser->mpeg2_wl_status          = MPEG2_WL_EMPTY;
238bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee        parser->mpeg2_curr_frame_headers = MPEG2_HEADER_NONE;
239bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee        /* Reset mpeg2_use_next_workload flag if it is set */
240bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee        if (parser->mpeg2_use_next_workload)
241bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee        {
242bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee            viddec_pm_set_late_frame_detect(parent);
243bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee            parser->mpeg2_use_next_workload  = false;
244bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee        }
245bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee        ret = VIDDEC_PARSE_FRMDONE;
246bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    }
247bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    return ret;
248bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee}
249bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
250bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee/* viddec_mpeg2_parse() - Parse metadata info from the buffer for the prev */
251bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee/* start code found. */
252bd8388b4555645b3d29abc6a94c303638064d69awonjong.leestatic mpeg2_status viddec_mpeg2_parse
253bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee(
254bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    void    *parent,
255bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    void    *ctxt
256bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee)
257bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee{
258bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    uint32_t current_sc = 0, sc_bits = MPEG2_SC_AND_PREFIX_SIZE;
259bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    int32_t  ret = MPEG2_SUCCESS;
260bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    struct viddec_mpeg2_parser *parser = (struct viddec_mpeg2_parser *) ctxt;
261bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
262bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    /* Reset frame start flag. For Mpeg1 we want to set frame start after
263bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee     we parsed pich header, since there is no extension*/
264bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    parser->mpeg2_frame_start =  (!parser->mpeg2_stream) && (parser->mpeg2_last_parsed_sc == MPEG2_SC_PICTURE);
265bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
266bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    /* Peak current start code - First 32 bits of the stream */
267bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    ret = viddec_pm_peek_bits(parent, &current_sc, sc_bits);
268bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    if (ret == -1)
269bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    {
270bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee        MPEG2_DEB("Unable to get start code.\n");
271bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee        return MPEG2_PARSE_ERROR;
272bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    }
273bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    current_sc &= MPEG2_BIT_MASK_8;
274bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    MPEG2_DEB("Start Code found = 0x%.8X\n", current_sc);
275bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
276bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    /* Get rid of the start code prefix for all start codes except slice */
277bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    /* start codes. */
278bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    if ((current_sc < MPEG2_SC_SLICE_MIN) || (current_sc > MPEG2_SC_SLICE_MAX))
279bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    {
280bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee        viddec_pm_skip_bits(parent, sc_bits);
281bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    }
282bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
283bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    /* Parse Metadata based on the start code found */
284bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    switch( current_sc )
285bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    {
286bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee        /* Sequence Start Code */
287bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee        case MPEG2_SC_SEQ_HDR:
288bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee        {
289bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee            parser->mpeg2_curr_seq_headers = MPEG2_HEADER_NONE;
290bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee            viddec_mpeg2_parse_seq_hdr(parent, ctxt);
291bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee        }
292bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee        break;
293bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
294bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee        /* Picture Start Code */
295bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee        case MPEG2_SC_PICTURE:
296bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee        {
297bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee            viddec_mpeg2_parse_pic_hdr(parent, ctxt);
298bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee        }
299bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee        break;
300bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
301bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee        /* Extension Code */
302bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee        case MPEG2_SC_EXT:
303bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee        {
304bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee            viddec_mpeg2_parse_ext(parent, ctxt);
305bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee        }
306bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee        break;
307bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
308bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee        /* Group of Pictures Header */
309bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee        case MPEG2_SC_GROUP:
310bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee        {
311bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee            viddec_mpeg2_parse_gop_hdr(parent, ctxt);
312bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee        }
313bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee        break;
314bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
315bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee        /* Unused Start Code */
316bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee        case MPEG2_SC_SEQ_END:
317bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee        case MPEG2_SC_SEQ_ERR:
318bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee            break;
319bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
320bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee        /* User Data */
321bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee        case MPEG2_SC_USER_DATA:
322bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee        {
323bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee            viddec_mpeg2_parse_and_append_user_data(parent, ctxt);
324bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee        }
325bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee        break;
326bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
327bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee        default:
328bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee        {
329bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee            /* Slice Data - Append slice data to the workload */
330bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee            if ((current_sc >= MPEG2_SC_SLICE_MIN) &&
331bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee                (current_sc <= MPEG2_SC_SLICE_MAX))
332bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee            {
333bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee                if (!parser->mpeg2_first_slice_flag)
334bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee                {
335bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee                    /* At this point, all the metadata required by the MPEG2 */
336bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee                    /* hardware for decoding is extracted and stored. So the */
337bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee                    /* metadata can be packed into workitems and emitted out.*/
338bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee                    viddec_mpeg2_emit_workload(parent, ctxt);
339bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
340bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee                    /* If the current picture is progressive or it is the */
341bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee                    /* second field of interlaced field picture then, set */
342bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee                    /* the workload done flag. */
343bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee                    if ((!parser->mpeg2_picture_interlaced)
344bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee                        || ((parser->mpeg2_picture_interlaced) && (!parser->mpeg2_first_field)))
345bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee                    {
346bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee                        parser->mpeg2_pic_metadata_complete = true;
347bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee                    }
348bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee                    else if ((parser->mpeg2_picture_interlaced) && (parser->mpeg2_first_field))
349bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee                    {
350bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee                        parser->mpeg2_curr_frame_headers = MPEG2_HEADER_NONE;
351bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee                    }
352bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
353bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee                    parser->mpeg2_first_slice_flag = true;
354bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee                }
355bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee                parser->mpeg2_last_parsed_slice_sc = current_sc;
356bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee                viddec_mpeg2_parse_and_append_slice_data(parent, ctxt);
357bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee                parser->mpeg2_wl_status |= MPEG2_WL_PARTIAL_SLICE;
358bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee            }
359bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee        }
360bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    } /* Switch */
361bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
362bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    /* Save last parsed start code */
363bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    parser->mpeg2_last_parsed_sc = current_sc;
364bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    return ret;
365bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee}
366bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
367bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee/* viddec_mpeg2_get_ops() - Register parser ops with the parser manager. */
368bd8388b4555645b3d29abc6a94c303638064d69awonjong.leevoid viddec_mpeg2_get_ops
369bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee(
370bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    viddec_parser_ops_t     *ops
371bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee)
372bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee{
373bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    ops->init         = viddec_mpeg2_parser_init;
374bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    ops->parse_syntax = viddec_mpeg2_parse;
375bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    ops->get_cxt_size = viddec_mpeg2_get_context_size;
376bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    ops->is_wkld_done = viddec_mpeg2_is_workload_done;
377bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    ops->is_frame_start = viddec_mpeg2_is_start_frame;
378bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    return;
379bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee}
380bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
381