Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(20)

Side by Side Diff: media/webm/webm_cluster_parser.cc

Issue 8775035: Add support for incremental cluster parsing. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Replace old list parsing with WebMListParser & implement incremental cluster parsing with that. Created 9 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "media/webm/webm_cluster_parser.h" 5 #include "media/webm/webm_cluster_parser.h"
6 6
7 #include "base/logging.h" 7 #include "base/logging.h"
8 #include "media/base/data_buffer.h" 8 #include "media/base/data_buffer.h"
9 #include "media/webm/webm_constants.h" 9 #include "media/webm/webm_constants.h"
10 10
11 namespace media { 11 namespace media {
12 12
13 static Buffer* CreateBuffer(const uint8* data, size_t size) { 13 static Buffer* CreateBuffer(const uint8* data, size_t size) {
14 scoped_array<uint8> buf(new uint8[size]); 14 scoped_array<uint8> buf(new uint8[size]);
15 memcpy(buf.get(), data, size); 15 memcpy(buf.get(), data, size);
16 return new DataBuffer(buf.release(), size); 16 return new DataBuffer(buf.release(), size);
17 } 17 }
18 18
19 WebMClusterParser::WebMClusterParser(int64 timecode_scale, 19 WebMClusterParser::WebMClusterParser(int64 timecode_scale,
20 int audio_track_num, 20 int audio_track_num,
21 base::TimeDelta audio_default_duration, 21 base::TimeDelta audio_default_duration,
22 int video_track_num, 22 int video_track_num,
23 base::TimeDelta video_default_duration) 23 base::TimeDelta video_default_duration)
24 : timecode_multiplier_(timecode_scale / 1000.0), 24 : timecode_multiplier_(timecode_scale / 1000.0),
25 audio_track_num_(audio_track_num), 25 audio_track_num_(audio_track_num),
26 audio_default_duration_(audio_default_duration), 26 audio_default_duration_(audio_default_duration),
27 video_track_num_(video_track_num), 27 video_track_num_(video_track_num),
28 video_default_duration_(video_default_duration), 28 video_default_duration_(video_default_duration),
29 parser_(kWebMIdCluster),
29 last_block_timecode_(-1), 30 last_block_timecode_(-1),
30 cluster_timecode_(-1) { 31 cluster_timecode_(-1) {
31 } 32 }
32 33
33 WebMClusterParser::~WebMClusterParser() {} 34 WebMClusterParser::~WebMClusterParser() {}
34 35
35 int WebMClusterParser::Parse(const uint8* buf, int size) { 36 int WebMClusterParser::Parse(const uint8* buf, int size) {
36 last_block_timecode_ = -1;
37 cluster_timecode_ = -1;
38 audio_buffers_.clear(); 37 audio_buffers_.clear();
39 video_buffers_.clear(); 38 video_buffers_.clear();
40 39
41 return WebMParseListElement(buf, size, kWebMIdCluster, 1, this); 40 int result = parser_.Parse(buf, size, this);
41
42 if (result <= 0)
43 return result;
44
45 if (parser_.IsParsingComplete()) {
46 // Reset the parser if we're done parsing so that
47 // it is ready to accept another cluster on the next
48 // call.
49 parser_.Reset();
50
51 last_block_timecode_ = -1;
52 cluster_timecode_ = -1;
53 }
54
55 return result;
42 } 56 }
43 57
44 bool WebMClusterParser::OnListStart(int id) { 58 bool WebMClusterParser::OnListStart(int id) {
45 if (id == kWebMIdCluster) 59 if (id == kWebMIdCluster)
46 cluster_timecode_ = -1; 60 cluster_timecode_ = -1;
47 61
48 return true; 62 return true;
49 } 63 }
50 64
51 bool WebMClusterParser::OnListEnd(int id) { 65 bool WebMClusterParser::OnListEnd(int id) {
52 if (id == kWebMIdCluster) 66 if (id == kWebMIdCluster)
53 cluster_timecode_ = -1; 67 cluster_timecode_ = -1;
54 68
55 return true; 69 return true;
56 } 70 }
57 71
58 bool WebMClusterParser::OnUInt(int id, int64 val) { 72 bool WebMClusterParser::OnUInt(int id, int64 val) {
59 if (id == kWebMIdTimecode) { 73 if (id == kWebMIdTimecode) {
60 if (cluster_timecode_ != -1) 74 if (cluster_timecode_ != -1)
61 return false; 75 return false;
62 76
63 cluster_timecode_ = val; 77 cluster_timecode_ = val;
64 } 78 }
65 79
66 return true; 80 return true;
67 } 81 }
68 82
69 bool WebMClusterParser::OnFloat(int id, double val) { 83 bool WebMClusterParser::OnFloat(int id, double val) {
70 VLOG(1) << "Unexpected float element with ID " << std::hex << id; 84 DVLOG(1) << "Unexpected float element with ID " << std::hex << id;
71 return false; 85 return false;
72 } 86 }
73 87
74 bool WebMClusterParser::OnBinary(int id, const uint8* data, int size) { 88 bool WebMClusterParser::OnBinary(int id, const uint8* data, int size) {
75 VLOG(1) << "Unexpected binary element with ID " << std::hex << id; 89 DVLOG(1) << "Unexpected binary element with ID " << std::hex << id;
76 return false; 90 return false;
77 } 91 }
78 92
79 bool WebMClusterParser::OnString(int id, const std::string& str) { 93 bool WebMClusterParser::OnString(int id, const std::string& str) {
80 VLOG(1) << "Unexpected string element with ID " << std::hex << id; 94 DVLOG(1) << "Unexpected string element with ID " << std::hex << id;
81 return false; 95 return false;
82 } 96 }
83 97
84 bool WebMClusterParser::OnSimpleBlock(int track_num, int timecode, 98 bool WebMClusterParser::OnSimpleBlock(int track_num, int timecode,
85 int flags, 99 int flags,
86 const uint8* data, int size) { 100 const uint8* data, int size) {
87 if (cluster_timecode_ == -1) { 101 if (cluster_timecode_ == -1) {
88 VLOG(1) << "Got SimpleBlock before cluster timecode."; 102 DVLOG(1) << "Got SimpleBlock before cluster timecode.";
89 return false; 103 return false;
90 } 104 }
91 105
92 if (timecode < 0) { 106 if (timecode < 0) {
93 VLOG(1) << "Got SimpleBlock with negative timecode offset " << timecode; 107 DVLOG(1) << "Got SimpleBlock with negative timecode offset " << timecode;
94 return false; 108 return false;
95 } 109 }
96 110
97 if (last_block_timecode_ != -1 && timecode < last_block_timecode_) { 111 if (last_block_timecode_ != -1 && timecode < last_block_timecode_) {
98 VLOG(1) << "Got SimpleBlock with a timecode before the previous block."; 112 DVLOG(1) << "Got SimpleBlock with a timecode before the previous block.";
99 return false; 113 return false;
100 } 114 }
101 115
102 last_block_timecode_ = timecode; 116 last_block_timecode_ = timecode;
103 117
104 base::TimeDelta timestamp = base::TimeDelta::FromMicroseconds( 118 base::TimeDelta timestamp = base::TimeDelta::FromMicroseconds(
105 (cluster_timecode_ + timecode) * timecode_multiplier_); 119 (cluster_timecode_ + timecode) * timecode_multiplier_);
106 120
107 scoped_refptr<Buffer> buffer(CreateBuffer(data, size)); 121 scoped_refptr<Buffer> buffer(CreateBuffer(data, size));
108 buffer->SetTimestamp(timestamp); 122 buffer->SetTimestamp(timestamp);
109 BufferQueue* queue = NULL; 123 BufferQueue* queue = NULL;
110 124
111 if (track_num == audio_track_num_) { 125 if (track_num == audio_track_num_) {
112 buffer->SetDuration(audio_default_duration_); 126 buffer->SetDuration(audio_default_duration_);
113 queue = &audio_buffers_; 127 queue = &audio_buffers_;
114 } else if (track_num == video_track_num_) { 128 } else if (track_num == video_track_num_) {
115 buffer->SetDuration(video_default_duration_); 129 buffer->SetDuration(video_default_duration_);
116 queue = &video_buffers_; 130 queue = &video_buffers_;
117 } else { 131 } else {
118 VLOG(1) << "Unexpected track number " << track_num; 132 DVLOG(1) << "Unexpected track number " << track_num;
119 return false; 133 return false;
120 } 134 }
121 135
122 if (!queue->empty() && 136 if (!queue->empty() &&
123 buffer->GetTimestamp() == queue->back()->GetTimestamp()) { 137 buffer->GetTimestamp() == queue->back()->GetTimestamp()) {
124 VLOG(1) << "Got SimpleBlock timecode is not strictly monotonically " 138 DVLOG(1) << "Got SimpleBlock timecode is not strictly monotonically "
125 << "increasing for track " << track_num; 139 << "increasing for track " << track_num;
126 return false; 140 return false;
127 } 141 }
128 142
129 queue->push_back(buffer); 143 queue->push_back(buffer);
130 return true; 144 return true;
131 } 145 }
132 146
133 } // namespace media 147 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698