• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #include "viddec_mp4_videoobjectplane.h"
2 
mp4_Parse_GroupOfVideoObjectPlane(void * parent,viddec_mp4_parser_t * parser)3 mp4_Status_t mp4_Parse_GroupOfVideoObjectPlane(void *parent, viddec_mp4_parser_t *parser)
4 {
5     mp4_Info_t* pInfo = &(parser->info);
6     uint32_t  code;
7     int32_t getbits=0;
8     mp4_Status_t ret = MP4_STATUS_REQD_DATA_ERROR;
9     mp4_GroupOfVideoObjectPlane_t *data;
10     uint32_t time_code = 0;
11 
12     data = &(pInfo->VisualObject.VideoObject.GroupOfVideoObjectPlane);
13 
14     do
15     {
16         getbits = viddec_pm_get_bits(parent, &code, 20);
17         BREAK_GETBITS_FAIL(getbits, ret);
18         ret = MP4_STATUS_OK;
19 
20         data->broken_link = ((code & 0x1) > 0);
21         data->closed_gov = ((code & 0x2) > 0);
22         time_code = code = code >> 2;
23         data->time_code_seconds = code & 0x3F;
24         code = code >> 6;
25         if((code & 1) == 0)
26         {/* SGA:Should we ignore marker bit? */
27             DEB("Error:mp4_Parse_GroupOfVideoObjectPlane: Invalid marker\n");
28         }
29         code = code >>1;
30         data->time_code_minutes = code & 0x3F;
31         code = code >> 6;
32         data->time_code_hours = code & 0x1F;
33 
34         // This is the timebase in full second units
35         data->time_base = data->time_code_seconds + (60*data->time_code_minutes) + (3600*data->time_code_hours);
36         // Need to convert this into no. of ticks
37         data->time_base *= pInfo->VisualObject.VideoObject.vop_time_increment_resolution;
38 
39     } while(0);
40 
41     mp4_set_hdr_bitstream_error(parser, true, ret);
42 
43     // POPULATE WORKLOAD ITEM
44     {
45         viddec_workload_item_t wi;
46 
47         wi.vwi_type = VIDDEC_WORKLOAD_MPEG4_GRP_VIDEO_OBJ;
48 
49         wi.mp4_gvop.gvop_info = 0;
50         wi.mp4_gvop.pad1 = 0;
51         wi.mp4_gvop.pad2 = 0;
52 
53         viddec_fw_mp4_gvop_set_broken_link(&wi.mp4_gvop, data->broken_link);
54         viddec_fw_mp4_gvop_set_closed_gov(&wi.mp4_gvop, data->closed_gov);
55         viddec_fw_mp4_gvop_set_time_code(&wi.mp4_gvop, time_code);
56 
57         ret = viddec_pm_append_workitem(parent, &wi);
58         if(ret == 1)
59             ret = MP4_STATUS_OK;
60     }
61 
62     return ret;
63 }
64 
mp4_brightness_change(void * parent,int32_t * b_change)65 static inline mp4_Status_t mp4_brightness_change(void *parent, int32_t *b_change)
66 {
67     uint32_t code;
68     int32_t getbits=0;
69 
70     *b_change = 0;
71     getbits = viddec_pm_peek_bits(parent, &code, 4);
72     if (code == 15)
73     {
74         getbits = viddec_pm_skip_bits(parent, 4);
75         getbits = viddec_pm_get_bits(parent, &code, 10);
76         *b_change = 625 + code;
77     }
78     else if (code == 14)
79     {
80         getbits = viddec_pm_skip_bits(parent, 4);
81         getbits = viddec_pm_get_bits(parent, &code, 9);
82         *b_change = 113 + code;
83     }
84     else if (code >= 12)
85     {
86         getbits = viddec_pm_skip_bits(parent, 3);
87         getbits = viddec_pm_get_bits(parent, &code, 7);
88         *b_change = (code < 64) ? ((int32_t)code - 112) : ((int32_t)code - 15);
89     }
90     else if (code >= 8)
91     {
92         getbits = viddec_pm_skip_bits(parent, 2);
93         getbits = viddec_pm_get_bits(parent, &code, 6);
94         *b_change = (code < 32) ? ((int32_t)code - 48) : ((int32_t)code - 15);
95     }
96     else
97     {
98         getbits = viddec_pm_skip_bits(parent, 1);
99         getbits = viddec_pm_get_bits(parent, &code, 5);
100         *b_change = (code < 16) ? ((int32_t)code - 16) : ((int32_t)code - 15);
101     }
102 
103     return ( (getbits == -1) ? MP4_STATUS_PARSE_ERROR: MP4_STATUS_OK);
104 }
mp4_Sprite_dmv_length(void * parent,int32_t * dmv_length)105 static inline int32_t mp4_Sprite_dmv_length(void * parent, int32_t *dmv_length)
106 {
107     uint32_t code, skip;
108     int32_t getbits=0;
109     mp4_Status_t ret= MP4_STATUS_PARSE_ERROR;
110     *dmv_length=0;
111     skip=3;
112     do{
113         getbits = viddec_pm_peek_bits(parent, &code, skip);
114         BREAK_GETBITS_REQD_MISSING(getbits, ret);
115 
116         if(code == 7)
117         {
118             viddec_pm_skip_bits(parent, skip);
119             getbits = viddec_pm_peek_bits(parent, &code, 9);
120             BREAK_GETBITS_REQD_MISSING(getbits, ret);
121 
122             skip=1;
123             while((code & 256) != 0)
124             {/* count number of 1 bits */
125                 code <<=1;
126                 skip++;
127             }
128             *dmv_length = 5 + skip;
129         }
130         else
131         {
132             skip=(code <= 1) ? 2 : 3;
133             *dmv_length = code - 1;
134         }
135         viddec_pm_skip_bits(parent, skip);
136         ret= MP4_STATUS_OK;
137 
138     }while(0);
139     return ret;
140 }
141 
142 static inline mp4_Status_t
mp4_Sprite_Trajectory(void * parent,mp4_VideoObjectLayer_t * vidObjLay,mp4_VideoObjectPlane_t * vidObjPlane)143 mp4_Sprite_Trajectory(void *parent, mp4_VideoObjectLayer_t *vidObjLay, mp4_VideoObjectPlane_t *vidObjPlane)
144 {
145     uint32_t code, i;
146     int32_t dmv_length=0, dmv_code=0, getbits=0;
147     mp4_Status_t ret = MP4_STATUS_OK;
148     for(i=0; i < (uint32_t)vidObjLay->sprite_info.no_of_sprite_warping_points; i++ )
149     {
150         ret = mp4_Sprite_dmv_length(parent, &dmv_length);
151         if(ret != MP4_STATUS_OK)
152         {
153             break;
154         }
155         if(dmv_length <= 0)
156         {
157             dmv_code = 0;
158         }
159         else
160         {
161             getbits = viddec_pm_get_bits(parent, &code, (uint32_t)dmv_length);
162             BREAK_GETBITS_REQD_MISSING(getbits, ret);
163             dmv_code = (int32_t)code;
164             if ((dmv_code & (1 << (dmv_length - 1))) == 0)
165             {
166                 dmv_code -= (1 << dmv_length) - 1;
167             }
168         }
169         getbits = viddec_pm_get_bits(parent, &code, 1);
170         BREAK_GETBITS_REQD_MISSING(getbits, ret);
171         if(code != 1)
172         {
173             ret = MP4_STATUS_NOTSUPPORT;
174             break;
175         }
176         vidObjPlane->warping_mv_code_du[i] = dmv_code;
177         /* TODO: create another inline function to avoid code duplication */
178         ret = mp4_Sprite_dmv_length(parent, &dmv_length);
179         if(ret != MP4_STATUS_OK)
180         {
181             break;
182         }
183         if(dmv_length <= 0)
184         {
185             dmv_code = 0;
186         }
187         else
188         {
189             getbits = viddec_pm_get_bits(parent, &code, (uint32_t)dmv_length);
190             BREAK_GETBITS_REQD_MISSING(getbits, ret);
191             dmv_code = (int32_t)code;
192             if ((dmv_code & (1 << (dmv_length - 1))) == 0)
193             {
194                 dmv_code -= (1 << dmv_length) - 1;
195             }
196         }
197         getbits = viddec_pm_get_bits(parent, &code, 1);
198         BREAK_GETBITS_REQD_MISSING(getbits, ret);
199         if(code != 1)
200         {
201             ret = MP4_STATUS_NOTSUPPORT;
202             break;
203         }
204         vidObjPlane->warping_mv_code_dv[i] = dmv_code;
205 
206     }
207     return ret;
208 }
209 
mp4_pvt_extract_modulotimebase_from_VideoObjectPlane(void * parent,uint32_t * base)210 static inline mp4_Status_t mp4_pvt_extract_modulotimebase_from_VideoObjectPlane(void *parent, uint32_t *base)
211 {
212     mp4_Status_t ret= MP4_STATUS_OK;
213     int32_t getbits=0;
214     uint32_t  code = 0;
215 
216     *base = 0;
217     do
218     {
219         getbits = viddec_pm_get_bits(parent, &code, 1);
220         BREAK_GETBITS_REQD_MISSING(getbits, ret);
221         *base += code;
222     }while(code != 0);
223     return ret;
224 }
225 
mp4_Parse_VideoObjectPlane(void * parent,viddec_mp4_parser_t * parser)226 mp4_Status_t mp4_Parse_VideoObjectPlane(void *parent, viddec_mp4_parser_t *parser)
227 {
228     uint32_t  code;
229     mp4_Info_t               *pInfo = &(parser->info);
230     mp4_VideoObjectLayer_t   *vidObjLay  = &(pInfo->VisualObject.VideoObject);
231     mp4_VideoObjectPlane_t   *vidObjPlane = &(pInfo->VisualObject.VideoObject.VideoObjectPlane);
232     int32_t getbits=0;
233     mp4_Status_t ret= MP4_STATUS_PARSE_ERROR;
234 
235     do
236     {
237         getbits = viddec_pm_get_bits(parent, &code, 2);
238         BREAK_GETBITS_REQD_MISSING(getbits, ret);
239         vidObjPlane->vop_coding_type = code & 0x3;
240         if( mp4_pvt_extract_modulotimebase_from_VideoObjectPlane(parent,
241                                                                  &(vidObjPlane->modulo_time_base)) == MP4_STATUS_REQD_DATA_ERROR)
242         {
243             break;
244         }
245 
246         getbits = viddec_pm_get_bits(parent, &code, 1);
247         /* TODO: check for marker bit validity */
248         {
249             uint32_t numbits=0;
250             numbits = vidObjLay->vop_time_increment_resolution_bits;
251             if(numbits == 0) numbits=1; /*TODO:check if its greater than 16 bits ?? */
252             getbits = viddec_pm_get_bits(parent, &code, numbits);
253             BREAK_GETBITS_REQD_MISSING(getbits, ret);
254             vidObjPlane->vop_time_increment = code;
255         }
256 
257         getbits = viddec_pm_get_bits(parent, &code, 2);
258         BREAK_GETBITS_REQD_MISSING(getbits, ret);
259 
260         vidObjPlane->vop_coded = code & 0x1;
261         if(vidObjPlane->vop_coded == 0)
262         {
263             ret = MP4_STATUS_OK;/* Exit point 1 */
264             break;
265         }
266 
267         if(vidObjLay->newpred_enable)
268         {
269             /* New pred mode not supported in HW */
270             DEB("Error: mp4_Parse_VideoObjectPlane: New pred in vidObjPlane is not supported\n");
271             ret = MP4_STATUS_NOTSUPPORT;
272             break;
273         }
274 
275         if ((vidObjLay->video_object_layer_shape != MP4_SHAPE_TYPE_BINARYONLY) &&
276             ((vidObjPlane->vop_coding_type == MP4_VOP_TYPE_P) ||
277              ((vidObjPlane->vop_coding_type == MP4_VOP_TYPE_S) &&
278               (vidObjLay->sprite_enable == MP4_SPRITE_GMC))))
279         {
280             getbits = viddec_pm_get_bits(parent, &code, 1);
281             BREAK_GETBITS_REQD_MISSING(getbits, ret);
282             vidObjPlane->vop_rounding_type = code;
283         }
284 
285         if (vidObjLay->reduced_resolution_vop_enable &&
286             (vidObjLay->video_object_layer_shape == MP4_SHAPE_TYPE_RECTANGULAR) &&
287             ((vidObjPlane->vop_coding_type == MP4_VOP_TYPE_I) ||
288              (vidObjPlane->vop_coding_type == MP4_VOP_TYPE_P)))
289         {
290             getbits = viddec_pm_get_bits(parent, &code, 1);
291             BREAK_GETBITS_REQD_MISSING(getbits, ret);
292             vidObjPlane->vop_reduced_resolution = code;
293             if (vidObjPlane->vop_reduced_resolution)
294             {
295                 DEB("Error: mp4_Parse_VideoObjectPlane: Reduced Resolution vidObjPlane is not supported\n");
296                 ret = MP4_STATUS_NOTSUPPORT;
297                 break;
298             }
299         }
300 
301         if (vidObjLay->video_object_layer_shape != MP4_SHAPE_TYPE_RECTANGULAR)
302         {
303             /* we support only rectangular shapes so the following logic is not required */
304             ret = MP4_STATUS_NOTSUPPORT;
305             break;
306         }
307 
308         if ((vidObjLay->video_object_layer_shape != MP4_SHAPE_TYPE_BINARYONLY) &&
309             (!vidObjLay->complexity_estimation_disable))
310         {
311             /* Not required according to DE team */
312             //read_vop_complexity_estimation_header();
313             ret = MP4_STATUS_NOTSUPPORT;
314             break;
315         }
316 
317         if (vidObjLay->video_object_layer_shape != MP4_SHAPE_TYPE_BINARYONLY)
318         {
319             getbits = viddec_pm_get_bits(parent, &code, 3);
320             BREAK_GETBITS_REQD_MISSING(getbits, ret);
321             vidObjPlane->intra_dc_vlc_thr = code;
322             if (vidObjLay->interlaced)
323             {
324                 getbits = viddec_pm_get_bits(parent, &code, 2);
325                 BREAK_GETBITS_REQD_MISSING(getbits, ret);
326                 vidObjPlane->top_field_first = ((code & 0x2) > 0);
327                 vidObjPlane->alternate_vertical_scan_flag = code & 0x1;
328             }
329         }
330 
331         if (((vidObjLay->sprite_enable == MP4_SPRITE_STATIC) || (vidObjLay->sprite_enable == MP4_SPRITE_GMC)) &&
332             (vidObjPlane->vop_coding_type == MP4_VOP_TYPE_S))
333         {
334             if (vidObjLay->sprite_info.no_of_sprite_warping_points > 0){
335                 if (mp4_Sprite_Trajectory(parent, vidObjLay, vidObjPlane) != MP4_STATUS_OK){
336                     break;
337                 }
338             }
339             vidObjPlane->brightness_change_factor = 0;
340             if (vidObjLay->sprite_info.sprite_brightness_change)
341             {
342                 int32_t change=0;
343                 if(mp4_brightness_change(parent, &change) == MP4_STATUS_PARSE_ERROR)
344                 {
345                     break;
346                 }
347                 vidObjPlane->brightness_change_factor = change;
348             }
349 
350             if (vidObjLay->sprite_enable == MP4_SPRITE_STATIC)
351             {
352                 /* SGA: IS decode sprite not required. Is static even supported */
353                 ret = MP4_STATUS_OK;/* Exit point 2 */
354                 break;
355             }
356         }
357 
358         if (vidObjLay->video_object_layer_shape != MP4_SHAPE_TYPE_BINARYONLY)
359         {
360             // Length of vop_quant is specified by quant_precision
361             getbits = viddec_pm_get_bits(parent, &code, vidObjLay->quant_precision);
362             BREAK_GETBITS_REQD_MISSING(getbits, ret);
363             vidObjPlane->vop_quant = code;
364             if (vidObjLay->video_object_layer_shape == MP4_SHAPE_TYPE_GRAYSCALE)
365             {
366                 ret = MP4_STATUS_NOTSUPPORT;
367                 break;
368             }
369             if (vidObjPlane->vop_coding_type != MP4_VOP_TYPE_I)
370             {
371                 vidObjPlane->vop_fcode_forward = 0;
372                 getbits = viddec_pm_get_bits(parent, &code, 3);
373                 BREAK_GETBITS_REQD_MISSING(getbits, ret);
374                 vidObjPlane->vop_fcode_forward = code & 0x7;
375                 if (vidObjPlane->vop_fcode_forward == 0)
376                 {
377                     DEB("Error: vop_fcode_forward == 0\n");
378                     break;
379                 }
380             }
381             if (vidObjPlane->vop_coding_type == MP4_VOP_TYPE_B)
382             {
383                 vidObjPlane->vop_fcode_backward = 0;
384                 getbits = viddec_pm_get_bits(parent, &code, 3);
385                 BREAK_GETBITS_REQD_MISSING(getbits, ret);
386                 vidObjPlane->vop_fcode_backward = code &0x7;
387                 if (vidObjPlane->vop_fcode_backward == 0)
388                 {
389                     DEB("Error: vop_fcode_backward == 0\n");
390                     break;
391                 }
392             }
393             if (!vidObjLay->scalability)
394             {
395                 if ((vidObjLay->video_object_layer_shape != MP4_SHAPE_TYPE_RECTANGULAR) &&
396                     (vidObjPlane->vop_coding_type != MP4_VOP_TYPE_I))
397                 {
398                     ret = MP4_STATUS_NOTSUPPORT;
399                     break;
400                 }
401                 // The remaining data contains the macroblock information that is handled by the BSP
402                 // The offsets to be sent to the BSP are obtained in the workload population
403             }
404             else
405             {
406                 ret = MP4_STATUS_NOTSUPPORT;
407                 break;
408             }
409         }
410         else
411         {/* Binary Not supported */
412             ret = MP4_STATUS_NOTSUPPORT;
413             break;
414         }
415         /* Since we made it all the way here it a success condition */
416         ret = MP4_STATUS_OK;  /* Exit point 3 */
417     }while(0);
418 
419     mp4_set_hdr_bitstream_error(parser, false, ret);
420 
421     return ret;
422 } // mp4_Parse_VideoObjectPlane
423