M4VD_EXTERNAL_BitstreamParser.c revision 3b25fdc4a33b53cfcf67315c2d42ad699b8cefe2
1/* 2 * Copyright (C) 2004-2011 NXP Software 3 * Copyright (C) 2011 The Android Open Source Project 4 * 5 * Licensed under the Apache License, Version 2.0 (the "License"); 6 * you may not use this file except in compliance with the License. 7 * You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 18#include "M4OSA_Types.h" 19#include "M4OSA_Debug.h" 20 21#include "M4VD_EXTERNAL_Interface.h" 22#include "M4VD_EXTERNAL_Internal.h" 23#include "M4VD_Tools.h" 24 25/** 26 ************************************************************************ 27 * @file M4VD_EXTERNAL_BitstreamParser.c 28 * @brief 29 * @note This file implements external Bitstream parser 30 ************************************************************************ 31 */ 32 33M4OSA_UInt32 M4VD_EXTERNAL_GetBitsFromMemory(M4VS_Bitstream_ctxt* parsingCtxt, 34 M4OSA_UInt32 nb_bits) 35{ 36 return(M4VD_Tools_GetBitsFromMemory(parsingCtxt,nb_bits)); 37} 38 39M4OSA_ERR M4VD_EXTERNAL_WriteBitsToMemory(M4OSA_UInt32 bitsToWrite, 40 M4OSA_MemAddr32 dest_bits, 41 M4OSA_UInt8 offset, M4OSA_UInt8 nb_bits) 42{ 43 return (M4VD_Tools_WriteBitsToMemory( bitsToWrite,dest_bits, 44 offset, nb_bits)); 45} 46 47M4OSA_ERR M4DECODER_EXTERNAL_ParseVideoDSI(M4OSA_UInt8* pVol, M4OSA_Int32 aVolSize, 48 M4DECODER_MPEG4_DecoderConfigInfo* pDci, 49 M4DECODER_VideoSize* pVideoSize) 50{ 51 M4VS_Bitstream_ctxt parsingCtxt; 52 M4OSA_UInt32 code, j; 53 M4OSA_MemAddr8 start; 54 M4OSA_UInt8 i; 55 M4OSA_UInt32 time_incr_length; 56 M4OSA_UInt8 vol_verid=0, b_hierarchy_type; 57 58 /* Parsing variables */ 59 M4OSA_UInt8 video_object_layer_shape = 0; 60 M4OSA_UInt8 sprite_enable = 0; 61 M4OSA_UInt8 reduced_resolution_vop_enable = 0; 62 M4OSA_UInt8 scalability = 0; 63 M4OSA_UInt8 enhancement_type = 0; 64 M4OSA_UInt8 complexity_estimation_disable = 0; 65 M4OSA_UInt8 interlaced = 0; 66 M4OSA_UInt8 sprite_warping_points = 0; 67 M4OSA_UInt8 sprite_brightness_change = 0; 68 M4OSA_UInt8 quant_precision = 0; 69 70 /* Fill the structure with default parameters */ 71 pVideoSize->m_uiWidth = 0; 72 pVideoSize->m_uiHeight = 0; 73 74 pDci->uiTimeScale = 0; 75 pDci->uiProfile = 0; 76 pDci->uiUseOfResynchMarker = 0; 77 pDci->bDataPartition = M4OSA_FALSE; 78 pDci->bUseOfRVLC = M4OSA_FALSE; 79 80 /* Reset the bitstream context */ 81 parsingCtxt.stream_byte = 0; 82 parsingCtxt.stream_index = 8; 83 parsingCtxt.in = (M4OSA_Int8 *)pVol; 84 85 start = (M4OSA_Int8 *)pVol; 86 87 /* Start parsing */ 88 while (parsingCtxt.in - start < aVolSize) 89 { 90 code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt, 8); 91 if (code == 0) 92 { 93 code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt, 8); 94 if (code == 0) 95 { 96 code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt, 8); 97 if (code == 1) 98 { 99 /* start code found */ 100 code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt, 8); 101 102 /* ----- 0x20..0x2F : video_object_layer_start_code ----- */ 103 104 if ((code > 0x1F) && (code < 0x30)) 105 { 106 code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt, 107 1);/* random accessible vol */ 108 code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt, 109 8);/* video object type indication */ 110 code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt, 111 1);/* is object layer identifier */ 112 if (code == 1) 113 { 114 code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt, 115 4); /* video object layer verid */ 116 vol_verid = (M4OSA_UInt8)code; 117 code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt, 118 3); /* video object layer priority */ 119 } 120 code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt, 121 4);/* aspect ratio */ 122 if (code == 15) 123 code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt, 124 16); /* par_width and par_height (8+8) */ 125 code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt, 126 1);/* vol control parameters */ 127 if (code == 1) 128 { 129 code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt, 130 3);/* chroma format + low delay (3+1) */ 131 code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt, 132 1);/* vbv parameters */ 133 if (code == 1) 134 { 135 code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt, 136 32);/* first and latter half bitrate + 2 marker bits 137 (15 + 1 + 15 + 1) */ 138 code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt, 139 31);/* first and latter half vbv buffer size + first 140 half vbv occupancy + marker bits (15+1+3+11+1)*/ 141 code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt, 142 16);/* first half vbv occupancy + marker bits (15+1)*/ 143 } 144 } 145 code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt, 146 2); /* video object layer shape */ 147 /* Need to save it for vop parsing */ 148 video_object_layer_shape = (M4OSA_UInt8)code; 149 150 if (code != 0) return 0; /* only rectangular case supported */ 151 152 code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt, 153 1); /* Marker bit */ 154 code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt, 155 16); /* VOP time increment resolution */ 156 pDci->uiTimeScale = code; 157 158 /* Computes time increment length */ 159 j = code - 1; 160 for (i = 0; (i < 32) && (j != 0); j >>=1) 161 { 162 i++; 163 } 164 time_incr_length = (i == 0) ? 1 : i; 165 166 code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt, 167 1);/* Marker bit */ 168 code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt, 169 1);/* Fixed VOP rate */ 170 if (code == 1) 171 { 172 code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt, 173 time_incr_length);/* Fixed VOP time increment */ 174 } 175 176 if(video_object_layer_shape != 1) /* 1 = Binary */ 177 { 178 if(video_object_layer_shape == 0) /* 0 = rectangular */ 179 { 180 code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt, 181 1);/* Marker bit */ 182 code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt, 183 13);/* Width */ 184 pVideoSize->m_uiWidth = code; 185 code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt, 186 1);/* Marker bit */ 187 code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt, 188 13);/* Height */ 189 pVideoSize->m_uiHeight = code; 190 code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt, 191 1);/* Marker bit */ 192 } 193 } 194 195 code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt, 196 1);/* interlaced */ 197 interlaced = (M4OSA_UInt8)code; 198 code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt, 199 1);/* OBMC disable */ 200 201 if(vol_verid == 1) 202 { 203 code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt, 204 1);/* sprite enable */ 205 sprite_enable = (M4OSA_UInt8)code; 206 } 207 else 208 { 209 code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt, 210 2);/* sprite enable */ 211 sprite_enable = (M4OSA_UInt8)code; 212 } 213 if ((sprite_enable == 1) || (sprite_enable == 2)) 214 /* Sprite static = 1 and Sprite GMC = 2 */ 215 { 216 if (sprite_enable != 2) 217 { 218 219 code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt, 220 13);/* sprite width */ 221 code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt, 222 1);/* Marker bit */ 223 code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt, 224 13);/* sprite height */ 225 code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt, 226 1);/* Marker bit */ 227 code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt, 228 13);/* sprite l coordinate */ 229 code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt, 230 1);/* Marker bit */ 231 code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt, 232 13);/* sprite top coordinate */ 233 code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt, 234 1);/* Marker bit */ 235 } 236 237 code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt, 238 6);/* sprite warping points */ 239 sprite_warping_points = (M4OSA_UInt8)code; 240 code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt, 241 2);/* sprite warping accuracy */ 242 code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt, 243 1);/* sprite brightness change */ 244 sprite_brightness_change = (M4OSA_UInt8)code; 245 if (sprite_enable != 2) 246 { 247 code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt, 248 1);/* low latency sprite enable */ 249 } 250 } 251 if ((vol_verid != 1) && (video_object_layer_shape != 0)) 252 { 253 code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt, 254 1);/* sadct disable */ 255 } 256 257 code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt, 1); /* not 8 bits */ 258 if (code) 259 { 260 code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt, 261 4);/* quant precision */ 262 quant_precision = (M4OSA_UInt8)code; 263 code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt, 264 4);/* bits per pixel */ 265 } 266 267 /* greyscale not supported */ 268 if(video_object_layer_shape == 3) 269 { 270 code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt, 271 3); /* nogray quant update + composition method + 272 linear composition */ 273 } 274 275 code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt, 276 1);/* quant type */ 277 if (code) 278 { 279 code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt, 280 1);/* load intra quant mat */ 281 if (code) 282 { 283 code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt, 8);/* */ 284 i = 1; 285 while (i < 64) 286 { 287 code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt, 8); 288 if (code == 0) 289 break; 290 i++; 291 } 292 } 293 294 code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt, 295 1);/* load non intra quant mat */ 296 if (code) 297 { 298 code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt, 8);/* */ 299 i = 1; 300 while (i < 64) 301 { 302 code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt, 8); 303 if (code == 0) 304 break; 305 i++; 306 } 307 } 308 } 309 310 if (vol_verid != 1) 311 { 312 code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt, 313 1);/* quarter sample */ 314 } 315 316 code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt, 317 1);/* complexity estimation disable */ 318 complexity_estimation_disable = (M4OSA_UInt8)code; 319 if (!code) 320 { 321 //return M4ERR_NOT_IMPLEMENTED; 322 } 323 324 code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt, 325 1);/* resync marker disable */ 326 pDci->uiUseOfResynchMarker = (code) ? 0 : 1; 327 328 code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt, 329 1);/* data partitionned */ 330 pDci->bDataPartition = (code) ? M4OSA_TRUE : M4OSA_FALSE; 331 if (code) 332 { 333 /* reversible VLC */ 334 code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt, 1); 335 pDci->bUseOfRVLC = (code) ? M4OSA_TRUE : M4OSA_FALSE; 336 } 337 338 if (vol_verid != 1) 339 { 340 code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt, 1);/* newpred */ 341 if (code) 342 { 343 //return M4ERR_PARAMETER; 344 } 345 /* reduced resolution vop enable */ 346 code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt, 1); 347 reduced_resolution_vop_enable = (M4OSA_UInt8)code; 348 } 349 350 code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt, 1);/* scalability */ 351 scalability = (M4OSA_UInt8)code; 352 if (code) 353 { 354 /* hierarchy type */ 355 code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt, 1); 356 b_hierarchy_type = (M4OSA_UInt8)code; 357 /* ref layer id */ 358 code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt, 4); 359 /* ref sampling direct */ 360 code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt, 1); 361 /* hor sampling factor N */ 362 code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt, 5); 363 /* hor sampling factor M */ 364 code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt, 5); 365 /* vert sampling factor N */ 366 code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt, 5); 367 /* vert sampling factor M */ 368 code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt, 5); 369 /* enhancement type */ 370 code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt, 1); 371 enhancement_type = (M4OSA_UInt8)code; 372 if ((!b_hierarchy_type) && (video_object_layer_shape == 1)) 373 { 374 /* use ref shape */ 375 code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt, 1); 376 /* use ref texture */ 377 code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt, 1); 378 /* shape hor sampling factor N */ 379 code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt, 5); 380 /* shape hor sampling factor M */ 381 code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt, 5); 382 /* shape vert sampling factor N */ 383 code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt, 5); 384 /* shape vert sampling factor M */ 385 code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt, 5); 386 } 387 } 388 break; 389 } 390 391 /* ----- 0xB0 : visual_object_sequence_start_code ----- */ 392 393 else if(code == 0xB0) 394 { 395 /* profile_and_level_indication */ 396 code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt, 8); 397 pDci->uiProfile = (M4OSA_UInt8)code; 398 } 399 400 /* ----- 0xB5 : visual_object_start_code ----- */ 401 402 else if(code == 0xB5) 403 { 404 /* is object layer identifier */ 405 code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt, 1); 406 if (code == 1) 407 { 408 /* visual object verid */ 409 code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt, 4); 410 vol_verid = (M4OSA_UInt8)code; 411 /* visual object layer priority */ 412 code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt, 3); 413 } 414 else 415 { 416 /* Realign on byte */ 417 code = M4VD_EXTERNAL_GetBitsFromMemory(&parsingCtxt, 7); 418 vol_verid = 1; 419 } 420 } 421 422 /* ----- end ----- */ 423 } 424 else 425 { 426 if ((code >> 2) == 0x20) 427 { 428 /* H263 ...-> wrong*/ 429 break; 430 } 431 } 432 } 433 } 434 } 435 436 return M4NO_ERROR; 437} 438 439M4OSA_ERR M4DECODER_EXTERNAL_ParseAVCDSI(M4OSA_UInt8* pDSI, M4OSA_Int32 DSISize, 440 M4DECODER_AVCProfileLevel *profile) 441{ 442 M4OSA_ERR err = M4NO_ERROR; 443 M4OSA_Bool NALSPS_and_Profile0Found = M4OSA_FALSE; 444 M4OSA_UInt16 index = 28; /* the 29th byte is SPS start */ 445 M4OSA_Bool constraintSet3; 446 447 if (DSISize <= index) { 448 M4OSA_TRACE1_0("M4DECODER_EXTERNAL_ParseAVCDSI: DSI is invalid"); 449 *profile = M4DECODER_AVC_kProfile_and_Level_Out_Of_Range; 450 return M4ERR_PARAMETER; 451 } 452 453 /* check for baseline profile */ 454 if(((pDSI[index] & 0x1f) == 0x07) && (pDSI[index+1] == 0x42)) 455 { 456 NALSPS_and_Profile0Found = M4OSA_TRUE; 457 } 458 459 if(M4OSA_FALSE == NALSPS_and_Profile0Found) 460 { 461 M4OSA_TRACE1_1("M4DECODER_EXTERNAL_ParseAVCDSI: index bad = %d", index); 462 *profile = M4DECODER_AVC_kProfile_and_Level_Out_Of_Range; 463 } 464 else 465 { 466 M4OSA_TRACE1_1("M4DECODER_EXTERNAL_ParseAVCDSI: index = %d", index); 467 constraintSet3 = (pDSI[index+2] & 0x10); 468 M4OSA_TRACE1_1("M4DECODER_EXTERNAL_ParseAVCDSI: level = %d", pDSI[index+3]); 469 switch(pDSI[index+3]) 470 { 471 case 10: 472 *profile = M4DECODER_AVC_kProfile_0_Level_1; 473 break; 474 case 11: 475 if(constraintSet3) 476 *profile = M4DECODER_AVC_kProfile_0_Level_1b; 477 else 478 *profile = M4DECODER_AVC_kProfile_0_Level_1_1; 479 break; 480 case 12: 481 *profile = M4DECODER_AVC_kProfile_0_Level_1_2; 482 break; 483 case 13: 484 *profile = M4DECODER_AVC_kProfile_0_Level_1_3; 485 break; 486 case 20: 487 *profile = M4DECODER_AVC_kProfile_0_Level_2; 488 break; 489 case 21: 490 *profile = M4DECODER_AVC_kProfile_0_Level_2_1; 491 break; 492 case 22: 493 *profile = M4DECODER_AVC_kProfile_0_Level_2_2; 494 break; 495 case 30: 496 *profile = M4DECODER_AVC_kProfile_0_Level_3; 497 break; 498 case 31: 499 *profile = M4DECODER_AVC_kProfile_0_Level_3_1; 500 break; 501 case 32: 502 *profile = M4DECODER_AVC_kProfile_0_Level_3_2; 503 break; 504 case 40: 505 *profile = M4DECODER_AVC_kProfile_0_Level_4; 506 break; 507 case 41: 508 *profile = M4DECODER_AVC_kProfile_0_Level_4_1; 509 break; 510 case 42: 511 *profile = M4DECODER_AVC_kProfile_0_Level_4_2; 512 break; 513 case 50: 514 *profile = M4DECODER_AVC_kProfile_0_Level_5; 515 break; 516 case 51: 517 *profile = M4DECODER_AVC_kProfile_0_Level_5_1; 518 break; 519 default: 520 *profile = M4DECODER_AVC_kProfile_and_Level_Out_Of_Range; 521 } 522 } 523 return err; 524} 525 526