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/filters/frame_processor.h" | 5 #include "media/filters/frame_processor.h" |
6 | 6 |
7 #include <stdint.h> | 7 #include <stdint.h> |
8 | 8 |
9 #include <cstdlib> | 9 #include <cstdlib> |
10 | 10 |
11 #include "base/macros.h" | 11 #include "base/macros.h" |
12 #include "base/stl_util.h" | 12 #include "base/memory/ptr_util.h" |
13 #include "media/base/stream_parser_buffer.h" | 13 #include "media/base/stream_parser_buffer.h" |
14 #include "media/base/timestamp_constants.h" | 14 #include "media/base/timestamp_constants.h" |
15 | 15 |
16 namespace media { | 16 namespace media { |
17 | 17 |
18 const int kMaxDroppedPrerollWarnings = 10; | 18 const int kMaxDroppedPrerollWarnings = 10; |
19 const int kMaxDtsBeyondPtsWarnings = 10; | 19 const int kMaxDtsBeyondPtsWarnings = 10; |
20 | 20 |
21 // Helper class to capture per-track details needed by a frame processor. Some | 21 // Helper class to capture per-track details needed by a frame processor. Some |
22 // of this information may be duplicated in the short-term in the associated | 22 // of this information may be duplicated in the short-term in the associated |
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
165 const scoped_refptr<MediaLog>& media_log) | 165 const scoped_refptr<MediaLog>& media_log) |
166 : group_start_timestamp_(kNoTimestamp), | 166 : group_start_timestamp_(kNoTimestamp), |
167 update_duration_cb_(update_duration_cb), | 167 update_duration_cb_(update_duration_cb), |
168 media_log_(media_log) { | 168 media_log_(media_log) { |
169 DVLOG(2) << __func__ << "()"; | 169 DVLOG(2) << __func__ << "()"; |
170 DCHECK(!update_duration_cb.is_null()); | 170 DCHECK(!update_duration_cb.is_null()); |
171 } | 171 } |
172 | 172 |
173 FrameProcessor::~FrameProcessor() { | 173 FrameProcessor::~FrameProcessor() { |
174 DVLOG(2) << __func__ << "()"; | 174 DVLOG(2) << __func__ << "()"; |
175 base::STLDeleteValues(&track_buffers_); | |
176 } | 175 } |
177 | 176 |
178 void FrameProcessor::SetSequenceMode(bool sequence_mode) { | 177 void FrameProcessor::SetSequenceMode(bool sequence_mode) { |
179 DVLOG(2) << __func__ << "(" << sequence_mode << ")"; | 178 DVLOG(2) << __func__ << "(" << sequence_mode << ")"; |
180 // Per June 9, 2016 MSE spec editor's draft: | 179 // Per June 9, 2016 MSE spec editor's draft: |
181 // https://rawgit.com/w3c/media-source/d8f901f22/ | 180 // https://rawgit.com/w3c/media-source/d8f901f22/ |
182 // index.html#widl-SourceBuffer-mode | 181 // index.html#widl-SourceBuffer-mode |
183 // Step 7: If the new mode equals "sequence", then set the group start | 182 // Step 7: If the new mode equals "sequence", then set the group start |
184 // timestamp to the group end timestamp. | 183 // timestamp to the group end timestamp. |
185 if (sequence_mode) { | 184 if (sequence_mode) { |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
253 DVLOG(2) << __func__ << "(): id=" << id; | 252 DVLOG(2) << __func__ << "(): id=" << id; |
254 | 253 |
255 MseTrackBuffer* existing_track = FindTrack(id); | 254 MseTrackBuffer* existing_track = FindTrack(id); |
256 DCHECK(!existing_track); | 255 DCHECK(!existing_track); |
257 if (existing_track) { | 256 if (existing_track) { |
258 MEDIA_LOG(ERROR, media_log_) << "Failure adding track with duplicate ID " | 257 MEDIA_LOG(ERROR, media_log_) << "Failure adding track with duplicate ID " |
259 << id; | 258 << id; |
260 return false; | 259 return false; |
261 } | 260 } |
262 | 261 |
263 track_buffers_[id] = new MseTrackBuffer(stream); | 262 track_buffers_[id] = base::MakeUnique<MseTrackBuffer>(stream); |
264 return true; | 263 return true; |
265 } | 264 } |
266 | 265 |
267 bool FrameProcessor::UpdateTrack(StreamParser::TrackId old_id, | 266 bool FrameProcessor::UpdateTrack(StreamParser::TrackId old_id, |
268 StreamParser::TrackId new_id) { | 267 StreamParser::TrackId new_id) { |
269 DVLOG(2) << __func__ << "() : old_id=" << old_id << ", new_id=" << new_id; | 268 DVLOG(2) << __func__ << "() : old_id=" << old_id << ", new_id=" << new_id; |
270 | 269 |
271 if (old_id == new_id || !FindTrack(old_id) || FindTrack(new_id)) { | 270 if (old_id == new_id || !FindTrack(old_id) || FindTrack(new_id)) { |
272 MEDIA_LOG(ERROR, media_log_) << "Failure updating track id from " << old_id | 271 MEDIA_LOG(ERROR, media_log_) << "Failure updating track id from " << old_id |
273 << " to " << new_id; | 272 << " to " << new_id; |
274 return false; | 273 return false; |
275 } | 274 } |
276 | 275 |
277 track_buffers_[new_id] = track_buffers_[old_id]; | 276 track_buffers_[new_id] = std::move(track_buffers_[old_id]); |
278 CHECK_EQ(1u, track_buffers_.erase(old_id)); | 277 CHECK_EQ(1u, track_buffers_.erase(old_id)); |
279 return true; | 278 return true; |
280 } | 279 } |
281 | 280 |
282 void FrameProcessor::SetAllTrackBuffersNeedRandomAccessPoint() { | 281 void FrameProcessor::SetAllTrackBuffersNeedRandomAccessPoint() { |
283 for (TrackBufferMap::iterator itr = track_buffers_.begin(); | 282 for (auto itr = track_buffers_.begin(); itr != track_buffers_.end(); ++itr) { |
284 itr != track_buffers_.end(); | |
285 ++itr) { | |
286 itr->second->set_needs_random_access_point(true); | 283 itr->second->set_needs_random_access_point(true); |
287 } | 284 } |
288 } | 285 } |
289 | 286 |
290 void FrameProcessor::Reset() { | 287 void FrameProcessor::Reset() { |
291 DVLOG(2) << __func__ << "()"; | 288 DVLOG(2) << __func__ << "()"; |
292 for (TrackBufferMap::iterator itr = track_buffers_.begin(); | 289 for (auto itr = track_buffers_.begin(); itr != track_buffers_.end(); ++itr) { |
293 itr != track_buffers_.end(); ++itr) { | |
294 itr->second->Reset(); | 290 itr->second->Reset(); |
295 } | 291 } |
296 | 292 |
297 // Maintain current |coded_frame_group_last_dts_| state for Reset() during | 293 // Maintain current |coded_frame_group_last_dts_| state for Reset() during |
298 // sequence mode. Reset it here only if in segments mode. In sequence mode, | 294 // sequence mode. Reset it here only if in segments mode. In sequence mode, |
299 // the current coded frame group may be continued across Reset() operations to | 295 // the current coded frame group may be continued across Reset() operations to |
300 // allow the stream to coaelesce what might otherwise be gaps in the buffered | 296 // allow the stream to coalesce what might otherwise be gaps in the buffered |
301 // ranges. See also the declaration for |coded_frame_group_last_dts_|. | 297 // ranges. See also the declaration for |coded_frame_group_last_dts_|. |
302 if (!sequence_mode_) { | 298 if (!sequence_mode_) { |
303 coded_frame_group_last_dts_ = kNoDecodeTimestamp(); | 299 coded_frame_group_last_dts_ = kNoDecodeTimestamp(); |
304 return; | 300 return; |
305 } | 301 } |
306 | 302 |
307 // Sequence mode | 303 // Sequence mode |
308 DCHECK(kNoTimestamp != group_end_timestamp_); | 304 DCHECK(kNoTimestamp != group_end_timestamp_); |
309 group_start_timestamp_ = group_end_timestamp_; | 305 group_start_timestamp_ = group_end_timestamp_; |
310 } | 306 } |
311 | 307 |
312 void FrameProcessor::OnPossibleAudioConfigUpdate( | 308 void FrameProcessor::OnPossibleAudioConfigUpdate( |
313 const AudioDecoderConfig& config) { | 309 const AudioDecoderConfig& config) { |
314 DCHECK(config.IsValidConfig()); | 310 DCHECK(config.IsValidConfig()); |
315 | 311 |
316 // Always clear the preroll buffer when a config update is received. | 312 // Always clear the preroll buffer when a config update is received. |
317 audio_preroll_buffer_ = NULL; | 313 audio_preroll_buffer_ = NULL; |
318 | 314 |
319 if (config.Matches(current_audio_config_)) | 315 if (config.Matches(current_audio_config_)) |
320 return; | 316 return; |
321 | 317 |
322 current_audio_config_ = config; | 318 current_audio_config_ = config; |
323 sample_duration_ = base::TimeDelta::FromSecondsD( | 319 sample_duration_ = base::TimeDelta::FromSecondsD( |
324 1.0 / current_audio_config_.samples_per_second()); | 320 1.0 / current_audio_config_.samples_per_second()); |
325 } | 321 } |
326 | 322 |
327 MseTrackBuffer* FrameProcessor::FindTrack(StreamParser::TrackId id) { | 323 MseTrackBuffer* FrameProcessor::FindTrack(StreamParser::TrackId id) { |
328 TrackBufferMap::iterator itr = track_buffers_.find(id); | 324 auto itr = track_buffers_.find(id); |
329 if (itr == track_buffers_.end()) | 325 if (itr == track_buffers_.end()) |
330 return NULL; | 326 return NULL; |
331 | 327 |
332 return itr->second; | 328 return itr->second.get(); |
333 } | 329 } |
334 | 330 |
335 void FrameProcessor::NotifyStartOfCodedFrameGroup( | 331 void FrameProcessor::NotifyStartOfCodedFrameGroup( |
336 DecodeTimestamp start_timestamp) { | 332 DecodeTimestamp start_timestamp) { |
337 DVLOG(2) << __func__ << "(" << start_timestamp.InSecondsF() << ")"; | 333 DVLOG(2) << __func__ << "(" << start_timestamp.InSecondsF() << ")"; |
338 | 334 |
339 for (TrackBufferMap::iterator itr = track_buffers_.begin(); | 335 for (auto itr = track_buffers_.begin(); itr != track_buffers_.end(); ++itr) { |
340 itr != track_buffers_.end(); | |
341 ++itr) { | |
342 itr->second->stream()->OnStartOfCodedFrameGroup(start_timestamp); | 336 itr->second->stream()->OnStartOfCodedFrameGroup(start_timestamp); |
343 } | 337 } |
344 } | 338 } |
345 | 339 |
346 bool FrameProcessor::FlushProcessedFrames() { | 340 bool FrameProcessor::FlushProcessedFrames() { |
347 DVLOG(2) << __func__ << "()"; | 341 DVLOG(2) << __func__ << "()"; |
348 | 342 |
349 bool result = true; | 343 bool result = true; |
350 for (TrackBufferMap::iterator itr = track_buffers_.begin(); | 344 for (auto itr = track_buffers_.begin(); itr != track_buffers_.end(); ++itr) { |
351 itr != track_buffers_.end(); | |
352 ++itr) { | |
353 if (!itr->second->FlushProcessedFrames()) | 345 if (!itr->second->FlushProcessedFrames()) |
354 result = false; | 346 result = false; |
355 } | 347 } |
356 | 348 |
357 return result; | 349 return result; |
358 } | 350 } |
359 | 351 |
360 bool FrameProcessor::HandlePartialAppendWindowTrimming( | 352 bool FrameProcessor::HandlePartialAppendWindowTrimming( |
361 base::TimeDelta append_window_start, | 353 base::TimeDelta append_window_start, |
362 base::TimeDelta append_window_end, | 354 base::TimeDelta append_window_end, |
(...skipping 383 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
746 // Step 21 is currently handled differently. See MediaSourceState's | 738 // Step 21 is currently handled differently. See MediaSourceState's |
747 // |auto_update_timestamp_offset_|. | 739 // |auto_update_timestamp_offset_|. |
748 return true; | 740 return true; |
749 } | 741 } |
750 | 742 |
751 NOTREACHED(); | 743 NOTREACHED(); |
752 return false; | 744 return false; |
753 } | 745 } |
754 | 746 |
755 } // namespace media | 747 } // namespace media |
OLD | NEW |