OLD | NEW |
---|---|
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 |
OLD | NEW |