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

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 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
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
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698