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

Side by Side Diff: media/filters/chunk_demuxer.cc

Issue 195973006: Allow StreamParsers to request automatic timestampOffset updates. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 6 years, 9 months 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) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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/chunk_demuxer.h" 5 #include "media/filters/chunk_demuxer.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <limits> 8 #include <limits>
9 #include <list> 9 #include <list>
10 10
(...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after
170 // Called by the |stream_parser_| when new buffers have been parsed. 170 // Called by the |stream_parser_| when new buffers have been parsed.
171 // It processes the new buffers using |frame_processor_|, which includes 171 // It processes the new buffers using |frame_processor_|, which includes
172 // appending the processed frames to associated demuxer streams for each 172 // appending the processed frames to associated demuxer streams for each
173 // frame's track. 173 // frame's track.
174 // Returns true on a successful call. Returns false if an error occurred while 174 // Returns true on a successful call. Returns false if an error occurred while
175 // processing the buffers. 175 // processing the buffers.
176 bool OnNewBuffers(const StreamParser::BufferQueue& audio_buffers, 176 bool OnNewBuffers(const StreamParser::BufferQueue& audio_buffers,
177 const StreamParser::BufferQueue& video_buffers, 177 const StreamParser::BufferQueue& video_buffers,
178 const StreamParser::TextBufferQueueMap& text_map); 178 const StreamParser::TextBufferQueueMap& text_map);
179 179
180 void OnSourceInitDone(bool success,
181 TimeDelta duration,
182 bool auto_update_timestamp_offset);
183
180 CreateDemuxerStreamCB create_demuxer_stream_cb_; 184 CreateDemuxerStreamCB create_demuxer_stream_cb_;
181 NewTextTrackCB new_text_track_cb_; 185 NewTextTrackCB new_text_track_cb_;
182 186
183 // During Append(), if OnNewBuffers() coded frame processing updates the 187 // During Append(), if OnNewBuffers() coded frame processing updates the
184 // timestamp offset then |*timestamp_offset_during_append_| is also updated 188 // timestamp offset then |*timestamp_offset_during_append_| is also updated
185 // so Append()'s caller can know the new offset. This pointer is only non-NULL 189 // so Append()'s caller can know the new offset. This pointer is only non-NULL
186 // during the lifetime of an Append() call. 190 // during the lifetime of an Append() call.
187 TimeDelta* timestamp_offset_during_append_; 191 TimeDelta* timestamp_offset_during_append_;
188 192
189 // During Append(), coded frame processing triggered by OnNewBuffers() 193 // During Append(), coded frame processing triggered by OnNewBuffers()
(...skipping 19 matching lines...) Expand all
209 scoped_ptr<StreamParser> stream_parser_; 213 scoped_ptr<StreamParser> stream_parser_;
210 214
211 ChunkDemuxerStream* audio_; // Not owned by |this|. 215 ChunkDemuxerStream* audio_; // Not owned by |this|.
212 ChunkDemuxerStream* video_; // Not owned by |this|. 216 ChunkDemuxerStream* video_; // Not owned by |this|.
213 217
214 typedef std::map<StreamParser::TrackId, ChunkDemuxerStream*> TextStreamMap; 218 typedef std::map<StreamParser::TrackId, ChunkDemuxerStream*> TextStreamMap;
215 TextStreamMap text_stream_map_; // |this| owns the map's stream pointers. 219 TextStreamMap text_stream_map_; // |this| owns the map's stream pointers.
216 220
217 scoped_ptr<FrameProcessorBase> frame_processor_; 221 scoped_ptr<FrameProcessorBase> frame_processor_;
218 LogCB log_cb_; 222 LogCB log_cb_;
223 StreamParser::InitCB init_cb_;
224
225 // Indicates that timestampOffset should be updated automatically during
226 // OnNewBuffers() based on the earliest end timestamp of the buffers provided.
227 bool auto_update_timestamp_offset_;
219 228
220 DISALLOW_COPY_AND_ASSIGN(SourceState); 229 DISALLOW_COPY_AND_ASSIGN(SourceState);
221 }; 230 };
222 231
223 SourceState::SourceState( 232 SourceState::SourceState(
224 scoped_ptr<StreamParser> stream_parser, 233 scoped_ptr<StreamParser> stream_parser,
225 scoped_ptr<FrameProcessorBase> frame_processor, 234 scoped_ptr<FrameProcessorBase> frame_processor,
226 const LogCB& log_cb, 235 const LogCB& log_cb,
227 const CreateDemuxerStreamCB& create_demuxer_stream_cb) 236 const CreateDemuxerStreamCB& create_demuxer_stream_cb)
228 : create_demuxer_stream_cb_(create_demuxer_stream_cb), 237 : create_demuxer_stream_cb_(create_demuxer_stream_cb),
229 timestamp_offset_during_append_(NULL), 238 timestamp_offset_during_append_(NULL),
230 new_media_segment_(false), 239 new_media_segment_(false),
231 parsing_media_segment_(false), 240 parsing_media_segment_(false),
232 stream_parser_(stream_parser.release()), 241 stream_parser_(stream_parser.release()),
233 audio_(NULL), 242 audio_(NULL),
234 video_(NULL), 243 video_(NULL),
235 frame_processor_(frame_processor.release()), 244 frame_processor_(frame_processor.release()),
236 log_cb_(log_cb) { 245 log_cb_(log_cb),
246 auto_update_timestamp_offset_(false) {
237 DCHECK(!create_demuxer_stream_cb_.is_null()); 247 DCHECK(!create_demuxer_stream_cb_.is_null());
238 DCHECK(frame_processor_); 248 DCHECK(frame_processor_);
239 } 249 }
240 250
241 SourceState::~SourceState() { 251 SourceState::~SourceState() {
242 Shutdown(); 252 Shutdown();
243 253
244 STLDeleteValues(&text_stream_map_); 254 STLDeleteValues(&text_stream_map_);
245 } 255 }
246 256
247 void SourceState::Init(const StreamParser::InitCB& init_cb, 257 void SourceState::Init(const StreamParser::InitCB& init_cb,
248 bool allow_audio, 258 bool allow_audio,
249 bool allow_video, 259 bool allow_video,
250 const StreamParser::NeedKeyCB& need_key_cb, 260 const StreamParser::NeedKeyCB& need_key_cb,
251 const NewTextTrackCB& new_text_track_cb) { 261 const NewTextTrackCB& new_text_track_cb) {
252 new_text_track_cb_ = new_text_track_cb; 262 new_text_track_cb_ = new_text_track_cb;
263 init_cb_ = init_cb;
253 264
254 stream_parser_->Init(init_cb, 265 stream_parser_->Init(base::Bind(&SourceState::OnSourceInitDone,
266 base::Unretained(this)),
255 base::Bind(&SourceState::OnNewConfigs, 267 base::Bind(&SourceState::OnNewConfigs,
256 base::Unretained(this), 268 base::Unretained(this),
257 allow_audio, 269 allow_audio,
258 allow_video), 270 allow_video),
259 base::Bind(&SourceState::OnNewBuffers, 271 base::Bind(&SourceState::OnNewBuffers,
260 base::Unretained(this)), 272 base::Unretained(this)),
261 new_text_track_cb_.is_null(), 273 new_text_track_cb_.is_null(),
262 need_key_cb, 274 need_key_cb,
263 base::Bind(&SourceState::OnNewMediaSegment, 275 base::Bind(&SourceState::OnNewMediaSegment,
264 base::Unretained(this)), 276 base::Unretained(this)),
(...skipping 366 matching lines...) Expand 10 before | Expand all | Expand 10 after
631 new_media_segment_ = false; 643 new_media_segment_ = false;
632 } 644 }
633 645
634 bool SourceState::OnNewBuffers( 646 bool SourceState::OnNewBuffers(
635 const StreamParser::BufferQueue& audio_buffers, 647 const StreamParser::BufferQueue& audio_buffers,
636 const StreamParser::BufferQueue& video_buffers, 648 const StreamParser::BufferQueue& video_buffers,
637 const StreamParser::TextBufferQueueMap& text_map) { 649 const StreamParser::TextBufferQueueMap& text_map) {
638 DVLOG(2) << "OnNewBuffers()"; 650 DVLOG(2) << "OnNewBuffers()";
639 DCHECK(timestamp_offset_during_append_); 651 DCHECK(timestamp_offset_during_append_);
640 652
641 return frame_processor_->ProcessFrames( 653 const bool success =
642 audio_buffers, video_buffers, text_map, 654 frame_processor_->ProcessFrames(audio_buffers,
643 append_window_start_during_append_, append_window_end_during_append_, 655 video_buffers,
644 &new_media_segment_, timestamp_offset_during_append_); 656 text_map,
657 append_window_start_during_append_,
658 append_window_end_during_append_,
659 &new_media_segment_,
660 timestamp_offset_during_append_);
661
662 if (auto_update_timestamp_offset_) {
663 const bool have_video_buffers = !video_buffers.empty();
664 base::TimeDelta new_timestamp_offset =
acolwell GONE FROM CHROMIUM 2014/03/17 22:52:17 nit: Drop base:: since we've got a using directive
DaleCurtis 2014/03/18 00:14:02 Done.
665 have_video_buffers ? video_buffers.back()->timestamp() +
666 video_buffers.back()->duration()
667 : audio_buffers.back()->timestamp() +
acolwell GONE FROM CHROMIUM 2014/03/17 22:52:17 You need an empty guard here if we only happened t
DaleCurtis 2014/03/18 00:14:02 Reflowed to a multi-if statement + helper function
668 audio_buffers.back()->duration();
669 if (have_video_buffers && !audio_buffers.empty()) {
670 new_timestamp_offset = std::min(
671 new_timestamp_offset,
672 audio_buffers.back()->timestamp() + audio_buffers.back()->duration());
673 }
674
675 *timestamp_offset_during_append_ = new_timestamp_offset;
acolwell GONE FROM CHROMIUM 2014/03/17 22:52:17 You might need to snapshot *timestamp_offset_durin
DaleCurtis 2014/03/18 00:14:02 +wolenetz, what do you think? Probably we both sho
676 }
677
678 return success;
679 }
680
681 void SourceState::OnSourceInitDone(bool success,
682 TimeDelta duration,
683 bool auto_update_timestamp_offset) {
684 auto_update_timestamp_offset_ = auto_update_timestamp_offset;
685 init_cb_.Run(success, duration, auto_update_timestamp_offset);
645 } 686 }
646 687
647 ChunkDemuxerStream::ChunkDemuxerStream(Type type) 688 ChunkDemuxerStream::ChunkDemuxerStream(Type type)
648 : type_(type), 689 : type_(type),
649 state_(UNINITIALIZED) { 690 state_(UNINITIALIZED) {
650 } 691 }
651 692
652 void ChunkDemuxerStream::StartReturningData() { 693 void ChunkDemuxerStream::StartReturningData() {
653 DVLOG(1) << "ChunkDemuxerStream::StartReturningData()"; 694 DVLOG(1) << "ChunkDemuxerStream::StartReturningData()";
654 base::AutoLock auto_lock(lock_); 695 base::AutoLock auto_lock(lock_);
(...skipping 754 matching lines...) Expand 10 before | Expand all | Expand 10 after
1409 lock_.AssertAcquired(); 1450 lock_.AssertAcquired();
1410 for (SourceStateMap::const_iterator itr = source_state_map_.begin(); 1451 for (SourceStateMap::const_iterator itr = source_state_map_.begin();
1411 itr != source_state_map_.end(); ++itr) { 1452 itr != source_state_map_.end(); ++itr) {
1412 if (itr->second->IsSeekWaitingForData()) 1453 if (itr->second->IsSeekWaitingForData())
1413 return true; 1454 return true;
1414 } 1455 }
1415 1456
1416 return false; 1457 return false;
1417 } 1458 }
1418 1459
1419 void ChunkDemuxer::OnSourceInitDone(bool success, TimeDelta duration) { 1460 void ChunkDemuxer::OnSourceInitDone(bool success,
1420 DVLOG(1) << "OnSourceInitDone(" << success << ", " 1461 TimeDelta duration,
1421 << duration.InSecondsF() << ")"; 1462 bool auto_update_timestamp_offset) {
acolwell GONE FROM CHROMIUM 2014/03/17 22:52:17 nit: No need to expose this detail to ChunkDemuxer
DaleCurtis 2014/03/18 00:14:02 Done.
1463 DVLOG(1) << "OnSourceInitDone(" << success << ", " << duration.InSecondsF()
1464 << ", " << auto_update_timestamp_offset << ")";
1422 lock_.AssertAcquired(); 1465 lock_.AssertAcquired();
1423 DCHECK_EQ(state_, INITIALIZING); 1466 DCHECK_EQ(state_, INITIALIZING);
1424 if (!success || (!audio_ && !video_)) { 1467 if (!success || (!audio_ && !video_)) {
1425 ReportError_Locked(DEMUXER_ERROR_COULD_NOT_OPEN); 1468 ReportError_Locked(DEMUXER_ERROR_COULD_NOT_OPEN);
1426 return; 1469 return;
1427 } 1470 }
1428 1471
1429 if (duration != TimeDelta() && duration_ == kNoTimestamp()) 1472 if (duration != TimeDelta() && duration_ == kNoTimestamp())
1430 UpdateDuration(duration); 1473 UpdateDuration(duration);
1431 1474
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after
1573 } 1616 }
1574 1617
1575 void ChunkDemuxer::ShutdownAllStreams() { 1618 void ChunkDemuxer::ShutdownAllStreams() {
1576 for (SourceStateMap::iterator itr = source_state_map_.begin(); 1619 for (SourceStateMap::iterator itr = source_state_map_.begin();
1577 itr != source_state_map_.end(); ++itr) { 1620 itr != source_state_map_.end(); ++itr) {
1578 itr->second->Shutdown(); 1621 itr->second->Shutdown();
1579 } 1622 }
1580 } 1623 }
1581 1624
1582 } // namespace media 1625 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698