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" |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
47 statistics_cb_ = statistics_cb; | 47 statistics_cb_ = statistics_cb; |
48 init_cb_ = init_cb; | 48 init_cb_ = init_cb; |
49 stream_ = stream; | 49 stream_ = stream; |
50 | 50 |
51 state_ = STATE_INITIALIZING; | 51 state_ = STATE_INITIALIZING; |
52 // TODO(xhwang): VideoDecoderSelector only needs a config to select a decoder. | 52 // TODO(xhwang): VideoDecoderSelector only needs a config to select a decoder. |
53 decoder_selector_->SelectVideoDecoder( | 53 decoder_selector_->SelectVideoDecoder( |
54 stream, base::Bind(&VideoFrameStream::OnDecoderSelected, weak_this_)); | 54 stream, base::Bind(&VideoFrameStream::OnDecoderSelected, weak_this_)); |
55 } | 55 } |
56 | 56 |
57 void VideoFrameStream::Read(const VideoDecoder::ReadCB& read_cb) { | 57 void VideoFrameStream::Read(const ReadCB& read_cb) { |
58 DCHECK(message_loop_->BelongsToCurrentThread()); | 58 DCHECK(message_loop_->BelongsToCurrentThread()); |
59 DCHECK(state_ == STATE_NORMAL || state_ == STATE_FLUSHING_DECODER || | 59 DCHECK(state_ == STATE_NORMAL || state_ == STATE_FLUSHING_DECODER || |
60 state_ == STATE_ERROR) << state_; | 60 state_ == STATE_ERROR) << state_; |
61 // No two reads in the flight at any time. | 61 // No two reads in the flight at any time. |
62 DCHECK(read_cb_.is_null()); | 62 DCHECK(read_cb_.is_null()); |
63 // No read during resetting or stopping process. | 63 // No read during resetting or stopping process. |
64 DCHECK(reset_cb_.is_null()); | 64 DCHECK(reset_cb_.is_null()); |
65 DCHECK(stop_cb_.is_null()); | 65 DCHECK(stop_cb_.is_null()); |
66 | 66 |
67 if (state_ == STATE_ERROR) { | 67 if (state_ == STATE_ERROR) { |
68 message_loop_->PostTask(FROM_HERE, base::Bind( | 68 message_loop_->PostTask(FROM_HERE, base::Bind( |
69 read_cb, VideoDecoder::kDecodeError, scoped_refptr<VideoFrame>())); | 69 read_cb, DECODE_ERROR, scoped_refptr<VideoFrame>())); |
70 return; | 70 return; |
71 } | 71 } |
72 | 72 |
73 read_cb_ = read_cb; | 73 read_cb_ = read_cb; |
74 | 74 |
75 if (state_ == STATE_FLUSHING_DECODER) { | 75 if (state_ == STATE_FLUSHING_DECODER) { |
76 FlushDecoder(); | 76 FlushDecoder(); |
77 return; | 77 return; |
78 } | 78 } |
79 | 79 |
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
181 base::ResetAndReturn(&init_cb_).Run(true, decoder_->HasAlpha()); | 181 base::ResetAndReturn(&init_cb_).Run(true, decoder_->HasAlpha()); |
182 } | 182 } |
183 | 183 |
184 // Stop() called during initialization. | 184 // Stop() called during initialization. |
185 if (!stop_cb_.is_null()) { | 185 if (!stop_cb_.is_null()) { |
186 Stop(base::ResetAndReturn(&stop_cb_)); | 186 Stop(base::ResetAndReturn(&stop_cb_)); |
187 return; | 187 return; |
188 } | 188 } |
189 } | 189 } |
190 | 190 |
191 void VideoFrameStream::SatisfyRead(VideoDecoder::Status status, | 191 void VideoFrameStream::SatisfyRead(Status status, |
192 const scoped_refptr<VideoFrame>& frame) { | 192 const scoped_refptr<VideoFrame>& frame) { |
193 DCHECK(!read_cb_.is_null()); | 193 DCHECK(!read_cb_.is_null()); |
194 base::ResetAndReturn(&read_cb_).Run(status, frame); | 194 base::ResetAndReturn(&read_cb_).Run(status, frame); |
195 } | 195 } |
196 | 196 |
197 void VideoFrameStream::AbortRead() { | 197 void VideoFrameStream::AbortRead() { |
198 SatisfyRead(VideoDecoder::kOk, NULL); | 198 SatisfyRead(ABORTED, NULL); |
199 } | 199 } |
200 | 200 |
201 void VideoFrameStream::Decode(const scoped_refptr<DecoderBuffer>& buffer) { | 201 void VideoFrameStream::Decode(const scoped_refptr<DecoderBuffer>& buffer) { |
202 DCHECK(state_ == STATE_NORMAL || state_ == STATE_FLUSHING_DECODER) << state_; | 202 DCHECK(state_ == STATE_NORMAL || state_ == STATE_FLUSHING_DECODER) << state_; |
203 DCHECK(!read_cb_.is_null()); | 203 DCHECK(!read_cb_.is_null()); |
204 DCHECK(reset_cb_.is_null()); | 204 DCHECK(reset_cb_.is_null()); |
205 DCHECK(stop_cb_.is_null()); | 205 DCHECK(stop_cb_.is_null()); |
206 DCHECK(buffer); | 206 DCHECK(buffer); |
207 | 207 |
208 int buffer_size = buffer->end_of_stream() ? 0 : buffer->data_size(); | 208 int buffer_size = buffer->end_of_stream() ? 0 : buffer->data_size(); |
209 decoder_->Decode(buffer, base::Bind(&VideoFrameStream::OnFrameReady, | 209 decoder_->Decode(buffer, base::Bind(&VideoFrameStream::OnFrameReady, |
210 weak_this_, buffer_size)); | 210 weak_this_, buffer_size)); |
211 } | 211 } |
212 | 212 |
213 void VideoFrameStream::FlushDecoder() { | 213 void VideoFrameStream::FlushDecoder() { |
214 Decode(DecoderBuffer::CreateEOSBuffer()); | 214 Decode(DecoderBuffer::CreateEOSBuffer()); |
215 } | 215 } |
216 | 216 |
217 void VideoFrameStream::OnFrameReady(int buffer_size, | 217 void VideoFrameStream::OnFrameReady(int buffer_size, |
218 const VideoDecoder::Status status, | 218 const VideoDecoder::Status status, |
219 const scoped_refptr<VideoFrame>& frame) { | 219 const scoped_refptr<VideoFrame>& frame) { |
220 DCHECK(state_ == STATE_NORMAL || state_ == STATE_FLUSHING_DECODER) << state_; | 220 DCHECK(state_ == STATE_NORMAL || state_ == STATE_FLUSHING_DECODER) << state_; |
221 DCHECK(!read_cb_.is_null()); | 221 DCHECK(!read_cb_.is_null()); |
222 | 222 |
223 if (status == VideoDecoder::kDecodeError || | 223 if (status == VideoDecoder::kDecodeError) { |
224 status == VideoDecoder::kDecryptError) { | |
225 DCHECK(!frame.get()); | 224 DCHECK(!frame.get()); |
226 state_ = STATE_ERROR; | 225 state_ = STATE_ERROR; |
227 SatisfyRead(status, NULL); | 226 SatisfyRead(DECODE_ERROR, NULL); |
228 return; | 227 return; |
229 } | 228 } |
230 | 229 |
| 230 if (status == VideoDecoder::kDecryptError) { |
| 231 DCHECK(!frame.get()); |
| 232 state_ = STATE_ERROR; |
| 233 SatisfyRead(DECRYPT_ERROR, NULL); |
| 234 return; |
| 235 } |
| 236 |
231 // Any successful decode counts! | 237 // Any successful decode counts! |
232 if (buffer_size > 0) { | 238 if (buffer_size > 0) { |
233 PipelineStatistics statistics; | 239 PipelineStatistics statistics; |
234 statistics.video_bytes_decoded = buffer_size; | 240 statistics.video_bytes_decoded = buffer_size; |
235 statistics_cb_.Run(statistics); | 241 statistics_cb_.Run(statistics); |
236 } | 242 } |
237 | 243 |
238 // Drop decoding result if Reset()/Stop() was called during decoding. | 244 // Drop decoding result if Reset()/Stop() was called during decoding. |
239 // The stopping/resetting process will be handled when the decoder is | 245 // The stopping/resetting process will be handled when the decoder is |
240 // stopped/reset. | 246 // stopped/reset. |
(...skipping 10 matching lines...) Expand all Loading... |
251 } | 257 } |
252 | 258 |
253 if (status == VideoDecoder::kNotEnoughData) { | 259 if (status == VideoDecoder::kNotEnoughData) { |
254 if (state_ == STATE_NORMAL) | 260 if (state_ == STATE_NORMAL) |
255 ReadFromDemuxerStream(); | 261 ReadFromDemuxerStream(); |
256 else if (state_ == STATE_FLUSHING_DECODER) | 262 else if (state_ == STATE_FLUSHING_DECODER) |
257 FlushDecoder(); | 263 FlushDecoder(); |
258 return; | 264 return; |
259 } | 265 } |
260 | 266 |
261 SatisfyRead(status, frame); | 267 SatisfyRead(OK, frame); |
262 } | 268 } |
263 | 269 |
264 void VideoFrameStream::ReadFromDemuxerStream() { | 270 void VideoFrameStream::ReadFromDemuxerStream() { |
265 DCHECK_EQ(state_, STATE_NORMAL) << state_; | 271 DCHECK_EQ(state_, STATE_NORMAL) << state_; |
266 DCHECK(!read_cb_.is_null()); | 272 DCHECK(!read_cb_.is_null()); |
267 DCHECK(reset_cb_.is_null()); | 273 DCHECK(reset_cb_.is_null()); |
268 DCHECK(stop_cb_.is_null()); | 274 DCHECK(stop_cb_.is_null()); |
269 | 275 |
270 state_ = STATE_PENDING_DEMUXER_READ; | 276 state_ = STATE_PENDING_DEMUXER_READ; |
271 stream_->Read(base::Bind(&VideoFrameStream::OnBufferReady, weak_this_)); | 277 stream_->Read(base::Bind(&VideoFrameStream::OnBufferReady, weak_this_)); |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
304 return; | 310 return; |
305 } | 311 } |
306 | 312 |
307 if (!reset_cb_.is_null()) { | 313 if (!reset_cb_.is_null()) { |
308 AbortRead(); | 314 AbortRead(); |
309 Reset(base::ResetAndReturn(&reset_cb_)); | 315 Reset(base::ResetAndReturn(&reset_cb_)); |
310 return; | 316 return; |
311 } | 317 } |
312 | 318 |
313 if (status == DemuxerStream::kAborted) { | 319 if (status == DemuxerStream::kAborted) { |
314 AbortRead(); | 320 SatisfyRead(DEMUXER_READ_ABORTED, NULL); |
315 return; | 321 return; |
316 } | 322 } |
317 | 323 |
318 DCHECK(status == DemuxerStream::kOk) << status; | 324 DCHECK(status == DemuxerStream::kOk) << status; |
319 Decode(buffer); | 325 Decode(buffer); |
320 } | 326 } |
321 | 327 |
322 void VideoFrameStream::ReinitializeDecoder() { | 328 void VideoFrameStream::ReinitializeDecoder() { |
323 DCHECK(message_loop_->BelongsToCurrentThread()); | 329 DCHECK(message_loop_->BelongsToCurrentThread()); |
324 DCHECK_EQ(state_, STATE_FLUSHING_DECODER) << state_; | 330 DCHECK_EQ(state_, STATE_FLUSHING_DECODER) << state_; |
(...skipping 22 matching lines...) Expand all Loading... |
347 | 353 |
348 if (!reset_cb_.is_null()) | 354 if (!reset_cb_.is_null()) |
349 base::ResetAndReturn(&reset_cb_).Run(); | 355 base::ResetAndReturn(&reset_cb_).Run(); |
350 | 356 |
351 // If !stop_cb_.is_null(), it will be handled in OnDecoderStopped(). | 357 // If !stop_cb_.is_null(), it will be handled in OnDecoderStopped(). |
352 | 358 |
353 if (read_cb_.is_null()) | 359 if (read_cb_.is_null()) |
354 return; | 360 return; |
355 | 361 |
356 if (!stop_cb_.is_null()) { | 362 if (!stop_cb_.is_null()) { |
357 base::ResetAndReturn(&read_cb_).Run(VideoDecoder::kOk, NULL); | 363 base::ResetAndReturn(&read_cb_).Run(ABORTED, NULL); |
358 return; | 364 return; |
359 } | 365 } |
360 | 366 |
361 if (state_ == STATE_ERROR) { | 367 if (state_ == STATE_ERROR) { |
362 SatisfyRead(VideoDecoder::kDecodeError, NULL); | 368 SatisfyRead(DECODE_ERROR, NULL); |
363 return; | 369 return; |
364 } | 370 } |
365 | 371 |
366 ReadFromDemuxerStream(); | 372 ReadFromDemuxerStream(); |
367 } | 373 } |
368 | 374 |
369 void VideoFrameStream::ResetDecoder() { | 375 void VideoFrameStream::ResetDecoder() { |
370 DCHECK(message_loop_->BelongsToCurrentThread()); | 376 DCHECK(message_loop_->BelongsToCurrentThread()); |
371 DCHECK(state_ == STATE_NORMAL || state_ == STATE_FLUSHING_DECODER || | 377 DCHECK(state_ == STATE_NORMAL || state_ == STATE_FLUSHING_DECODER || |
372 state_ == STATE_ERROR) << state_; | 378 state_ == STATE_ERROR) << state_; |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
411 DCHECK(!stop_cb_.is_null()); | 417 DCHECK(!stop_cb_.is_null()); |
412 | 418 |
413 state_ = STATE_STOPPED; | 419 state_ = STATE_STOPPED; |
414 stream_ = NULL; | 420 stream_ = NULL; |
415 decoder_.reset(); | 421 decoder_.reset(); |
416 decrypting_demuxer_stream_.reset(); | 422 decrypting_demuxer_stream_.reset(); |
417 base::ResetAndReturn(&stop_cb_).Run(); | 423 base::ResetAndReturn(&stop_cb_).Run(); |
418 } | 424 } |
419 | 425 |
420 } // namespace media | 426 } // namespace media |
OLD | NEW |