Chromium Code Reviews| 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 |