• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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