15d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "media/formats/webm/webm_info_parser.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h"
85d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "media/formats/webm/webm_constants.h"
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace media {
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Default timecode scale if the TimecodeScale element is
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// not specified in the INFO element.
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const int kWebMDefaultTimecodeScale = 1000000;
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)WebMInfoParser::WebMInfoParser()
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : timecode_scale_(-1),
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      duration_(-1) {
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)WebMInfoParser::~WebMInfoParser() {}
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int WebMInfoParser::Parse(const uint8* buf, int size) {
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  timecode_scale_ = -1;
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  duration_ = -1;
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  WebMListParser parser(kWebMIdInfo, this);
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int result = parser.Parse(buf, size);
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (result <= 0)
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return result;
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // For now we do all or nothing parsing.
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return parser.IsParsingComplete() ? result : 0;
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)WebMParserClient* WebMInfoParser::OnListStart(int id) { return this; }
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool WebMInfoParser::OnListEnd(int id) {
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (id == kWebMIdInfo && timecode_scale_ == -1) {
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Set timecode scale to default value if it isn't present in
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // the Info element.
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    timecode_scale_ = kWebMDefaultTimecodeScale;
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool WebMInfoParser::OnUInt(int id, int64 val) {
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (id != kWebMIdTimecodeScale)
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return true;
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (timecode_scale_ != -1) {
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DVLOG(1) << "Multiple values for id " << std::hex << id << " specified";
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  timecode_scale_ = val;
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool WebMInfoParser::OnFloat(int id, double val) {
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (id != kWebMIdDuration) {
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DVLOG(1) << "Unexpected float for id" << std::hex << id;
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (duration_ != -1) {
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DVLOG(1) << "Multiple values for duration.";
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  duration_ = val;
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool WebMInfoParser::OnBinary(int id, const uint8* data, int size) {
770529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  if (id == kWebMIdDateUTC) {
780529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    if (size != 8)
790529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      return false;
800529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
810529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    int64 date_in_nanoseconds = 0;
820529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    for (int i = 0; i < size; ++i)
830529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      date_in_nanoseconds = (date_in_nanoseconds << 8) | data[i];
840529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
850529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    base::Time::Exploded exploded_epoch;
860529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    exploded_epoch.year = 2001;
870529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    exploded_epoch.month = 1;
880529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    exploded_epoch.day_of_month = 1;
890529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    exploded_epoch.hour = 0;
900529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    exploded_epoch.minute = 0;
910529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    exploded_epoch.second = 0;
920529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    exploded_epoch.millisecond = 0;
930529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    date_utc_ = base::Time::FromUTCExploded(exploded_epoch) +
940529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch        base::TimeDelta::FromMicroseconds(date_in_nanoseconds / 1000);
950529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  }
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool WebMInfoParser::OnString(int id, const std::string& str) {
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace media
104