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/gpu_video_decoder.h" | 5 #include "media/filters/gpu_video_decoder.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/message_loop.h" | 9 #include "base/message_loop.h" |
10 #include "base/stl_util.h" | 10 #include "base/stl_util.h" |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
46 MessageLoop* vda_loop, | 46 MessageLoop* vda_loop, |
47 const scoped_refptr<Factories>& factories) | 47 const scoped_refptr<Factories>& factories) |
48 : gvd_loop_proxy_(message_loop->message_loop_proxy()), | 48 : gvd_loop_proxy_(message_loop->message_loop_proxy()), |
49 vda_loop_proxy_(vda_loop->message_loop_proxy()), | 49 vda_loop_proxy_(vda_loop->message_loop_proxy()), |
50 factories_(factories), | 50 factories_(factories), |
51 state_(kNormal), | 51 state_(kNormal), |
52 demuxer_read_in_progress_(false), | 52 demuxer_read_in_progress_(false), |
53 decoder_texture_target_(0), | 53 decoder_texture_target_(0), |
54 next_picture_buffer_id_(0), | 54 next_picture_buffer_id_(0), |
55 next_bitstream_buffer_id_(0), | 55 next_bitstream_buffer_id_(0), |
56 shutting_down_(false) { | 56 shutting_down_(false), |
| 57 error_occured_(false) { |
57 DCHECK(gvd_loop_proxy_ && factories_); | 58 DCHECK(gvd_loop_proxy_ && factories_); |
58 } | 59 } |
59 | 60 |
60 GpuVideoDecoder::~GpuVideoDecoder() { | 61 GpuVideoDecoder::~GpuVideoDecoder() { |
61 DCHECK(!vda_); // Stop should have been already called. | 62 DCHECK(!vda_); // Stop should have been already called. |
62 DCHECK(pending_read_cb_.is_null()); | 63 DCHECK(pending_read_cb_.is_null()); |
63 for (size_t i = 0; i < available_shm_segments_.size(); ++i) { | 64 for (size_t i = 0; i < available_shm_segments_.size(); ++i) { |
64 available_shm_segments_[i]->shm->Close(); | 65 available_shm_segments_[i]->shm->Close(); |
65 delete available_shm_segments_[i]; | 66 delete available_shm_segments_[i]; |
66 } | 67 } |
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
185 status_cb.Run(PIPELINE_OK); | 186 status_cb.Run(PIPELINE_OK); |
186 } | 187 } |
187 | 188 |
188 void GpuVideoDecoder::Read(const ReadCB& read_cb) { | 189 void GpuVideoDecoder::Read(const ReadCB& read_cb) { |
189 if (!gvd_loop_proxy_->BelongsToCurrentThread()) { | 190 if (!gvd_loop_proxy_->BelongsToCurrentThread()) { |
190 gvd_loop_proxy_->PostTask(FROM_HERE, base::Bind( | 191 gvd_loop_proxy_->PostTask(FROM_HERE, base::Bind( |
191 &GpuVideoDecoder::Read, this, read_cb)); | 192 &GpuVideoDecoder::Read, this, read_cb)); |
192 return; | 193 return; |
193 } | 194 } |
194 | 195 |
| 196 if (error_occured_) { |
| 197 read_cb.Run(kDecodeError, NULL); |
| 198 return; |
| 199 } |
| 200 |
195 if (!vda_) { | 201 if (!vda_) { |
196 read_cb.Run(VideoFrame::CreateEmptyFrame()); | 202 read_cb.Run(kOk, VideoFrame::CreateEmptyFrame()); |
197 return; | 203 return; |
198 } | 204 } |
199 | 205 |
200 DCHECK(pending_reset_cb_.is_null()); | 206 DCHECK(pending_reset_cb_.is_null()); |
201 DCHECK(pending_read_cb_.is_null()); | 207 DCHECK(pending_read_cb_.is_null()); |
202 pending_read_cb_ = read_cb; | 208 pending_read_cb_ = read_cb; |
203 | 209 |
204 if (!ready_video_frames_.empty()) { | 210 if (!ready_video_frames_.empty()) { |
205 EnqueueFrameAndTriggerFrameDelivery(NULL); | 211 EnqueueFrameAndTriggerFrameDelivery(NULL); |
206 return; | 212 return; |
(...skipping 19 matching lines...) Expand all Loading... |
226 &GpuVideoDecoder::RequestBufferDecode, this, buffer)); | 232 &GpuVideoDecoder::RequestBufferDecode, this, buffer)); |
227 return; | 233 return; |
228 } | 234 } |
229 demuxer_read_in_progress_ = false; | 235 demuxer_read_in_progress_ = false; |
230 | 236 |
231 if (!buffer) { | 237 if (!buffer) { |
232 if (pending_read_cb_.is_null()) | 238 if (pending_read_cb_.is_null()) |
233 return; | 239 return; |
234 | 240 |
235 gvd_loop_proxy_->PostTask(FROM_HERE, base::Bind( | 241 gvd_loop_proxy_->PostTask(FROM_HERE, base::Bind( |
236 pending_read_cb_, scoped_refptr<VideoFrame>())); | 242 pending_read_cb_, kOk, scoped_refptr<VideoFrame>())); |
237 pending_read_cb_.Reset(); | 243 pending_read_cb_.Reset(); |
238 return; | 244 return; |
239 } | 245 } |
240 | 246 |
241 if (!vda_) { | 247 if (!vda_) { |
242 EnqueueFrameAndTriggerFrameDelivery(VideoFrame::CreateEmptyFrame()); | 248 EnqueueFrameAndTriggerFrameDelivery(VideoFrame::CreateEmptyFrame()); |
243 return; | 249 return; |
244 } | 250 } |
245 | 251 |
246 if (buffer->IsEndOfStream()) { | 252 if (buffer->IsEndOfStream()) { |
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
408 | 414 |
409 if (frame) | 415 if (frame) |
410 ready_video_frames_.push_back(frame); | 416 ready_video_frames_.push_back(frame); |
411 else | 417 else |
412 DCHECK(!ready_video_frames_.empty()); | 418 DCHECK(!ready_video_frames_.empty()); |
413 | 419 |
414 if (pending_read_cb_.is_null()) | 420 if (pending_read_cb_.is_null()) |
415 return; | 421 return; |
416 | 422 |
417 gvd_loop_proxy_->PostTask(FROM_HERE, base::Bind( | 423 gvd_loop_proxy_->PostTask(FROM_HERE, base::Bind( |
418 pending_read_cb_, ready_video_frames_.front())); | 424 pending_read_cb_, kOk, ready_video_frames_.front())); |
419 pending_read_cb_.Reset(); | 425 pending_read_cb_.Reset(); |
420 ready_video_frames_.pop_front(); | 426 ready_video_frames_.pop_front(); |
421 } | 427 } |
422 | 428 |
423 void GpuVideoDecoder::ReusePictureBuffer(int64 picture_buffer_id) { | 429 void GpuVideoDecoder::ReusePictureBuffer(int64 picture_buffer_id) { |
424 if (!gvd_loop_proxy_->BelongsToCurrentThread()) { | 430 if (!gvd_loop_proxy_->BelongsToCurrentThread()) { |
425 gvd_loop_proxy_->PostTask(FROM_HERE, base::Bind( | 431 gvd_loop_proxy_->PostTask(FROM_HERE, base::Bind( |
426 &GpuVideoDecoder::ReusePictureBuffer, this, picture_buffer_id)); | 432 &GpuVideoDecoder::ReusePictureBuffer, this, picture_buffer_id)); |
427 return; | 433 return; |
428 } | 434 } |
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
529 void GpuVideoDecoder::NotifyError(media::VideoDecodeAccelerator::Error error) { | 535 void GpuVideoDecoder::NotifyError(media::VideoDecodeAccelerator::Error error) { |
530 if (!gvd_loop_proxy_->BelongsToCurrentThread()) { | 536 if (!gvd_loop_proxy_->BelongsToCurrentThread()) { |
531 gvd_loop_proxy_->PostTask(FROM_HERE, base::Bind( | 537 gvd_loop_proxy_->PostTask(FROM_HERE, base::Bind( |
532 &GpuVideoDecoder::NotifyError, this, error)); | 538 &GpuVideoDecoder::NotifyError, this, error)); |
533 return; | 539 return; |
534 } | 540 } |
535 if (!vda_) | 541 if (!vda_) |
536 return; | 542 return; |
537 vda_ = NULL; | 543 vda_ = NULL; |
538 DLOG(ERROR) << "VDA Error: " << error; | 544 DLOG(ERROR) << "VDA Error: " << error; |
539 if (host()) | 545 |
540 host()->SetError(PIPELINE_ERROR_DECODE); | 546 error_occured_ = true; |
| 547 |
| 548 if (!pending_read_cb_.is_null()) { |
| 549 base::ResetAndReturn(&pending_read_cb_).Run(kDecodeError, NULL); |
| 550 return; |
| 551 } |
541 } | 552 } |
542 | 553 |
543 } // namespace media | 554 } // namespace media |
OLD | NEW |