OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 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 | 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/formats/webm/webm_stream_parser.h" | 5 #include "media/formats/webm/webm_stream_parser.h" |
6 | 6 |
7 #include <string> | 7 #include <string> |
8 | 8 |
9 #include "base/callback.h" | 9 #include "base/callback.h" |
10 #include "base/callback_helpers.h" | 10 #include "base/callback_helpers.h" |
11 #include "base/logging.h" | 11 #include "base/logging.h" |
12 #include "media/formats/webm/webm_cluster_parser.h" | 12 #include "media/formats/webm/webm_cluster_parser.h" |
13 #include "media/formats/webm/webm_constants.h" | 13 #include "media/formats/webm/webm_constants.h" |
14 #include "media/formats/webm/webm_content_encodings.h" | 14 #include "media/formats/webm/webm_content_encodings.h" |
15 #include "media/formats/webm/webm_crypto_helpers.h" | 15 #include "media/formats/webm/webm_crypto_helpers.h" |
16 #include "media/formats/webm/webm_info_parser.h" | 16 #include "media/formats/webm/webm_info_parser.h" |
17 #include "media/formats/webm/webm_tracks_parser.h" | 17 #include "media/formats/webm/webm_tracks_parser.h" |
18 | 18 |
19 namespace media { | 19 namespace media { |
20 | 20 |
| 21 static const int64 kUnknownElementSize = 0xffffffffffffff; |
| 22 |
21 WebMStreamParser::WebMStreamParser() | 23 WebMStreamParser::WebMStreamParser() |
22 : state_(kWaitingForInit), | 24 : state_(kWaitingForInit), |
| 25 unknown_segment_size_(false), |
23 parsing_cluster_(false) { | 26 parsing_cluster_(false) { |
24 } | 27 } |
25 | 28 |
26 WebMStreamParser::~WebMStreamParser() { | 29 WebMStreamParser::~WebMStreamParser() { |
27 } | 30 } |
28 | 31 |
29 void WebMStreamParser::Init(const InitCB& init_cb, | 32 void WebMStreamParser::Init(const InitCB& init_cb, |
30 const NewConfigCB& config_cb, | 33 const NewConfigCB& config_cb, |
31 const NewBuffersCB& new_buffers_cb, | 34 const NewBuffersCB& new_buffers_cb, |
32 bool ignore_text_tracks, | 35 bool ignore_text_tracks, |
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
143 case kWebMIdCues: | 146 case kWebMIdCues: |
144 case kWebMIdChapters: | 147 case kWebMIdChapters: |
145 if (cur_size < (result + element_size)) { | 148 if (cur_size < (result + element_size)) { |
146 // We don't have the whole element yet. Signal we need more data. | 149 // We don't have the whole element yet. Signal we need more data. |
147 return 0; | 150 return 0; |
148 } | 151 } |
149 // Skip the element. | 152 // Skip the element. |
150 return result + element_size; | 153 return result + element_size; |
151 break; | 154 break; |
152 case kWebMIdSegment: | 155 case kWebMIdSegment: |
| 156 // Segment of unknown size indicates live stream. |
| 157 if (element_size == kUnknownElementSize) |
| 158 unknown_segment_size_ = true; |
153 // Just consume the segment header. | 159 // Just consume the segment header. |
154 return result; | 160 return result; |
155 break; | 161 break; |
156 case kWebMIdInfo: | 162 case kWebMIdInfo: |
157 // We've found the element we are looking for. | 163 // We've found the element we are looking for. |
158 break; | 164 break; |
159 default: { | 165 default: { |
160 MEDIA_LOG(log_cb_) << "Unexpected element ID 0x" << std::hex << id; | 166 MEDIA_LOG(log_cb_) << "Unexpected element ID 0x" << std::hex << id; |
161 return -1; | 167 return -1; |
162 } | 168 } |
163 } | 169 } |
164 | 170 |
165 WebMInfoParser info_parser; | 171 WebMInfoParser info_parser; |
166 result = info_parser.Parse(cur, cur_size); | 172 result = info_parser.Parse(cur, cur_size); |
167 | 173 |
168 if (result <= 0) | 174 if (result <= 0) |
169 return result; | 175 return result; |
170 | 176 |
171 cur += result; | 177 cur += result; |
172 cur_size -= result; | 178 cur_size -= result; |
173 bytes_parsed += result; | 179 bytes_parsed += result; |
174 | 180 |
175 WebMTracksParser tracks_parser(log_cb_, ignore_text_tracks_); | 181 bool live_mode = unknown_segment_size_ && (info_parser.duration() <= 0) && |
| 182 !info_parser.date_utc().is_null(); |
| 183 WebMTracksParser tracks_parser(log_cb_, ignore_text_tracks_, live_mode); |
176 result = tracks_parser.Parse(cur, cur_size); | 184 result = tracks_parser.Parse(cur, cur_size); |
177 | 185 |
178 if (result <= 0) | 186 if (result <= 0) |
179 return result; | 187 return result; |
180 | 188 |
181 bytes_parsed += result; | 189 bytes_parsed += result; |
182 | 190 |
183 double timecode_scale_in_us = info_parser.timecode_scale() / 1000.0; | 191 double timecode_scale_in_us = info_parser.timecode_scale() / 1000.0; |
184 base::TimeDelta duration = kInfiniteDuration(); | 192 base::TimeDelta duration = kInfiniteDuration(); |
185 | 193 |
(...skipping 10 matching lines...) Expand all Loading... |
196 if (video_config.is_encrypted()) | 204 if (video_config.is_encrypted()) |
197 FireNeedKey(tracks_parser.video_encryption_key_id()); | 205 FireNeedKey(tracks_parser.video_encryption_key_id()); |
198 | 206 |
199 if (!config_cb_.Run(audio_config, | 207 if (!config_cb_.Run(audio_config, |
200 video_config, | 208 video_config, |
201 tracks_parser.text_tracks())) { | 209 tracks_parser.text_tracks())) { |
202 DVLOG(1) << "New config data isn't allowed."; | 210 DVLOG(1) << "New config data isn't allowed."; |
203 return -1; | 211 return -1; |
204 } | 212 } |
205 | 213 |
206 | |
207 cluster_parser_.reset(new WebMClusterParser( | 214 cluster_parser_.reset(new WebMClusterParser( |
208 info_parser.timecode_scale(), | 215 info_parser.timecode_scale(), |
209 tracks_parser.audio_track_num(), | 216 tracks_parser.audio_track_num(), |
210 tracks_parser.GetAudioDefaultDuration(timecode_scale_in_us), | 217 tracks_parser.GetAudioDefaultDuration(timecode_scale_in_us), |
211 tracks_parser.video_track_num(), | 218 tracks_parser.video_track_num(), |
212 tracks_parser.GetVideoDefaultDuration(timecode_scale_in_us), | 219 tracks_parser.GetVideoDefaultDuration(timecode_scale_in_us), |
213 tracks_parser.text_tracks(), | 220 tracks_parser.text_tracks(), |
214 tracks_parser.ignored_tracks(), | 221 tracks_parser.ignored_tracks(), |
215 tracks_parser.audio_encryption_key_id(), | 222 tracks_parser.audio_encryption_key_id(), |
216 tracks_parser.video_encryption_key_id(), | 223 tracks_parser.video_encryption_key_id(), |
217 log_cb_)); | 224 log_cb_)); |
218 | 225 |
219 ChangeState(kParsingClusters); | 226 ChangeState(kParsingClusters); |
220 | 227 |
221 if (!init_cb_.is_null()) | 228 if (!init_cb_.is_null()) { |
222 base::ResetAndReturn(&init_cb_).Run( | 229 base::ResetAndReturn(&init_cb_).Run( |
223 true, duration, info_parser.date_utc(), false); | 230 true, duration, info_parser.date_utc(), false, live_mode); |
| 231 } |
224 | 232 |
225 return bytes_parsed; | 233 return bytes_parsed; |
226 } | 234 } |
227 | 235 |
228 int WebMStreamParser::ParseCluster(const uint8* data, int size) { | 236 int WebMStreamParser::ParseCluster(const uint8* data, int size) { |
229 if (!cluster_parser_) | 237 if (!cluster_parser_) |
230 return -1; | 238 return -1; |
231 | 239 |
232 int id; | 240 int id; |
233 int64 element_size; | 241 int64 element_size; |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
285 | 293 |
286 return bytes_parsed; | 294 return bytes_parsed; |
287 } | 295 } |
288 | 296 |
289 void WebMStreamParser::FireNeedKey(const std::string& key_id) { | 297 void WebMStreamParser::FireNeedKey(const std::string& key_id) { |
290 std::vector<uint8> key_id_vector(key_id.begin(), key_id.end()); | 298 std::vector<uint8> key_id_vector(key_id.begin(), key_id.end()); |
291 need_key_cb_.Run(kWebMEncryptInitDataType, key_id_vector); | 299 need_key_cb_.Run(kWebMEncryptInitDataType, key_id_vector); |
292 } | 300 } |
293 | 301 |
294 } // namespace media | 302 } // namespace media |
OLD | NEW |