| Index: media/formats/mp4/box_definitions.cc
|
| diff --git a/media/formats/mp4/box_definitions.cc b/media/formats/mp4/box_definitions.cc
|
| index 705232f4efe6332403008a1e502b1ec2fc073d3d..a95c78f9d163da7dbd052c74b3690b25cb46e7a3 100644
|
| --- a/media/formats/mp4/box_definitions.cc
|
| +++ b/media/formats/mp4/box_definitions.cc
|
| @@ -434,8 +434,29 @@ FourCC HandlerReference::BoxType() const { return FOURCC_HDLR; }
|
|
|
| bool HandlerReference::Parse(BoxReader* reader) {
|
| FourCC hdlr_type;
|
| - RCHECK(reader->SkipBytes(8) && reader->ReadFourCC(&hdlr_type));
|
| - // Note: remaining fields in box ignored
|
| + RCHECK(reader->ReadFullBoxHeader() && reader->SkipBytes(4) &&
|
| + reader->ReadFourCC(&hdlr_type) && reader->SkipBytes(12));
|
| +
|
| + // Now we should be at the beginning of the |name| field of HDLR box. The
|
| + // |name| is a zero-terminated ASCII string in ISO BMFF, but it was a
|
| + // Pascal-style counted string in older QT/Mov formats. So we'll read the
|
| + // remaining box bytes first, then if the last one is zero, we strip the last
|
| + // zero byte, otherwise we'll string the first byte (containing the length of
|
| + // the Pascal-style string).
|
| + std::vector<uint8_t> name_bytes;
|
| + RCHECK(reader->ReadVec(&name_bytes, reader->size() - reader->pos()));
|
| + if (name_bytes.size() == 0) {
|
| + name = "";
|
| + } else if (name_bytes.back() == 0) {
|
| + // This is a zero-terminated C-style string, exclude the last byte.
|
| + name = std::string(name_bytes.begin(), name_bytes.end() - 1);
|
| + } else {
|
| + // Check that the length of the Pascal-style string is correct.
|
| + RCHECK(name_bytes[0] == (name_bytes.size() - 1));
|
| + // Skip the first byte, containing the length of the Pascal-string.
|
| + name = std::string(name_bytes.begin() + 1, name_bytes.end());
|
| + }
|
| +
|
| if (hdlr_type == FOURCC_VIDE) {
|
| type = kVideo;
|
| } else if (hdlr_type == FOURCC_SOUN) {
|
| @@ -691,7 +712,8 @@ MediaHeader::MediaHeader()
|
| : creation_time(0),
|
| modification_time(0),
|
| timescale(0),
|
| - duration(0) {}
|
| + duration(0),
|
| + language_code(0) {}
|
| MediaHeader::~MediaHeader() {}
|
| FourCC MediaHeader::BoxType() const { return FOURCC_MDHD; }
|
|
|
| @@ -699,18 +721,43 @@ bool MediaHeader::Parse(BoxReader* reader) {
|
| RCHECK(reader->ReadFullBoxHeader());
|
|
|
| if (reader->version() == 1) {
|
| - RCHECK(reader->Read8(&creation_time) &&
|
| - reader->Read8(&modification_time) &&
|
| - reader->Read4(×cale) &&
|
| - reader->Read8(&duration));
|
| + RCHECK(reader->Read8(&creation_time) && reader->Read8(&modification_time) &&
|
| + reader->Read4(×cale) && reader->Read8(&duration) &&
|
| + reader->Read2(&language_code));
|
| } else {
|
| RCHECK(reader->Read4Into8(&creation_time) &&
|
| reader->Read4Into8(&modification_time) &&
|
| - reader->Read4(×cale) &&
|
| - reader->Read4Into8(&duration));
|
| + reader->Read4(×cale) && reader->Read4Into8(&duration) &&
|
| + reader->Read2(&language_code));
|
| }
|
| - // Skip language information
|
| - return reader->SkipBytes(4);
|
| + // ISO 639-2/T language code only uses 15 lower bits, so reset the 16th bit.
|
| + language_code &= 0x7fff;
|
| + // Skip playback quality information
|
| + return reader->SkipBytes(2);
|
| +}
|
| +
|
| +std::string MediaHeader::language() const {
|
| + if (language_code == 0x7fff || language_code < 0x400) {
|
| + return "und";
|
| + }
|
| + char lang_chars[4];
|
| + lang_chars[3] = 0;
|
| + lang_chars[2] = 0x60 + (language_code & 0x1f);
|
| + lang_chars[1] = 0x60 + ((language_code >> 5) & 0x1f);
|
| + lang_chars[0] = 0x60 + ((language_code >> 10) & 0x1f);
|
| +
|
| + if (lang_chars[0] < 'a' || lang_chars[0] > 'z' || lang_chars[1] < 'a' ||
|
| + lang_chars[1] > 'z' || lang_chars[2] < 'a' || lang_chars[2] > 'z') {
|
| + // Got unexpected characteds in ISO 639-2/T language code. Something must be
|
| + // wrong with the input file, report 'und' language to be safe.
|
| + DVLOG(2) << "Ignoring MDHD language_code (non ISO 639-2 compliant): "
|
| + << lang_chars;
|
| + lang_chars[0] = 'u';
|
| + lang_chars[1] = 'n';
|
| + lang_chars[2] = 'd';
|
| + }
|
| +
|
| + return lang_chars;
|
| }
|
|
|
| MediaInformation::MediaInformation() {}
|
|
|