| OLD | NEW |
| 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2013 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/video_frame_stream.h" | 5 #include "media/filters/video_frame_stream.h" |
| 6 | 6 |
| 7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/callback_helpers.h" | 8 #include "base/callback_helpers.h" |
| 9 #include "base/location.h" | 9 #include "base/location.h" |
| 10 #include "base/logging.h" | 10 #include "base/logging.h" |
| 11 #include "base/message_loop_proxy.h" | 11 #include "base/message_loop_proxy.h" |
| 12 #include "media/base/bind_to_loop.h" | 12 #include "media/base/bind_to_loop.h" |
| 13 #include "media/base/demuxer_stream.h" | 13 #include "media/base/demuxer_stream.h" |
| 14 #include "media/base/video_decoder_config.h" | 14 #include "media/base/video_decoder_config.h" |
| 15 #include "media/filters/decrypting_demuxer_stream.h" | 15 #include "media/filters/decrypting_demuxer_stream.h" |
| 16 #include "media/filters/video_decoder_selector.h" | 16 #include "media/filters/video_decoder_selector.h" |
| 17 | 17 |
| 18 namespace media { | 18 namespace media { |
| 19 | 19 |
| 20 VideoFrameStream::VideoFrameStream( | 20 VideoFrameStream::VideoFrameStream( |
| 21 const scoped_refptr<base::MessageLoopProxy>& message_loop, | 21 const scoped_refptr<base::MessageLoopProxy>& message_loop, |
| 22 ScopedVector<VideoDecoder> decoders, |
| 22 const SetDecryptorReadyCB& set_decryptor_ready_cb) | 23 const SetDecryptorReadyCB& set_decryptor_ready_cb) |
| 23 : message_loop_(message_loop), | 24 : message_loop_(message_loop), |
| 24 weak_factory_(this), | 25 weak_factory_(this), |
| 25 state_(UNINITIALIZED), | 26 state_(UNINITIALIZED), |
| 26 set_decryptor_ready_cb_(set_decryptor_ready_cb) { | 27 decoder_selector_( |
| 28 message_loop_, decoders.Pass(), set_decryptor_ready_cb) { |
| 27 } | 29 } |
| 28 | 30 |
| 29 VideoFrameStream::~VideoFrameStream() { | 31 VideoFrameStream::~VideoFrameStream() { |
| 30 DCHECK(state_ == UNINITIALIZED || state_ == STOPPED) << state_; | 32 DCHECK(state_ == UNINITIALIZED || state_ == STOPPED) << state_; |
| 31 } | 33 } |
| 32 | 34 |
| 33 void VideoFrameStream::Initialize(const scoped_refptr<DemuxerStream>& stream, | 35 void VideoFrameStream::Initialize(const scoped_refptr<DemuxerStream>& stream, |
| 34 const VideoDecoderList& decoders, | |
| 35 const StatisticsCB& statistics_cb, | 36 const StatisticsCB& statistics_cb, |
| 36 const InitCB& init_cb) { | 37 const InitCB& init_cb) { |
| 37 DCHECK(message_loop_->BelongsToCurrentThread()); | 38 DCHECK(message_loop_->BelongsToCurrentThread()); |
| 38 DCHECK_EQ(state_, UNINITIALIZED); | 39 DCHECK_EQ(state_, UNINITIALIZED); |
| 39 | 40 |
| 40 weak_this_ = weak_factory_.GetWeakPtr(); | 41 weak_this_ = weak_factory_.GetWeakPtr(); |
| 41 | 42 |
| 42 DCHECK(init_cb_.is_null()); | 43 DCHECK(init_cb_.is_null()); |
| 43 DCHECK(!init_cb.is_null()); | 44 DCHECK(!init_cb.is_null()); |
| 44 init_cb_ = init_cb; | 45 init_cb_ = init_cb; |
| 45 stream_ = stream; | 46 stream_ = stream; |
| 46 | 47 |
| 47 scoped_ptr<VideoDecoderSelector> decoder_selector( | 48 decoder_selector_.SelectVideoDecoder(this, statistics_cb, base::Bind( |
| 48 new VideoDecoderSelector(message_loop_, | 49 &VideoFrameStream::OnDecoderSelected, weak_this_)); |
| 49 decoders, | |
| 50 set_decryptor_ready_cb_)); | |
| 51 | |
| 52 // To avoid calling |decoder_selector| methods and passing ownership of | |
| 53 // |decoder_selector| in the same line. | |
| 54 VideoDecoderSelector* decoder_selector_ptr = decoder_selector.get(); | |
| 55 | |
| 56 decoder_selector_ptr->SelectVideoDecoder( | |
| 57 this, | |
| 58 statistics_cb, | |
| 59 base::Bind(&VideoFrameStream::OnDecoderSelected, weak_this_, | |
| 60 base::Passed(&decoder_selector))); | |
| 61 } | 50 } |
| 62 | 51 |
| 63 void VideoFrameStream::ReadFrame(const VideoDecoder::ReadCB& read_cb) { | 52 void VideoFrameStream::ReadFrame(const VideoDecoder::ReadCB& read_cb) { |
| 64 DCHECK(message_loop_->BelongsToCurrentThread()); | 53 DCHECK(message_loop_->BelongsToCurrentThread()); |
| 65 DCHECK_EQ(state_, NORMAL); | 54 DCHECK_EQ(state_, NORMAL); |
| 66 // No two reads in the flight at any time. | 55 // No two reads in the flight at any time. |
| 67 DCHECK(read_cb_.is_null()); | 56 DCHECK(read_cb_.is_null()); |
| 68 // No read during resetting or stopping process. | 57 // No read during resetting or stopping process. |
| 69 DCHECK(reset_cb_.is_null()); | 58 DCHECK(reset_cb_.is_null()); |
| 70 DCHECK(stop_cb_.is_null()); | 59 DCHECK(stop_cb_.is_null()); |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 121 StopDecoder(); | 110 StopDecoder(); |
| 122 return; | 111 return; |
| 123 } | 112 } |
| 124 | 113 |
| 125 state_ = STOPPED; | 114 state_ = STOPPED; |
| 126 // Break the ref-count loop so we don't leak objects. | 115 // Break the ref-count loop so we don't leak objects. |
| 127 // TODO(scherkus): Make DemuxerStream and/or VideoDecoder not ref-counted so | 116 // TODO(scherkus): Make DemuxerStream and/or VideoDecoder not ref-counted so |
| 128 // we don't need this here. See: http://crbug.com/173313 | 117 // we don't need this here. See: http://crbug.com/173313 |
| 129 stream_ = NULL; | 118 stream_ = NULL; |
| 130 decrypting_demuxer_stream_ = NULL; | 119 decrypting_demuxer_stream_ = NULL; |
| 131 decoder_ = NULL; | 120 decoder_.reset(); |
| 132 message_loop_->PostTask(FROM_HERE, base::ResetAndReturn(&stop_cb_)); | 121 message_loop_->PostTask(FROM_HERE, base::ResetAndReturn(&stop_cb_)); |
| 133 } | 122 } |
| 134 | 123 |
| 135 bool VideoFrameStream::HasOutputFrameAvailable() const { | 124 bool VideoFrameStream::HasOutputFrameAvailable() const { |
| 136 DCHECK(message_loop_->BelongsToCurrentThread()); | 125 DCHECK(message_loop_->BelongsToCurrentThread()); |
| 137 return decoder_->HasOutputFrameAvailable(); | 126 return decoder_->HasOutputFrameAvailable(); |
| 138 } | 127 } |
| 139 | 128 |
| 140 void VideoFrameStream::Read(const ReadCB& read_cb) { | 129 void VideoFrameStream::Read(const ReadCB& read_cb) { |
| 141 DCHECK(message_loop_->BelongsToCurrentThread()); | 130 DCHECK(message_loop_->BelongsToCurrentThread()); |
| (...skipping 15 matching lines...) Expand all Loading... |
| 157 DCHECK(message_loop_->BelongsToCurrentThread()); | 146 DCHECK(message_loop_->BelongsToCurrentThread()); |
| 158 return VIDEO; | 147 return VIDEO; |
| 159 } | 148 } |
| 160 | 149 |
| 161 void VideoFrameStream::EnableBitstreamConverter() { | 150 void VideoFrameStream::EnableBitstreamConverter() { |
| 162 DCHECK(message_loop_->BelongsToCurrentThread()); | 151 DCHECK(message_loop_->BelongsToCurrentThread()); |
| 163 stream_->EnableBitstreamConverter(); | 152 stream_->EnableBitstreamConverter(); |
| 164 } | 153 } |
| 165 | 154 |
| 166 void VideoFrameStream::OnDecoderSelected( | 155 void VideoFrameStream::OnDecoderSelected( |
| 167 scoped_ptr<VideoDecoderSelector> decoder_selector, | 156 scoped_ptr<VideoDecoder> selected_decoder, |
| 168 const scoped_refptr<VideoDecoder>& selected_decoder, | |
| 169 const scoped_refptr<DecryptingDemuxerStream>& decrypting_demuxer_stream) { | 157 const scoped_refptr<DecryptingDemuxerStream>& decrypting_demuxer_stream) { |
| 170 DCHECK(message_loop_->BelongsToCurrentThread()); | 158 DCHECK(message_loop_->BelongsToCurrentThread()); |
| 171 DCHECK_EQ(state_, UNINITIALIZED); | 159 DCHECK_EQ(state_, UNINITIALIZED); |
| 172 DCHECK(!init_cb_.is_null()); | 160 DCHECK(!init_cb_.is_null()); |
| 173 | 161 |
| 174 if (!selected_decoder) { | 162 if (!selected_decoder) { |
| 175 state_ = UNINITIALIZED; | 163 state_ = UNINITIALIZED; |
| 176 base::ResetAndReturn(&init_cb_).Run(false, false); | 164 base::ResetAndReturn(&init_cb_).Run(false, false); |
| 177 } else { | 165 } else { |
| 178 decoder_ = selected_decoder; | 166 decoder_ = selected_decoder.Pass(); |
| 179 decrypting_demuxer_stream_ = decrypting_demuxer_stream; | 167 decrypting_demuxer_stream_ = decrypting_demuxer_stream; |
| 180 state_ = NORMAL; | 168 state_ = NORMAL; |
| 181 base::ResetAndReturn(&init_cb_).Run(true, decoder_->HasAlpha()); | 169 base::ResetAndReturn(&init_cb_).Run(true, decoder_->HasAlpha()); |
| 182 } | 170 } |
| 183 | 171 |
| 184 // Stop() called during initialization. | 172 // Stop() called during initialization. |
| 185 if (!stop_cb_.is_null()) { | 173 if (!stop_cb_.is_null()) { |
| 186 Stop(base::ResetAndReturn(&stop_cb_)); | 174 Stop(base::ResetAndReturn(&stop_cb_)); |
| 187 return; | 175 return; |
| 188 } | 176 } |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 232 DCHECK(read_cb_.is_null()); | 220 DCHECK(read_cb_.is_null()); |
| 233 DCHECK(reset_cb_.is_null()); | 221 DCHECK(reset_cb_.is_null()); |
| 234 DCHECK(!stop_cb_.is_null()); | 222 DCHECK(!stop_cb_.is_null()); |
| 235 | 223 |
| 236 state_ = STOPPED; | 224 state_ = STOPPED; |
| 237 // Break the ref-count loop so we don't leak objects. | 225 // Break the ref-count loop so we don't leak objects. |
| 238 // TODO(scherkus): Make DemuxerStream and/or VideoDecoder not ref-counted so | 226 // TODO(scherkus): Make DemuxerStream and/or VideoDecoder not ref-counted so |
| 239 // we don't need this here. See: http://crbug.com/173313 | 227 // we don't need this here. See: http://crbug.com/173313 |
| 240 stream_ = NULL; | 228 stream_ = NULL; |
| 241 decrypting_demuxer_stream_ = NULL; | 229 decrypting_demuxer_stream_ = NULL; |
| 242 decoder_ = NULL; | 230 decoder_.reset(); |
| 243 base::ResetAndReturn(&stop_cb_).Run(); | 231 base::ResetAndReturn(&stop_cb_).Run(); |
| 244 } | 232 } |
| 245 | 233 |
| 246 } // namespace media | 234 } // namespace media |
| OLD | NEW |