1 #include "viddec_mp4_videoobjectlayer.h"
2
3 const unsigned char mp4_DefaultIntraQuantMatrix[64] = {
4 8, 17, 18, 19, 21, 23, 25, 27,
5 17, 18, 19, 21, 23, 25, 27, 28,
6 20, 21, 22, 23, 24, 26, 28, 30,
7 21, 22, 23, 24, 26, 28, 30, 32,
8 22, 23, 24, 26, 28, 30, 32, 35,
9 23, 24, 26, 28, 30, 32, 35, 38,
10 25, 26, 28, 30, 32, 35, 38, 41,
11 27, 28, 30, 32, 35, 38, 41, 45
12 };
13 const unsigned char mp4_DefaultNonIntraQuantMatrix[64] = {
14 16, 17, 18, 19, 20, 21, 22, 23,
15 17, 18, 19, 20, 21, 22, 23, 24,
16 18, 19, 20, 21, 22, 23, 24, 25,
17 19, 20, 21, 22, 23, 24, 26, 27,
18 20, 21, 22, 23, 25, 26, 27, 28,
19 21, 22, 23, 24, 26, 27, 28, 30,
20 22, 23, 24, 26, 27, 28, 30, 31,
21 23, 24, 25, 27, 28, 30, 31, 33
22 };
23 const unsigned char mp4_ClassicalZigzag[64] = {
24 0, 1, 8, 16, 9, 2, 3, 10, 17, 24, 32, 25, 18, 11, 4, 5,
25 12, 19, 26, 33, 40, 48, 41, 34, 27, 20, 13, 6, 7, 14, 21, 28,
26 35, 42, 49, 56, 57, 50, 43, 36, 29, 22, 15, 23, 30, 37, 44, 51,
27 58, 59, 52, 45, 38, 31, 39, 46, 53, 60, 61, 54, 47, 55, 62, 63
28 };
29
mp4_GetMacroBlockNumberSize(int nmb)30 static inline int mp4_GetMacroBlockNumberSize(int nmb)
31 {
32 int nb = 0;
33 nmb --;
34 do {
35 nmb >>= 1;
36 nb ++;
37 } while (nmb);
38 return nb;
39 }
40
mp4_copy_default_table(const uint8_t * src,uint8_t * dst,uint32_t len)41 static inline void mp4_copy_default_table(const uint8_t *src, uint8_t *dst, uint32_t len)
42 {
43 uint32_t i;
44 for(i=0; i< len; i++)
45 dst[i] = src[i];
46 }
47
48
mp4_Parse_QuantMatrix(void * parent,uint8_t * pQM)49 static inline mp4_Status_t mp4_Parse_QuantMatrix(void *parent, uint8_t *pQM)
50 {
51 uint32_t i,code=0;
52 uint8_t last=0;
53 int32_t getbits=0;
54 mp4_Status_t ret = MP4_STATUS_OK;
55
56 for (i = 0; i < 64; i ++)
57 {
58 getbits = viddec_pm_get_bits(parent, &code, 8);
59 BREAK_GETBITS_REQD_MISSING(getbits, ret);
60 if (code == 0) break;
61 pQM[mp4_ClassicalZigzag[i]] = (uint8_t)(code & 0xFF);
62 }
63 last = pQM[mp4_ClassicalZigzag[i-1]];
64 for (; i < 64; i ++)
65 {
66 pQM[mp4_ClassicalZigzag[i]] = last;
67 }
68 return ret;;
69 }
70
mp4_pvt_valid_object_type_indication(uint8_t val)71 static inline uint8_t mp4_pvt_valid_object_type_indication(uint8_t val)
72 {
73 return ((1 <= val) || (val <= 18));
74 }
75
mp4_pvt_valid_object_layer_verid(uint8_t val)76 static inline uint8_t mp4_pvt_valid_object_layer_verid(uint8_t val)
77 {
78 uint8_t ret=false;
79 switch(val)
80 {
81 case 1:
82 case 2:
83 case 4:
84 case 5:
85 {
86 ret = true;
87 break;
88 }
89 default:
90 {
91 break;
92 }
93 }
94 return ret;
95 }
96
97 static mp4_Status_t
mp4_pvt_VOL_volcontrolparameters(void * parent,viddec_mp4_parser_t * parser)98 mp4_pvt_VOL_volcontrolparameters(void *parent, viddec_mp4_parser_t *parser)
99 {
100 mp4_VOLControlParameters_t *cxt = &(parser->info.VisualObject.VideoObject.VOLControlParameters);
101 mp4_Status_t ret = MP4_STATUS_PARSE_ERROR;
102 int32_t getbits=0;
103 uint32_t code=0;
104
105 do
106 {
107 getbits = viddec_pm_get_bits(parent, &(code), 4);
108 BREAK_GETBITS_REQD_MISSING(getbits, ret);
109 cxt->chroma_format = (code >> 2) & 0x3;
110 cxt->low_delay = ((code & 0x2) > 0);
111 cxt->vbv_parameters = code & 0x1;
112
113 if (cxt->chroma_format != MP4_CHROMA_FORMAT_420)
114 {
115 DEB("Warning: mp4_Parse_VideoObject:vol_control_parameters.chroma_format != 4:2:0\n");
116 cxt->chroma_format= MP4_CHROMA_FORMAT_420;
117 parser->bitstream_error |= MP4_BS_ERROR_HDR_UNSUP;
118 ret = MP4_STATUS_NOTSUPPORT;
119 }
120
121 if(cxt->vbv_parameters)
122 {/* TODO: Check for validity of marker bits */
123 getbits = viddec_pm_get_bits(parent, &(code), 32);
124 BREAK_GETBITS_REQD_MISSING(getbits, ret);
125 /* 32 bits= firsthalf(15) + M + LatterHalf(15) + M */
126 cxt->bit_rate = (code & 0xFFFE) >> 1; // Get rid of 1 marker bit
127 cxt->bit_rate |= ((code & 0xFFFE0000) >> 2); // Get rid of 2 marker bits
128
129 if(cxt->bit_rate == 0)
130 {
131 DEB("Error: mp4_Parse_VideoObject:vidObjLay->VOLControlParameters.bit_rate = 0\n");
132 parser->bitstream_error |= MP4_BS_ERROR_HDR_UNSUP;
133 ret = MP4_STATUS_NOTSUPPORT;
134 // Do we need to really break here? Why not just set an error and proceed
135 //break;
136 }
137
138 getbits = viddec_pm_get_bits(parent, &(code), 19);
139 BREAK_GETBITS_REQD_MISSING(getbits, ret);
140 /* 19 bits= firsthalf(15) + M + LatterHalf(3)*/
141 cxt->vbv_buffer_size = code & 0x7;
142 cxt->vbv_buffer_size |= ( (code >> 4) & 0x7FFF);
143 if(cxt->vbv_buffer_size == 0)
144 {
145 DEB("Error: mp4_Parse_VideoObject:vidObjLay->VOLControlParameters.vbv_buffer_size = 0\n");
146 parser->bitstream_error |= MP4_BS_ERROR_HDR_UNSUP;
147 ret = MP4_STATUS_NOTSUPPORT;
148 // Do we need to really break here? Why not just set an error and proceed
149 //break;
150 }
151
152 getbits = viddec_pm_get_bits(parent, &(code), 28);
153 BREAK_GETBITS_REQD_MISSING(getbits, ret);
154 /* 28 bits= firsthalf(11) + M + LatterHalf(15) + M */
155 code = code >>1;
156 cxt->vbv_occupancy = code & 0x7FFF;
157 code = code >>16;
158 cxt->vbv_occupancy |= (code & 0x07FF);
159 }
160 ret = MP4_STATUS_OK;
161 } while(0);
162
163 return ret;
164 }
165
mp4_pvt_count_number_of_bits(uint32_t val)166 static uint32_t mp4_pvt_count_number_of_bits(uint32_t val)
167 {
168 uint32_t num_bits=0;
169 do{
170 val >>= 1;
171 num_bits++;
172 }while(val);
173 return num_bits;
174 }
175
176 static mp4_Status_t
mp4_Parse_VOL_sprite(void * parent,viddec_mp4_parser_t * parser)177 mp4_Parse_VOL_sprite(void *parent, viddec_mp4_parser_t *parser)
178 {
179 mp4_VideoObjectLayer_t *vidObjLay = (&parser->info.VisualObject.VideoObject);
180 mp4_VOLSpriteInfo_t *cxt = &(vidObjLay->sprite_info);
181 uint32_t sprite_enable = vidObjLay->sprite_enable;
182 uint32_t code;
183 mp4_Status_t ret = MP4_STATUS_PARSE_ERROR;
184 int32_t getbits=0;
185
186 do{
187 if ((sprite_enable == MP4_SPRITE_STATIC) ||
188 (sprite_enable == MP4_SPRITE_GMC))
189 {
190 if (sprite_enable != MP4_SPRITE_GMC)
191 {
192 /* This is not a supported type by HW */
193 DEB("ERROR: mp4_Parse_VideoObject:sprite_enable = %.2X\n", sprite_enable);
194 ret = MP4_STATUS_NOTSUPPORT | MP4_STATUS_REQD_DATA_ERROR;
195 break;
196 }
197
198 getbits = viddec_pm_get_bits(parent, &(code), 9);
199 BREAK_GETBITS_REQD_MISSING(getbits, ret);
200 cxt->sprite_brightness_change = code & 0x1;
201 cxt->sprite_warping_accuracy = (code >> 1) & 0x3;
202 cxt->no_of_sprite_warping_points = code >> 3;
203 if(cxt->no_of_sprite_warping_points > 1)
204 {
205 DEB("Error: mp4_Parse_VideoObject:bad no_of_sprite_warping_points %d\n",
206 cxt->no_of_sprite_warping_points);
207 ret = MP4_STATUS_NOTSUPPORT | MP4_STATUS_REQD_DATA_ERROR;
208 break;
209 }
210
211 if((vidObjLay->sprite_enable == MP4_SPRITE_GMC) && (cxt->sprite_brightness_change))
212 {
213 DEB("Error: mp4_Parse_VideoObject:sprite_brightness_change should be 0 for GMC sprites\n");
214 ret = MP4_STATUS_NOTSUPPORT | MP4_STATUS_REQD_DATA_ERROR;
215 break;
216 }
217
218 if (vidObjLay->sprite_enable != MP4_SPRITE_GMC)
219 {
220 DEB("ERROR: mp4_Parse_VideoObject:sprite_enable = %.2X\n", sprite_enable);
221 ret = MP4_STATUS_NOTSUPPORT | MP4_STATUS_REQD_DATA_ERROR;
222 break;
223 }
224 }
225 ret = MP4_STATUS_OK;
226 }while(0);
227
228 return ret;
229 }
230
mp4_Parse_VOL_quant_mat(void * parent,mp4_VideoObjectLayer_t * vidObjLay)231 static mp4_Status_t mp4_Parse_VOL_quant_mat(void *parent, mp4_VideoObjectLayer_t *vidObjLay)
232 {
233 uint32_t code;
234 mp4_Status_t ret = MP4_STATUS_PARSE_ERROR;
235 int32_t getbits=0;
236 mp4_VOLQuant_mat_t *quant = &(vidObjLay->quant_mat_info);
237
238 do{
239 getbits = viddec_pm_get_bits(parent, &(code), 1);
240 BREAK_GETBITS_REQD_MISSING(getbits, ret);
241 quant->load_intra_quant_mat = code;
242 if (quant->load_intra_quant_mat)
243 {
244 mp4_Parse_QuantMatrix(parent, &(quant->intra_quant_mat[0]));
245 }
246 else
247 {
248 mp4_copy_default_table((const uint8_t *)&mp4_DefaultIntraQuantMatrix[0], (uint8_t *)&(quant->intra_quant_mat[0]), 64);
249 }
250
251 getbits = viddec_pm_get_bits(parent, &(code), 1);
252 BREAK_GETBITS_REQD_MISSING(getbits, ret);
253 quant->load_nonintra_quant_mat = code;
254 if (quant->load_nonintra_quant_mat)
255 {
256 mp4_Parse_QuantMatrix(parent, &(quant->nonintra_quant_mat[0]));
257 }
258 else
259 {
260 mp4_copy_default_table((const uint8_t *)&mp4_DefaultNonIntraQuantMatrix[0], (uint8_t *)&(quant->nonintra_quant_mat[0]), 64);
261 }
262 ret = MP4_STATUS_OK;
263 }while(0);
264 return ret;
265 }
266
mp4_Parse_VOL_notbinaryonly(void * parent,viddec_mp4_parser_t * parser)267 static mp4_Status_t mp4_Parse_VOL_notbinaryonly(void *parent, viddec_mp4_parser_t *parser)
268 {
269 uint32_t code;
270 mp4_Info_t *pInfo = &(parser->info);
271 mp4_VideoObjectLayer_t *vidObjLay = &(pInfo->VisualObject.VideoObject);
272 mp4_Status_t ret = MP4_STATUS_PARSE_ERROR;
273 int32_t getbits=0;
274
275 do{
276 if (vidObjLay->video_object_layer_shape == MP4_SHAPE_TYPE_RECTANGULAR)
277 {
278 /* TODO: check for validity of marker bits */
279 getbits = viddec_pm_get_bits(parent, &(code), 29);
280 BREAK_GETBITS_REQD_MISSING(getbits, ret);
281 vidObjLay->video_object_layer_height = (code >> 1) & 0x1FFF;
282 vidObjLay->video_object_layer_width = (code >> 15) & 0x1FFF;
283 }
284
285 getbits = viddec_pm_get_bits(parent, &(code), 2);
286 BREAK_GETBITS_REQD_MISSING(getbits, ret);
287 vidObjLay->interlaced = ((code & 0x2) > 0);
288 vidObjLay->obmc_disable = ((code & 0x1) > 0);
289
290 {
291 uint32_t num_bits=1;
292 if(vidObjLay->video_object_layer_verid != 1) num_bits=2;
293 getbits = viddec_pm_get_bits(parent, &(code), num_bits);
294 BREAK_GETBITS_REQD_MISSING(getbits, ret);
295 vidObjLay->sprite_enable = code;
296 }
297
298 ret = mp4_Parse_VOL_sprite(parent, parser);
299 if(ret != MP4_STATUS_OK)
300 {
301 break;
302 }
303
304 if ((vidObjLay->video_object_layer_verid != 1) &&
305 (vidObjLay->video_object_layer_shape != MP4_SHAPE_TYPE_RECTANGULAR))
306 {
307 /* not supported shape*/
308 DEB("Error: mp4_Parse_VideoObject: sadct_disable, not supp\n");
309 ret = MP4_STATUS_NOTSUPPORT | MP4_STATUS_REQD_DATA_ERROR;
310 break;
311 }
312
313 getbits = viddec_pm_get_bits(parent, &(code), 1);
314 BREAK_GETBITS_FAIL(getbits, ret);
315 vidObjLay->not_8_bit = (code > 0 );
316 if(vidObjLay->not_8_bit)
317 {
318 /* 8 bit is only supported mode*/
319 DEB("Error: mp4_Parse_VideoObject: not_8_bit, not supp\n");
320 ret = MP4_STATUS_NOTSUPPORT | MP4_STATUS_REQD_DATA_ERROR;
321 break;
322 }
323 else
324 {/* We use default values since only 8 bit mode is supported */
325 vidObjLay->quant_precision = 5;
326 vidObjLay->bits_per_pixel = 8;
327 }
328
329 if (vidObjLay->video_object_layer_shape == MP4_SHAPE_TYPE_GRAYSCALE)
330 {
331 /* Should not get here as shape is checked earlier */
332 DEB("Error: mp4_Parse_VideoObject: GRAYSCALE, not supp\n");
333 ret = MP4_STATUS_NOTSUPPORT | MP4_STATUS_REQD_DATA_ERROR;
334 break;
335 }
336
337 getbits = viddec_pm_get_bits(parent, &(code), 1);
338 BREAK_GETBITS_REQD_MISSING(getbits, ret);
339 vidObjLay->quant_type = code;
340 if (vidObjLay->quant_type)
341 {
342 ret = mp4_Parse_VOL_quant_mat(parent, vidObjLay);
343 if(ret != MP4_STATUS_OK)
344 {
345 break;
346 }
347 }
348
349 if (vidObjLay->video_object_layer_verid != 1)
350 {
351 getbits = viddec_pm_get_bits(parent, &(code), 1);
352 BREAK_GETBITS_REQD_MISSING(getbits, ret);
353 vidObjLay->quarter_sample = code;
354 }
355
356 getbits = viddec_pm_get_bits(parent, &(code), 1);
357 BREAK_GETBITS_REQD_MISSING(getbits, ret);
358 vidObjLay->complexity_estimation_disable = code;
359 if(!vidObjLay->complexity_estimation_disable)
360 {/* complexity estimation not supported */
361 DEB("Error: mp4_Parse_VideoObject: vidObjLay->complexity_estimation_disable, not supp\n");
362 ret = MP4_STATUS_NOTSUPPORT | MP4_STATUS_REQD_DATA_ERROR;
363 break;
364 }
365
366 getbits = viddec_pm_get_bits(parent, &(code), 2);
367 BREAK_GETBITS_REQD_MISSING(getbits, ret);
368 vidObjLay->resync_marker_disable = ((code & 0x2) > 0);
369 vidObjLay->data_partitioned = code & 0x1;
370 if(vidObjLay->data_partitioned)
371 {
372 getbits = viddec_pm_get_bits(parent, &(code), 1);
373 BREAK_GETBITS_REQD_MISSING(getbits, ret);
374 vidObjLay->reversible_vlc = code;
375 }
376
377 if (vidObjLay->video_object_layer_verid != 1)
378 {
379 getbits = viddec_pm_get_bits(parent, &(code), 1);
380 BREAK_GETBITS_FAIL(getbits, ret);
381 vidObjLay->newpred_enable = code;
382 if(vidObjLay->newpred_enable)
383 {
384 DEB("Error: NEWPRED mode is not supported\n");
385 ret = MP4_STATUS_NOTSUPPORT | MP4_STATUS_REQD_DATA_ERROR;
386 break;
387 }
388 getbits = viddec_pm_get_bits(parent, &(code), 1);
389 BREAK_GETBITS_FAIL(getbits, ret);
390 vidObjLay->reduced_resolution_vop_enable = code;
391 }
392
393 getbits = viddec_pm_get_bits(parent, &(code), 1);
394 BREAK_GETBITS_FAIL(getbits, ret);
395 vidObjLay->scalability = code;
396 if(vidObjLay->scalability)
397 {
398 DEB("Error: VOL scalability is not supported\n");
399 ret = MP4_STATUS_NOTSUPPORT | MP4_STATUS_REQD_DATA_ERROR;
400 break;
401 }
402
403 // No need to parse further - none of the fields are interesting to parser/decoder/user
404 ret = MP4_STATUS_OK;
405 }while(0);
406 return ret;
407 }
408
mp4_Parse_VideoObjectLayer(void * parent,viddec_mp4_parser_t * parser)409 mp4_Status_t mp4_Parse_VideoObjectLayer(void *parent, viddec_mp4_parser_t *parser)
410 {
411 uint32_t code;
412 mp4_Info_t *pInfo = &(parser->info);
413 mp4_VisualObject_t *visObj = &(pInfo->VisualObject);
414 mp4_VideoObjectLayer_t *vidObjLay = &(pInfo->VisualObject.VideoObject);
415 mp4_Status_t ret = MP4_STATUS_PARSE_ERROR;
416 int32_t getbits=0;
417
418 //DEB("entering mp4_Parse_VideoObjectLayer: bs_err: %d, ret: %d\n", parser->bitstream_error, ret);
419 do{
420 vidObjLay->VideoObjectPlane.sprite_transmit_mode = MP4_SPRITE_TRANSMIT_MODE_PIECE;
421
422 vidObjLay->short_video_header = 0;
423 vidObjLay->video_object_layer_id = (parser->current_sc & 0xF);
424
425 getbits = viddec_pm_get_bits(parent, &code, 9);
426 BREAK_GETBITS_REQD_MISSING(getbits, ret);
427 vidObjLay->video_object_type_indication = code & 0xFF;
428 vidObjLay->random_accessible_vol = ((code & 0x100) > 0);
429
430 if(!mp4_pvt_valid_object_type_indication(vidObjLay->video_object_type_indication))
431 { /* Streams with "unknown" type mismatch with ref */
432 DEB("Warning: video_object_type_indication = %d, forcing to 1\n",
433 vidObjLay->video_object_type_indication);
434 vidObjLay->video_object_type_indication = 1;
435 }
436
437 if(vidObjLay->video_object_type_indication == MP4_VIDEO_OBJECT_TYPE_FINE_GRANULARITY_SCALABLE)
438 {/* This is not a supported type by HW */
439 DEB("ERROR: mp4_Parse_VideoObject:video_object_type_indication = %.2X\n",
440 vidObjLay->video_object_type_indication);
441 ret = MP4_STATUS_NOTSUPPORT | MP4_STATUS_REQD_DATA_ERROR;
442 break;
443 }
444 else
445 {
446 getbits = viddec_pm_get_bits(parent, &(code), 1);
447 BREAK_GETBITS_REQD_MISSING(getbits, ret);
448 vidObjLay->is_object_layer_identifier = code;
449 vidObjLay->video_object_layer_verid =
450 (mp4_pvt_valid_object_layer_verid(visObj->visual_object_verid)) ? visObj->visual_object_verid : 1;
451
452 if (vidObjLay->is_object_layer_identifier)
453 {
454 getbits = viddec_pm_get_bits(parent, &(code), 7);
455 BREAK_GETBITS_REQD_MISSING(getbits, ret);
456 vidObjLay->video_object_layer_priority = code & 0x7;
457 vidObjLay->video_object_layer_verid = (code >> 3) & 0xF;
458 if(!mp4_pvt_valid_object_layer_verid(vidObjLay->video_object_layer_verid))
459 {
460 DEB("Error: mp4_Parse_VideoObject:is_identifier = %d, expected[1,5]\n",
461 vidObjLay->video_object_layer_verid);
462 ret = MP4_STATUS_NOTSUPPORT | MP4_STATUS_REQD_DATA_ERROR;
463 break;
464 }
465 /* Video object layer ID supercedes visual object ID */
466 visObj->visual_object_verid = vidObjLay->video_object_layer_verid;
467 }
468
469 getbits = viddec_pm_get_bits(parent, &(code), 4);
470 BREAK_GETBITS_REQD_MISSING(getbits, ret);
471 vidObjLay->aspect_ratio_info = code & 0xF;
472 if(vidObjLay->aspect_ratio_info == MP4_ASPECT_RATIO_EXTPAR)
473 {
474 getbits = viddec_pm_get_bits(parent, &(code), 16);
475 BREAK_GETBITS_REQD_MISSING(getbits, ret);
476 vidObjLay->aspect_ratio_info_par_width = (code >> 8) & 0xFF;
477 vidObjLay->aspect_ratio_info_par_height = code & 0xFF;
478 }
479
480 getbits = viddec_pm_get_bits(parent, &(code), 1);
481 BREAK_GETBITS_REQD_MISSING(getbits, ret);
482 vidObjLay->is_vol_control_parameters = code;
483 if(vidObjLay->is_vol_control_parameters)
484 {
485 ret = mp4_pvt_VOL_volcontrolparameters(parent, parser);
486 if(ret != MP4_STATUS_OK)
487 {
488 break;
489 }
490 }
491
492 getbits = viddec_pm_get_bits(parent, &(code), 2);
493 BREAK_GETBITS_REQD_MISSING(getbits, ret);
494 vidObjLay->video_object_layer_shape = code;
495 /* If shape is not rectangluar exit early without parsing */
496 if (vidObjLay->video_object_layer_shape != MP4_SHAPE_TYPE_RECTANGULAR)
497 {
498 DEB("Error: mp4_Parse_VideoObject: shape not rectangluar(%d):%d\n",
499 MP4_SHAPE_TYPE_RECTANGULAR, vidObjLay->video_object_layer_shape);
500 ret = MP4_STATUS_NOTSUPPORT | MP4_STATUS_REQD_DATA_ERROR;
501 break;
502 }
503
504 if ((vidObjLay->video_object_layer_verid != 1) &&
505 (vidObjLay->video_object_layer_shape == MP4_SHAPE_TYPE_GRAYSCALE))
506 {/* Grayscale not supported */
507 DEB("Error: MP4_SHAPE_TYPE_GRAYSCALE not supported\n");
508 ret = MP4_STATUS_NOTSUPPORT | MP4_STATUS_REQD_DATA_ERROR;
509 break;
510 }
511
512 getbits = viddec_pm_get_bits(parent, &(code), 19);
513 BREAK_GETBITS_REQD_MISSING(getbits, ret);
514 /* TODO: check validity of marker */
515 vidObjLay->vop_time_increment_resolution = (code >> 2) & 0xFFFF;
516 vidObjLay->fixed_vop_rate = code & 0x1;
517
518 if(vidObjLay->vop_time_increment_resolution == 0)
519 {
520 DEB("Error: 0 value for vop_time_increment_resolution\n");
521 ret = MP4_STATUS_NOTSUPPORT | MP4_STATUS_REQD_DATA_ERROR;
522 break;
523 }
524 /* calculate number bits in vop_time_increment_resolution */
525 vidObjLay->vop_time_increment_resolution_bits = (uint8_t)mp4_pvt_count_number_of_bits(
526 (uint32_t)(vidObjLay->vop_time_increment_resolution -1));
527
528 if(vidObjLay->fixed_vop_rate)
529 {
530 getbits = viddec_pm_get_bits(parent, &(code), vidObjLay->vop_time_increment_resolution_bits);
531 BREAK_GETBITS_REQD_MISSING(getbits, ret);
532 vidObjLay->fixed_vop_time_increment = code;
533 }
534
535 if (vidObjLay->video_object_layer_shape != MP4_SHAPE_TYPE_BINARYONLY)
536 {
537 ret = mp4_Parse_VOL_notbinaryonly(parent, parser);
538 if(ret != MP4_STATUS_OK)
539 {
540 break;
541 }
542 }
543 else
544 {
545 DEB("Error: MP4_SHAPE_TYPE_BINARYONLY not supported\n");
546 ret = MP4_STATUS_NOTSUPPORT | MP4_STATUS_REQD_DATA_ERROR;
547 break;
548 }
549 }
550
551 vidObjLay->VideoObjectPlane.sprite_transmit_mode = MP4_SPRITE_TRANSMIT_MODE_PIECE;
552 ret = MP4_STATUS_OK;
553 } while(0);
554
555 mp4_set_hdr_bitstream_error(parser, true, ret);
556 if(ret != MP4_STATUS_OK)
557 parser->bitstream_error |= MP4_BS_ERROR_HDR_NONDEC;
558 //DEB("before wkld mp4_Parse_VideoObjectLayer: bs_err: %d, ret: %d\n", parser->bitstream_error, ret);
559
560 // POPULATE WORKLOAD ITEM
561 {
562 viddec_workload_item_t wi;
563 viddec_workload_t *wl = viddec_pm_get_header(parent);
564
565 wi.vwi_type = VIDDEC_WORKLOAD_MPEG4_VIDEO_OBJ;
566
567 wi.mp4_vol.vol_aspect_ratio = 0;
568 wi.mp4_vol.vol_bit_rate = 0;
569 wi.mp4_vol.vol_frame_rate = 0;
570
571 viddec_fw_mp4_vol_set_aspect_ratio_info(&wi.mp4_vol, vidObjLay->aspect_ratio_info);
572 viddec_fw_mp4_vol_set_par_width(&wi.mp4_vol, vidObjLay->aspect_ratio_info_par_width);
573 viddec_fw_mp4_vol_set_par_height(&wi.mp4_vol, vidObjLay->aspect_ratio_info_par_height);
574 viddec_fw_mp4_vol_set_control_param(&wi.mp4_vol, vidObjLay->is_vol_control_parameters);
575 viddec_fw_mp4_vol_set_chroma_format(&wi.mp4_vol, vidObjLay->VOLControlParameters.chroma_format);
576 viddec_fw_mp4_vol_set_interlaced(&wi.mp4_vol, vidObjLay->interlaced);
577 viddec_fw_mp4_vol_set_fixed_vop_rate(&wi.mp4_vol, vidObjLay->fixed_vop_rate);
578
579 viddec_fw_mp4_vol_set_vbv_param(&wi.mp4_vol, vidObjLay->VOLControlParameters.vbv_parameters);
580 viddec_fw_mp4_vol_set_bit_rate(&wi.mp4_vol, vidObjLay->VOLControlParameters.bit_rate);
581
582 viddec_fw_mp4_vol_set_fixed_vop_time_increment(&wi.mp4_vol, vidObjLay->fixed_vop_time_increment);
583 viddec_fw_mp4_vol_set_vop_time_increment_resolution(&wi.mp4_vol, vidObjLay->vop_time_increment_resolution);
584
585 ret = viddec_pm_append_workitem(parent, &wi);
586 if(ret == 1)
587 ret = MP4_STATUS_OK;
588
589 memset(&(wl->attrs), 0, sizeof(viddec_frame_attributes_t));
590
591 wl->attrs.cont_size.width = vidObjLay->video_object_layer_width;
592 wl->attrs.cont_size.height = vidObjLay->video_object_layer_height;
593 }
594
595 return ret;
596 }
597