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 10namespace media { 11 12// Default timecode scale if the TimecodeScale element is 13// not specified in the INFO element. 14static const int kWebMDefaultTimecodeScale = 1000000; 15 16WebMInfoParser::WebMInfoParser() 17 : timecode_scale_(-1), 18 duration_(-1) { 19} 20 21WebMInfoParser::~WebMInfoParser() {} 22 23int 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 37WebMParserClient* WebMInfoParser::OnListStart(int id) { return this; } 38 39bool 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 48bool 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 61bool 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 76bool 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 99bool WebMInfoParser::OnString(int id, const std::string& str) { 100 return true; 101} 102 103} // namespace media 104