OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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 "media/formats/webm/webm_parser.h" | 5 #include "media/formats/webm/webm_parser.h" |
6 | 6 |
7 // This file contains code to parse WebM file elements. It was created | 7 // This file contains code to parse WebM file elements. It was created |
8 // from information in the Matroska spec. | 8 // from information in the Matroska spec. |
9 // http://www.matroska.org/technical/specs/index.html | 9 // http://www.matroska.org/technical/specs/index.html |
10 // This file contains code for encrypted WebM. Current WebM | 10 // This file contains code for encrypted WebM. Current WebM |
11 // encrypted request for comments specification is here | 11 // encrypted request for comments specification is here |
12 // http://wiki.webmproject.org/encryption/webm-encryption-rfc | 12 // http://wiki.webmproject.org/encryption/webm-encryption-rfc |
13 | 13 |
14 #include <iomanip> | 14 #include <iomanip> |
| 15 #include <limits> |
15 | 16 |
16 #include "base/logging.h" | 17 #include "base/logging.h" |
17 #include "base/numerics/safe_conversions.h" | 18 #include "base/numerics/safe_conversions.h" |
18 #include "media/formats/webm/webm_constants.h" | 19 #include "media/formats/webm/webm_constants.h" |
19 | 20 |
20 namespace media { | 21 namespace media { |
21 | 22 |
22 enum ElementType { | 23 enum ElementType { |
23 UNKNOWN, | 24 UNKNOWN, |
24 LIST, // Referred to as Master Element in the Matroska spec. | 25 LIST, // Referred to as Master Element in the Matroska spec. |
(...skipping 391 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
416 // |size| - The number of bytes in |buf| | 417 // |size| - The number of bytes in |buf| |
417 // |max_bytes| - The maximum number of bytes the field can be. ID fields | 418 // |max_bytes| - The maximum number of bytes the field can be. ID fields |
418 // set this to 4 & element size fields set this to 8. If the | 419 // set this to 4 & element size fields set this to 8. If the |
419 // first byte indicates a larger field size than this it is a | 420 // first byte indicates a larger field size than this it is a |
420 // parser error. | 421 // parser error. |
421 // |mask_first_byte| - For element size fields the field length encoding bits | 422 // |mask_first_byte| - For element size fields the field length encoding bits |
422 // need to be masked off. This parameter is true for | 423 // need to be masked off. This parameter is true for |
423 // element size fields and is false for ID field values. | 424 // element size fields and is false for ID field values. |
424 // | 425 // |
425 // Returns: The number of bytes parsed on success. -1 on error. | 426 // Returns: The number of bytes parsed on success. -1 on error. |
426 static int ParseWebMElementHeaderField(const uint8* buf, int size, | 427 static int ParseWebMElementHeaderField(const uint8_t* buf, |
427 int max_bytes, bool mask_first_byte, | 428 int size, |
428 int64* num) { | 429 int max_bytes, |
| 430 bool mask_first_byte, |
| 431 int64_t* num) { |
429 DCHECK(buf); | 432 DCHECK(buf); |
430 DCHECK(num); | 433 DCHECK(num); |
431 | 434 |
432 if (size < 0) | 435 if (size < 0) |
433 return -1; | 436 return -1; |
434 | 437 |
435 if (size == 0) | 438 if (size == 0) |
436 return 0; | 439 return 0; |
437 | 440 |
438 int mask = 0x80; | 441 int mask = 0x80; |
439 uint8 ch = buf[0]; | 442 uint8_t ch = buf[0]; |
440 int extra_bytes = -1; | 443 int extra_bytes = -1; |
441 bool all_ones = false; | 444 bool all_ones = false; |
442 for (int i = 0; i < max_bytes; ++i) { | 445 for (int i = 0; i < max_bytes; ++i) { |
443 if ((ch & mask) != 0) { | 446 if ((ch & mask) != 0) { |
444 mask = ~mask & 0xff; | 447 mask = ~mask & 0xff; |
445 *num = mask_first_byte ? ch & mask : ch; | 448 *num = mask_first_byte ? ch & mask : ch; |
446 all_ones = (ch & mask) == mask; | 449 all_ones = (ch & mask) == mask; |
447 extra_bytes = i; | 450 extra_bytes = i; |
448 break; | 451 break; |
449 } | 452 } |
450 mask = 0x80 | mask >> 1; | 453 mask = 0x80 | mask >> 1; |
451 } | 454 } |
452 | 455 |
453 if (extra_bytes == -1) | 456 if (extra_bytes == -1) |
454 return -1; | 457 return -1; |
455 | 458 |
456 // Return 0 if we need more data. | 459 // Return 0 if we need more data. |
457 if ((1 + extra_bytes) > size) | 460 if ((1 + extra_bytes) > size) |
458 return 0; | 461 return 0; |
459 | 462 |
460 int bytes_used = 1; | 463 int bytes_used = 1; |
461 | 464 |
462 for (int i = 0; i < extra_bytes; ++i) { | 465 for (int i = 0; i < extra_bytes; ++i) { |
463 ch = buf[bytes_used++]; | 466 ch = buf[bytes_used++]; |
464 all_ones &= (ch == 0xff); | 467 all_ones &= (ch == 0xff); |
465 *num = (*num << 8) | ch; | 468 *num = (*num << 8) | ch; |
466 } | 469 } |
467 | 470 |
468 if (all_ones) | 471 if (all_ones) |
469 *num = kint64max; | 472 *num = std::numeric_limits<int64_t>::max(); |
470 | 473 |
471 return bytes_used; | 474 return bytes_used; |
472 } | 475 } |
473 | 476 |
474 int WebMParseElementHeader(const uint8* buf, int size, | 477 int WebMParseElementHeader(const uint8_t* buf, |
475 int* id, int64* element_size) { | 478 int size, |
| 479 int* id, |
| 480 int64_t* element_size) { |
476 DCHECK(buf); | 481 DCHECK(buf); |
477 DCHECK_GE(size, 0); | 482 DCHECK_GE(size, 0); |
478 DCHECK(id); | 483 DCHECK(id); |
479 DCHECK(element_size); | 484 DCHECK(element_size); |
480 | 485 |
481 if (size == 0) | 486 if (size == 0) |
482 return 0; | 487 return 0; |
483 | 488 |
484 int64 tmp = 0; | 489 int64_t tmp = 0; |
485 int num_id_bytes = ParseWebMElementHeaderField(buf, size, 4, false, &tmp); | 490 int num_id_bytes = ParseWebMElementHeaderField(buf, size, 4, false, &tmp); |
486 | 491 |
487 if (num_id_bytes <= 0) | 492 if (num_id_bytes <= 0) |
488 return num_id_bytes; | 493 return num_id_bytes; |
489 | 494 |
490 if (tmp == kint64max) | 495 if (tmp == std::numeric_limits<int64_t>::max()) |
491 tmp = kWebMReservedId; | 496 tmp = kWebMReservedId; |
492 | 497 |
493 *id = static_cast<int>(tmp); | 498 *id = static_cast<int>(tmp); |
494 | 499 |
495 int num_size_bytes = ParseWebMElementHeaderField(buf + num_id_bytes, | 500 int num_size_bytes = ParseWebMElementHeaderField(buf + num_id_bytes, |
496 size - num_id_bytes, | 501 size - num_id_bytes, |
497 8, true, &tmp); | 502 8, true, &tmp); |
498 | 503 |
499 if (num_size_bytes <= 0) | 504 if (num_size_bytes <= 0) |
500 return num_size_bytes; | 505 return num_size_bytes; |
501 | 506 |
502 if (tmp == kint64max) | 507 if (tmp == std::numeric_limits<int64_t>::max()) |
503 tmp = kWebMUnknownSize; | 508 tmp = kWebMUnknownSize; |
504 | 509 |
505 *element_size = tmp; | 510 *element_size = tmp; |
506 DVLOG(3) << "WebMParseElementHeader() : id " << std::hex << *id << std::dec | 511 DVLOG(3) << "WebMParseElementHeader() : id " << std::hex << *id << std::dec |
507 << " size " << *element_size; | 512 << " size " << *element_size; |
508 return num_id_bytes + num_size_bytes; | 513 return num_id_bytes + num_size_bytes; |
509 } | 514 } |
510 | 515 |
511 // Finds ElementType for a specific ID. | 516 // Finds ElementType for a specific ID. |
512 static ElementType FindIdType(int id, | 517 static ElementType FindIdType(int id, |
(...skipping 23 matching lines...) Expand all Loading... |
536 } | 541 } |
537 | 542 |
538 static int FindListLevel(int id) { | 543 static int FindListLevel(int id) { |
539 const ListElementInfo* list_info = FindListInfo(id); | 544 const ListElementInfo* list_info = FindListInfo(id); |
540 if (list_info) | 545 if (list_info) |
541 return list_info->level_; | 546 return list_info->level_; |
542 | 547 |
543 return -1; | 548 return -1; |
544 } | 549 } |
545 | 550 |
546 static int ParseUInt(const uint8* buf, int size, int id, | 551 static int ParseUInt(const uint8_t* buf, |
| 552 int size, |
| 553 int id, |
547 WebMParserClient* client) { | 554 WebMParserClient* client) { |
548 if ((size <= 0) || (size > 8)) | 555 if ((size <= 0) || (size > 8)) |
549 return -1; | 556 return -1; |
550 | 557 |
551 // Read in the big-endian integer. | 558 // Read in the big-endian integer. |
552 uint64 value = 0; | 559 uint64_t value = 0; |
553 for (int i = 0; i < size; ++i) | 560 for (int i = 0; i < size; ++i) |
554 value = (value << 8) | buf[i]; | 561 value = (value << 8) | buf[i]; |
555 | 562 |
556 // We use int64 in place of uint64 everywhere for convenience. See this bug | 563 // We use int64_t in place of uint64_t everywhere for convenience. See this |
| 564 // bug |
557 // for more details: http://crbug.com/366750#c3 | 565 // for more details: http://crbug.com/366750#c3 |
558 if (!base::IsValueInRangeForNumericType<int64>(value)) | 566 if (!base::IsValueInRangeForNumericType<int64_t>(value)) |
559 return -1; | 567 return -1; |
560 | 568 |
561 if (!client->OnUInt(id, value)) | 569 if (!client->OnUInt(id, value)) |
562 return -1; | 570 return -1; |
563 | 571 |
564 return size; | 572 return size; |
565 } | 573 } |
566 | 574 |
567 static int ParseFloat(const uint8* buf, int size, int id, | 575 static int ParseFloat(const uint8_t* buf, |
| 576 int size, |
| 577 int id, |
568 WebMParserClient* client) { | 578 WebMParserClient* client) { |
569 | |
570 if ((size != 4) && (size != 8)) | 579 if ((size != 4) && (size != 8)) |
571 return -1; | 580 return -1; |
572 | 581 |
573 double value = -1; | 582 double value = -1; |
574 | 583 |
575 // Read the bytes from big-endian form into a native endian integer. | 584 // Read the bytes from big-endian form into a native endian integer. |
576 int64 tmp = 0; | 585 int64_t tmp = 0; |
577 for (int i = 0; i < size; ++i) | 586 for (int i = 0; i < size; ++i) |
578 tmp = (tmp << 8) | buf[i]; | 587 tmp = (tmp << 8) | buf[i]; |
579 | 588 |
580 // Use a union to convert the integer bit pattern into a floating point | 589 // Use a union to convert the integer bit pattern into a floating point |
581 // number. | 590 // number. |
582 if (size == 4) { | 591 if (size == 4) { |
583 union { | 592 union { |
584 int32 src; | 593 int32_t src; |
585 float dst; | 594 float dst; |
586 } tmp2; | 595 } tmp2; |
587 tmp2.src = static_cast<int32>(tmp); | 596 tmp2.src = static_cast<int32_t>(tmp); |
588 value = tmp2.dst; | 597 value = tmp2.dst; |
589 } else if (size == 8) { | 598 } else if (size == 8) { |
590 union { | 599 union { |
591 int64 src; | 600 int64_t src; |
592 double dst; | 601 double dst; |
593 } tmp2; | 602 } tmp2; |
594 tmp2.src = tmp; | 603 tmp2.src = tmp; |
595 value = tmp2.dst; | 604 value = tmp2.dst; |
596 } else { | 605 } else { |
597 return -1; | 606 return -1; |
598 } | 607 } |
599 | 608 |
600 if (!client->OnFloat(id, value)) | 609 if (!client->OnFloat(id, value)) |
601 return -1; | 610 return -1; |
602 | 611 |
603 return size; | 612 return size; |
604 } | 613 } |
605 | 614 |
606 static int ParseBinary(const uint8* buf, int size, int id, | 615 static int ParseBinary(const uint8_t* buf, |
| 616 int size, |
| 617 int id, |
607 WebMParserClient* client) { | 618 WebMParserClient* client) { |
608 return client->OnBinary(id, buf, size) ? size : -1; | 619 return client->OnBinary(id, buf, size) ? size : -1; |
609 } | 620 } |
610 | 621 |
611 static int ParseString(const uint8* buf, int size, int id, | 622 static int ParseString(const uint8_t* buf, |
| 623 int size, |
| 624 int id, |
612 WebMParserClient* client) { | 625 WebMParserClient* client) { |
613 const uint8* end = static_cast<const uint8*>(memchr(buf, '\0', size)); | 626 const uint8_t* end = static_cast<const uint8_t*>(memchr(buf, '\0', size)); |
614 int length = (end != NULL) ? static_cast<int>(end - buf) : size; | 627 int length = (end != NULL) ? static_cast<int>(end - buf) : size; |
615 std::string str(reinterpret_cast<const char*>(buf), length); | 628 std::string str(reinterpret_cast<const char*>(buf), length); |
616 return client->OnString(id, str) ? size : -1; | 629 return client->OnString(id, str) ? size : -1; |
617 } | 630 } |
618 | 631 |
619 static int ParseNonListElement(ElementType type, int id, int64 element_size, | 632 static int ParseNonListElement(ElementType type, |
620 const uint8* buf, int size, | 633 int id, |
| 634 int64_t element_size, |
| 635 const uint8_t* buf, |
| 636 int size, |
621 WebMParserClient* client) { | 637 WebMParserClient* client) { |
622 DCHECK_GE(size, element_size); | 638 DCHECK_GE(size, element_size); |
623 | 639 |
624 int result = -1; | 640 int result = -1; |
625 switch(type) { | 641 switch(type) { |
626 case LIST: | 642 case LIST: |
627 NOTIMPLEMENTED(); | 643 NOTIMPLEMENTED(); |
628 result = -1; | 644 result = -1; |
629 break; | 645 break; |
630 case UINT: | 646 case UINT: |
(...skipping 26 matching lines...) Expand all Loading... |
657 WebMParserClient* WebMParserClient::OnListStart(int id) { | 673 WebMParserClient* WebMParserClient::OnListStart(int id) { |
658 DVLOG(1) << "Unexpected list element start with ID " << std::hex << id; | 674 DVLOG(1) << "Unexpected list element start with ID " << std::hex << id; |
659 return NULL; | 675 return NULL; |
660 } | 676 } |
661 | 677 |
662 bool WebMParserClient::OnListEnd(int id) { | 678 bool WebMParserClient::OnListEnd(int id) { |
663 DVLOG(1) << "Unexpected list element end with ID " << std::hex << id; | 679 DVLOG(1) << "Unexpected list element end with ID " << std::hex << id; |
664 return false; | 680 return false; |
665 } | 681 } |
666 | 682 |
667 bool WebMParserClient::OnUInt(int id, int64 val) { | 683 bool WebMParserClient::OnUInt(int id, int64_t val) { |
668 DVLOG(1) << "Unexpected unsigned integer element with ID " << std::hex << id; | 684 DVLOG(1) << "Unexpected unsigned integer element with ID " << std::hex << id; |
669 return false; | 685 return false; |
670 } | 686 } |
671 | 687 |
672 bool WebMParserClient::OnFloat(int id, double val) { | 688 bool WebMParserClient::OnFloat(int id, double val) { |
673 DVLOG(1) << "Unexpected float element with ID " << std::hex << id; | 689 DVLOG(1) << "Unexpected float element with ID " << std::hex << id; |
674 return false; | 690 return false; |
675 } | 691 } |
676 | 692 |
677 bool WebMParserClient::OnBinary(int id, const uint8* data, int size) { | 693 bool WebMParserClient::OnBinary(int id, const uint8_t* data, int size) { |
678 DVLOG(1) << "Unexpected binary element with ID " << std::hex << id; | 694 DVLOG(1) << "Unexpected binary element with ID " << std::hex << id; |
679 return false; | 695 return false; |
680 } | 696 } |
681 | 697 |
682 bool WebMParserClient::OnString(int id, const std::string& str) { | 698 bool WebMParserClient::OnString(int id, const std::string& str) { |
683 DVLOG(1) << "Unexpected string element with ID " << std::hex << id; | 699 DVLOG(1) << "Unexpected string element with ID " << std::hex << id; |
684 return false; | 700 return false; |
685 } | 701 } |
686 | 702 |
687 WebMListParser::WebMListParser(int id, WebMParserClient* client) | 703 WebMListParser::WebMListParser(int id, WebMParserClient* client) |
688 : state_(NEED_LIST_HEADER), | 704 : state_(NEED_LIST_HEADER), |
689 root_id_(id), | 705 root_id_(id), |
690 root_level_(FindListLevel(id)), | 706 root_level_(FindListLevel(id)), |
691 root_client_(client) { | 707 root_client_(client) { |
692 DCHECK_GE(root_level_, 0); | 708 DCHECK_GE(root_level_, 0); |
693 DCHECK(client); | 709 DCHECK(client); |
694 } | 710 } |
695 | 711 |
696 WebMListParser::~WebMListParser() {} | 712 WebMListParser::~WebMListParser() {} |
697 | 713 |
698 void WebMListParser::Reset() { | 714 void WebMListParser::Reset() { |
699 ChangeState(NEED_LIST_HEADER); | 715 ChangeState(NEED_LIST_HEADER); |
700 list_state_stack_.clear(); | 716 list_state_stack_.clear(); |
701 } | 717 } |
702 | 718 |
703 int WebMListParser::Parse(const uint8* buf, int size) { | 719 int WebMListParser::Parse(const uint8_t* buf, int size) { |
704 DCHECK(buf); | 720 DCHECK(buf); |
705 | 721 |
706 if (size < 0 || state_ == PARSE_ERROR || state_ == DONE_PARSING_LIST) | 722 if (size < 0 || state_ == PARSE_ERROR || state_ == DONE_PARSING_LIST) |
707 return -1; | 723 return -1; |
708 | 724 |
709 if (size == 0) | 725 if (size == 0) |
710 return 0; | 726 return 0; |
711 | 727 |
712 const uint8* cur = buf; | 728 const uint8_t* cur = buf; |
713 int cur_size = size; | 729 int cur_size = size; |
714 int bytes_parsed = 0; | 730 int bytes_parsed = 0; |
715 | 731 |
716 while (cur_size > 0 && state_ != PARSE_ERROR && state_ != DONE_PARSING_LIST) { | 732 while (cur_size > 0 && state_ != PARSE_ERROR && state_ != DONE_PARSING_LIST) { |
717 int element_id = 0; | 733 int element_id = 0; |
718 int64 element_size = 0; | 734 int64_t element_size = 0; |
719 int result = WebMParseElementHeader(cur, cur_size, &element_id, | 735 int result = WebMParseElementHeader(cur, cur_size, &element_id, |
720 &element_size); | 736 &element_size); |
721 | 737 |
722 if (result < 0) | 738 if (result < 0) |
723 return result; | 739 return result; |
724 | 740 |
725 if (result == 0) | 741 if (result == 0) |
726 return bytes_parsed; | 742 return bytes_parsed; |
727 | 743 |
728 switch(state_) { | 744 switch(state_) { |
(...skipping 13 matching lines...) Expand all Loading... |
742 | 758 |
743 ChangeState(INSIDE_LIST); | 759 ChangeState(INSIDE_LIST); |
744 if (!OnListStart(root_id_, element_size)) | 760 if (!OnListStart(root_id_, element_size)) |
745 return -1; | 761 return -1; |
746 | 762 |
747 break; | 763 break; |
748 } | 764 } |
749 | 765 |
750 case INSIDE_LIST: { | 766 case INSIDE_LIST: { |
751 int header_size = result; | 767 int header_size = result; |
752 const uint8* element_data = cur + header_size; | 768 const uint8_t* element_data = cur + header_size; |
753 int element_data_size = cur_size - header_size; | 769 int element_data_size = cur_size - header_size; |
754 | 770 |
755 if (element_size < element_data_size) | 771 if (element_size < element_data_size) |
756 element_data_size = element_size; | 772 element_data_size = element_size; |
757 | 773 |
758 result = ParseListElement(header_size, element_id, element_size, | 774 result = ParseListElement(header_size, element_id, element_size, |
759 element_data, element_data_size); | 775 element_data, element_data_size); |
760 | 776 |
761 DCHECK_LE(result, header_size + element_data_size); | 777 DCHECK_LE(result, header_size + element_data_size); |
762 if (result < 0) { | 778 if (result < 0) { |
(...skipping 23 matching lines...) Expand all Loading... |
786 | 802 |
787 bool WebMListParser::IsParsingComplete() const { | 803 bool WebMListParser::IsParsingComplete() const { |
788 return state_ == DONE_PARSING_LIST; | 804 return state_ == DONE_PARSING_LIST; |
789 } | 805 } |
790 | 806 |
791 void WebMListParser::ChangeState(State new_state) { | 807 void WebMListParser::ChangeState(State new_state) { |
792 state_ = new_state; | 808 state_ = new_state; |
793 } | 809 } |
794 | 810 |
795 int WebMListParser::ParseListElement(int header_size, | 811 int WebMListParser::ParseListElement(int header_size, |
796 int id, int64 element_size, | 812 int id, |
797 const uint8* data, int size) { | 813 int64_t element_size, |
| 814 const uint8_t* data, |
| 815 int size) { |
798 DCHECK_GT(list_state_stack_.size(), 0u); | 816 DCHECK_GT(list_state_stack_.size(), 0u); |
799 | 817 |
800 ListState& list_state = list_state_stack_.back(); | 818 ListState& list_state = list_state_stack_.back(); |
801 DCHECK(list_state.element_info_); | 819 DCHECK(list_state.element_info_); |
802 | 820 |
803 const ListElementInfo* element_info = list_state.element_info_; | 821 const ListElementInfo* element_info = list_state.element_info_; |
804 ElementType id_type = | 822 ElementType id_type = |
805 FindIdType(id, element_info->id_info_, element_info->id_info_count_); | 823 FindIdType(id, element_info->id_info_, element_info->id_info_count_); |
806 | 824 |
807 // Unexpected ID. | 825 // Unexpected ID. |
(...skipping 12 matching lines...) Expand all Loading... |
820 return -1; | 838 return -1; |
821 | 839 |
822 // Check to see if all open lists have ended. | 840 // Check to see if all open lists have ended. |
823 if (list_state_stack_.size() == 0) | 841 if (list_state_stack_.size() == 0) |
824 return 0; | 842 return 0; |
825 | 843 |
826 list_state = list_state_stack_.back(); | 844 list_state = list_state_stack_.back(); |
827 } | 845 } |
828 | 846 |
829 // Make sure the whole element can fit inside the current list. | 847 // Make sure the whole element can fit inside the current list. |
830 int64 total_element_size = header_size + element_size; | 848 int64_t total_element_size = header_size + element_size; |
831 if (list_state.size_ != kWebMUnknownSize && | 849 if (list_state.size_ != kWebMUnknownSize && |
832 list_state.size_ < list_state.bytes_parsed_ + total_element_size) { | 850 list_state.size_ < list_state.bytes_parsed_ + total_element_size) { |
833 return -1; | 851 return -1; |
834 } | 852 } |
835 | 853 |
836 if (id_type == LIST) { | 854 if (id_type == LIST) { |
837 list_state.bytes_parsed_ += header_size; | 855 list_state.bytes_parsed_ += header_size; |
838 | 856 |
839 if (!OnListStart(id, element_size)) | 857 if (!OnListStart(id, element_size)) |
840 return -1; | 858 return -1; |
(...skipping 21 matching lines...) Expand all Loading... |
862 | 880 |
863 // See if we have reached the end of the current list. | 881 // See if we have reached the end of the current list. |
864 if (list_state.bytes_parsed_ == list_state.size_) { | 882 if (list_state.bytes_parsed_ == list_state.size_) { |
865 if (!OnListEnd()) | 883 if (!OnListEnd()) |
866 return -1; | 884 return -1; |
867 } | 885 } |
868 | 886 |
869 return result; | 887 return result; |
870 } | 888 } |
871 | 889 |
872 bool WebMListParser::OnListStart(int id, int64 size) { | 890 bool WebMListParser::OnListStart(int id, int64_t size) { |
873 const ListElementInfo* element_info = FindListInfo(id); | 891 const ListElementInfo* element_info = FindListInfo(id); |
874 if (!element_info) | 892 if (!element_info) |
875 return false; | 893 return false; |
876 | 894 |
877 int current_level = root_level_ + list_state_stack_.size() - 1; | 895 int current_level = root_level_ + list_state_stack_.size() - 1; |
878 if (current_level + 1 != element_info->level_) | 896 if (current_level + 1 != element_info->level_) |
879 return false; | 897 return false; |
880 | 898 |
881 WebMParserClient* current_list_client = NULL; | 899 WebMParserClient* current_list_client = NULL; |
882 if (!list_state_stack_.empty()) { | 900 if (!list_state_stack_.empty()) { |
(...skipping 17 matching lines...) Expand all Loading... |
900 if (size == 0) | 918 if (size == 0) |
901 return OnListEnd(); | 919 return OnListEnd(); |
902 | 920 |
903 return true; | 921 return true; |
904 } | 922 } |
905 | 923 |
906 bool WebMListParser::OnListEnd() { | 924 bool WebMListParser::OnListEnd() { |
907 int lists_ended = 0; | 925 int lists_ended = 0; |
908 for (; !list_state_stack_.empty(); ++lists_ended) { | 926 for (; !list_state_stack_.empty(); ++lists_ended) { |
909 const ListState& list_state = list_state_stack_.back(); | 927 const ListState& list_state = list_state_stack_.back(); |
910 int64 bytes_parsed = list_state.bytes_parsed_; | 928 int64_t bytes_parsed = list_state.bytes_parsed_; |
911 int id = list_state.id_; | 929 int id = list_state.id_; |
912 | 930 |
913 if (bytes_parsed != list_state.size_) | 931 if (bytes_parsed != list_state.size_) |
914 break; | 932 break; |
915 | 933 |
916 list_state_stack_.pop_back(); | 934 list_state_stack_.pop_back(); |
917 | 935 |
918 WebMParserClient* client = NULL; | 936 WebMParserClient* client = NULL; |
919 if (!list_state_stack_.empty()) { | 937 if (!list_state_stack_.empty()) { |
920 // Update the bytes_parsed_ for the parent element. | 938 // Update the bytes_parsed_ for the parent element. |
(...skipping 24 matching lines...) Expand all Loading... |
945 if (kSegmentIds[i].id_ == id_b) | 963 if (kSegmentIds[i].id_ == id_b) |
946 return true; | 964 return true; |
947 } | 965 } |
948 } | 966 } |
949 | 967 |
950 // kWebMIdSegment siblings. | 968 // kWebMIdSegment siblings. |
951 return ((id_b == kWebMIdSegment) || (id_b == kWebMIdEBMLHeader)); | 969 return ((id_b == kWebMIdSegment) || (id_b == kWebMIdEBMLHeader)); |
952 } | 970 } |
953 | 971 |
954 } // namespace media | 972 } // namespace media |
OLD | NEW |