Shaka Packager SDK
Loading...
Searching...
No Matches
webm_info_parser.cc
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 <packager/media/formats/webm/webm_info_parser.h>
6
7#include <chrono>
8#include <cstdint>
9#include <ctime>
10#include <ios>
11#include <string>
12
13#include <absl/log/log.h>
14
15#include <packager/media/formats/webm/webm_constants.h>
16#include <packager/media/formats/webm/webm_parser.h>
17
18namespace shaka {
19namespace media {
20
21// Default timecode scale if the TimecodeScale element is
22// not specified in the INFO element.
23static const int kWebMDefaultTimecodeScale = 1000000;
24
25WebMInfoParser::WebMInfoParser() : timecode_scale_(-1), duration_(-1) {}
26
27WebMInfoParser::~WebMInfoParser() {}
28
29int WebMInfoParser::Parse(const uint8_t* buf, int size) {
30 timecode_scale_ = -1;
31 duration_ = -1;
32
33 WebMListParser parser(kWebMIdInfo, this);
34 int result = parser.Parse(buf, size);
35
36 if (result <= 0)
37 return result;
38
39 // For now we do all or nothing parsing.
40 return parser.IsParsingComplete() ? result : 0;
41}
42
43WebMParserClient* WebMInfoParser::OnListStart(int /*id*/) {
44 return this;
45}
46
47bool WebMInfoParser::OnListEnd(int id) {
48 if (id == kWebMIdInfo && timecode_scale_ == -1) {
49 // Set timecode scale to default value if it isn't present in
50 // the Info element.
51 timecode_scale_ = kWebMDefaultTimecodeScale;
52 }
53 return true;
54}
55
56bool WebMInfoParser::OnUInt(int id, int64_t val) {
57 if (id != kWebMIdTimecodeScale)
58 return true;
59
60 if (timecode_scale_ != -1) {
61 DVLOG(1) << "Multiple values for id " << std::hex << id << " specified";
62 return false;
63 }
64
65 timecode_scale_ = val;
66 return true;
67}
68
69bool WebMInfoParser::OnFloat(int id, double val) {
70 if (id != kWebMIdDuration) {
71 DVLOG(1) << "Unexpected float for id" << std::hex << id;
72 return false;
73 }
74
75 if (duration_ != -1) {
76 DVLOG(1) << "Multiple values for duration.";
77 return false;
78 }
79
80 duration_ = val;
81 return true;
82}
83
84bool WebMInfoParser::OnBinary(int id, const uint8_t* data, int size) {
85 if (id == kWebMIdDateUTC) {
86 if (size != 8)
87 return false;
88
89 int64_t date_in_nanoseconds = 0;
90 for (int i = 0; i < size; ++i)
91 date_in_nanoseconds = (date_in_nanoseconds << 8) | data[i];
92
93 std::tm exploded_epoch;
94 exploded_epoch.tm_year = 2001;
95 exploded_epoch.tm_mon = 1;
96 exploded_epoch.tm_mday = 1;
97 exploded_epoch.tm_hour = 0;
98 exploded_epoch.tm_min = 0;
99 exploded_epoch.tm_sec = 0;
100
101 date_utc_ =
102 std::chrono::system_clock::from_time_t(std::mktime(&exploded_epoch)) +
103 std::chrono::microseconds(date_in_nanoseconds / 1000);
104 }
105 return true;
106}
107
108bool WebMInfoParser::OnString(int /*id*/, const std::string& /*str*/) {
109 return true;
110}
111
112} // namespace media
113} // namespace shaka
int Parse(const uint8_t *buf, int size)
All the methods that are virtual are virtual for mocking.