1 #include "viddec_mp4_videoobjectplane.h" 2 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 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 } 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 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 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 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