| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "content/common/gpu/media/h264_parser.h" | |
| 6 | |
| 7 #include "base/logging.h" | 5 #include "base/logging.h" |
| 8 #include "base/memory/scoped_ptr.h" | 6 #include "base/memory/scoped_ptr.h" |
| 9 #include "base/stl_util.h" | 7 #include "base/stl_util.h" |
| 10 | 8 |
| 11 namespace content { | 9 #include "media/filters/h264_parser.h" |
| 10 |
| 11 namespace media { |
| 12 | 12 |
| 13 bool H264SliceHeader::IsPSlice() const { | 13 bool H264SliceHeader::IsPSlice() const { |
| 14 return (slice_type % 5 == kPSlice); | 14 return (slice_type % 5 == kPSlice); |
| 15 } | 15 } |
| 16 | 16 |
| 17 bool H264SliceHeader::IsBSlice() const { | 17 bool H264SliceHeader::IsBSlice() const { |
| 18 return (slice_type % 5 == kBSlice); | 18 return (slice_type % 5 == kBSlice); |
| 19 } | 19 } |
| 20 | 20 |
| 21 bool H264SliceHeader::IsISlice() const { | 21 bool H264SliceHeader::IsISlice() const { |
| (...skipping 21 matching lines...) Expand all Loading... |
| 43 } | 43 } |
| 44 | 44 |
| 45 H264SliceHeader::H264SliceHeader() { | 45 H264SliceHeader::H264SliceHeader() { |
| 46 memset(this, 0, sizeof(*this)); | 46 memset(this, 0, sizeof(*this)); |
| 47 } | 47 } |
| 48 | 48 |
| 49 H264SEIMessage::H264SEIMessage() { | 49 H264SEIMessage::H264SEIMessage() { |
| 50 memset(this, 0, sizeof(*this)); | 50 memset(this, 0, sizeof(*this)); |
| 51 } | 51 } |
| 52 | 52 |
| 53 #define READ_BITS_OR_RETURN(num_bits, out) \ | 53 #define READ_BITS_OR_RETURN(num_bits, out) \ |
| 54 do { \ | 54 do { \ |
| 55 int _out; \ | 55 int _out; \ |
| 56 if (!br_.ReadBits(num_bits, &_out)) { \ | 56 if (!br_.ReadBits(num_bits, &_out)) { \ |
| 57 DVLOG(1) << "Error in stream: unexpected EOS while trying to read " #out; \ | 57 DVLOG(1) \ |
| 58 return kInvalidStream; \ | 58 << "Error in stream: unexpected EOS while trying to read " #out; \ |
| 59 } \ | 59 return kInvalidStream; \ |
| 60 *out = _out; \ | 60 } \ |
| 61 } while (0) | 61 *out = _out; \ |
| 62 } while (0) |
| 62 | 63 |
| 63 #define READ_BOOL_OR_RETURN(out) \ | 64 #define READ_BOOL_OR_RETURN(out) \ |
| 64 do { \ | 65 do { \ |
| 65 int _out; \ | 66 int _out; \ |
| 66 if (!br_.ReadBits(1, &_out)) { \ | 67 if (!br_.ReadBits(1, &_out)) { \ |
| 67 DVLOG(1) << "Error in stream: unexpected EOS while trying to read " #out; \ | 68 DVLOG(1) \ |
| 68 return kInvalidStream; \ | 69 << "Error in stream: unexpected EOS while trying to read " #out; \ |
| 69 } \ | 70 return kInvalidStream; \ |
| 70 *out = _out != 0; \ | 71 } \ |
| 71 } while (0) | 72 *out = _out != 0; \ |
| 73 } while (0) |
| 72 | 74 |
| 73 #define READ_UE_OR_RETURN(out) \ | 75 #define READ_UE_OR_RETURN(out) \ |
| 74 do { \ | 76 do { \ |
| 75 if (ReadUE(out) != kOk) { \ | 77 if (ReadUE(out) != kOk) { \ |
| 76 DVLOG(1) << "Error in stream: invalid value while trying to read " #out; \ | 78 DVLOG(1) << "Error in stream: invalid value while trying to read " #out; \ |
| 77 return kInvalidStream; \ | 79 return kInvalidStream; \ |
| 78 } \ | 80 } \ |
| 79 } while (0) | 81 } while (0) |
| 80 | 82 |
| 81 #define READ_SE_OR_RETURN(out) \ | 83 #define READ_SE_OR_RETURN(out) \ |
| 82 do { \ | 84 do { \ |
| 83 if (ReadSE(out) != kOk) { \ | 85 if (ReadSE(out) != kOk) { \ |
| 84 DVLOG(1) << "Error in stream: invalid value while trying to read " #out; \ | 86 DVLOG(1) << "Error in stream: invalid value while trying to read " #out; \ |
| 85 return kInvalidStream; \ | 87 return kInvalidStream; \ |
| 86 } \ | 88 } \ |
| 87 } while (0) | 89 } while (0) |
| 88 | 90 |
| 89 #define IN_RANGE_OR_RETURN(val, min, max) \ | 91 #define IN_RANGE_OR_RETURN(val, min, max) \ |
| 90 do { \ | 92 do { \ |
| 91 if ((val) < (min) || (val) > (max)) { \ | 93 if ((val) < (min) || (val) > (max)) { \ |
| 92 DVLOG(1) << "Error in stream: invalid value, expected " #val " to be" \ | 94 DVLOG(1) << "Error in stream: invalid value, expected " #val " to be" \ |
| 93 << " in range [" << (min) << ":" << (max) << "]" \ | 95 << " in range [" << (min) << ":" << (max) << "]" \ |
| 94 << " found " << (val) << " instead"; \ | 96 << " found " << (val) << " instead"; \ |
| 95 return kInvalidStream; \ | 97 return kInvalidStream; \ |
| 96 } \ | 98 } \ |
| 97 } while (0) | 99 } while (0) |
| 98 | 100 |
| 99 #define TRUE_OR_RETURN(a) \ | 101 #define TRUE_OR_RETURN(a) \ |
| 100 do { \ | 102 do { \ |
| 101 if (!(a)) { \ | 103 if (!(a)) { \ |
| 102 DVLOG(1) << "Error in stream: invalid value, expected " << #a; \ | 104 DVLOG(1) << "Error in stream: invalid value, expected " << #a; \ |
| 103 return kInvalidStream; \ | 105 return kInvalidStream; \ |
| 104 } \ | 106 } \ |
| 105 } while (0) | 107 } while (0) |
| 106 | 108 |
| 107 H264Parser::H264Parser() { | 109 H264Parser::H264Parser() { |
| 108 Reset(); | 110 Reset(); |
| 109 } | 111 } |
| 110 | 112 |
| 111 H264Parser::~H264Parser() { | 113 H264Parser::~H264Parser() { |
| 112 STLDeleteValues(&active_SPSes_); | 114 STLDeleteValues(&active_SPSes_); |
| 113 STLDeleteValues(&active_PPSes_); | 115 STLDeleteValues(&active_PPSes_); |
| 114 } | 116 } |
| 115 | 117 |
| (...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 241 return res; | 243 return res; |
| 242 | 244 |
| 243 if (ue % 2 == 0) | 245 if (ue % 2 == 0) |
| 244 *val = -(ue / 2); | 246 *val = -(ue / 2); |
| 245 else | 247 else |
| 246 *val = ue / 2 + 1; | 248 *val = ue / 2 + 1; |
| 247 | 249 |
| 248 return kOk; | 250 return kOk; |
| 249 } | 251 } |
| 250 | 252 |
| 251 H264Parser::Result H264Parser::AdvanceToNextNALU(H264NALU *nalu) { | 253 H264Parser::Result H264Parser::AdvanceToNextNALU(H264NALU* nalu) { |
| 252 int data; | 254 int data; |
| 253 off_t off_to_nalu_start; | 255 off_t off_to_nalu_start; |
| 254 | 256 |
| 255 if (!LocateNALU(stream_, bytes_left_, &off_to_nalu_start, &nalu->size)) { | 257 if (!LocateNALU(stream_, bytes_left_, &off_to_nalu_start, &nalu->size)) { |
| 256 DVLOG(4) << "Could not find next NALU, bytes left in stream: " | 258 DVLOG(4) << "Could not find next NALU, bytes left in stream: " |
| 257 << bytes_left_; | 259 << bytes_left_; |
| 258 return kEOStream; | 260 return kEOStream; |
| 259 } | 261 } |
| 260 | 262 |
| 261 nalu->data = stream_ + off_to_nalu_start; | 263 nalu->data = stream_ + off_to_nalu_start; |
| (...skipping 22 matching lines...) Expand all Loading... |
| 284 DVLOG(4) << "NALU type: " << static_cast<int>(nalu->nal_unit_type) | 286 DVLOG(4) << "NALU type: " << static_cast<int>(nalu->nal_unit_type) |
| 285 << " at: " << reinterpret_cast<const void*>(nalu->data) | 287 << " at: " << reinterpret_cast<const void*>(nalu->data) |
| 286 << " size: " << nalu->size | 288 << " size: " << nalu->size |
| 287 << " ref: " << static_cast<int>(nalu->nal_ref_idc); | 289 << " ref: " << static_cast<int>(nalu->nal_ref_idc); |
| 288 | 290 |
| 289 return kOk; | 291 return kOk; |
| 290 } | 292 } |
| 291 | 293 |
| 292 // Default scaling lists (per spec). | 294 // Default scaling lists (per spec). |
| 293 static const int kDefault4x4Intra[kH264ScalingList4x4Length] = { | 295 static const int kDefault4x4Intra[kH264ScalingList4x4Length] = { |
| 294 6, 13, 13, 20, 20, 20, 28, 28, 28, 28, 32, 32, 32, 37, 37, 42, }; | 296 6, 13, 13, 20, 20, 20, 28, 28, 28, 28, 32, 32, 32, 37, 37, 42, }; |
| 295 | 297 |
| 296 static const int kDefault4x4Inter[kH264ScalingList4x4Length] = { | 298 static const int kDefault4x4Inter[kH264ScalingList4x4Length] = { |
| 297 10, 14, 14, 20, 20, 20, 24, 24, 24, 24, 27, 27, 27, 30, 30, 34, }; | 299 10, 14, 14, 20, 20, 20, 24, 24, 24, 24, 27, 27, 27, 30, 30, 34, }; |
| 298 | 300 |
| 299 static const int kDefault8x8Intra[kH264ScalingList8x8Length] = { | 301 static const int kDefault8x8Intra[kH264ScalingList8x8Length] = { |
| 300 6, 10, 10, 13, 11, 13, 16, 16, 16, 16, 18, 18, 18, 18, 18, 23, | 302 6, 10, 10, 13, 11, 13, 16, 16, 16, 16, 18, 18, 18, 18, 18, 23, |
| 301 23, 23, 23, 23, 23, 25, 25, 25, 25, 25, 25, 25, 27, 27, 27, 27, | 303 23, 23, 23, 23, 23, 25, 25, 25, 25, 25, 25, 25, 27, 27, 27, 27, |
| 302 27, 27, 27, 27, 29, 29, 29, 29, 29, 29, 29, 31, 31, 31, 31, 31, | 304 27, 27, 27, 27, 29, 29, 29, 29, 29, 29, 29, 31, 31, 31, 31, 31, |
| 303 31, 33, 33, 33, 33, 33, 36, 36, 36, 36, 38, 38, 38, 40, 40, 42, }; | 305 31, 33, 33, 33, 33, 33, 36, 36, 36, 36, 38, 38, 38, 40, 40, 42, }; |
| 304 | 306 |
| 305 static const int kDefault8x8Inter[kH264ScalingList8x8Length] = { | 307 static const int kDefault8x8Inter[kH264ScalingList8x8Length] = { |
| 306 9, 13, 13, 15, 13, 15, 17, 17, 17, 17, 19, 19, 19, 19, 19, 21, | 308 9, 13, 13, 15, 13, 15, 17, 17, 17, 17, 19, 19, 19, 19, 19, 21, |
| 307 21, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22, 22, 24, 24, 24, 24, | 309 21, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22, 22, 24, 24, 24, 24, |
| 308 24, 24, 24, 24, 25, 25, 25, 25, 25, 25, 25, 27, 27, 27, 27, 27, | 310 24, 24, 24, 24, 25, 25, 25, 25, 25, 25, 25, 27, 27, 27, 27, 27, |
| 309 27, 28, 28, 28, 28, 28, 30, 30, 30, 30, 32, 32, 32, 33, 33, 35, }; | 311 27, 28, 28, 28, 28, 28, 30, 30, 30, 30, 32, 32, 32, 33, 33, 35, }; |
| 310 | 312 |
| 311 static inline void DefaultScalingList4x4( | 313 static inline void DefaultScalingList4x4( |
| 312 int i, | 314 int i, |
| 313 int scaling_list4x4[][kH264ScalingList4x4Length]) { | 315 int scaling_list4x4[][kH264ScalingList4x4Length]) { |
| 314 DCHECK_LT(i, 6); | 316 DCHECK_LT(i, 6); |
| 315 | 317 |
| 316 if (i < 3) | 318 if (i < 3) |
| 317 memcpy(scaling_list4x4[i], kDefault4x4Intra, sizeof(kDefault4x4Intra)); | 319 memcpy(scaling_list4x4[i], kDefault4x4Intra, sizeof(kDefault4x4Intra)); |
| 318 else if (i < 6) | 320 else if (i < 6) |
| 319 memcpy(scaling_list4x4[i], kDefault4x4Inter, sizeof(kDefault4x4Inter)); | 321 memcpy(scaling_list4x4[i], kDefault4x4Inter, sizeof(kDefault4x4Inter)); |
| 320 } | 322 } |
| 321 | 323 |
| 322 static inline void DefaultScalingList8x8( | 324 static inline void DefaultScalingList8x8( |
| 323 int i, | 325 int i, |
| 324 int scaling_list8x8[][kH264ScalingList8x8Length]) { | 326 int scaling_list8x8[][kH264ScalingList8x8Length]) { |
| 325 DCHECK_LT(i, 6); | 327 DCHECK_LT(i, 6); |
| 326 | 328 |
| 327 if (i % 2 == 0) | 329 if (i % 2 == 0) |
| 328 memcpy(scaling_list8x8[i], kDefault8x8Intra, sizeof(kDefault8x8Intra)); | 330 memcpy(scaling_list8x8[i], kDefault8x8Intra, sizeof(kDefault8x8Intra)); |
| 329 else | 331 else |
| 330 memcpy(scaling_list8x8[i], kDefault8x8Inter, sizeof(kDefault8x8Inter)); | 332 memcpy(scaling_list8x8[i], kDefault8x8Inter, sizeof(kDefault8x8Inter)); |
| 331 } | 333 } |
| 332 | 334 |
| 333 static void FallbackScalingList4x4( | 335 static void FallbackScalingList4x4( |
| 334 int i, | 336 int i, |
| 335 const int default_scaling_list_intra[], | 337 const int default_scaling_list_intra[], |
| 336 const int default_scaling_list_inter[], | 338 const int default_scaling_list_inter[], |
| 337 int scaling_list4x4[][kH264ScalingList4x4Length]) { | 339 int scaling_list4x4[][kH264ScalingList4x4Length]) { |
| 338 static const int kScalingList4x4ByteSize = sizeof(scaling_list4x4[0][0]) * | 340 static const int kScalingList4x4ByteSize = |
| 339 kH264ScalingList4x4Length; | 341 sizeof(scaling_list4x4[0][0]) * kH264ScalingList4x4Length; |
| 340 | 342 |
| 341 switch (i) { | 343 switch (i) { |
| 342 case 0: | 344 case 0: |
| 343 memcpy(scaling_list4x4[i], default_scaling_list_intra, | 345 memcpy(scaling_list4x4[i], default_scaling_list_intra, |
| 344 kScalingList4x4ByteSize); | 346 kScalingList4x4ByteSize); |
| 345 break; | 347 break; |
| 346 | 348 |
| 347 case 1: | 349 case 1: |
| 348 memcpy(scaling_list4x4[i], scaling_list4x4[0], | 350 memcpy(scaling_list4x4[i], scaling_list4x4[0], kScalingList4x4ByteSize); |
| 349 kScalingList4x4ByteSize); | |
| 350 break; | 351 break; |
| 351 | 352 |
| 352 case 2: | 353 case 2: |
| 353 memcpy(scaling_list4x4[i], scaling_list4x4[1], | 354 memcpy(scaling_list4x4[i], scaling_list4x4[1], kScalingList4x4ByteSize); |
| 354 kScalingList4x4ByteSize); | |
| 355 break; | 355 break; |
| 356 | 356 |
| 357 case 3: | 357 case 3: |
| 358 memcpy(scaling_list4x4[i], default_scaling_list_inter, | 358 memcpy(scaling_list4x4[i], default_scaling_list_inter, |
| 359 kScalingList4x4ByteSize); | 359 kScalingList4x4ByteSize); |
| 360 break; | 360 break; |
| 361 | 361 |
| 362 case 4: | 362 case 4: |
| 363 memcpy(scaling_list4x4[i], scaling_list4x4[3], | 363 memcpy(scaling_list4x4[i], scaling_list4x4[3], kScalingList4x4ByteSize); |
| 364 kScalingList4x4ByteSize); | |
| 365 break; | 364 break; |
| 366 | 365 |
| 367 case 5: | 366 case 5: |
| 368 memcpy(scaling_list4x4[i], scaling_list4x4[4], | 367 memcpy(scaling_list4x4[i], scaling_list4x4[4], kScalingList4x4ByteSize); |
| 369 kScalingList4x4ByteSize); | |
| 370 break; | 368 break; |
| 371 | 369 |
| 372 default: | 370 default: |
| 373 NOTREACHED(); | 371 NOTREACHED(); |
| 374 break; | 372 break; |
| 375 } | 373 } |
| 376 } | 374 } |
| 377 | 375 |
| 378 static void FallbackScalingList8x8( | 376 static void FallbackScalingList8x8( |
| 379 int i, | 377 int i, |
| 380 const int default_scaling_list_intra[], | 378 const int default_scaling_list_intra[], |
| 381 const int default_scaling_list_inter[], | 379 const int default_scaling_list_inter[], |
| 382 int scaling_list8x8[][kH264ScalingList8x8Length]) { | 380 int scaling_list8x8[][kH264ScalingList8x8Length]) { |
| 383 static const int kScalingList8x8ByteSize = sizeof(scaling_list8x8[0][0]) * | 381 static const int kScalingList8x8ByteSize = |
| 384 kH264ScalingList8x8Length; | 382 sizeof(scaling_list8x8[0][0]) * kH264ScalingList8x8Length; |
| 385 | 383 |
| 386 switch (i) { | 384 switch (i) { |
| 387 case 0: | 385 case 0: |
| 388 memcpy(scaling_list8x8[i], default_scaling_list_intra, | 386 memcpy(scaling_list8x8[i], default_scaling_list_intra, |
| 389 kScalingList8x8ByteSize); | 387 kScalingList8x8ByteSize); |
| 390 break; | 388 break; |
| 391 | 389 |
| 392 case 1: | 390 case 1: |
| 393 memcpy(scaling_list8x8[i], default_scaling_list_inter, | 391 memcpy(scaling_list8x8[i], default_scaling_list_inter, |
| 394 kScalingList8x8ByteSize); | 392 kScalingList8x8ByteSize); |
| 395 break; | 393 break; |
| 396 | 394 |
| 397 case 2: | 395 case 2: |
| 398 memcpy(scaling_list8x8[i], scaling_list8x8[0], | 396 memcpy(scaling_list8x8[i], scaling_list8x8[0], kScalingList8x8ByteSize); |
| 399 kScalingList8x8ByteSize); | |
| 400 break; | 397 break; |
| 401 | 398 |
| 402 case 3: | 399 case 3: |
| 403 memcpy(scaling_list8x8[i], scaling_list8x8[1], | 400 memcpy(scaling_list8x8[i], scaling_list8x8[1], kScalingList8x8ByteSize); |
| 404 kScalingList8x8ByteSize); | |
| 405 break; | 401 break; |
| 406 | 402 |
| 407 case 4: | 403 case 4: |
| 408 memcpy(scaling_list8x8[i], scaling_list8x8[2], | 404 memcpy(scaling_list8x8[i], scaling_list8x8[2], kScalingList8x8ByteSize); |
| 409 kScalingList8x8ByteSize); | |
| 410 break; | 405 break; |
| 411 | 406 |
| 412 case 5: | 407 case 5: |
| 413 memcpy(scaling_list8x8[i], scaling_list8x8[3], | 408 memcpy(scaling_list8x8[i], scaling_list8x8[3], kScalingList8x8ByteSize); |
| 414 kScalingList8x8ByteSize); | |
| 415 break; | 409 break; |
| 416 | 410 |
| 417 default: | 411 default: |
| 418 NOTREACHED(); | 412 NOTREACHED(); |
| 419 break; | 413 break; |
| 420 } | 414 } |
| 421 } | 415 } |
| 422 | 416 |
| 423 H264Parser::Result H264Parser::ParseScalingList(int size, | 417 H264Parser::Result H264Parser::ParseScalingList(int size, |
| 424 int* scaling_list, | 418 int* scaling_list, |
| (...skipping 29 matching lines...) Expand all Loading... |
| 454 bool seq_scaling_list_present_flag; | 448 bool seq_scaling_list_present_flag; |
| 455 bool use_default; | 449 bool use_default; |
| 456 Result res; | 450 Result res; |
| 457 | 451 |
| 458 // Parse scaling_list4x4. | 452 // Parse scaling_list4x4. |
| 459 for (int i = 0; i < 6; ++i) { | 453 for (int i = 0; i < 6; ++i) { |
| 460 READ_BOOL_OR_RETURN(&seq_scaling_list_present_flag); | 454 READ_BOOL_OR_RETURN(&seq_scaling_list_present_flag); |
| 461 | 455 |
| 462 if (seq_scaling_list_present_flag) { | 456 if (seq_scaling_list_present_flag) { |
| 463 res = ParseScalingList(arraysize(sps->scaling_list4x4[i]), | 457 res = ParseScalingList(arraysize(sps->scaling_list4x4[i]), |
| 464 sps->scaling_list4x4[i], &use_default); | 458 sps->scaling_list4x4[i], |
| 459 &use_default); |
| 465 if (res != kOk) | 460 if (res != kOk) |
| 466 return res; | 461 return res; |
| 467 | 462 |
| 468 if (use_default) | 463 if (use_default) |
| 469 DefaultScalingList4x4(i, sps->scaling_list4x4); | 464 DefaultScalingList4x4(i, sps->scaling_list4x4); |
| 470 | 465 |
| 471 } else { | 466 } else { |
| 472 FallbackScalingList4x4(i, kDefault4x4Intra, kDefault4x4Inter, | 467 FallbackScalingList4x4( |
| 473 sps->scaling_list4x4); | 468 i, kDefault4x4Intra, kDefault4x4Inter, sps->scaling_list4x4); |
| 474 } | 469 } |
| 475 } | 470 } |
| 476 | 471 |
| 477 // Parse scaling_list8x8. | 472 // Parse scaling_list8x8. |
| 478 for (int i = 0; i < ((sps->chroma_format_idc != 3) ? 2 : 6); ++i) { | 473 for (int i = 0; i < ((sps->chroma_format_idc != 3) ? 2 : 6); ++i) { |
| 479 READ_BOOL_OR_RETURN(&seq_scaling_list_present_flag); | 474 READ_BOOL_OR_RETURN(&seq_scaling_list_present_flag); |
| 480 | 475 |
| 481 if (seq_scaling_list_present_flag) { | 476 if (seq_scaling_list_present_flag) { |
| 482 res = ParseScalingList(arraysize(sps->scaling_list8x8[i]), | 477 res = ParseScalingList(arraysize(sps->scaling_list8x8[i]), |
| 483 sps->scaling_list8x8[i], &use_default); | 478 sps->scaling_list8x8[i], |
| 479 &use_default); |
| 484 if (res != kOk) | 480 if (res != kOk) |
| 485 return res; | 481 return res; |
| 486 | 482 |
| 487 if (use_default) | 483 if (use_default) |
| 488 DefaultScalingList8x8(i, sps->scaling_list8x8); | 484 DefaultScalingList8x8(i, sps->scaling_list8x8); |
| 489 | 485 |
| 490 } else { | 486 } else { |
| 491 FallbackScalingList8x8(i, kDefault8x8Intra, kDefault8x8Inter, | 487 FallbackScalingList8x8( |
| 492 sps->scaling_list8x8); | 488 i, kDefault8x8Intra, kDefault8x8Inter, sps->scaling_list8x8); |
| 493 } | 489 } |
| 494 } | 490 } |
| 495 | 491 |
| 496 return kOk; | 492 return kOk; |
| 497 } | 493 } |
| 498 | 494 |
| 499 H264Parser::Result H264Parser::ParsePPSScalingLists(const H264SPS& sps, | 495 H264Parser::Result H264Parser::ParsePPSScalingLists(const H264SPS& sps, |
| 500 H264PPS* pps) { | 496 H264PPS* pps) { |
| 501 // See 7.4.2.2. | 497 // See 7.4.2.2. |
| 502 bool pic_scaling_list_present_flag; | 498 bool pic_scaling_list_present_flag; |
| 503 bool use_default; | 499 bool use_default; |
| 504 Result res; | 500 Result res; |
| 505 | 501 |
| 506 for (int i = 0; i < 6; ++i) { | 502 for (int i = 0; i < 6; ++i) { |
| 507 READ_BOOL_OR_RETURN(&pic_scaling_list_present_flag); | 503 READ_BOOL_OR_RETURN(&pic_scaling_list_present_flag); |
| 508 | 504 |
| 509 if (pic_scaling_list_present_flag) { | 505 if (pic_scaling_list_present_flag) { |
| 510 res = ParseScalingList(arraysize(pps->scaling_list4x4[i]), | 506 res = ParseScalingList(arraysize(pps->scaling_list4x4[i]), |
| 511 pps->scaling_list4x4[i], &use_default); | 507 pps->scaling_list4x4[i], |
| 508 &use_default); |
| 512 if (res != kOk) | 509 if (res != kOk) |
| 513 return res; | 510 return res; |
| 514 | 511 |
| 515 if (use_default) | 512 if (use_default) |
| 516 DefaultScalingList4x4(i, pps->scaling_list4x4); | 513 DefaultScalingList4x4(i, pps->scaling_list4x4); |
| 517 | 514 |
| 518 } else { | 515 } else { |
| 519 if (sps.seq_scaling_matrix_present_flag) { | 516 if (sps.seq_scaling_matrix_present_flag) { |
| 520 // Table 7-2 fallback rule A in spec. | 517 // Table 7-2 fallback rule A in spec. |
| 521 FallbackScalingList4x4(i, kDefault4x4Intra, kDefault4x4Inter, | 518 FallbackScalingList4x4( |
| 522 pps->scaling_list4x4); | 519 i, kDefault4x4Intra, kDefault4x4Inter, pps->scaling_list4x4); |
| 523 } else { | 520 } else { |
| 524 // Table 7-2 fallback rule B in spec. | 521 // Table 7-2 fallback rule B in spec. |
| 525 FallbackScalingList4x4(i, sps.scaling_list4x4[0], | 522 FallbackScalingList4x4(i, |
| 526 sps.scaling_list4x4[3], pps->scaling_list4x4); | 523 sps.scaling_list4x4[0], |
| 524 sps.scaling_list4x4[3], |
| 525 pps->scaling_list4x4); |
| 527 } | 526 } |
| 528 } | 527 } |
| 529 } | 528 } |
| 530 | 529 |
| 531 if (pps->transform_8x8_mode_flag) { | 530 if (pps->transform_8x8_mode_flag) { |
| 532 for (int i = 0; i < ((sps.chroma_format_idc != 3) ? 2 : 6); ++i) { | 531 for (int i = 0; i < ((sps.chroma_format_idc != 3) ? 2 : 6); ++i) { |
| 533 READ_BOOL_OR_RETURN(&pic_scaling_list_present_flag); | 532 READ_BOOL_OR_RETURN(&pic_scaling_list_present_flag); |
| 534 | 533 |
| 535 if (pic_scaling_list_present_flag) { | 534 if (pic_scaling_list_present_flag) { |
| 536 res = ParseScalingList(arraysize(pps->scaling_list8x8[i]), | 535 res = ParseScalingList(arraysize(pps->scaling_list8x8[i]), |
| 537 pps->scaling_list8x8[i], &use_default); | 536 pps->scaling_list8x8[i], |
| 537 &use_default); |
| 538 if (res != kOk) | 538 if (res != kOk) |
| 539 return res; | 539 return res; |
| 540 | 540 |
| 541 if (use_default) | 541 if (use_default) |
| 542 DefaultScalingList8x8(i, pps->scaling_list8x8); | 542 DefaultScalingList8x8(i, pps->scaling_list8x8); |
| 543 | 543 |
| 544 } else { | 544 } else { |
| 545 if (sps.seq_scaling_matrix_present_flag) { | 545 if (sps.seq_scaling_matrix_present_flag) { |
| 546 // Table 7-2 fallback rule A in spec. | 546 // Table 7-2 fallback rule A in spec. |
| 547 FallbackScalingList8x8(i, kDefault8x8Intra, | 547 FallbackScalingList8x8( |
| 548 kDefault8x8Inter, pps->scaling_list8x8); | 548 i, kDefault8x8Intra, kDefault8x8Inter, pps->scaling_list8x8); |
| 549 } else { | 549 } else { |
| 550 // Table 7-2 fallback rule B in spec. | 550 // Table 7-2 fallback rule B in spec. |
| 551 FallbackScalingList8x8(i, sps.scaling_list8x8[0], | 551 FallbackScalingList8x8(i, |
| 552 sps.scaling_list8x8[1], pps->scaling_list8x8); | 552 sps.scaling_list8x8[0], |
| 553 sps.scaling_list8x8[1], |
| 554 pps->scaling_list8x8); |
| 553 } | 555 } |
| 554 } | 556 } |
| 555 } | 557 } |
| 556 } | 558 } |
| 557 return kOk; | 559 return kOk; |
| 558 } | 560 } |
| 559 | 561 |
| 560 static void FillDefaultSeqScalingLists(H264SPS* sps) { | 562 static void FillDefaultSeqScalingLists(H264SPS* sps) { |
| 561 for (int i = 0; i < 6; ++i) | 563 for (int i = 0; i < 6; ++i) |
| 562 for (int j = 0; j < kH264ScalingList4x4Length; ++j) | 564 for (int j = 0; j < kH264ScalingList4x4Length; ++j) |
| (...skipping 15 matching lines...) Expand all Loading... |
| 578 | 580 |
| 579 READ_BITS_OR_RETURN(8, &sps->profile_idc); | 581 READ_BITS_OR_RETURN(8, &sps->profile_idc); |
| 580 READ_BITS_OR_RETURN(6, &sps->constraint_setx_flag); | 582 READ_BITS_OR_RETURN(6, &sps->constraint_setx_flag); |
| 581 READ_BITS_OR_RETURN(2, &data); | 583 READ_BITS_OR_RETURN(2, &data); |
| 582 READ_BITS_OR_RETURN(8, &sps->level_idc); | 584 READ_BITS_OR_RETURN(8, &sps->level_idc); |
| 583 READ_UE_OR_RETURN(&sps->seq_parameter_set_id); | 585 READ_UE_OR_RETURN(&sps->seq_parameter_set_id); |
| 584 TRUE_OR_RETURN(sps->seq_parameter_set_id < 32); | 586 TRUE_OR_RETURN(sps->seq_parameter_set_id < 32); |
| 585 | 587 |
| 586 if (sps->profile_idc == 100 || sps->profile_idc == 110 || | 588 if (sps->profile_idc == 100 || sps->profile_idc == 110 || |
| 587 sps->profile_idc == 122 || sps->profile_idc == 244 || | 589 sps->profile_idc == 122 || sps->profile_idc == 244 || |
| 588 sps->profile_idc == 44 || sps->profile_idc == 83 || | 590 sps->profile_idc == 44 || sps->profile_idc == 83 || |
| 589 sps->profile_idc == 86 || sps->profile_idc == 118 || | 591 sps->profile_idc == 86 || sps->profile_idc == 118 || |
| 590 sps->profile_idc == 128) { | 592 sps->profile_idc == 128) { |
| 591 READ_UE_OR_RETURN(&sps->chroma_format_idc); | 593 READ_UE_OR_RETURN(&sps->chroma_format_idc); |
| 592 TRUE_OR_RETURN(sps->chroma_format_idc < 4); | 594 TRUE_OR_RETURN(sps->chroma_format_idc < 4); |
| 593 | 595 |
| 594 if (sps->chroma_format_idc == 3) | 596 if (sps->chroma_format_idc == 3) |
| 595 READ_BOOL_OR_RETURN(&sps->separate_colour_plane_flag); | 597 READ_BOOL_OR_RETURN(&sps->separate_colour_plane_flag); |
| 596 | 598 |
| 597 READ_UE_OR_RETURN(&sps->bit_depth_luma_minus8); | 599 READ_UE_OR_RETURN(&sps->bit_depth_luma_minus8); |
| 598 TRUE_OR_RETURN(sps->bit_depth_luma_minus8 < 7); | 600 TRUE_OR_RETURN(sps->bit_depth_luma_minus8 < 7); |
| 599 | 601 |
| (...skipping 290 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 890 shdr->luma_log2_weight_denom, | 892 shdr->luma_log2_weight_denom, |
| 891 shdr->chroma_log2_weight_denom, | 893 shdr->chroma_log2_weight_denom, |
| 892 &shdr->pred_weight_table_l1); | 894 &shdr->pred_weight_table_l1); |
| 893 if (res != kOk) | 895 if (res != kOk) |
| 894 return res; | 896 return res; |
| 895 } | 897 } |
| 896 | 898 |
| 897 return kOk; | 899 return kOk; |
| 898 } | 900 } |
| 899 | 901 |
| 900 H264Parser::Result H264Parser::ParseDecRefPicMarking(H264SliceHeader *shdr) { | 902 H264Parser::Result H264Parser::ParseDecRefPicMarking(H264SliceHeader* shdr) { |
| 901 if (shdr->idr_pic_flag) { | 903 if (shdr->idr_pic_flag) { |
| 902 READ_BOOL_OR_RETURN(&shdr->no_output_of_prior_pics_flag); | 904 READ_BOOL_OR_RETURN(&shdr->no_output_of_prior_pics_flag); |
| 903 READ_BOOL_OR_RETURN(&shdr->long_term_reference_flag); | 905 READ_BOOL_OR_RETURN(&shdr->long_term_reference_flag); |
| 904 } else { | 906 } else { |
| 905 READ_BOOL_OR_RETURN(&shdr->adaptive_ref_pic_marking_mode_flag); | 907 READ_BOOL_OR_RETURN(&shdr->adaptive_ref_pic_marking_mode_flag); |
| 906 | 908 |
| 907 H264DecRefPicMarking* marking; | 909 H264DecRefPicMarking* marking; |
| 908 if (shdr->adaptive_ref_pic_marking_mode_flag) { | 910 if (shdr->adaptive_ref_pic_marking_mode_flag) { |
| 909 size_t i; | 911 size_t i; |
| 910 for (i = 0; i < arraysize(shdr->ref_pic_marking); ++i) { | 912 for (i = 0; i < arraysize(shdr->ref_pic_marking); ++i) { |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 966 TRUE_OR_RETURN(pps); | 968 TRUE_OR_RETURN(pps); |
| 967 | 969 |
| 968 sps = GetSPS(pps->seq_parameter_set_id); | 970 sps = GetSPS(pps->seq_parameter_set_id); |
| 969 TRUE_OR_RETURN(sps); | 971 TRUE_OR_RETURN(sps); |
| 970 | 972 |
| 971 if (sps->separate_colour_plane_flag) { | 973 if (sps->separate_colour_plane_flag) { |
| 972 DVLOG(1) << "Interlaced streams not supported"; | 974 DVLOG(1) << "Interlaced streams not supported"; |
| 973 return kUnsupportedStream; | 975 return kUnsupportedStream; |
| 974 } | 976 } |
| 975 | 977 |
| 976 READ_BITS_OR_RETURN(sps->log2_max_frame_num_minus4 + 4, | 978 READ_BITS_OR_RETURN(sps->log2_max_frame_num_minus4 + 4, &shdr->frame_num); |
| 977 &shdr->frame_num); | |
| 978 if (!sps->frame_mbs_only_flag) { | 979 if (!sps->frame_mbs_only_flag) { |
| 979 READ_BOOL_OR_RETURN(&shdr->field_pic_flag); | 980 READ_BOOL_OR_RETURN(&shdr->field_pic_flag); |
| 980 if (shdr->field_pic_flag) { | 981 if (shdr->field_pic_flag) { |
| 981 DVLOG(1) << "Interlaced streams not supported"; | 982 DVLOG(1) << "Interlaced streams not supported"; |
| 982 return kUnsupportedStream; | 983 return kUnsupportedStream; |
| 983 } | 984 } |
| 984 } | 985 } |
| 985 | 986 |
| 986 if (shdr->idr_pic_flag) | 987 if (shdr->idr_pic_flag) |
| 987 READ_UE_OR_RETURN(&shdr->idr_pic_id); | 988 READ_UE_OR_RETURN(&shdr->idr_pic_id); |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1046 if (res != kOk) | 1047 if (res != kOk) |
| 1047 return res; | 1048 return res; |
| 1048 } | 1049 } |
| 1049 | 1050 |
| 1050 if (nalu.nal_ref_idc != 0) { | 1051 if (nalu.nal_ref_idc != 0) { |
| 1051 res = ParseDecRefPicMarking(shdr); | 1052 res = ParseDecRefPicMarking(shdr); |
| 1052 if (res != kOk) | 1053 if (res != kOk) |
| 1053 return res; | 1054 return res; |
| 1054 } | 1055 } |
| 1055 | 1056 |
| 1056 if (pps->entropy_coding_mode_flag && | 1057 if (pps->entropy_coding_mode_flag && !shdr->IsISlice() && |
| 1057 !shdr->IsISlice() && !shdr->IsSISlice()) { | 1058 !shdr->IsSISlice()) { |
| 1058 READ_UE_OR_RETURN(&shdr->cabac_init_idc); | 1059 READ_UE_OR_RETURN(&shdr->cabac_init_idc); |
| 1059 TRUE_OR_RETURN(shdr->cabac_init_idc < 3); | 1060 TRUE_OR_RETURN(shdr->cabac_init_idc < 3); |
| 1060 } | 1061 } |
| 1061 | 1062 |
| 1062 READ_SE_OR_RETURN(&shdr->slice_qp_delta); | 1063 READ_SE_OR_RETURN(&shdr->slice_qp_delta); |
| 1063 | 1064 |
| 1064 if (shdr->IsSPSlice() || shdr->IsSISlice()) { | 1065 if (shdr->IsSPSlice() || shdr->IsSISlice()) { |
| 1065 if (shdr->IsSPSlice()) | 1066 if (shdr->IsSPSlice()) |
| 1066 READ_BOOL_OR_RETURN(&shdr->sp_for_switch_flag); | 1067 READ_BOOL_OR_RETURN(&shdr->sp_for_switch_flag); |
| 1067 READ_SE_OR_RETURN(&shdr->slice_qs_delta); | 1068 READ_SE_OR_RETURN(&shdr->slice_qs_delta); |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1111 sei_msg->payload_size += byte; | 1112 sei_msg->payload_size += byte; |
| 1112 | 1113 |
| 1113 DVLOG(4) << "Found SEI message type: " << sei_msg->type | 1114 DVLOG(4) << "Found SEI message type: " << sei_msg->type |
| 1114 << " payload size: " << sei_msg->payload_size; | 1115 << " payload size: " << sei_msg->payload_size; |
| 1115 | 1116 |
| 1116 switch (sei_msg->type) { | 1117 switch (sei_msg->type) { |
| 1117 case H264SEIMessage::kSEIRecoveryPoint: | 1118 case H264SEIMessage::kSEIRecoveryPoint: |
| 1118 READ_UE_OR_RETURN(&sei_msg->recovery_point.recovery_frame_cnt); | 1119 READ_UE_OR_RETURN(&sei_msg->recovery_point.recovery_frame_cnt); |
| 1119 READ_BOOL_OR_RETURN(&sei_msg->recovery_point.exact_match_flag); | 1120 READ_BOOL_OR_RETURN(&sei_msg->recovery_point.exact_match_flag); |
| 1120 READ_BOOL_OR_RETURN(&sei_msg->recovery_point.broken_link_flag); | 1121 READ_BOOL_OR_RETURN(&sei_msg->recovery_point.broken_link_flag); |
| 1121 READ_BITS_OR_RETURN(2, | 1122 READ_BITS_OR_RETURN(2, &sei_msg->recovery_point.changing_slice_group_idc); |
| 1122 &sei_msg->recovery_point.changing_slice_group_idc); | |
| 1123 break; | 1123 break; |
| 1124 | 1124 |
| 1125 default: | 1125 default: |
| 1126 DVLOG(4) << "Unsupported SEI message"; | 1126 DVLOG(4) << "Unsupported SEI message"; |
| 1127 break; | 1127 break; |
| 1128 } | 1128 } |
| 1129 | 1129 |
| 1130 return kOk; | 1130 return kOk; |
| 1131 } | 1131 } |
| 1132 | 1132 |
| 1133 } // namespace content | 1133 } // namespace media |
| OLD | NEW |