| 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 |