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 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
61 DCHECK(gvd_loop_proxy_ && factories_); | 61 DCHECK(gvd_loop_proxy_ && factories_); |
62 } | 62 } |
63 | 63 |
64 void GpuVideoDecoder::Reset(const base::Closure& closure) { | 64 void GpuVideoDecoder::Reset(const base::Closure& closure) { |
65 if (!gvd_loop_proxy_->BelongsToCurrentThread() || | 65 if (!gvd_loop_proxy_->BelongsToCurrentThread() || |
66 state_ == kDrainingDecoder) { | 66 state_ == kDrainingDecoder) { |
67 gvd_loop_proxy_->PostTask(FROM_HERE, base::Bind( | 67 gvd_loop_proxy_->PostTask(FROM_HERE, base::Bind( |
68 &GpuVideoDecoder::Reset, this, closure)); | 68 &GpuVideoDecoder::Reset, this, closure)); |
69 return; | 69 return; |
70 } | 70 } |
71 | 71 |
Ryan Sleevi
2012/07/16 21:26:07
So the invariant here is that:
gvd_loop_proxy->Be
| |
72 // Throw away any already-decoded, not-yet-delivered frames. | 72 // Throw away any already-decoded, not-yet-delivered frames. |
73 ready_video_frames_.clear(); | 73 ready_video_frames_.clear(); |
74 | 74 |
75 if (!vda_) { | 75 if (!vda_.get()) { |
76 closure.Run(); | 76 closure.Run(); |
77 return; | 77 return; |
78 } | 78 } |
79 | 79 |
80 DCHECK(pending_reset_cb_.is_null()); | 80 DCHECK(pending_reset_cb_.is_null()); |
81 DCHECK(!closure.is_null()); | 81 DCHECK(!closure.is_null()); |
82 | 82 |
83 // VideoRendererBase::Flush() can't complete while it has a pending read to | 83 // VideoRendererBase::Flush() can't complete while it has a pending read to |
84 // us, so we fulfill such a read here. | 84 // us, so we fulfill such a read here. |
85 if (!pending_read_cb_.is_null()) | 85 if (!pending_read_cb_.is_null()) |
86 EnqueueFrameAndTriggerFrameDelivery(VideoFrame::CreateEmptyFrame()); | 86 EnqueueFrameAndTriggerFrameDelivery(VideoFrame::CreateEmptyFrame()); |
87 | 87 |
88 if (shutting_down_) { | 88 if (shutting_down_) { |
89 // Immediately fire the callback instead of waiting for the reset to | 89 // Immediately fire the callback instead of waiting for the reset to |
90 // complete (which will happen after PipelineImpl::Stop() completes). | 90 // complete (which will happen after PipelineImpl::Stop() completes). |
91 gvd_loop_proxy_->PostTask(FROM_HERE, closure); | 91 gvd_loop_proxy_->PostTask(FROM_HERE, closure); |
92 } else { | 92 } else { |
93 pending_reset_cb_ = closure; | 93 pending_reset_cb_ = closure; |
94 } | 94 } |
95 | 95 |
96 vda_loop_proxy_->PostTask(FROM_HERE, base::Bind( | 96 vda_loop_proxy_->PostTask(FROM_HERE, base::Bind( |
97 &VideoDecodeAccelerator::Reset, vda_)); | 97 &VideoDecodeAccelerator::Reset, vda_->AsWeakPtr())); |
Ryan Sleevi
2012/07/16 21:26:07
Now, you're posing vda_ as a WeakPtr to vda_loop_p
Ami GONE FROM CHROMIUM
2012/07/16 21:31:58
Blort, you were too quick for me.
This file in rie
| |
98 } | 98 } |
99 | 99 |
100 void GpuVideoDecoder::Stop(const base::Closure& closure) { | 100 void GpuVideoDecoder::Stop(const base::Closure& closure) { |
101 if (!gvd_loop_proxy_->BelongsToCurrentThread()) { | 101 if (!gvd_loop_proxy_->BelongsToCurrentThread()) { |
102 gvd_loop_proxy_->PostTask(FROM_HERE, base::Bind( | 102 gvd_loop_proxy_->PostTask(FROM_HERE, base::Bind( |
103 &GpuVideoDecoder::Stop, this, closure)); | 103 &GpuVideoDecoder::Stop, this, closure)); |
104 return; | 104 return; |
105 } | 105 } |
106 if (!vda_) { | 106 if (!vda_.get()) { |
107 closure.Run(); | 107 closure.Run(); |
108 return; | 108 return; |
109 } | 109 } |
110 VideoDecodeAccelerator* vda = vda_.get(); | |
110 vda_loop_proxy_->PostTask(FROM_HERE, base::Bind( | 111 vda_loop_proxy_->PostTask(FROM_HERE, base::Bind( |
111 &VideoDecodeAccelerator::Destroy, vda_)); | 112 &VideoDecodeAccelerator::Destroy, base::Unretained(vda), |
112 vda_ = NULL; | 113 base::Passed(&vda_))); |
113 closure.Run(); | 114 closure.Run(); |
114 } | 115 } |
115 | 116 |
116 void GpuVideoDecoder::Initialize(const scoped_refptr<DemuxerStream>& stream, | 117 void GpuVideoDecoder::Initialize(const scoped_refptr<DemuxerStream>& stream, |
117 const PipelineStatusCB& orig_status_cb, | 118 const PipelineStatusCB& orig_status_cb, |
118 const StatisticsCB& statistics_cb) { | 119 const StatisticsCB& statistics_cb) { |
119 if (!gvd_loop_proxy_->BelongsToCurrentThread()) { | 120 if (!gvd_loop_proxy_->BelongsToCurrentThread()) { |
120 gvd_loop_proxy_->PostTask(FROM_HERE, base::Bind( | 121 gvd_loop_proxy_->PostTask(FROM_HERE, base::Bind( |
121 &GpuVideoDecoder::Initialize, | 122 &GpuVideoDecoder::Initialize, |
122 this, stream, orig_status_cb, statistics_cb)); | 123 this, stream, orig_status_cb, statistics_cb)); |
(...skipping 11 matching lines...) Expand all Loading... | |
134 | 135 |
135 const VideoDecoderConfig& config = stream->video_decoder_config(); | 136 const VideoDecoderConfig& config = stream->video_decoder_config(); |
136 // TODO(scherkus): this check should go in Pipeline prior to creating | 137 // TODO(scherkus): this check should go in Pipeline prior to creating |
137 // decoder objects. | 138 // decoder objects. |
138 if (!config.IsValidConfig()) { | 139 if (!config.IsValidConfig()) { |
139 DLOG(ERROR) << "Invalid video stream - " << config.AsHumanReadableString(); | 140 DLOG(ERROR) << "Invalid video stream - " << config.AsHumanReadableString(); |
140 status_cb.Run(PIPELINE_ERROR_DECODE); | 141 status_cb.Run(PIPELINE_ERROR_DECODE); |
141 return; | 142 return; |
142 } | 143 } |
143 | 144 |
144 vda_ = factories_->CreateVideoDecodeAccelerator(config.profile(), this); | 145 vda_.reset(factories_->CreateVideoDecodeAccelerator(config.profile(), this)); |
145 if (!vda_) { | 146 if (!vda_.get()) { |
146 status_cb.Run(DECODER_ERROR_NOT_SUPPORTED); | 147 status_cb.Run(DECODER_ERROR_NOT_SUPPORTED); |
147 return; | 148 return; |
148 } | 149 } |
149 | 150 |
150 demuxer_stream_ = stream; | 151 demuxer_stream_ = stream; |
151 statistics_cb_ = statistics_cb; | 152 statistics_cb_ = statistics_cb; |
152 | 153 |
153 demuxer_stream_->EnableBitstreamConverter(); | 154 demuxer_stream_->EnableBitstreamConverter(); |
154 | 155 |
155 natural_size_ = config.natural_size(); | 156 natural_size_ = config.natural_size(); |
156 config_frame_duration_ = GetFrameDuration(config); | 157 config_frame_duration_ = GetFrameDuration(config); |
157 | 158 |
158 DVLOG(1) << "GpuVideoDecoder::Initialize() succeeded."; | 159 DVLOG(1) << "GpuVideoDecoder::Initialize() succeeded."; |
159 status_cb.Run(PIPELINE_OK); | 160 status_cb.Run(PIPELINE_OK); |
160 } | 161 } |
161 | 162 |
162 void GpuVideoDecoder::Read(const ReadCB& read_cb) { | 163 void GpuVideoDecoder::Read(const ReadCB& read_cb) { |
163 if (!gvd_loop_proxy_->BelongsToCurrentThread()) { | 164 if (!gvd_loop_proxy_->BelongsToCurrentThread()) { |
164 gvd_loop_proxy_->PostTask(FROM_HERE, base::Bind( | 165 gvd_loop_proxy_->PostTask(FROM_HERE, base::Bind( |
165 &GpuVideoDecoder::Read, this, read_cb)); | 166 &GpuVideoDecoder::Read, this, read_cb)); |
166 return; | 167 return; |
167 } | 168 } |
168 | 169 |
169 if (error_occured_) { | 170 if (error_occured_) { |
170 read_cb.Run(kDecodeError, NULL); | 171 read_cb.Run(kDecodeError, NULL); |
171 return; | 172 return; |
172 } | 173 } |
173 | 174 |
174 if (!vda_) { | 175 if (!vda_.get()) { |
175 read_cb.Run(kOk, VideoFrame::CreateEmptyFrame()); | 176 read_cb.Run(kOk, VideoFrame::CreateEmptyFrame()); |
176 return; | 177 return; |
177 } | 178 } |
178 | 179 |
179 DCHECK(pending_reset_cb_.is_null()); | 180 DCHECK(pending_reset_cb_.is_null()); |
180 DCHECK(pending_read_cb_.is_null()); | 181 DCHECK(pending_read_cb_.is_null()); |
181 pending_read_cb_ = read_cb; | 182 pending_read_cb_ = read_cb; |
182 | 183 |
183 if (!ready_video_frames_.empty()) { | 184 if (!ready_video_frames_.empty()) { |
184 EnqueueFrameAndTriggerFrameDelivery(NULL); | 185 EnqueueFrameAndTriggerFrameDelivery(NULL); |
(...skipping 26 matching lines...) Expand all Loading... | |
211 if (!buffer) { | 212 if (!buffer) { |
212 if (pending_read_cb_.is_null()) | 213 if (pending_read_cb_.is_null()) |
213 return; | 214 return; |
214 | 215 |
215 gvd_loop_proxy_->PostTask(FROM_HERE, base::Bind( | 216 gvd_loop_proxy_->PostTask(FROM_HERE, base::Bind( |
216 pending_read_cb_, kOk, scoped_refptr<VideoFrame>())); | 217 pending_read_cb_, kOk, scoped_refptr<VideoFrame>())); |
217 pending_read_cb_.Reset(); | 218 pending_read_cb_.Reset(); |
218 return; | 219 return; |
219 } | 220 } |
220 | 221 |
221 if (!vda_) { | 222 if (!vda_.get()) { |
222 EnqueueFrameAndTriggerFrameDelivery(VideoFrame::CreateEmptyFrame()); | 223 EnqueueFrameAndTriggerFrameDelivery(VideoFrame::CreateEmptyFrame()); |
223 return; | 224 return; |
224 } | 225 } |
225 | 226 |
226 if (buffer->IsEndOfStream()) { | 227 if (buffer->IsEndOfStream()) { |
227 if (state_ == kNormal) { | 228 if (state_ == kNormal) { |
228 state_ = kDrainingDecoder; | 229 state_ = kDrainingDecoder; |
229 vda_loop_proxy_->PostTask(FROM_HERE, base::Bind( | 230 vda_loop_proxy_->PostTask(FROM_HERE, base::Bind( |
230 &VideoDecodeAccelerator::Flush, vda_)); | 231 &VideoDecodeAccelerator::Flush, vda_->AsWeakPtr())); |
231 } | 232 } |
232 return; | 233 return; |
233 } | 234 } |
234 | 235 |
235 size_t size = buffer->GetDataSize(); | 236 size_t size = buffer->GetDataSize(); |
236 SHMBuffer* shm_buffer = GetSHM(size); | 237 SHMBuffer* shm_buffer = GetSHM(size); |
237 memcpy(shm_buffer->shm->memory(), buffer->GetData(), size); | 238 memcpy(shm_buffer->shm->memory(), buffer->GetData(), size); |
238 BitstreamBuffer bitstream_buffer( | 239 BitstreamBuffer bitstream_buffer( |
239 next_bitstream_buffer_id_++, shm_buffer->shm->handle(), size); | 240 next_bitstream_buffer_id_++, shm_buffer->shm->handle(), size); |
240 bool inserted = bitstream_buffers_in_decoder_.insert(std::make_pair( | 241 bool inserted = bitstream_buffers_in_decoder_.insert(std::make_pair( |
241 bitstream_buffer.id(), BufferPair(shm_buffer, buffer))).second; | 242 bitstream_buffer.id(), BufferPair(shm_buffer, buffer))).second; |
242 DCHECK(inserted); | 243 DCHECK(inserted); |
243 RecordBufferTimeData(bitstream_buffer, *buffer); | 244 RecordBufferTimeData(bitstream_buffer, *buffer); |
244 | 245 |
245 vda_loop_proxy_->PostTask(FROM_HERE, base::Bind( | 246 vda_loop_proxy_->PostTask(FROM_HERE, base::Bind( |
246 &VideoDecodeAccelerator::Decode, vda_, bitstream_buffer)); | 247 &VideoDecodeAccelerator::Decode, vda_->AsWeakPtr(), bitstream_buffer)); |
247 } | 248 } |
248 | 249 |
249 void GpuVideoDecoder::RecordBufferTimeData( | 250 void GpuVideoDecoder::RecordBufferTimeData( |
250 const BitstreamBuffer& bitstream_buffer, const Buffer& buffer) { | 251 const BitstreamBuffer& bitstream_buffer, const Buffer& buffer) { |
251 base::TimeDelta duration = buffer.GetDuration(); | 252 base::TimeDelta duration = buffer.GetDuration(); |
252 if (duration == base::TimeDelta()) | 253 if (duration == base::TimeDelta()) |
253 duration = config_frame_duration_; | 254 duration = config_frame_duration_; |
254 input_buffer_time_data_.push_front(BufferTimeData( | 255 input_buffer_time_data_.push_front(BufferTimeData( |
255 bitstream_buffer.id(), buffer.GetTimestamp(), duration)); | 256 bitstream_buffer.id(), buffer.GetTimestamp(), duration)); |
256 // Why this value? Because why not. avformat.h:MAX_REORDER_DELAY is 16, but | 257 // Why this value? Because why not. avformat.h:MAX_REORDER_DELAY is 16, but |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
312 } | 313 } |
313 | 314 |
314 std::vector<uint32> texture_ids; | 315 std::vector<uint32> texture_ids; |
315 decoder_texture_target_ = texture_target; | 316 decoder_texture_target_ = texture_target; |
316 if (!factories_->CreateTextures( | 317 if (!factories_->CreateTextures( |
317 count, size, &texture_ids, decoder_texture_target_)) { | 318 count, size, &texture_ids, decoder_texture_target_)) { |
318 NotifyError(VideoDecodeAccelerator::PLATFORM_FAILURE); | 319 NotifyError(VideoDecodeAccelerator::PLATFORM_FAILURE); |
319 return; | 320 return; |
320 } | 321 } |
321 | 322 |
322 if (!vda_) | 323 if (!vda_.get()) |
323 return; | 324 return; |
324 | 325 |
325 std::vector<PictureBuffer> picture_buffers; | 326 std::vector<PictureBuffer> picture_buffers; |
326 for (size_t i = 0; i < texture_ids.size(); ++i) { | 327 for (size_t i = 0; i < texture_ids.size(); ++i) { |
327 picture_buffers.push_back(PictureBuffer( | 328 picture_buffers.push_back(PictureBuffer( |
328 next_picture_buffer_id_++, size, texture_ids[i])); | 329 next_picture_buffer_id_++, size, texture_ids[i])); |
329 bool inserted = picture_buffers_in_decoder_.insert(std::make_pair( | 330 bool inserted = picture_buffers_in_decoder_.insert(std::make_pair( |
330 picture_buffers.back().id(), picture_buffers.back())).second; | 331 picture_buffers.back().id(), picture_buffers.back())).second; |
331 DCHECK(inserted); | 332 DCHECK(inserted); |
332 } | 333 } |
333 vda_loop_proxy_->PostTask(FROM_HERE, base::Bind( | 334 vda_loop_proxy_->PostTask(FROM_HERE, base::Bind( |
334 &VideoDecodeAccelerator::AssignPictureBuffers, vda_, picture_buffers)); | 335 &VideoDecodeAccelerator::AssignPictureBuffers, vda_->AsWeakPtr(), |
336 picture_buffers)); | |
335 } | 337 } |
336 | 338 |
337 void GpuVideoDecoder::DismissPictureBuffer(int32 id) { | 339 void GpuVideoDecoder::DismissPictureBuffer(int32 id) { |
338 if (!gvd_loop_proxy_->BelongsToCurrentThread()) { | 340 if (!gvd_loop_proxy_->BelongsToCurrentThread()) { |
339 gvd_loop_proxy_->PostTask(FROM_HERE, base::Bind( | 341 gvd_loop_proxy_->PostTask(FROM_HERE, base::Bind( |
340 &GpuVideoDecoder::DismissPictureBuffer, this, id)); | 342 &GpuVideoDecoder::DismissPictureBuffer, this, id)); |
341 return; | 343 return; |
342 } | 344 } |
343 std::map<int32, PictureBuffer>::iterator it = | 345 std::map<int32, PictureBuffer>::iterator it = |
344 picture_buffers_in_decoder_.find(id); | 346 picture_buffers_in_decoder_.find(id); |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
402 pending_read_cb_.Reset(); | 404 pending_read_cb_.Reset(); |
403 ready_video_frames_.pop_front(); | 405 ready_video_frames_.pop_front(); |
404 } | 406 } |
405 | 407 |
406 void GpuVideoDecoder::ReusePictureBuffer(int64 picture_buffer_id) { | 408 void GpuVideoDecoder::ReusePictureBuffer(int64 picture_buffer_id) { |
407 if (!gvd_loop_proxy_->BelongsToCurrentThread()) { | 409 if (!gvd_loop_proxy_->BelongsToCurrentThread()) { |
408 gvd_loop_proxy_->PostTask(FROM_HERE, base::Bind( | 410 gvd_loop_proxy_->PostTask(FROM_HERE, base::Bind( |
409 &GpuVideoDecoder::ReusePictureBuffer, this, picture_buffer_id)); | 411 &GpuVideoDecoder::ReusePictureBuffer, this, picture_buffer_id)); |
410 return; | 412 return; |
411 } | 413 } |
412 if (!vda_) | 414 if (!vda_.get()) |
413 return; | 415 return; |
414 vda_loop_proxy_->PostTask(FROM_HERE, base::Bind( | 416 vda_loop_proxy_->PostTask(FROM_HERE, base::Bind( |
415 &VideoDecodeAccelerator::ReusePictureBuffer, vda_, picture_buffer_id)); | 417 &VideoDecodeAccelerator::ReusePictureBuffer, vda_->AsWeakPtr(), |
418 picture_buffer_id)); | |
416 } | 419 } |
417 | 420 |
418 GpuVideoDecoder::SHMBuffer* GpuVideoDecoder::GetSHM(size_t min_size) { | 421 GpuVideoDecoder::SHMBuffer* GpuVideoDecoder::GetSHM(size_t min_size) { |
419 DCHECK(gvd_loop_proxy_->BelongsToCurrentThread()); | 422 DCHECK(gvd_loop_proxy_->BelongsToCurrentThread()); |
420 if (available_shm_segments_.empty() || | 423 if (available_shm_segments_.empty() || |
421 available_shm_segments_.back()->size < min_size) { | 424 available_shm_segments_.back()->size < min_size) { |
422 size_t size_to_allocate = std::max(min_size, kSharedMemorySegmentBytes); | 425 size_t size_to_allocate = std::max(min_size, kSharedMemorySegmentBytes); |
423 base::SharedMemory* shm = factories_->CreateSharedMemory(size_to_allocate); | 426 base::SharedMemory* shm = factories_->CreateSharedMemory(size_to_allocate); |
424 DCHECK(shm); | 427 DCHECK(shm); |
425 return new SHMBuffer(shm, size_to_allocate); | 428 return new SHMBuffer(shm, size_to_allocate); |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
460 | 463 |
461 if (!pending_read_cb_.is_null() && pending_reset_cb_.is_null() && | 464 if (!pending_read_cb_.is_null() && pending_reset_cb_.is_null() && |
462 state_ != kDrainingDecoder && | 465 state_ != kDrainingDecoder && |
463 bitstream_buffers_in_decoder_.empty()) { | 466 bitstream_buffers_in_decoder_.empty()) { |
464 DCHECK(ready_video_frames_.empty()); | 467 DCHECK(ready_video_frames_.empty()); |
465 EnsureDemuxOrDecode(); | 468 EnsureDemuxOrDecode(); |
466 } | 469 } |
467 } | 470 } |
468 | 471 |
469 GpuVideoDecoder::~GpuVideoDecoder() { | 472 GpuVideoDecoder::~GpuVideoDecoder() { |
470 DCHECK(!vda_); // Stop should have been already called. | 473 DCHECK(!vda_.get()); // Stop should have been already called. |
471 DCHECK(pending_read_cb_.is_null()); | 474 DCHECK(pending_read_cb_.is_null()); |
472 for (size_t i = 0; i < available_shm_segments_.size(); ++i) { | 475 for (size_t i = 0; i < available_shm_segments_.size(); ++i) { |
473 available_shm_segments_[i]->shm->Close(); | 476 available_shm_segments_[i]->shm->Close(); |
474 delete available_shm_segments_[i]; | 477 delete available_shm_segments_[i]; |
475 } | 478 } |
476 available_shm_segments_.clear(); | 479 available_shm_segments_.clear(); |
477 for (std::map<int32, BufferPair>::iterator it = | 480 for (std::map<int32, BufferPair>::iterator it = |
478 bitstream_buffers_in_decoder_.begin(); | 481 bitstream_buffers_in_decoder_.begin(); |
479 it != bitstream_buffers_in_decoder_.end(); ++it) { | 482 it != bitstream_buffers_in_decoder_.end(); ++it) { |
480 it->second.shm_buffer->shm->Close(); | 483 it->second.shm_buffer->shm->Close(); |
(...skipping 22 matching lines...) Expand all Loading... | |
503 EnqueueFrameAndTriggerFrameDelivery(VideoFrame::CreateEmptyFrame()); | 506 EnqueueFrameAndTriggerFrameDelivery(VideoFrame::CreateEmptyFrame()); |
504 } | 507 } |
505 | 508 |
506 void GpuVideoDecoder::NotifyResetDone() { | 509 void GpuVideoDecoder::NotifyResetDone() { |
507 if (!gvd_loop_proxy_->BelongsToCurrentThread()) { | 510 if (!gvd_loop_proxy_->BelongsToCurrentThread()) { |
508 gvd_loop_proxy_->PostTask(FROM_HERE, base::Bind( | 511 gvd_loop_proxy_->PostTask(FROM_HERE, base::Bind( |
509 &GpuVideoDecoder::NotifyResetDone, this)); | 512 &GpuVideoDecoder::NotifyResetDone, this)); |
510 return; | 513 return; |
511 } | 514 } |
512 | 515 |
513 if (!vda_) | 516 if (!vda_.get()) |
514 return; | 517 return; |
515 | 518 |
516 DCHECK(ready_video_frames_.empty()); | 519 DCHECK(ready_video_frames_.empty()); |
517 | 520 |
518 // This needs to happen after the Reset() on vda_ is done to ensure pictures | 521 // This needs to happen after the Reset() on vda_ is done to ensure pictures |
519 // delivered during the reset can find their time data. | 522 // delivered during the reset can find their time data. |
520 input_buffer_time_data_.clear(); | 523 input_buffer_time_data_.clear(); |
521 | 524 |
522 if (!pending_reset_cb_.is_null()) | 525 if (!pending_reset_cb_.is_null()) |
523 base::ResetAndReturn(&pending_reset_cb_).Run(); | 526 base::ResetAndReturn(&pending_reset_cb_).Run(); |
524 | 527 |
525 if (!pending_read_cb_.is_null()) | 528 if (!pending_read_cb_.is_null()) |
526 EnqueueFrameAndTriggerFrameDelivery(VideoFrame::CreateEmptyFrame()); | 529 EnqueueFrameAndTriggerFrameDelivery(VideoFrame::CreateEmptyFrame()); |
527 } | 530 } |
528 | 531 |
529 void GpuVideoDecoder::NotifyError(media::VideoDecodeAccelerator::Error error) { | 532 void GpuVideoDecoder::NotifyError(media::VideoDecodeAccelerator::Error error) { |
530 if (!gvd_loop_proxy_->BelongsToCurrentThread()) { | 533 if (!gvd_loop_proxy_->BelongsToCurrentThread()) { |
531 gvd_loop_proxy_->PostTask(FROM_HERE, base::Bind( | 534 gvd_loop_proxy_->PostTask(FROM_HERE, base::Bind( |
532 &GpuVideoDecoder::NotifyError, this, error)); | 535 &GpuVideoDecoder::NotifyError, this, error)); |
533 return; | 536 return; |
534 } | 537 } |
535 if (!vda_) | 538 if (!vda_.get()) |
536 return; | 539 return; |
537 vda_ = NULL; | 540 vda_loop_proxy_->DeleteSoon(FROM_HERE, vda_.release()); |
538 DLOG(ERROR) << "VDA Error: " << error; | 541 DLOG(ERROR) << "VDA Error: " << error; |
539 | 542 |
540 error_occured_ = true; | 543 error_occured_ = true; |
541 | 544 |
542 if (!pending_read_cb_.is_null()) { | 545 if (!pending_read_cb_.is_null()) { |
543 base::ResetAndReturn(&pending_read_cb_).Run(kDecodeError, NULL); | 546 base::ResetAndReturn(&pending_read_cb_).Run(kDecodeError, NULL); |
544 return; | 547 return; |
545 } | 548 } |
546 } | 549 } |
547 | 550 |
548 } // namespace media | 551 } // namespace media |
OLD | NEW |