OLD | NEW |
---|---|
(Empty) | |
1 // Copyright (c) 2011 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/webm/webm_cluster_parser.h" | |
6 | |
7 #include "base/logging.h" | |
8 #include "media/base/data_buffer.h" | |
9 #include "media/webm/webm_constants.h" | |
10 | |
11 namespace media { | |
12 | |
13 WebMClusterParser::WebMClusterParser(int64 timecode_scale, | |
14 int audio_track_num, | |
15 base::TimeDelta audio_default_duration, | |
16 int video_track_num, | |
17 base::TimeDelta video_default_duration) | |
18 : timecode_multiplier_(timecode_scale / 1000.0), | |
19 audio_track_num_(audio_track_num), | |
20 audio_default_duration_(audio_default_duration), | |
21 video_track_num_(video_track_num), | |
22 video_default_duration_(video_default_duration), | |
23 last_block_timecode_(-1), | |
24 cluster_timecode_(-1) { | |
25 } | |
26 | |
27 WebMClusterParser::~WebMClusterParser() {} | |
28 | |
29 int WebMClusterParser::Parse(const uint8* buf, int size) { | |
30 last_block_timecode_ = -1; | |
31 cluster_timecode_ = -1; | |
32 audio_buffers_.clear(); | |
33 video_buffers_.clear(); | |
34 | |
35 return WebMParseListElement(buf, size, kWebMIdCluster, 1, this); | |
36 } | |
37 | |
38 bool WebMClusterParser::OnListStart(int id) { | |
39 if (id == kWebMIdCluster) | |
40 cluster_timecode_ = -1; | |
41 | |
42 return true; | |
43 } | |
44 | |
45 bool WebMClusterParser::OnListEnd(int id) { | |
46 if (id == kWebMIdCluster) | |
47 cluster_timecode_ = -1; | |
48 | |
49 return true; | |
50 } | |
51 | |
52 bool WebMClusterParser::OnUInt(int id, int64 val) { | |
53 if (id == kWebMIdTimecode) { | |
54 if (cluster_timecode_ != -1) | |
55 return false; | |
56 | |
57 cluster_timecode_ = val; | |
58 } | |
59 | |
60 return true; | |
61 } | |
62 | |
63 bool WebMClusterParser::OnFloat(int id, double val) { | |
64 VLOG(1) << "Unexpected float element with ID " << std::hex << id; | |
65 return false; | |
66 } | |
67 | |
68 bool WebMClusterParser::OnBinary(int id, const uint8* data, int size) { | |
69 VLOG(1) << "Unexpected binary element with ID " << std::hex << id; | |
70 return false; | |
71 } | |
72 | |
73 bool WebMClusterParser::OnString(int id, const std::string& str) { | |
74 VLOG(1) << "Unexpected string element with ID " << std::hex << id; | |
75 return false; | |
76 } | |
77 | |
78 bool WebMClusterParser::OnSimpleBlock(int track_num, int timecode, | |
79 int flags, | |
80 const uint8* data, int size) { | |
81 if (cluster_timecode_ == -1) { | |
82 VLOG(1) << "Got SimpleBlock before cluster timecode."; | |
83 return false; | |
84 } | |
85 | |
86 if (timecode < 0) { | |
87 VLOG(1) << "Got SimpleBlock with negative timecode offset " << timecode; | |
88 return false; | |
89 } | |
90 | |
91 if (last_block_timecode_ != -1 && timecode < last_block_timecode_) { | |
92 VLOG(1) << "Got SimpleBlock with a timecode before the previous block."; | |
93 return false; | |
94 } | |
95 | |
96 last_block_timecode_ = timecode; | |
97 | |
98 base::TimeDelta timestamp = base::TimeDelta::FromMicroseconds( | |
99 (cluster_timecode_ + timecode) * timecode_multiplier_); | |
100 | |
101 scoped_refptr<Buffer> buffer(CreateBuffer(data, size)); | |
102 buffer->SetTimestamp(timestamp); | |
103 BufferQueue* queue = NULL; | |
104 | |
105 if (track_num == audio_track_num_) { | |
106 buffer->SetDuration(audio_default_duration_); | |
107 queue = &audio_buffers_; | |
108 } else if (track_num == video_track_num_) { | |
109 buffer->SetDuration(video_default_duration_); | |
110 queue = &video_buffers_; | |
111 } else { | |
112 VLOG(1) << "Unexpected track number " << track_num; | |
113 return false; | |
114 } | |
115 | |
116 if (!queue->empty() && | |
117 buffer->GetTimestamp() == queue->back()->GetTimestamp()) { | |
118 VLOG(1) << "Got SimpleBlock timecode is not strictly monotonically " | |
119 << "increasing for track " << track_num; | |
120 return false; | |
121 } | |
122 | |
123 queue->push_back(buffer); | |
124 return true; | |
125 } | |
126 | |
127 // static | |
128 Buffer* WebMClusterParser::CreateBuffer(const uint8* data, size_t size) { | |
scherkus (not reviewing)
2011/06/28 20:03:29
does this need to be part of the class?
I'd move
acolwell GONE FROM CHROMIUM
2011/06/29 16:38:43
Done.
| |
129 scoped_array<uint8> buf(new uint8[size]); | |
130 memcpy(buf.get(), data, size); | |
131 return new DataBuffer(buf.release(), size); | |
132 } | |
133 | |
134 } // namespace media | |
OLD | NEW |