Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(864)

Side by Side Diff: media/filters/gpu_video_decoder.cc

Issue 10749019: VideoDecodeAccelerator now SupportsWeakPtr instead of being RefCountedThreadSafe. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: . Created 8 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
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, weak_vda_));
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 vda_loop_proxy_->PostTask(FROM_HERE, base::Bind( 110 vda_loop_proxy_->PostTask(FROM_HERE, base::Bind(
111 &VideoDecodeAccelerator::Destroy, vda_)); 111 &VideoDecodeAccelerator::Destroy, weak_vda_, base::Passed(&vda_)));
112 vda_ = NULL;
113 closure.Run(); 112 closure.Run();
114 } 113 }
115 114
116 void GpuVideoDecoder::Initialize(const scoped_refptr<DemuxerStream>& stream, 115 void GpuVideoDecoder::Initialize(const scoped_refptr<DemuxerStream>& stream,
117 const PipelineStatusCB& orig_status_cb, 116 const PipelineStatusCB& orig_status_cb,
118 const StatisticsCB& statistics_cb) { 117 const StatisticsCB& statistics_cb) {
119 if (!gvd_loop_proxy_->BelongsToCurrentThread()) { 118 if (!gvd_loop_proxy_->BelongsToCurrentThread()) {
120 gvd_loop_proxy_->PostTask(FROM_HERE, base::Bind( 119 gvd_loop_proxy_->PostTask(FROM_HERE, base::Bind(
121 &GpuVideoDecoder::Initialize, 120 &GpuVideoDecoder::Initialize,
122 this, stream, orig_status_cb, statistics_cb)); 121 this, stream, orig_status_cb, statistics_cb));
(...skipping 11 matching lines...) Expand all
134 133
135 const VideoDecoderConfig& config = stream->video_decoder_config(); 134 const VideoDecoderConfig& config = stream->video_decoder_config();
136 // TODO(scherkus): this check should go in Pipeline prior to creating 135 // TODO(scherkus): this check should go in Pipeline prior to creating
137 // decoder objects. 136 // decoder objects.
138 if (!config.IsValidConfig()) { 137 if (!config.IsValidConfig()) {
139 DLOG(ERROR) << "Invalid video stream - " << config.AsHumanReadableString(); 138 DLOG(ERROR) << "Invalid video stream - " << config.AsHumanReadableString();
140 status_cb.Run(PIPELINE_ERROR_DECODE); 139 status_cb.Run(PIPELINE_ERROR_DECODE);
141 return; 140 return;
142 } 141 }
143 142
144 vda_ = factories_->CreateVideoDecodeAccelerator(config.profile(), this); 143 VideoDecodeAccelerator* vda =
145 if (!vda_) { 144 factories_->CreateVideoDecodeAccelerator(config.profile(), this);
145 if (!vda) {
146 status_cb.Run(DECODER_ERROR_NOT_SUPPORTED); 146 status_cb.Run(DECODER_ERROR_NOT_SUPPORTED);
147 return; 147 return;
148 } 148 }
149 149
150 demuxer_stream_ = stream; 150 demuxer_stream_ = stream;
151 statistics_cb_ = statistics_cb; 151 statistics_cb_ = statistics_cb;
152 152
153 demuxer_stream_->EnableBitstreamConverter(); 153 demuxer_stream_->EnableBitstreamConverter();
154 154
155 natural_size_ = config.natural_size(); 155 natural_size_ = config.natural_size();
156 config_frame_duration_ = GetFrameDuration(config); 156 config_frame_duration_ = GetFrameDuration(config);
157 157
158 DVLOG(1) << "GpuVideoDecoder::Initialize() succeeded."; 158 DVLOG(1) << "GpuVideoDecoder::Initialize() succeeded.";
159 status_cb.Run(PIPELINE_OK); 159 vda_loop_proxy_->PostTaskAndReply(
160 FROM_HERE,
161 base::Bind(&GpuVideoDecoder::SetVDA, this, vda),
162 base::Bind(status_cb, PIPELINE_OK));
163 }
164
165 void GpuVideoDecoder::SetVDA(VideoDecodeAccelerator* vda) {
166 DCHECK(vda_loop_proxy_->BelongsToCurrentThread());
167 vda_.reset(vda);
168 weak_vda_ = vda->AsWeakPtr();
160 } 169 }
161 170
162 void GpuVideoDecoder::Read(const ReadCB& read_cb) { 171 void GpuVideoDecoder::Read(const ReadCB& read_cb) {
163 if (!gvd_loop_proxy_->BelongsToCurrentThread()) { 172 if (!gvd_loop_proxy_->BelongsToCurrentThread()) {
164 gvd_loop_proxy_->PostTask(FROM_HERE, base::Bind( 173 gvd_loop_proxy_->PostTask(FROM_HERE, base::Bind(
165 &GpuVideoDecoder::Read, this, read_cb)); 174 &GpuVideoDecoder::Read, this, read_cb));
166 return; 175 return;
167 } 176 }
168 177
169 if (error_occured_) { 178 if (error_occured_) {
170 read_cb.Run(kDecodeError, NULL); 179 read_cb.Run(kDecodeError, NULL);
171 return; 180 return;
172 } 181 }
173 182
174 if (!vda_) { 183 if (!vda_.get()) {
175 read_cb.Run(kOk, VideoFrame::CreateEmptyFrame()); 184 read_cb.Run(kOk, VideoFrame::CreateEmptyFrame());
176 return; 185 return;
177 } 186 }
178 187
179 DCHECK(pending_reset_cb_.is_null()); 188 DCHECK(pending_reset_cb_.is_null());
180 DCHECK(pending_read_cb_.is_null()); 189 DCHECK(pending_read_cb_.is_null());
181 pending_read_cb_ = read_cb; 190 pending_read_cb_ = read_cb;
182 191
183 if (!ready_video_frames_.empty()) { 192 if (!ready_video_frames_.empty()) {
184 EnqueueFrameAndTriggerFrameDelivery(NULL); 193 EnqueueFrameAndTriggerFrameDelivery(NULL);
(...skipping 26 matching lines...) Expand all
211 if (!buffer) { 220 if (!buffer) {
212 if (pending_read_cb_.is_null()) 221 if (pending_read_cb_.is_null())
213 return; 222 return;
214 223
215 gvd_loop_proxy_->PostTask(FROM_HERE, base::Bind( 224 gvd_loop_proxy_->PostTask(FROM_HERE, base::Bind(
216 pending_read_cb_, kOk, scoped_refptr<VideoFrame>())); 225 pending_read_cb_, kOk, scoped_refptr<VideoFrame>()));
217 pending_read_cb_.Reset(); 226 pending_read_cb_.Reset();
218 return; 227 return;
219 } 228 }
220 229
221 if (!vda_) { 230 if (!vda_.get()) {
222 EnqueueFrameAndTriggerFrameDelivery(VideoFrame::CreateEmptyFrame()); 231 EnqueueFrameAndTriggerFrameDelivery(VideoFrame::CreateEmptyFrame());
223 return; 232 return;
224 } 233 }
225 234
226 if (buffer->IsEndOfStream()) { 235 if (buffer->IsEndOfStream()) {
227 if (state_ == kNormal) { 236 if (state_ == kNormal) {
228 state_ = kDrainingDecoder; 237 state_ = kDrainingDecoder;
229 vda_loop_proxy_->PostTask(FROM_HERE, base::Bind( 238 vda_loop_proxy_->PostTask(FROM_HERE, base::Bind(
230 &VideoDecodeAccelerator::Flush, vda_)); 239 &VideoDecodeAccelerator::Flush, weak_vda_));
231 } 240 }
232 return; 241 return;
233 } 242 }
234 243
235 size_t size = buffer->GetDataSize(); 244 size_t size = buffer->GetDataSize();
236 SHMBuffer* shm_buffer = GetSHM(size); 245 SHMBuffer* shm_buffer = GetSHM(size);
237 memcpy(shm_buffer->shm->memory(), buffer->GetData(), size); 246 memcpy(shm_buffer->shm->memory(), buffer->GetData(), size);
238 BitstreamBuffer bitstream_buffer( 247 BitstreamBuffer bitstream_buffer(
239 next_bitstream_buffer_id_++, shm_buffer->shm->handle(), size); 248 next_bitstream_buffer_id_++, shm_buffer->shm->handle(), size);
240 bool inserted = bitstream_buffers_in_decoder_.insert(std::make_pair( 249 bool inserted = bitstream_buffers_in_decoder_.insert(std::make_pair(
241 bitstream_buffer.id(), BufferPair(shm_buffer, buffer))).second; 250 bitstream_buffer.id(), BufferPair(shm_buffer, buffer))).second;
242 DCHECK(inserted); 251 DCHECK(inserted);
243 RecordBufferTimeData(bitstream_buffer, *buffer); 252 RecordBufferTimeData(bitstream_buffer, *buffer);
244 253
245 vda_loop_proxy_->PostTask(FROM_HERE, base::Bind( 254 vda_loop_proxy_->PostTask(FROM_HERE, base::Bind(
246 &VideoDecodeAccelerator::Decode, vda_, bitstream_buffer)); 255 &VideoDecodeAccelerator::Decode, weak_vda_, bitstream_buffer));
247 } 256 }
248 257
249 void GpuVideoDecoder::RecordBufferTimeData( 258 void GpuVideoDecoder::RecordBufferTimeData(
250 const BitstreamBuffer& bitstream_buffer, const Buffer& buffer) { 259 const BitstreamBuffer& bitstream_buffer, const Buffer& buffer) {
251 base::TimeDelta duration = buffer.GetDuration(); 260 base::TimeDelta duration = buffer.GetDuration();
252 if (duration == base::TimeDelta()) 261 if (duration == base::TimeDelta())
253 duration = config_frame_duration_; 262 duration = config_frame_duration_;
254 input_buffer_time_data_.push_front(BufferTimeData( 263 input_buffer_time_data_.push_front(BufferTimeData(
255 bitstream_buffer.id(), buffer.GetTimestamp(), duration)); 264 bitstream_buffer.id(), buffer.GetTimestamp(), duration));
256 // Why this value? Because why not. avformat.h:MAX_REORDER_DELAY is 16, but 265 // 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
312 } 321 }
313 322
314 std::vector<uint32> texture_ids; 323 std::vector<uint32> texture_ids;
315 decoder_texture_target_ = texture_target; 324 decoder_texture_target_ = texture_target;
316 if (!factories_->CreateTextures( 325 if (!factories_->CreateTextures(
317 count, size, &texture_ids, decoder_texture_target_)) { 326 count, size, &texture_ids, decoder_texture_target_)) {
318 NotifyError(VideoDecodeAccelerator::PLATFORM_FAILURE); 327 NotifyError(VideoDecodeAccelerator::PLATFORM_FAILURE);
319 return; 328 return;
320 } 329 }
321 330
322 if (!vda_) 331 if (!vda_.get())
323 return; 332 return;
324 333
325 std::vector<PictureBuffer> picture_buffers; 334 std::vector<PictureBuffer> picture_buffers;
326 for (size_t i = 0; i < texture_ids.size(); ++i) { 335 for (size_t i = 0; i < texture_ids.size(); ++i) {
327 picture_buffers.push_back(PictureBuffer( 336 picture_buffers.push_back(PictureBuffer(
328 next_picture_buffer_id_++, size, texture_ids[i])); 337 next_picture_buffer_id_++, size, texture_ids[i]));
329 bool inserted = picture_buffers_in_decoder_.insert(std::make_pair( 338 bool inserted = picture_buffers_in_decoder_.insert(std::make_pair(
330 picture_buffers.back().id(), picture_buffers.back())).second; 339 picture_buffers.back().id(), picture_buffers.back())).second;
331 DCHECK(inserted); 340 DCHECK(inserted);
332 } 341 }
333 vda_loop_proxy_->PostTask(FROM_HERE, base::Bind( 342 vda_loop_proxy_->PostTask(FROM_HERE, base::Bind(
334 &VideoDecodeAccelerator::AssignPictureBuffers, vda_, picture_buffers)); 343 &VideoDecodeAccelerator::AssignPictureBuffers, weak_vda_,
344 picture_buffers));
335 } 345 }
336 346
337 void GpuVideoDecoder::DismissPictureBuffer(int32 id) { 347 void GpuVideoDecoder::DismissPictureBuffer(int32 id) {
338 if (!gvd_loop_proxy_->BelongsToCurrentThread()) { 348 if (!gvd_loop_proxy_->BelongsToCurrentThread()) {
339 gvd_loop_proxy_->PostTask(FROM_HERE, base::Bind( 349 gvd_loop_proxy_->PostTask(FROM_HERE, base::Bind(
340 &GpuVideoDecoder::DismissPictureBuffer, this, id)); 350 &GpuVideoDecoder::DismissPictureBuffer, this, id));
341 return; 351 return;
342 } 352 }
343 std::map<int32, PictureBuffer>::iterator it = 353 std::map<int32, PictureBuffer>::iterator it =
344 picture_buffers_in_decoder_.find(id); 354 picture_buffers_in_decoder_.find(id);
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
402 pending_read_cb_.Reset(); 412 pending_read_cb_.Reset();
403 ready_video_frames_.pop_front(); 413 ready_video_frames_.pop_front();
404 } 414 }
405 415
406 void GpuVideoDecoder::ReusePictureBuffer(int64 picture_buffer_id) { 416 void GpuVideoDecoder::ReusePictureBuffer(int64 picture_buffer_id) {
407 if (!gvd_loop_proxy_->BelongsToCurrentThread()) { 417 if (!gvd_loop_proxy_->BelongsToCurrentThread()) {
408 gvd_loop_proxy_->PostTask(FROM_HERE, base::Bind( 418 gvd_loop_proxy_->PostTask(FROM_HERE, base::Bind(
409 &GpuVideoDecoder::ReusePictureBuffer, this, picture_buffer_id)); 419 &GpuVideoDecoder::ReusePictureBuffer, this, picture_buffer_id));
410 return; 420 return;
411 } 421 }
412 if (!vda_) 422 if (!vda_.get())
413 return; 423 return;
414 vda_loop_proxy_->PostTask(FROM_HERE, base::Bind( 424 vda_loop_proxy_->PostTask(FROM_HERE, base::Bind(
415 &VideoDecodeAccelerator::ReusePictureBuffer, vda_, picture_buffer_id)); 425 &VideoDecodeAccelerator::ReusePictureBuffer, weak_vda_,
426 picture_buffer_id));
416 } 427 }
417 428
418 GpuVideoDecoder::SHMBuffer* GpuVideoDecoder::GetSHM(size_t min_size) { 429 GpuVideoDecoder::SHMBuffer* GpuVideoDecoder::GetSHM(size_t min_size) {
419 DCHECK(gvd_loop_proxy_->BelongsToCurrentThread()); 430 DCHECK(gvd_loop_proxy_->BelongsToCurrentThread());
420 if (available_shm_segments_.empty() || 431 if (available_shm_segments_.empty() ||
421 available_shm_segments_.back()->size < min_size) { 432 available_shm_segments_.back()->size < min_size) {
422 size_t size_to_allocate = std::max(min_size, kSharedMemorySegmentBytes); 433 size_t size_to_allocate = std::max(min_size, kSharedMemorySegmentBytes);
423 base::SharedMemory* shm = factories_->CreateSharedMemory(size_to_allocate); 434 base::SharedMemory* shm = factories_->CreateSharedMemory(size_to_allocate);
424 DCHECK(shm); 435 DCHECK(shm);
425 return new SHMBuffer(shm, size_to_allocate); 436 return new SHMBuffer(shm, size_to_allocate);
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
460 471
461 if (!pending_read_cb_.is_null() && pending_reset_cb_.is_null() && 472 if (!pending_read_cb_.is_null() && pending_reset_cb_.is_null() &&
462 state_ != kDrainingDecoder && 473 state_ != kDrainingDecoder &&
463 bitstream_buffers_in_decoder_.empty()) { 474 bitstream_buffers_in_decoder_.empty()) {
464 DCHECK(ready_video_frames_.empty()); 475 DCHECK(ready_video_frames_.empty());
465 EnsureDemuxOrDecode(); 476 EnsureDemuxOrDecode();
466 } 477 }
467 } 478 }
468 479
469 GpuVideoDecoder::~GpuVideoDecoder() { 480 GpuVideoDecoder::~GpuVideoDecoder() {
470 DCHECK(!vda_); // Stop should have been already called. 481 DCHECK(!vda_.get()); // Stop should have been already called.
471 DCHECK(pending_read_cb_.is_null()); 482 DCHECK(pending_read_cb_.is_null());
472 for (size_t i = 0; i < available_shm_segments_.size(); ++i) { 483 for (size_t i = 0; i < available_shm_segments_.size(); ++i) {
473 available_shm_segments_[i]->shm->Close(); 484 available_shm_segments_[i]->shm->Close();
474 delete available_shm_segments_[i]; 485 delete available_shm_segments_[i];
475 } 486 }
476 available_shm_segments_.clear(); 487 available_shm_segments_.clear();
477 for (std::map<int32, BufferPair>::iterator it = 488 for (std::map<int32, BufferPair>::iterator it =
478 bitstream_buffers_in_decoder_.begin(); 489 bitstream_buffers_in_decoder_.begin();
479 it != bitstream_buffers_in_decoder_.end(); ++it) { 490 it != bitstream_buffers_in_decoder_.end(); ++it) {
480 it->second.shm_buffer->shm->Close(); 491 it->second.shm_buffer->shm->Close();
(...skipping 22 matching lines...) Expand all
503 EnqueueFrameAndTriggerFrameDelivery(VideoFrame::CreateEmptyFrame()); 514 EnqueueFrameAndTriggerFrameDelivery(VideoFrame::CreateEmptyFrame());
504 } 515 }
505 516
506 void GpuVideoDecoder::NotifyResetDone() { 517 void GpuVideoDecoder::NotifyResetDone() {
507 if (!gvd_loop_proxy_->BelongsToCurrentThread()) { 518 if (!gvd_loop_proxy_->BelongsToCurrentThread()) {
508 gvd_loop_proxy_->PostTask(FROM_HERE, base::Bind( 519 gvd_loop_proxy_->PostTask(FROM_HERE, base::Bind(
509 &GpuVideoDecoder::NotifyResetDone, this)); 520 &GpuVideoDecoder::NotifyResetDone, this));
510 return; 521 return;
511 } 522 }
512 523
513 if (!vda_) 524 if (!vda_.get())
514 return; 525 return;
515 526
516 DCHECK(ready_video_frames_.empty()); 527 DCHECK(ready_video_frames_.empty());
517 528
518 // This needs to happen after the Reset() on vda_ is done to ensure pictures 529 // This needs to happen after the Reset() on vda_ is done to ensure pictures
519 // delivered during the reset can find their time data. 530 // delivered during the reset can find their time data.
520 input_buffer_time_data_.clear(); 531 input_buffer_time_data_.clear();
521 532
522 if (!pending_reset_cb_.is_null()) 533 if (!pending_reset_cb_.is_null())
523 base::ResetAndReturn(&pending_reset_cb_).Run(); 534 base::ResetAndReturn(&pending_reset_cb_).Run();
524 535
525 if (!pending_read_cb_.is_null()) 536 if (!pending_read_cb_.is_null())
526 EnqueueFrameAndTriggerFrameDelivery(VideoFrame::CreateEmptyFrame()); 537 EnqueueFrameAndTriggerFrameDelivery(VideoFrame::CreateEmptyFrame());
527 } 538 }
528 539
529 void GpuVideoDecoder::NotifyError(media::VideoDecodeAccelerator::Error error) { 540 void GpuVideoDecoder::NotifyError(media::VideoDecodeAccelerator::Error error) {
530 if (!gvd_loop_proxy_->BelongsToCurrentThread()) { 541 if (!gvd_loop_proxy_->BelongsToCurrentThread()) {
531 gvd_loop_proxy_->PostTask(FROM_HERE, base::Bind( 542 gvd_loop_proxy_->PostTask(FROM_HERE, base::Bind(
532 &GpuVideoDecoder::NotifyError, this, error)); 543 &GpuVideoDecoder::NotifyError, this, error));
533 return; 544 return;
534 } 545 }
535 if (!vda_) 546 if (!vda_.get())
536 return; 547 return;
537 vda_ = NULL; 548 vda_loop_proxy_->DeleteSoon(FROM_HERE, vda_.release());
538 DLOG(ERROR) << "VDA Error: " << error; 549 DLOG(ERROR) << "VDA Error: " << error;
539 550
540 error_occured_ = true; 551 error_occured_ = true;
541 552
542 if (!pending_read_cb_.is_null()) { 553 if (!pending_read_cb_.is_null()) {
543 base::ResetAndReturn(&pending_read_cb_).Run(kDecodeError, NULL); 554 base::ResetAndReturn(&pending_read_cb_).Run(kDecodeError, NULL);
544 return; 555 return;
545 } 556 }
546 } 557 }
547 558
548 } // namespace media 559 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698