1 /* ///////////////////////////////////////////////////////////////////////
2 //
3 // INTEL CORPORATION PROPRIETARY INFORMATION
4 // This software is supplied under the terms of a license agreement or
5 // nondisclosure agreement with Intel Corporation and may not be copied
6 // or disclosed except in accordance with the terms of that agreement.
7 // Copyright (c) 2008 Intel Corporation. All Rights Reserved.
8 //
9 // Description: Parses VC-1 picture layer for advanced profile.
10 //
11 */
12
13 #include "vc1parse.h"
14 #include "viddec_fw_debug.h"
15
16 /*------------------------------------------------------------------------------
17 * Parse picture layer. This function parses the picture header for advanced
18 * profile down to POSTPROC syntax element.
19 * Table 18 of SMPTE 421M for progressive I or BI picture.
20 * Table 20 of SMPTE 421M for progressive P picture.
21 * Table 22 of SMPTE 421M for progressive B picture.
22 * Table 23 of SMPTE 421M for skipped picture.
23 * Table 82 of SMPTE 421M for interlace I or BI frame.
24 * Table 83 of SMPTE 421M for interlace P frame.
25 * Table 84 of SMPTE 421M for interlace B frame.
26 *------------------------------------------------------------------------------
27 */
28
vc1_ParsePictureHeader_Adv(void * ctxt,vc1_Info * pInfo)29 vc1_Status vc1_ParsePictureHeader_Adv(void* ctxt, vc1_Info *pInfo)
30 {
31 uint32_t i = 0;
32 uint32_t tempValue;
33 vc1_Status status = VC1_STATUS_OK;
34 uint32_t number_of_pan_scan_window;
35 vc1_metadata_t *md = &pInfo->metadata;
36 vc1_PictureLayerHeader *picLayerHeader = &pInfo->picLayerHeader;
37
38 if (md->INTERLACE == 1)
39 {
40 VC1_GET_BITS9(1, picLayerHeader->FCM);
41 if (picLayerHeader->FCM)
42 {
43 VC1_GET_BITS9(1, picLayerHeader->FCM);
44 if (picLayerHeader->FCM)
45 {
46 picLayerHeader->FCM = VC1_FCM_FIELD_INTERLACE;
47 return VC1_STATUS_PARSE_ERROR;
48 }
49 else
50 picLayerHeader->FCM = VC1_FCM_FRAME_INTERLACE;
51 }
52 else
53 picLayerHeader->FCM = VC1_FCM_PROGRESSIVE;
54 }
55 else
56 picLayerHeader->FCM = VC1_FCM_PROGRESSIVE;
57
58
59 VC1_GET_BITS9(1, picLayerHeader->PTYPE);
60 if (picLayerHeader->PTYPE)
61 {
62 VC1_GET_BITS9(1, picLayerHeader->PTYPE);
63 if (picLayerHeader->PTYPE)
64 {
65 VC1_GET_BITS9(1, picLayerHeader->PTYPE);
66 if (picLayerHeader->PTYPE)
67 {
68 VC1_GET_BITS9(1, picLayerHeader->PTYPE);
69 if (picLayerHeader->PTYPE)
70 picLayerHeader->PTYPE = VC1_SKIPPED_FRAME;
71 else
72 picLayerHeader->PTYPE = VC1_BI_FRAME;
73 }
74 else
75 picLayerHeader->PTYPE = VC1_I_FRAME;
76 }
77 else
78 picLayerHeader->PTYPE = VC1_B_FRAME;
79 }
80 else
81 picLayerHeader->PTYPE = VC1_P_FRAME;
82
83 if (picLayerHeader->PTYPE != VC1_SKIPPED_FRAME)
84 {
85 if (md->TFCNTRFLAG)
86 {
87 VC1_GET_BITS9(8, picLayerHeader->TFCNTR); /* TFCNTR. */
88 }
89 }
90
91 if (md->PULLDOWN)
92 {
93 if ((md->INTERLACE == 0) || (md->PSF == 1))
94 {
95 VC1_GET_BITS9(2, picLayerHeader->RPTFRM);
96 }
97 else
98 {
99 VC1_GET_BITS9(1, picLayerHeader->TFF);
100 VC1_GET_BITS9(1, picLayerHeader->RFF);
101 }
102 }
103
104 if (md->PANSCAN_FLAG == 1)
105 {
106 VC1_GET_BITS9(1, picLayerHeader->PS_PRESENT); /* PS_PRESENT. */
107 if (picLayerHeader->PS_PRESENT == 1)
108 {
109 if ((md->INTERLACE == 1) &&
110 (md->PSF == 0))
111 {
112 if (md->PULLDOWN == 1)
113 number_of_pan_scan_window = 2 + picLayerHeader->RFF;
114 else
115 number_of_pan_scan_window = 2;
116 }
117 else
118 {
119 if (md->PULLDOWN == 1)
120 number_of_pan_scan_window = 1 + picLayerHeader->RPTFRM;
121 else
122 number_of_pan_scan_window = 1;
123 }
124 picLayerHeader->number_of_pan_scan_window = number_of_pan_scan_window;
125
126 for (i = 0; i < number_of_pan_scan_window; i++)
127 {
128 VC1_GET_BITS(18, picLayerHeader->PAN_SCAN_WINDOW[i].hoffset); /* PS_HOFFSET. */
129 VC1_GET_BITS(18, picLayerHeader->PAN_SCAN_WINDOW[i].voffset); /* PS_VOFFSET. */
130 VC1_GET_BITS(14, picLayerHeader->PAN_SCAN_WINDOW[i].width); /* PS_WIDTH. */
131 VC1_GET_BITS(14, picLayerHeader->PAN_SCAN_WINDOW[i].height); /* PS_HEIGHT. */
132 }
133 }
134 }
135
136 if (picLayerHeader->PTYPE != VC1_SKIPPED_FRAME)
137 {
138 VC1_GET_BITS9(1, picLayerHeader->RNDCTRL);
139 md->RNDCTRL = picLayerHeader->RNDCTRL;
140
141 if ((md->INTERLACE == 1) ||
142 (picLayerHeader->FCM != VC1_FCM_PROGRESSIVE))
143 {
144 VC1_GET_BITS9(1, picLayerHeader->UVSAMP);
145 }
146
147 if ((md->FINTERPFLAG == 1) &&
148 (picLayerHeader->FCM == VC1_FCM_PROGRESSIVE))
149 {
150 VC1_GET_BITS9(1, tempValue); /* INTERPFRM. */
151 }
152
153 if ((picLayerHeader->PTYPE == VC1_B_FRAME) &&
154 (picLayerHeader->FCM == VC1_FCM_PROGRESSIVE))
155 {
156 if ((status = vc1_DecodeHuffmanPair(ctxt, VC1_BFRACTION_TBL,
157 &picLayerHeader->BFRACTION_NUM, &picLayerHeader->BFRACTION_DEN))
158 != VC1_STATUS_OK)
159 {
160 return status;
161 }
162 }
163
164 VC1_GET_BITS9(5, picLayerHeader->PQINDEX);
165 if ((status = vc1_CalculatePQuant(pInfo)) != VC1_STATUS_OK)
166 return status;
167
168 if (picLayerHeader->PQINDEX <= 8)
169 {
170 VC1_GET_BITS9(1, picLayerHeader->HALFQP);
171 }
172 else
173 picLayerHeader->HALFQP = 0;
174
175 if (md->QUANTIZER == 1)
176 {
177 VC1_GET_BITS9(1, picLayerHeader->PQUANTIZER);
178 picLayerHeader->UniformQuant = picLayerHeader->PQUANTIZER;
179 }
180
181 if (md->POSTPROCFLAG == 1)
182 {
183 VC1_GET_BITS9(2, picLayerHeader->POSTPROC);
184 }
185 }
186
187 return vc1_ParsePictureFieldHeader_Adv(ctxt, pInfo);
188 }
189
190 /*------------------------------------------------------------------------------
191 * Parse picture layer. This function parses the picture header for advanced
192 * profile down to BFRACTION syntax element.
193 * Table 85 of SMPTE 421M.
194 *------------------------------------------------------------------------------
195 */
196
vc1_ParseFieldHeader_Adv(void * ctxt,vc1_Info * pInfo)197 vc1_Status vc1_ParseFieldHeader_Adv(void* ctxt, vc1_Info *pInfo)
198 {
199 uint32_t i = 0;
200 vc1_Status status = VC1_STATUS_OK;
201 uint32_t number_of_pan_scan_window;
202 vc1_metadata_t *md = &pInfo->metadata;
203 vc1_PictureLayerHeader *picLayerHeader = &pInfo->picLayerHeader;
204
205 VC1_GET_BITS9(1, picLayerHeader->FCM);
206 if (picLayerHeader->FCM)
207 {
208 VC1_GET_BITS9(1, picLayerHeader->FCM);
209 if (picLayerHeader->FCM)
210 picLayerHeader->FCM = VC1_FCM_FIELD_INTERLACE;
211 else
212 picLayerHeader->FCM = VC1_FCM_FRAME_INTERLACE;
213 }
214 else
215 picLayerHeader->FCM = VC1_FCM_PROGRESSIVE;
216 if (picLayerHeader->FCM != VC1_FCM_FIELD_INTERLACE)
217 return VC1_STATUS_PARSE_ERROR;
218
219 VC1_GET_BITS9(3, picLayerHeader->FPTYPE);
220 if (picLayerHeader->FPTYPE == 0)
221 {
222 picLayerHeader->PTypeField1 = VC1_I_FRAME;
223 picLayerHeader->PTypeField2 = VC1_I_FRAME;
224 }
225 else if (picLayerHeader->FPTYPE == 1)
226 {
227 picLayerHeader->PTypeField1 = VC1_I_FRAME;
228 picLayerHeader->PTypeField2 = VC1_P_FRAME;
229 }
230 else if (picLayerHeader->FPTYPE == 2)
231 {
232 picLayerHeader->PTypeField1 = VC1_P_FRAME;
233 picLayerHeader->PTypeField2 = VC1_I_FRAME;
234 }
235 else if (picLayerHeader->FPTYPE == 3)
236 {
237 picLayerHeader->PTypeField1 = VC1_P_FRAME;
238 picLayerHeader->PTypeField2 = VC1_P_FRAME;
239 }
240 else if (picLayerHeader->FPTYPE == 4)
241 {
242 picLayerHeader->PTypeField1 = VC1_B_FRAME;
243 picLayerHeader->PTypeField2 = VC1_B_FRAME;
244 }
245 else if (picLayerHeader->FPTYPE == 5)
246 {
247 picLayerHeader->PTypeField1 = VC1_B_FRAME;
248 picLayerHeader->PTypeField2 = VC1_BI_FRAME;
249 }
250 else if (picLayerHeader->FPTYPE == 6)
251 {
252 picLayerHeader->PTypeField1 = VC1_BI_FRAME;
253 picLayerHeader->PTypeField2 = VC1_B_FRAME;
254 }
255 else if (picLayerHeader->FPTYPE == 7)
256 {
257 picLayerHeader->PTypeField1 = VC1_BI_FRAME;
258 picLayerHeader->PTypeField2 = VC1_BI_FRAME;
259 }
260
261 if (md->TFCNTRFLAG)
262 {
263 VC1_GET_BITS9(8, picLayerHeader->TFCNTR);
264 }
265
266 if (md->PULLDOWN == 1)
267 {
268 if (md->PSF == 1)
269 {
270 VC1_GET_BITS9(2, picLayerHeader->RPTFRM);
271 }
272 else
273 {
274 VC1_GET_BITS9(1, picLayerHeader->TFF);
275 VC1_GET_BITS9(1, picLayerHeader->RFF);
276 }
277 } else
278 picLayerHeader->TFF = 1;
279
280 if (md->PANSCAN_FLAG == 1)
281 {
282 VC1_GET_BITS9(1, picLayerHeader->PS_PRESENT);
283 if (picLayerHeader->PS_PRESENT)
284 {
285 if (md->PULLDOWN)
286 number_of_pan_scan_window = 2 + picLayerHeader->RFF;
287 else
288 number_of_pan_scan_window = 2;
289 picLayerHeader->number_of_pan_scan_window =number_of_pan_scan_window;
290
291 for (i = 0; i < number_of_pan_scan_window; i++)
292 {
293 VC1_GET_BITS(18, picLayerHeader->PAN_SCAN_WINDOW[i].hoffset); /* PS_HOFFSET. */
294 VC1_GET_BITS(18, picLayerHeader->PAN_SCAN_WINDOW[i].voffset); /* PS_VOFFSET. */
295 VC1_GET_BITS(14, picLayerHeader->PAN_SCAN_WINDOW[i].width); /* PS_WIDTH. */
296 VC1_GET_BITS(14, picLayerHeader->PAN_SCAN_WINDOW[i].height); /* PS_HEIGHT. */
297 }
298 }
299 }
300 VC1_GET_BITS9(1, md->RNDCTRL);
301
302 #ifdef VBP
303 picLayerHeader->RNDCTRL = md->RNDCTRL;
304 #endif
305
306 VC1_GET_BITS9(1, picLayerHeader->UVSAMP);
307
308 if ((md->REFDIST_FLAG == 1) && (picLayerHeader->FPTYPE <= 3))
309 {
310 int32_t tmp;
311 if ((status = vc1_DecodeHuffmanOne(ctxt, &tmp,
312 VC1_REFDIST_TBL)) != VC1_STATUS_OK)
313 {
314 return status;
315 }
316 md->REFDIST = tmp;
317 }
318
319 if ((picLayerHeader->FPTYPE >= 4) && (picLayerHeader->FPTYPE <= 7))
320 {
321 if ((status = vc1_DecodeHuffmanPair(ctxt, VC1_BFRACTION_TBL,
322 &picLayerHeader->BFRACTION_NUM, &picLayerHeader->BFRACTION_DEN)) !=
323 VC1_STATUS_OK)
324 {
325 return status;
326 }
327 }
328
329 if (picLayerHeader->CurrField == 0)
330 {
331 picLayerHeader->PTYPE = picLayerHeader->PTypeField1;
332 picLayerHeader->BottomField = (uint8_t) (1 - picLayerHeader->TFF);
333 }
334 else
335 {
336 picLayerHeader->BottomField = (uint8_t) (picLayerHeader->TFF);
337 picLayerHeader->PTYPE = picLayerHeader->PTypeField2;
338 }
339
340 return vc1_ParsePictureFieldHeader_Adv(ctxt, pInfo);
341 }
342
343 /*------------------------------------------------------------------------------
344 * Parse picture layer. This function calls the appropriate function to further
345 * parse the picture header for advanced profile down to macroblock layer.
346 *------------------------------------------------------------------------------
347 */
348
vc1_ParsePictureFieldHeader_Adv(void * ctxt,vc1_Info * pInfo)349 vc1_Status vc1_ParsePictureFieldHeader_Adv(void* ctxt, vc1_Info *pInfo)
350 {
351 vc1_Status status = VC1_STATUS_PARSE_ERROR;
352
353 if (pInfo->picLayerHeader.FCM == VC1_FCM_PROGRESSIVE)
354 {
355 if ((pInfo->picLayerHeader.PTYPE == VC1_I_FRAME) ||
356 (pInfo->picLayerHeader.PTYPE == VC1_BI_FRAME))
357 {
358 status = vc1_ParsePictureHeader_ProgressiveIpicture_Adv(ctxt, pInfo);
359 }
360 else if (pInfo->picLayerHeader.PTYPE == VC1_P_FRAME)
361 status = vc1_ParsePictureHeader_ProgressivePpicture_Adv(ctxt, pInfo);
362 else if (pInfo->picLayerHeader.PTYPE == VC1_B_FRAME)
363 status = vc1_ParsePictureHeader_ProgressiveBpicture_Adv(ctxt, pInfo);
364 else if (pInfo->picLayerHeader.PTYPE == VC1_SKIPPED_FRAME)
365 status = VC1_STATUS_OK;
366 }
367 else if (pInfo->picLayerHeader.FCM == VC1_FCM_FRAME_INTERLACE)
368 {
369 if ((pInfo->picLayerHeader.PTYPE == VC1_I_FRAME) ||
370 (pInfo->picLayerHeader.PTYPE == VC1_BI_FRAME))
371 {
372 status = vc1_ParsePictureHeader_InterlaceIpicture_Adv(ctxt, pInfo);
373 }
374 else if (pInfo->picLayerHeader.PTYPE == VC1_P_FRAME)
375 status = vc1_ParsePictureHeader_InterlacePpicture_Adv(ctxt, pInfo);
376 else if (pInfo->picLayerHeader.PTYPE == VC1_B_FRAME)
377 status = vc1_ParsePictureHeader_InterlaceBpicture_Adv(ctxt, pInfo);
378 else if (pInfo->picLayerHeader.PTYPE == VC1_SKIPPED_FRAME)
379 status = VC1_STATUS_OK;
380 }
381 else if (pInfo->picLayerHeader.FCM == VC1_FCM_FIELD_INTERLACE)
382 {
383 int ptype;
384 if( pInfo->picLayerHeader.CurrField == 0)
385 ptype = pInfo->picLayerHeader.PTypeField1;
386 else
387 ptype = pInfo->picLayerHeader.PTypeField2;
388
389 if ((ptype == VC1_I_FRAME) ||
390 (ptype == VC1_BI_FRAME))
391 {
392 status = vc1_ParseFieldHeader_InterlaceIpicture_Adv(ctxt, pInfo);
393 }
394 else if (ptype == VC1_P_FRAME)
395 status = vc1_ParseFieldHeader_InterlacePpicture_Adv(ctxt, pInfo);
396 else if (ptype == VC1_B_FRAME)
397 status = vc1_ParseFieldHeader_InterlaceBpicture_Adv(ctxt, pInfo);
398 else if (ptype == VC1_SKIPPED_FRAME)
399 status = VC1_STATUS_OK;
400 }
401
402 return status;
403 }
404