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
3 // found in the LICENSE file.
4
5 #include "media/formats/webm/webm_info_parser.h"
6
7 #include "base/logging.h"
8 #include "media/formats/webm/webm_constants.h"
9
10 namespace media {
11
12 // Default timecode scale if the TimecodeScale element is
13 // not specified in the INFO element.
14 static const int kWebMDefaultTimecodeScale = 1000000;
15
WebMInfoParser()16 WebMInfoParser::WebMInfoParser()
17 : timecode_scale_(-1),
18 duration_(-1) {
19 }
20
~WebMInfoParser()21 WebMInfoParser::~WebMInfoParser() {}
22
Parse(const uint8 * buf,int size)23 int WebMInfoParser::Parse(const uint8* buf, int size) {
24 timecode_scale_ = -1;
25 duration_ = -1;
26
27 WebMListParser parser(kWebMIdInfo, this);
28 int result = parser.Parse(buf, size);
29
30 if (result <= 0)
31 return result;
32
33 // For now we do all or nothing parsing.
34 return parser.IsParsingComplete() ? result : 0;
35 }
36
OnListStart(int id)37 WebMParserClient* WebMInfoParser::OnListStart(int id) { return this; }
38
OnListEnd(int id)39 bool WebMInfoParser::OnListEnd(int id) {
40 if (id == kWebMIdInfo && timecode_scale_ == -1) {
41 // Set timecode scale to default value if it isn't present in
42 // the Info element.
43 timecode_scale_ = kWebMDefaultTimecodeScale;
44 }
45 return true;
46 }
47
OnUInt(int id,int64 val)48 bool WebMInfoParser::OnUInt(int id, int64 val) {
49 if (id != kWebMIdTimecodeScale)
50 return true;
51
52 if (timecode_scale_ != -1) {
53 DVLOG(1) << "Multiple values for id " << std::hex << id << " specified";
54 return false;
55 }
56
57 timecode_scale_ = val;
58 return true;
59 }
60
OnFloat(int id,double val)61 bool WebMInfoParser::OnFloat(int id, double val) {
62 if (id != kWebMIdDuration) {
63 DVLOG(1) << "Unexpected float for id" << std::hex << id;
64 return false;
65 }
66
67 if (duration_ != -1) {
68 DVLOG(1) << "Multiple values for duration.";
69 return false;
70 }
71
72 duration_ = val;
73 return true;
74 }
75
OnBinary(int id,const uint8 * data,int size)76 bool WebMInfoParser::OnBinary(int id, const uint8* data, int size) {
77 if (id == kWebMIdDateUTC) {
78 if (size != 8)
79 return false;
80
81 int64 date_in_nanoseconds = 0;
82 for (int i = 0; i < size; ++i)
83 date_in_nanoseconds = (date_in_nanoseconds << 8) | data[i];
84
85 base::Time::Exploded exploded_epoch;
86 exploded_epoch.year = 2001;
87 exploded_epoch.month = 1;
88 exploded_epoch.day_of_month = 1;
89 exploded_epoch.hour = 0;
90 exploded_epoch.minute = 0;
91 exploded_epoch.second = 0;
92 exploded_epoch.millisecond = 0;
93 date_utc_ = base::Time::FromUTCExploded(exploded_epoch) +
94 base::TimeDelta::FromMicroseconds(date_in_nanoseconds / 1000);
95 }
96 return true;
97 }
98
OnString(int id,const std::string & str)99 bool WebMInfoParser::OnString(int id, const std::string& str) {
100 return true;
101 }
102
103 } // namespace media
104