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

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

Issue 125543002: Add plumbing and support for crossfading StreamParserBuffers. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: ChunkDemuxerStream. Created 6 years, 11 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
« no previous file with comments | « media/base/stream_parser_buffer.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 <deque> 8 #include <deque>
9 #include <limits> 9 #include <limits>
10 #include <list> 10 #include <list>
(...skipping 283 matching lines...) Expand 10 before | Expand all | Expand 10 after
294 RETURNING_DATA_FOR_READS, 294 RETURNING_DATA_FOR_READS,
295 RETURNING_ABORT_FOR_READS, 295 RETURNING_ABORT_FOR_READS,
296 SHUTDOWN, 296 SHUTDOWN,
297 }; 297 };
298 298
299 // Assigns |state_| to |state| 299 // Assigns |state_| to |state|
300 void ChangeState_Locked(State state); 300 void ChangeState_Locked(State state);
301 301
302 void CompletePendingReadIfPossible_Locked(); 302 void CompletePendingReadIfPossible_Locked();
303 303
304 // Gets the value to pass to the next Read() callback. Returns true if 304 // Retrieves a new buffer from SourceBufferStream::GetNextBuffer() and handles
305 // |status| and |buffer| should be passed to the callback. False indicates 305 // splice frame buffers. For normal buffers, the status is simply passed
306 // that |status| and |buffer| were not set and more data is needed. 306 // through. Splice frame buffers will return kSuccess for buffer within the
307 bool GetNextBuffer_Locked(DemuxerStream::Status* status, 307 // crossfade along with a kConfigChange in between fade out and fade in.
308 scoped_refptr<StreamParserBuffer>* buffer); 308 SourceBufferStream::Status GetNextBuffer_Locked(
309 scoped_refptr<StreamParserBuffer>* buffer);
309 310
310 // Specifies the type of the stream. 311 // Specifies the type of the stream.
311 Type type_; 312 Type type_;
312 313
313 scoped_ptr<SourceBufferStream> stream_; 314 scoped_ptr<SourceBufferStream> stream_;
314 315
315 mutable base::Lock lock_; 316 mutable base::Lock lock_;
316 State state_; 317 State state_;
317 ReadCB read_cb_; 318 ReadCB read_cb_;
318 319
320 // Used by GetNextBuffer_Locked() when a buffer with fade out is returned from
321 // the SourceBufferStream. Will be set to the returned buffer and will be
322 // consumed after the fade out section has been exhausted.
323 scoped_refptr<StreamParserBuffer> fade_in_buffer_;
324
325 // Indicates which of the fade out preroll buffers in |fade_in_buffer_| should
326 // be handled out next.
327 size_t fade_out_preroll_index_;
328
319 DISALLOW_IMPLICIT_CONSTRUCTORS(ChunkDemuxerStream); 329 DISALLOW_IMPLICIT_CONSTRUCTORS(ChunkDemuxerStream);
320 }; 330 };
321 331
322 SourceState::SourceState(scoped_ptr<StreamParser> stream_parser, 332 SourceState::SourceState(scoped_ptr<StreamParser> stream_parser,
323 const LogCB& log_cb, 333 const LogCB& log_cb,
324 const CreateDemuxerStreamCB& create_demuxer_stream_cb, 334 const CreateDemuxerStreamCB& create_demuxer_stream_cb,
325 const IncreaseDurationCB& increase_duration_cb) 335 const IncreaseDurationCB& increase_duration_cb)
326 : create_demuxer_stream_cb_(create_demuxer_stream_cb), 336 : create_demuxer_stream_cb_(create_demuxer_stream_cb),
327 increase_duration_cb_(increase_duration_cb), 337 increase_duration_cb_(increase_duration_cb),
328 append_window_end_(kInfiniteDuration()), 338 append_window_end_(kInfiniteDuration()),
(...skipping 413 matching lines...) Expand 10 before | Expand all | Expand 10 after
742 752
743 *needs_keyframe = false; 753 *needs_keyframe = false;
744 } 754 }
745 755
746 filtered_buffers->push_back(*itr); 756 filtered_buffers->push_back(*itr);
747 } 757 }
748 } 758 }
749 759
750 ChunkDemuxerStream::ChunkDemuxerStream(Type type) 760 ChunkDemuxerStream::ChunkDemuxerStream(Type type)
751 : type_(type), 761 : type_(type),
752 state_(UNINITIALIZED) { 762 state_(UNINITIALIZED),
763 fade_out_preroll_index_(0) {
753 } 764 }
754 765
755 void ChunkDemuxerStream::StartReturningData() { 766 void ChunkDemuxerStream::StartReturningData() {
756 DVLOG(1) << "ChunkDemuxerStream::StartReturningData()"; 767 DVLOG(1) << "ChunkDemuxerStream::StartReturningData()";
757 base::AutoLock auto_lock(lock_); 768 base::AutoLock auto_lock(lock_);
758 DCHECK(read_cb_.is_null()); 769 DCHECK(read_cb_.is_null());
759 ChangeState_Locked(RETURNING_DATA_FOR_READS); 770 ChangeState_Locked(RETURNING_DATA_FOR_READS);
771 fade_in_buffer_ = NULL;
772 fade_out_preroll_index_ = 0;
760 } 773 }
761 774
762 void ChunkDemuxerStream::AbortReads() { 775 void ChunkDemuxerStream::AbortReads() {
763 DVLOG(1) << "ChunkDemuxerStream::AbortReads()"; 776 DVLOG(1) << "ChunkDemuxerStream::AbortReads()";
764 base::AutoLock auto_lock(lock_); 777 base::AutoLock auto_lock(lock_);
765 ChangeState_Locked(RETURNING_ABORT_FOR_READS); 778 ChangeState_Locked(RETURNING_ABORT_FOR_READS);
766 if (!read_cb_.is_null()) 779 if (!read_cb_.is_null())
767 base::ResetAndReturn(&read_cb_).Run(kAborted, NULL); 780 base::ResetAndReturn(&read_cb_).Run(kAborted, NULL);
768 } 781 }
769 782
(...skipping 190 matching lines...) Expand 10 before | Expand all | Expand 10 after
960 DCHECK(!read_cb_.is_null()); 973 DCHECK(!read_cb_.is_null());
961 974
962 DemuxerStream::Status status; 975 DemuxerStream::Status status;
963 scoped_refptr<StreamParserBuffer> buffer; 976 scoped_refptr<StreamParserBuffer> buffer;
964 977
965 switch (state_) { 978 switch (state_) {
966 case UNINITIALIZED: 979 case UNINITIALIZED:
967 NOTREACHED(); 980 NOTREACHED();
968 return; 981 return;
969 case RETURNING_DATA_FOR_READS: 982 case RETURNING_DATA_FOR_READS:
970 switch (stream_->GetNextBuffer(&buffer)) { 983 switch (GetNextBuffer_Locked(&buffer)) {
971 case SourceBufferStream::kSuccess: 984 case SourceBufferStream::kSuccess:
972 status = DemuxerStream::kOk; 985 status = DemuxerStream::kOk;
973 break; 986 break;
974 case SourceBufferStream::kNeedBuffer: 987 case SourceBufferStream::kNeedBuffer:
975 // Return early without calling |read_cb_| since we don't have 988 // Return early without calling |read_cb_| since we don't have
976 // any data to return yet. 989 // any data to return yet.
977 return; 990 return;
978 case SourceBufferStream::kEndOfStream: 991 case SourceBufferStream::kEndOfStream:
979 status = DemuxerStream::kOk; 992 status = DemuxerStream::kOk;
980 buffer = StreamParserBuffer::CreateEOSBuffer(); 993 buffer = StreamParserBuffer::CreateEOSBuffer();
(...skipping 14 matching lines...) Expand all
995 break; 1008 break;
996 case SHUTDOWN: 1009 case SHUTDOWN:
997 status = DemuxerStream::kOk; 1010 status = DemuxerStream::kOk;
998 buffer = StreamParserBuffer::CreateEOSBuffer(); 1011 buffer = StreamParserBuffer::CreateEOSBuffer();
999 break; 1012 break;
1000 } 1013 }
1001 1014
1002 base::ResetAndReturn(&read_cb_).Run(status, buffer); 1015 base::ResetAndReturn(&read_cb_).Run(status, buffer);
1003 } 1016 }
1004 1017
1018 SourceBufferStream::Status ChunkDemuxerStream::GetNextBuffer_Locked(
1019 scoped_refptr<StreamParserBuffer>* out_buffer) {
1020 lock_.AssertAcquired();
1021
1022 if (!fade_in_buffer_) {
1023 const SourceBufferStream::Status status =
1024 stream_->GetNextBuffer(out_buffer);
1025
1026 // Just return if GetNextBuffer() failed or there's no fade out preroll,
1027 // there's nothing else to do.
1028 if (status != SourceBufferStream::kSuccess ||
1029 (*out_buffer)->GetFadeOutPreroll().empty()) {
1030 return status;
1031 }
1032
1033 // Setup fade in buffer and fall through into splice frame buffer handling.
1034 fade_out_preroll_index_ = 0;
1035 fade_in_buffer_ = *out_buffer;
1036 }
1037
1038 DCHECK(fade_in_buffer_);
1039 const size_t fade_out_size = fade_in_buffer_->GetFadeOutPreroll().size();
1040
1041 // Are there any fade out buffers left to hand out?
1042 if (fade_out_preroll_index_ < fade_out_size) {
1043 *out_buffer =
acolwell GONE FROM CHROMIUM 2014/01/08 18:13:26 I think you need to be careful here because I beli
DaleCurtis 2014/01/08 18:45:55 Ah you're right on both counts. Crap; this will pr
DaleCurtis 2014/01/08 22:23:52 Actually, we could keep the code here if we extend
DaleCurtis 2014/01/08 23:00:38 Ahgh, an issue with this idea is when the next buf
1044 fade_in_buffer_->GetFadeOutPreroll()[fade_out_preroll_index_++];
1045 return SourceBufferStream::kSuccess;
1046 }
1047
1048 // Did we hand out the last fade out buffer on the last call?
1049 if (fade_out_preroll_index_ == fade_out_size) {
1050 fade_out_preroll_index_++;
1051 return SourceBufferStream::kConfigChange;
1052 }
1053
1054 // All fade out buffers have been handed out and a config change completed, so
1055 // hand out the final buffer for fade in.
1056 DCHECK_GT(fade_out_preroll_index_, fade_out_size);
1057 *out_buffer = fade_in_buffer_;
1058 fade_in_buffer_ = NULL;
1059 fade_out_preroll_index_ = 0;
1060 return SourceBufferStream::kSuccess;
1061 }
1062
1005 ChunkDemuxer::ChunkDemuxer(const base::Closure& open_cb, 1063 ChunkDemuxer::ChunkDemuxer(const base::Closure& open_cb,
1006 const NeedKeyCB& need_key_cb, 1064 const NeedKeyCB& need_key_cb,
1007 const LogCB& log_cb) 1065 const LogCB& log_cb)
1008 : state_(WAITING_FOR_INIT), 1066 : state_(WAITING_FOR_INIT),
1009 cancel_next_seek_(false), 1067 cancel_next_seek_(false),
1010 host_(NULL), 1068 host_(NULL),
1011 open_cb_(open_cb), 1069 open_cb_(open_cb),
1012 need_key_cb_(need_key_cb), 1070 need_key_cb_(need_key_cb),
1013 enable_text_(false), 1071 enable_text_(false),
1014 log_cb_(log_cb), 1072 log_cb_(log_cb),
(...skipping 651 matching lines...) Expand 10 before | Expand all | Expand 10 after
1666 } 1724 }
1667 1725
1668 void ChunkDemuxer::CompletePendingReadsIfPossible() { 1726 void ChunkDemuxer::CompletePendingReadsIfPossible() {
1669 for (SourceStateMap::iterator itr = source_state_map_.begin(); 1727 for (SourceStateMap::iterator itr = source_state_map_.begin();
1670 itr != source_state_map_.end(); ++itr) { 1728 itr != source_state_map_.end(); ++itr) {
1671 itr->second->CompletePendingReadIfPossible(); 1729 itr->second->CompletePendingReadIfPossible();
1672 } 1730 }
1673 } 1731 }
1674 1732
1675 } // namespace media 1733 } // namespace media
OLDNEW
« no previous file with comments | « media/base/stream_parser_buffer.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698