Index: media/formats/mp4/box_definitions.cc |
diff --git a/media/formats/mp4/box_definitions.cc b/media/formats/mp4/box_definitions.cc |
index a792c90d9ba8e27ef17724bdb5f717966c9470be..684b92fdf74320cb406a6c231d56f7c4b2661660 100644 |
--- a/media/formats/mp4/box_definitions.cc |
+++ b/media/formats/mp4/box_definitions.cc |
@@ -375,8 +375,23 @@ 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). |
wolenetz
2016/03/05 03:26:20
A pascal-style string that is shorter than (remain
servolk
2016/03/07 23:45:01
Sure, I've added an RCHECK to ensure that the leng
|
+ std::vector<uint8_t> name_bytes; |
+ RCHECK(reader->ReadVec(&name_bytes, reader->size() - reader->pos())); |
+ if (name_bytes.back() == 0) |
+ name_bytes.pop_back(); |
+ else |
+ name_bytes.erase(name_bytes.begin()); |
+ name = std::string(name_bytes.begin(), name_bytes.end()); |
+ |
if (hdlr_type == FOURCC_VIDE) { |
type = kVideo; |
} else if (hdlr_type == FOURCC_SOUN) { |
@@ -632,7 +647,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; } |
@@ -640,18 +656,29 @@ 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 playback quality information |
+ return reader->SkipBytes(2); |
+} |
+ |
+std::string MediaHeader::language() const { |
+ if (language_code == 0x7fff || language_code < 0x400) { |
wolenetz
2016/03/05 03:26:21
A couple questions about this line:
1) Where do th
servolk
2016/03/07 23:45:01
1) I took those numbers from https://developer.app
wolenetz
2016/03/10 19:53:29
Acknowledged.
|
+ return "und"; |
} |
- // Skip language information |
- return reader->SkipBytes(4); |
+ char lang_chars[4]; |
+ lang_chars[3] = 0; |
+ lang_chars[2] = 0x60 + (language_code & 0x1f); |
wolenetz
2016/03/05 03:26:21
nit: constrain each of lang_chars[0..2] to be with
servolk
2016/03/07 23:45:01
Done.
|
+ lang_chars[1] = 0x60 + ((language_code >> 5) & 0x1f); |
+ lang_chars[0] = 0x60 + ((language_code >> 10) & 0x1f); |
+ return lang_chars; |
} |
MediaInformation::MediaInformation() {} |