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 bitstream layers down to but not including 10 // macroblock layer. 11 // 12 */ 13 14 #include "viddec_fw_debug.h" 15 #include "vc1parse.h" 16 17 #define VC1_PIXEL_IN_LUMA 16 18 19 /*------------------------------------------------------------------------------ 20 * Parse modified rcv file, start codes are inserted using rcv2vc1.c. 21 * source is in 22 * http://svn.jf.intel.com/svn/DHG_Src/CESWE_Src/DEV/trunk/sv/mfd/tools/utils. 23 * Assumme rcv file width < 90,112 pixel to differenciate from real VC1 24 * advanced profile header. 25 * Original rcv description is in annex L 26 * Table 263 of SMPTE 421M. 27 */ 28 vc1_Status vc1_ParseRCVSequenceLayer (void* ctxt, vc1_Info *pInfo) 29 { 30 uint32_t result; 31 vc1_Status status = VC1_STATUS_OK; 32 vc1_metadata_t *md = &pInfo->metadata; 33 vc1_RcvSequenceHeader rcv; 34 35 memset(&rcv, 0, sizeof(vc1_RcvSequenceHeader)); 36 37 result = viddec_pm_get_bits(ctxt, &rcv.struct_a_rcv, 32); 38 md->width = rcv.struct_a.HORIZ_SIZE; 39 md->height = rcv.struct_a.VERT_SIZE; 40 41 result = viddec_pm_get_bits(ctxt, &rcv.struct_c_rcv, 32); 42 md->PROFILE = rcv.struct_c.PROFILE >> 2; 43 md->LOOPFILTER = rcv.struct_c.LOOPFILTER; 44 md->MULTIRES = rcv.struct_c.MULTIRES; 45 md->FASTUVMC = rcv.struct_c.FASTUVMC; 46 md->EXTENDED_MV = rcv.struct_c.EXTENDED_MV; 47 md->DQUANT = rcv.struct_c.DQUANT; 48 md->VSTRANSFORM = rcv.struct_c.VSTRANSFORM; 49 md->OVERLAP = rcv.struct_c.OVERLAP; 50 md->RANGERED = rcv.struct_c.RANGERED; 51 md->MAXBFRAMES = rcv.struct_c.MAXBFRAMES; 52 md->QUANTIZER = rcv.struct_c.QUANTIZER; 53 md->FINTERPFLAG = rcv.struct_c.FINTERPFLAG; 54 #ifdef VBP 55 md->SYNCMARKER = rcv.struct_c.SYNCMARKER; 56 #endif 57 58 if ((md->PROFILE == VC1_PROFILE_SIMPLE) || 59 (md->MULTIRES && md->PROFILE == VC1_PROFILE_MAIN)) 60 { 61 md->DQUANT = 0; 62 } 63 // TODO: NEED TO CHECK RESERVED BITS ARE 0 64 65 md->widthMB = (md->width + 15 ) / VC1_PIXEL_IN_LUMA; 66 md->heightMB = (md->height + 15) / VC1_PIXEL_IN_LUMA; 67 68 DEB("rcv: beforemod: res: %dx%d\n", md->width, md->height); 69 70 /* WL takes resolution in unit of 2 pel - sec. 6.2.13.1 */ 71 md->width = md->width/2 -1; 72 md->height = md->height/2 -1; 73 74 DEB("rcv: res: %dx%d\n", md->width, md->height); 75 76 // POPULATE WORKLOAD ITEM 77 { 78 viddec_workload_item_t wi; 79 80 wi.vwi_type = VIDDEC_WORKLOAD_VC1_SEQ_HDR_STRUCT_A_C; 81 82 wi.vc1_sh_struct_a_c.size = 0; 83 wi.vc1_sh_struct_a_c.flags = 0; 84 wi.vc1_sh_struct_a_c.pad = 0; 85 86 viddec_fw_vc1_set_rcv_horiz_size(&wi.vc1_sh_struct_a_c, rcv.struct_a.HORIZ_SIZE); 87 viddec_fw_vc1_set_rcv_vert_size(&wi.vc1_sh_struct_a_c, rcv.struct_a.VERT_SIZE); 88 89 viddec_fw_vc1_set_rcv_bitrtq_postproc(&wi.vc1_sh_struct_a_c, rcv.struct_c.BITRTQ_POSTPROC); 90 viddec_fw_vc1_set_rcv_frmrtq_postproc(&wi.vc1_sh_struct_a_c, rcv.struct_c.FRMRTQ_POSTPROC); 91 viddec_fw_vc1_set_rcv_profile(&wi.vc1_sh_struct_a_c, rcv.struct_c.PROFILE); 92 viddec_fw_vc1_set_rcv_level(&wi.vc1_sh_struct_a_c, 0); 93 viddec_fw_vc1_set_rcv_cbr(&wi.vc1_sh_struct_a_c, 0); 94 viddec_fw_vc1_set_rcv_rangered(&wi.vc1_sh_struct_a_c, rcv.struct_c.RANGERED); 95 viddec_fw_vc1_set_rcv_maxbframes(&wi.vc1_sh_struct_a_c, rcv.struct_c.MAXBFRAMES); 96 viddec_fw_vc1_set_rcv_finterpflag(&wi.vc1_sh_struct_a_c, rcv.struct_c.FINTERPFLAG); 97 98 result = viddec_pm_append_workitem(ctxt, &wi); 99 } 100 101 return status; 102 } 103 104 /*------------------------------------------------------------------------------ 105 * Parse sequence layer. This function is only applicable to advanced profile 106 * as simple and main profiles use other mechanisms to communicate these 107 * metadata. 108 * Table 3 of SMPTE 421M. 109 * Table 13 of SMPTE 421M for HRD_PARAM(). 110 *------------------------------------------------------------------------------ 111 */ 112 113 vc1_Status vc1_ParseSequenceLayer(void* ctxt, vc1_Info *pInfo) 114 { 115 uint32_t tempValue; 116 vc1_Status status = VC1_STATUS_OK; 117 vc1_metadata_t *md = &pInfo->metadata; 118 vc1_SequenceLayerHeader sh; 119 uint32_t result; 120 121 memset(&sh, 0, sizeof(vc1_SequenceLayerHeader)); 122 123 // PARSE SEQUENCE HEADER 124 result = viddec_pm_get_bits(ctxt, &sh.flags, 15); 125 if(result == 1) 126 { 127 md->PROFILE = sh.seq_flags.PROFILE; 128 #ifdef VBP 129 md->LEVEL = sh.seq_flags.LEVEL; 130 #endif 131 } 132 133 result = viddec_pm_get_bits(ctxt, &sh.max_size, 32); 134 if(result == 1) 135 { 136 md->POSTPROCFLAG = sh.seq_max_size.POSTPROCFLAG; 137 md->width = sh.seq_max_size.MAX_CODED_WIDTH; 138 md->height = sh.seq_max_size.MAX_CODED_HEIGHT; 139 md->PULLDOWN = sh.seq_max_size.PULLDOWN; 140 md->INTERLACE = sh.seq_max_size.INTERLACE; 141 md->TFCNTRFLAG = sh.seq_max_size.TFCNTRFLAG; 142 md->FINTERPFLAG = sh.seq_max_size.FINTERPFLAG; 143 md->PSF = sh.seq_max_size.PSF; 144 } 145 146 if (sh.seq_max_size.DISPLAY_EXT == 1) 147 { 148 result = viddec_pm_get_bits(ctxt, &sh.disp_size, 29); 149 if(result == 1) 150 { 151 if (sh.seq_disp_size.ASPECT_RATIO_FLAG == 1) 152 { 153 result = viddec_pm_get_bits(ctxt, &tempValue, 4); 154 sh.ASPECT_RATIO = tempValue; 155 if (sh.ASPECT_RATIO == 15) 156 { 157 result = viddec_pm_get_bits(ctxt, &sh.aspect_size, 16); 158 } 159 } 160 161 result = viddec_pm_get_bits(ctxt, &tempValue, 1); 162 sh.FRAMERATE_FLAG = tempValue; 163 if (sh.FRAMERATE_FLAG == 1) 164 { 165 result = viddec_pm_get_bits(ctxt, &tempValue, 1); 166 sh.FRAMERATEIND = tempValue; 167 if (sh.FRAMERATEIND == 0) 168 { 169 result = viddec_pm_get_bits(ctxt, &sh.framerate_fraction, 12); 170 } 171 else 172 { 173 result = viddec_pm_get_bits(ctxt, &tempValue, 16); 174 sh.FRAMERATEEXP = tempValue; 175 } 176 } 177 178 result = viddec_pm_get_bits(ctxt, &tempValue, 1); 179 sh.COLOR_FORMAT_FLAG = tempValue; 180 if (sh.COLOR_FORMAT_FLAG == 1) 181 { 182 result = viddec_pm_get_bits(ctxt, &sh.color_format, 24); 183 } 184 } // Successful get of display size 185 } // DISPLAY_EXT is 1 186 187 result = viddec_pm_get_bits(ctxt, &tempValue, 1); 188 sh.HRD_PARAM_FLAG = tempValue; 189 if (sh.HRD_PARAM_FLAG == 1) 190 { 191 /* HRD_PARAM(). */ 192 result = viddec_pm_get_bits(ctxt, &tempValue, 5); 193 sh.HRD_NUM_LEAKY_BUCKETS = tempValue; 194 md->HRD_NUM_LEAKY_BUCKETS = sh.HRD_NUM_LEAKY_BUCKETS; 195 // Skip the rest of the parsing - hrdinfo is not required for decode or for attributes 196 } 197 else 198 { 199 md->HRD_NUM_LEAKY_BUCKETS = 0; 200 } 201 202 md->widthMB = (((md->width + 1) * 2) + 15) / VC1_PIXEL_IN_LUMA; 203 md->heightMB = (((md->height + 1) * 2) + 15) / VC1_PIXEL_IN_LUMA; 204 205 DEB("md: res: %dx%d\n", md->width, md->height); 206 DEB("sh: dispres: %dx%d\n", sh.seq_disp_size.DISP_HORIZ_SIZE, sh.seq_disp_size.DISP_VERT_SIZE); 207 208 // POPULATE WORKLOAD ITEM 209 { 210 viddec_workload_item_t wi_sl, wi_de; 211 212 wi_sl.vwi_type = VIDDEC_WORKLOAD_SEQUENCE_INFO; 213 214 wi_sl.vc1_sl.size = 0; 215 wi_sl.vc1_sl.flags = 0; 216 wi_sl.vc1_sl.pad = 0; 217 218 viddec_fw_vc1_set_profile(&wi_sl.vc1_sl, sh.seq_flags.PROFILE); 219 viddec_fw_vc1_set_level(&wi_sl.vc1_sl, sh.seq_flags.LEVEL); 220 viddec_fw_vc1_set_colordiff_format(&wi_sl.vc1_sl, sh.seq_flags.COLORDIFF_FORMAT); 221 viddec_fw_vc1_set_pulldown(&wi_sl.vc1_sl, sh.seq_max_size.PULLDOWN); 222 viddec_fw_vc1_set_max_coded_width(&wi_sl.vc1_sl, sh.seq_max_size.MAX_CODED_WIDTH); 223 viddec_fw_vc1_set_max_coded_height(&wi_sl.vc1_sl, sh.seq_max_size.MAX_CODED_HEIGHT); 224 225 viddec_fw_vc1_set_bitrtq_postproc(&wi_sl.vc1_sl, sh.seq_flags.BITRTQ_POSTPROC); 226 viddec_fw_vc1_set_frmrtq_postproc(&wi_sl.vc1_sl, sh.seq_flags.FRMRTQ_POSTPROC); 227 viddec_fw_vc1_set_interlace(&wi_sl.vc1_sl, sh.seq_max_size.INTERLACE); 228 viddec_fw_vc1_set_tfcntrflag(&wi_sl.vc1_sl, sh.seq_max_size.TFCNTRFLAG); 229 viddec_fw_vc1_set_finterpflag(&wi_sl.vc1_sl, sh.seq_max_size.FINTERPFLAG); 230 viddec_fw_vc1_set_psf(&wi_sl.vc1_sl, sh.seq_max_size.PSF); 231 viddec_fw_vc1_set_display_ext(&wi_sl.vc1_sl, sh.seq_max_size.DISPLAY_EXT); 232 233 result = viddec_pm_append_workitem(ctxt, &wi_sl); 234 235 // send DISPLAY EXTENSION metadata if present 236 if (sh.seq_max_size.DISPLAY_EXT) 237 { 238 wi_de.vwi_type = VIDDEC_WORKLOAD_DISPLAY_INFO; 239 240 wi_de.vc1_sl_de.size = 0; 241 wi_de.vc1_sl_de.framerate = 0; 242 wi_de.vc1_sl_de.aspectsize = 0; 243 244 viddec_fw_vc1_set_disp_horiz_size(&wi_de.vc1_sl_de, sh.seq_disp_size.DISP_HORIZ_SIZE); 245 viddec_fw_vc1_set_disp_vert_size(&wi_de.vc1_sl_de, sh.seq_disp_size.DISP_VERT_SIZE); 246 viddec_fw_vc1_set_disp_aspect_ratio_flag(&wi_de.vc1_sl_de, sh.seq_disp_size.ASPECT_RATIO_FLAG); 247 viddec_fw_vc1_set_disp_color_format_flag(&wi_de.vc1_sl_de, sh.COLOR_FORMAT_FLAG); 248 viddec_fw_vc1_set_disp_framerate_flag(&wi_de.vc1_sl_de, sh.FRAMERATE_FLAG); 249 viddec_fw_vc1_set_disp_framerateind(&wi_de.vc1_sl_de, sh.FRAMERATEIND); 250 251 viddec_fw_vc1_set_disp_aspect_ratio(&wi_de.vc1_sl_de, sh.ASPECT_RATIO); 252 viddec_fw_vc1_set_disp_frameratenr(&wi_de.vc1_sl_de, sh.seq_framerate_fraction.FRAMERATENR); 253 viddec_fw_vc1_set_disp_frameratedr(&wi_de.vc1_sl_de, sh.seq_framerate_fraction.FRAMERATEDR); 254 viddec_fw_vc1_set_disp_framerateexp(&wi_de.vc1_sl_de, sh.FRAMERATEEXP); 255 256 viddec_fw_vc1_set_disp_aspect_ratio_horiz_size(&wi_de.vc1_sl_de, sh.seq_aspect_size.ASPECT_HORIZ_SIZE); 257 viddec_fw_vc1_set_disp_aspect_ratio_vert_size(&wi_de.vc1_sl_de, sh.seq_aspect_size.ASPECT_VERT_SIZE); 258 viddec_fw_vc1_set_disp_color_prim(&wi_de.vc1_sl_de, sh.seq_color_format.COLOR_PRIM); 259 viddec_fw_vc1_set_disp_transfer_char(&wi_de.vc1_sl_de, sh.seq_color_format.TRANSFER_CHAR); 260 261 result = viddec_pm_append_workitem(ctxt, &wi_de); 262 } 263 } 264 265 return status; 266 } 267 268 /*------------------------------------------------------------------------------ 269 * Parse entry point layer. This function is only applicable for advanced 270 * profile and is used to signal a random access point and changes in coding 271 * control parameters. 272 * Table 14 of SMPTE 421M. 273 * Table 15 of SMPTE 421M for HRD_FULLNESS(). 274 *------------------------------------------------------------------------------ 275 */ 276 vc1_Status vc1_ParseEntryPointLayer(void* ctxt, vc1_Info *pInfo) 277 { 278 vc1_Status status = VC1_STATUS_OK; 279 vc1_metadata_t *md = &pInfo->metadata; 280 vc1_EntryPointHeader ep; 281 uint32_t result; 282 uint32_t temp; 283 284 memset(&ep, 0, sizeof(vc1_EntryPointHeader)); 285 286 // PARSE ENTRYPOINT HEADER 287 result = viddec_pm_get_bits(ctxt, &ep.flags, 13); 288 if(result == 1) 289 { 290 // Skip the flags already peeked at (13) and the unneeded hrd_full data 291 // NOTE: HRD_NUM_LEAKY_BUCKETS is initialized to 0 when HRD_PARAM_FLAG is not present 292 int hrd_bits = md->HRD_NUM_LEAKY_BUCKETS * 8; 293 while(hrd_bits >= 32) 294 { 295 result = viddec_pm_skip_bits(ctxt, 32); 296 hrd_bits -= 32; 297 } 298 result = viddec_pm_skip_bits(ctxt, hrd_bits); 299 300 md->REFDIST = 0; 301 md->PANSCAN_FLAG = ep.ep_flags.PANSCAN_FLAG; 302 md->REFDIST_FLAG = ep.ep_flags.REFDIST_FLAG; 303 md->LOOPFILTER = ep.ep_flags.LOOPFILTER; 304 md->FASTUVMC = ep.ep_flags.FASTUVMC; 305 md->EXTENDED_MV = ep.ep_flags.EXTENDED_MV; 306 md->DQUANT = ep.ep_flags.DQUANT; 307 md->VSTRANSFORM = ep.ep_flags.VSTRANSFORM; 308 md->OVERLAP = ep.ep_flags.OVERLAP; 309 md->QUANTIZER = ep.ep_flags.QUANTIZER; 310 311 result = viddec_pm_get_bits(ctxt, &temp, 1); 312 if(result == 1) 313 { 314 ep.CODED_SIZE_FLAG = temp; 315 if(ep.CODED_SIZE_FLAG) 316 { 317 result = viddec_pm_get_bits(ctxt, &ep.size, 24); 318 md->width = ep.ep_size.CODED_WIDTH; 319 md->height = ep.ep_size.CODED_HEIGHT; 320 } 321 } 322 if(ep.ep_flags.EXTENDED_MV) 323 { 324 result = viddec_pm_get_bits(ctxt, &temp, 1); 325 md->EXTENDED_DMV = ep.EXTENDED_DMV = temp; 326 } 327 328 result = viddec_pm_get_bits(ctxt, &temp, 1); 329 if(result == 1) 330 { 331 md->RANGE_MAPY_FLAG = ep.RANGE_MAPY_FLAG = temp; 332 if(ep.RANGE_MAPY_FLAG) 333 { 334 result = viddec_pm_get_bits(ctxt, &temp, 3); 335 md->RANGE_MAPY = ep.RANGE_MAPY = temp; 336 } 337 } 338 339 result = viddec_pm_get_bits(ctxt, &temp, 1); 340 if(result == 1) 341 { 342 md->RANGE_MAPUV_FLAG = ep.RANGE_MAPUV_FLAG = temp; 343 if(ep.RANGE_MAPUV_FLAG) 344 { 345 result = viddec_pm_get_bits(ctxt, &temp, 3); 346 md->RANGE_MAPUV = ep.RANGE_MAPUV = temp; 347 } 348 } 349 } 350 351 // POPULATE WORKLOAD ITEM 352 { 353 viddec_workload_item_t wi; 354 355 wi.vwi_type = VIDDEC_WORKLOAD_GOP_INFO; 356 357 wi.vc1_ep.size = 0; 358 wi.vc1_ep.flags = 0; 359 wi.vc1_ep.pad = 0; 360 361 viddec_fw_vc1_set_ep_size_flag(&wi.vc1_ep, ep.CODED_SIZE_FLAG); 362 viddec_fw_vc1_set_ep_horiz_size(&wi.vc1_ep, ep.ep_size.CODED_WIDTH); 363 viddec_fw_vc1_set_ep_vert_size(&wi.vc1_ep, ep.ep_size.CODED_HEIGHT); 364 365 viddec_fw_vc1_set_ep_broken_link(&wi.vc1_ep, ep.ep_flags.BROKEN_LINK); 366 viddec_fw_vc1_set_ep_closed_entry(&wi.vc1_ep, ep.ep_flags.CLOSED_ENTRY); 367 viddec_fw_vc1_set_ep_panscan_flag(&wi.vc1_ep, ep.ep_flags.PANSCAN_FLAG); 368 viddec_fw_vc1_set_ep_range_mapy_flag(&wi.vc1_ep, ep.RANGE_MAPY_FLAG); 369 viddec_fw_vc1_set_ep_range_mapy(&wi.vc1_ep, ep.RANGE_MAPY); 370 viddec_fw_vc1_set_ep_range_mapuv_flag(&wi.vc1_ep, ep.RANGE_MAPUV_FLAG); 371 viddec_fw_vc1_set_ep_range_mapuv(&wi.vc1_ep, ep.RANGE_MAPUV); 372 373 result = viddec_pm_append_workitem(ctxt, &wi); 374 } 375 376 #ifdef VBP 377 md->BROKEN_LINK = ep.ep_flags.BROKEN_LINK; 378 md->CLOSED_ENTRY = ep.ep_flags.CLOSED_ENTRY; 379 #endif 380 381 DEB("ep: res: %dx%d\n", ep.ep_size.CODED_WIDTH, ep.ep_size.CODED_HEIGHT); 382 DEB("md: after ep: res: %dx%d\n", md->width, md->height); 383 return status; 384 } 385 386 /*------------------------------------------------------------------------------ 387 * Parse picture layer. This function parses the picture layer. 388 *------------------------------------------------------------------------------ 389 */ 390 391 vc1_Status vc1_ParsePictureLayer(void* ctxt, vc1_Info *pInfo) 392 { 393 vc1_Status status = VC1_STATUS_OK; 394 uint32_t temp; 395 int i; 396 397 for(i=0; i<VC1_MAX_BITPLANE_CHUNKS; i++) 398 { 399 pInfo->metadata.bp_raw[i] = true; 400 } 401 402 if (pInfo->metadata.PROFILE == VC1_PROFILE_ADVANCED) 403 { 404 VC1_PEEK_BITS(2, temp); /* fcm */ 405 if( (pInfo->metadata.INTERLACE == 1) && (temp == VC1_FCM_FIELD_INTERLACE)) 406 { 407 status = vc1_ParseFieldHeader_Adv(ctxt, pInfo); 408 } 409 else 410 { 411 status = vc1_ParsePictureHeader_Adv(ctxt, pInfo); 412 } 413 } 414 else 415 { 416 status = vc1_ParsePictureHeader(ctxt, pInfo); 417 } 418 419 return status; 420 } 421 422 /*------------------------------------------------------------------------------ 423 * Parse field picture layer. This function parses the field picture layer. 424 *------------------------------------------------------------------------------ 425 */ 426 427 vc1_Status vc1_ParseFieldLayer(void* ctxt, vc1_Info *pInfo) 428 { 429 vc1_Status status = VC1_STATUS_PARSE_ERROR; 430 vc1_PictureLayerHeader *picLayerHeader = &pInfo->picLayerHeader; 431 432 if (pInfo->metadata.PROFILE == VC1_PROFILE_ADVANCED) { 433 if (picLayerHeader->CurrField == 0) 434 { 435 picLayerHeader->PTYPE = picLayerHeader->PTypeField1; 436 picLayerHeader->BottomField = (uint8_t) (1 - picLayerHeader->TFF); 437 } 438 else 439 { 440 picLayerHeader->BottomField = (uint8_t) (picLayerHeader->TFF); 441 picLayerHeader->PTYPE = picLayerHeader->PTypeField2; 442 } 443 status = vc1_ParsePictureFieldHeader_Adv(ctxt, pInfo); 444 } 445 446 return status; 447 } 448 449 /*------------------------------------------------------------------------------ 450 * Parse slice layer. This function parses the slice layer, which is only 451 * supported by advanced profile. 452 * Table 26 of SMPTE 421M but skipping parsing of macroblock layer. 453 *------------------------------------------------------------------------------ 454 */ 455 456 vc1_Status vc1_ParseSliceLayer(void* ctxt, vc1_Info *pInfo) 457 { 458 uint32_t tempValue; 459 uint32_t SLICE_ADDR; 460 vc1_Status status = VC1_STATUS_OK; 461 462 VC1_GET_BITS9(9, SLICE_ADDR); 463 VC1_GET_BITS9(1, tempValue); /* PIC_HEADER_FLAG. */ 464 if (tempValue == 1) { 465 uint8_t *last_bufptr = pInfo->bufptr; 466 uint32_t last_bitoff = pInfo->bitoff; 467 status = vc1_ParsePictureLayer(ctxt, pInfo); 468 pInfo->picture_info_has_changed = 1; 469 if( status ) { 470 /* FIXME - is this a good way of handling this? Failed, see if it's for fields */ 471 pInfo->bufptr = last_bufptr; 472 pInfo->bitoff = last_bitoff; 473 status = vc1_ParseFieldHeader_Adv(ctxt, pInfo); 474 } 475 } else 476 pInfo->picture_info_has_changed = 0; 477 478 pInfo->picLayerHeader.SLICE_ADDR = SLICE_ADDR; 479 480 return status; 481 } 482 483 /*------------------------------------------------------------------------------ 484 * This function parses the user data information as defined in SMPTE 421M annex F. 485 * It then appends that data to the workload. 486 * Assume the flush byte 0x80 is within the 3 bytes before next start code. 487 * let's put 1 byte per item first 488 *------------------------------------------------------------------------------ 489 */ 490 vc1_Status vc1_ParseAndAppendUserData(void* ctxt, uint32_t sc) 491 { 492 vc1_Status status = VC1_STATUS_OK; 493 uint32_t user_data; 494 viddec_workload_item_t wi; 495 uint32_t ud_id; 496 497 /* find the scope based on start code sc */ 498 switch(sc) { 499 case vc1_SCSequenceUser: 500 wi.vwi_type = VIDDEC_WORKLOAD_SEQ_USER_DATA; 501 break; 502 case vc1_SCEntryPointUser: 503 wi.vwi_type = VIDDEC_WORKLOAD_GOP_USER_DATA; 504 break; 505 case vc1_SCFrameUser: 506 wi.vwi_type = VIDDEC_WORKLOAD_FRM_USER_DATA; 507 break; 508 case vc1_SCFieldUser: 509 wi.vwi_type = VIDDEC_WORKLOAD_FLD_USER_DATA; 510 break; 511 case vc1_SCSliceUser: 512 wi.vwi_type = VIDDEC_WORKLOAD_SLC_USER_DATA; 513 break; 514 default: 515 wi.vwi_type = VIDDEC_WORKLOAD_INVALID; //ERROR - should not happen 516 break; 517 } 518 519 /* get identifier - 4 bytes*/ 520 // Extract this information but discard it for now 521 VC1_GET_BITS(32, ud_id); 522 523 /* Read 1 byte of user data and store it in workitem for the current stream level (SEQ/GOP/PIC). 524 Keep adding data payloads till it reaches size 11. When it is 11, the maximum user data payload size, 525 append the workitem. This loop is repeated till all user data is extracted and appended. */ 526 wi.user_data.size = 0; 527 while(viddec_pm_get_bits(ctxt, &user_data, 8) != -1) 528 { 529 /* Store the valid byte in data payload */ 530 wi.user_data.data_payload[wi.user_data.size] = user_data; 531 wi.user_data.size++; 532 533 /* When size exceeds payload size, append workitem and continue */ 534 if (wi.user_data.size >= 11) 535 { 536 viddec_pm_setup_userdata(&wi); 537 viddec_pm_append_workitem(ctxt, &wi); 538 wi.user_data.size = 0; 539 } 540 if(user_data == 0x80) // flushing byte 541 break; 542 } 543 /* If size is not 0, append remaining user data. */ 544 if (wi.user_data.size > 0) 545 { 546 int i; 547 for(i=wi.user_data.size;i<11;i++) 548 { 549 wi.user_data.data_payload[i] = 0; 550 } 551 viddec_pm_setup_userdata(&wi); 552 viddec_pm_append_workitem(ctxt, &wi); 553 wi.user_data.size = 0; 554 } 555 556 return(status); 557 } // vc1_ParseAndAppendUserData 558