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

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

Issue 12989009: Remove reference counting from media::VideoDecoder and friends. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 years, 9 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/cpu.h" 9 #include "base/cpu.h"
10 #include "base/message_loop.h" 10 #include "base/message_loop.h"
11 #include "base/stl_util.h" 11 #include "base/stl_util.h"
12 #include "base/synchronization/waitable_event.h"
12 #include "media/base/bind_to_loop.h" 13 #include "media/base/bind_to_loop.h"
13 #include "media/base/decoder_buffer.h" 14 #include "media/base/decoder_buffer.h"
14 #include "media/base/demuxer_stream.h" 15 #include "media/base/demuxer_stream.h"
15 #include "media/base/pipeline.h" 16 #include "media/base/pipeline.h"
16 #include "media/base/pipeline_status.h" 17 #include "media/base/pipeline_status.h"
17 #include "media/base/video_decoder_config.h" 18 #include "media/base/video_decoder_config.h"
18 19
19 namespace media { 20 namespace media {
20 21
21 // Maximum number of concurrent VDA::Decode() operations GVD will maintain. 22 // Maximum number of concurrent VDA::Decode() operations GVD will maintain.
(...skipping 25 matching lines...) Expand all
47 : bitstream_buffer_id(bbid), timestamp(ts), visible_rect(vr), 48 : bitstream_buffer_id(bbid), timestamp(ts), visible_rect(vr),
48 natural_size(ns) { 49 natural_size(ns) {
49 } 50 }
50 51
51 GpuVideoDecoder::BufferData::~BufferData() {} 52 GpuVideoDecoder::BufferData::~BufferData() {}
52 53
53 GpuVideoDecoder::GpuVideoDecoder( 54 GpuVideoDecoder::GpuVideoDecoder(
54 const scoped_refptr<base::MessageLoopProxy>& message_loop, 55 const scoped_refptr<base::MessageLoopProxy>& message_loop,
55 const scoped_refptr<Factories>& factories) 56 const scoped_refptr<Factories>& factories)
56 : gvd_loop_proxy_(message_loop), 57 : gvd_loop_proxy_(message_loop),
58 weak_factory_(this),
57 vda_loop_proxy_(factories->GetMessageLoop()), 59 vda_loop_proxy_(factories->GetMessageLoop()),
58 factories_(factories), 60 factories_(factories),
59 state_(kNormal), 61 state_(kNormal),
60 demuxer_read_in_progress_(false), 62 demuxer_read_in_progress_(false),
61 decoder_texture_target_(0), 63 decoder_texture_target_(0),
62 next_picture_buffer_id_(0), 64 next_picture_buffer_id_(0),
63 next_bitstream_buffer_id_(0), 65 next_bitstream_buffer_id_(0),
64 error_occured_(false), 66 error_occured_(false),
65 available_pictures_(-1) { 67 available_pictures_(-1) {
66 DCHECK(factories_); 68 DCHECK(factories_);
67 } 69 }
68 70
69 void GpuVideoDecoder::Reset(const base::Closure& closure) { 71 void GpuVideoDecoder::Reset(const base::Closure& closure) {
70 DCHECK(gvd_loop_proxy_->BelongsToCurrentThread()); 72 DCHECK(gvd_loop_proxy_->BelongsToCurrentThread());
71 73
72 if (state_ == kDrainingDecoder) { 74 if (state_ == kDrainingDecoder) {
73 gvd_loop_proxy_->PostTask(FROM_HERE, base::Bind( 75 gvd_loop_proxy_->PostTask(FROM_HERE, base::Bind(
74 &GpuVideoDecoder::Reset, this, closure)); 76 &GpuVideoDecoder::Reset, weak_this_, closure));
75 // NOTE: if we're deferring Reset() until a Flush() completes, return 77 // NOTE: if we're deferring Reset() until a Flush() completes, return
76 // queued pictures to the VDA so they can be used to finish that Flush(). 78 // queued pictures to the VDA so they can be used to finish that Flush().
77 if (pending_read_cb_.is_null()) 79 if (pending_read_cb_.is_null())
78 ready_video_frames_.clear(); 80 ready_video_frames_.clear();
79 return; 81 return;
80 } 82 }
81 83
82 // Throw away any already-decoded, not-yet-delivered frames. 84 // Throw away any already-decoded, not-yet-delivered frames.
83 ready_video_frames_.clear(); 85 ready_video_frames_.clear();
84 86
(...skipping 18 matching lines...) Expand all
103 DCHECK(gvd_loop_proxy_->BelongsToCurrentThread()); 105 DCHECK(gvd_loop_proxy_->BelongsToCurrentThread());
104 if (vda_.get()) 106 if (vda_.get())
105 DestroyVDA(); 107 DestroyVDA();
106 BindToCurrentLoop(closure).Run(); 108 BindToCurrentLoop(closure).Run();
107 } 109 }
108 110
109 void GpuVideoDecoder::Initialize(const scoped_refptr<DemuxerStream>& stream, 111 void GpuVideoDecoder::Initialize(const scoped_refptr<DemuxerStream>& stream,
110 const PipelineStatusCB& orig_status_cb, 112 const PipelineStatusCB& orig_status_cb,
111 const StatisticsCB& statistics_cb) { 113 const StatisticsCB& statistics_cb) {
112 DCHECK(gvd_loop_proxy_->BelongsToCurrentThread()); 114 DCHECK(gvd_loop_proxy_->BelongsToCurrentThread());
115 weak_this_ = weak_factory_.GetWeakPtr();
116
113 PipelineStatusCB status_cb = CreateUMAReportingPipelineCB( 117 PipelineStatusCB status_cb = CreateUMAReportingPipelineCB(
114 "Media.GpuVideoDecoderInitializeStatus", 118 "Media.GpuVideoDecoderInitializeStatus",
115 BindToCurrentLoop(orig_status_cb)); 119 BindToCurrentLoop(orig_status_cb));
116 DCHECK(!demuxer_stream_); 120 DCHECK(!demuxer_stream_);
117 121
118 if (!stream) { 122 if (!stream) {
119 status_cb.Run(PIPELINE_ERROR_DECODE); 123 status_cb.Run(PIPELINE_ERROR_DECODE);
120 return; 124 return;
121 } 125 }
122 126
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
156 160
157 if (config.codec() == kCodecH264) 161 if (config.codec() == kCodecH264)
158 stream->EnableBitstreamConverter(); 162 stream->EnableBitstreamConverter();
159 163
160 demuxer_stream_ = stream; 164 demuxer_stream_ = stream;
161 statistics_cb_ = statistics_cb; 165 statistics_cb_ = statistics_cb;
162 166
163 DVLOG(1) << "GpuVideoDecoder::Initialize() succeeded."; 167 DVLOG(1) << "GpuVideoDecoder::Initialize() succeeded.";
164 vda_loop_proxy_->PostTaskAndReply( 168 vda_loop_proxy_->PostTaskAndReply(
165 FROM_HERE, 169 FROM_HERE,
166 base::Bind(&GpuVideoDecoder::SetVDA, this, vda), 170 base::Bind(&GpuVideoDecoder::SetVDA, weak_this_, vda),
167 base::Bind(status_cb, PIPELINE_OK)); 171 base::Bind(status_cb, PIPELINE_OK));
168 } 172 }
169 173
170 void GpuVideoDecoder::SetVDA(VideoDecodeAccelerator* vda) { 174 void GpuVideoDecoder::SetVDA(VideoDecodeAccelerator* vda) {
171 DCHECK(vda_loop_proxy_->BelongsToCurrentThread()); 175 DCHECK(vda_loop_proxy_->BelongsToCurrentThread());
172 DCHECK(!vda_.get()); 176 DCHECK(!vda_.get());
173 vda_.reset(vda); 177 vda_.reset(vda);
174 weak_vda_ = vda->AsWeakPtr(); 178 weak_vda_ = vda->AsWeakPtr();
175 } 179 }
176 180
177 void GpuVideoDecoder::DestroyTextures() { 181 void GpuVideoDecoder::DestroyTextures() {
178 for (std::map<int32, PictureBuffer>::iterator it = 182 for (std::map<int32, PictureBuffer>::iterator it =
179 picture_buffers_in_decoder_.begin(); 183 picture_buffers_in_decoder_.begin();
180 it != picture_buffers_in_decoder_.end(); ++it) { 184 it != picture_buffers_in_decoder_.end(); ++it) {
181 factories_->DeleteTexture(it->second.texture_id()); 185 factories_->DeleteTexture(it->second.texture_id());
182 } 186 }
183 picture_buffers_in_decoder_.clear(); 187 picture_buffers_in_decoder_.clear();
184 } 188 }
185 189
190 static void DestroyAndSignal(
191 base::WeakPtr<VideoDecodeAccelerator> weak_vda,
192 base::WaitableEvent* event) {
193 // XXX: how else would weak_vda be null?
scherkus (not reviewing) 2013/03/22 00:04:20 FYI
xhwang 2013/03/22 01:00:32 Defer this part to fischman :)
Ami GONE FROM CHROMIUM 2013/03/22 23:48:01 VDA unfortunately SupportsWeakPtr, so others can i
194 if (weak_vda)
195 weak_vda->Destroy();
196 event->Signal();
197 }
198
186 void GpuVideoDecoder::DestroyVDA() { 199 void GpuVideoDecoder::DestroyVDA() {
187 DCHECK(gvd_loop_proxy_->BelongsToCurrentThread()); 200 DCHECK(gvd_loop_proxy_->BelongsToCurrentThread());
188 VideoDecodeAccelerator* vda ALLOW_UNUSED = vda_.release(); 201 VideoDecodeAccelerator* vda ALLOW_UNUSED = vda_.release();
189 // Tricky: |this| needs to stay alive until after VDA::Destroy is actually 202
190 // called, not just posted, so we take an artificial ref to |this| and release 203 // Wait until VideoDecodeAccelerator::Destroy() completes.
scherkus (not reviewing) 2013/03/22 00:04:20 fischman: http://blog.operationreality.org/wp-cont
191 // it as |reply| after VDA::Destroy() returns. 204 base::WaitableEvent event(false, false);
192 AddRef(); 205 vda_loop_proxy_->PostTask(FROM_HERE, base::Bind(
193 vda_loop_proxy_->PostTaskAndReply( 206 &DestroyAndSignal, weak_vda_, &event));
194 FROM_HERE, 207 event.Wait();
Ami GONE FROM CHROMIUM 2013/03/22 23:48:01 This looks like a deadlock: Stop() calls this func
195 base::Bind(&VideoDecodeAccelerator::Destroy, weak_vda_),
196 base::Bind(&GpuVideoDecoder::Release, this));
197 208
198 DestroyTextures(); 209 DestroyTextures();
199 } 210 }
200 211
201 void GpuVideoDecoder::Read(const ReadCB& read_cb) { 212 void GpuVideoDecoder::Read(const ReadCB& read_cb) {
202 DCHECK(gvd_loop_proxy_->BelongsToCurrentThread()); 213 DCHECK(gvd_loop_proxy_->BelongsToCurrentThread());
203 DCHECK(pending_reset_cb_.is_null()); 214 DCHECK(pending_reset_cb_.is_null());
204 DCHECK(pending_read_cb_.is_null()); 215 DCHECK(pending_read_cb_.is_null());
205 pending_read_cb_ = BindToCurrentLoop(read_cb); 216 pending_read_cb_ = BindToCurrentLoop(read_cb);
206 217
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
238 return bitstream_buffers_in_decoder_.size() < kMaxInFlightDecodes; 249 return bitstream_buffers_in_decoder_.size() < kMaxInFlightDecodes;
239 } 250 }
240 251
241 void GpuVideoDecoder::RequestBufferDecode( 252 void GpuVideoDecoder::RequestBufferDecode(
242 DemuxerStream::Status status, 253 DemuxerStream::Status status,
243 const scoped_refptr<DecoderBuffer>& buffer) { 254 const scoped_refptr<DecoderBuffer>& buffer) {
244 DCHECK_EQ(status != DemuxerStream::kOk, !buffer) << status; 255 DCHECK_EQ(status != DemuxerStream::kOk, !buffer) << status;
245 256
246 if (!gvd_loop_proxy_->BelongsToCurrentThread()) { 257 if (!gvd_loop_proxy_->BelongsToCurrentThread()) {
247 gvd_loop_proxy_->PostTask(FROM_HERE, base::Bind( 258 gvd_loop_proxy_->PostTask(FROM_HERE, base::Bind(
248 &GpuVideoDecoder::RequestBufferDecode, this, status, buffer)); 259 &GpuVideoDecoder::RequestBufferDecode, weak_this_, status, buffer));
249 return; 260 return;
250 } 261 }
251 demuxer_read_in_progress_ = false; 262 demuxer_read_in_progress_ = false;
252 263
253 if (status != DemuxerStream::kOk) { 264 if (status != DemuxerStream::kOk) {
254 if (pending_read_cb_.is_null()) 265 if (pending_read_cb_.is_null())
255 return; 266 return;
256 267
257 // TODO(acolwell): Add support for reinitializing the decoder when 268 // TODO(acolwell): Add support for reinitializing the decoder when
258 // |status| == kConfigChanged. For now we just trigger a decode error. 269 // |status| == kConfigChanged. For now we just trigger a decode error.
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
344 355
345 void GpuVideoDecoder::NotifyInitializeDone() { 356 void GpuVideoDecoder::NotifyInitializeDone() {
346 NOTREACHED() << "GpuVideoDecodeAcceleratorHost::Initialize is synchronous!"; 357 NOTREACHED() << "GpuVideoDecodeAcceleratorHost::Initialize is synchronous!";
347 } 358 }
348 359
349 void GpuVideoDecoder::ProvidePictureBuffers(uint32 count, 360 void GpuVideoDecoder::ProvidePictureBuffers(uint32 count,
350 const gfx::Size& size, 361 const gfx::Size& size,
351 uint32 texture_target) { 362 uint32 texture_target) {
352 if (!gvd_loop_proxy_->BelongsToCurrentThread()) { 363 if (!gvd_loop_proxy_->BelongsToCurrentThread()) {
353 gvd_loop_proxy_->PostTask(FROM_HERE, base::Bind( 364 gvd_loop_proxy_->PostTask(FROM_HERE, base::Bind(
354 &GpuVideoDecoder::ProvidePictureBuffers, this, count, size, 365 &GpuVideoDecoder::ProvidePictureBuffers, weak_this_, count, size,
355 texture_target)); 366 texture_target));
356 return; 367 return;
357 } 368 }
358 369
359 std::vector<uint32> texture_ids; 370 std::vector<uint32> texture_ids;
360 decoder_texture_target_ = texture_target; 371 decoder_texture_target_ = texture_target;
361 if (!factories_->CreateTextures( 372 if (!factories_->CreateTextures(
362 count, size, &texture_ids, decoder_texture_target_)) { 373 count, size, &texture_ids, decoder_texture_target_)) {
363 NotifyError(VideoDecodeAccelerator::PLATFORM_FAILURE); 374 NotifyError(VideoDecodeAccelerator::PLATFORM_FAILURE);
364 return; 375 return;
(...skipping 14 matching lines...) Expand all
379 DCHECK(inserted); 390 DCHECK(inserted);
380 } 391 }
381 vda_loop_proxy_->PostTask(FROM_HERE, base::Bind( 392 vda_loop_proxy_->PostTask(FROM_HERE, base::Bind(
382 &VideoDecodeAccelerator::AssignPictureBuffers, weak_vda_, 393 &VideoDecodeAccelerator::AssignPictureBuffers, weak_vda_,
383 picture_buffers)); 394 picture_buffers));
384 } 395 }
385 396
386 void GpuVideoDecoder::DismissPictureBuffer(int32 id) { 397 void GpuVideoDecoder::DismissPictureBuffer(int32 id) {
387 if (!gvd_loop_proxy_->BelongsToCurrentThread()) { 398 if (!gvd_loop_proxy_->BelongsToCurrentThread()) {
388 gvd_loop_proxy_->PostTask(FROM_HERE, base::Bind( 399 gvd_loop_proxy_->PostTask(FROM_HERE, base::Bind(
389 &GpuVideoDecoder::DismissPictureBuffer, this, id)); 400 &GpuVideoDecoder::DismissPictureBuffer, weak_this_, id));
390 return; 401 return;
391 } 402 }
392 std::map<int32, PictureBuffer>::iterator it = 403 std::map<int32, PictureBuffer>::iterator it =
393 picture_buffers_in_decoder_.find(id); 404 picture_buffers_in_decoder_.find(id);
394 if (it == picture_buffers_in_decoder_.end()) { 405 if (it == picture_buffers_in_decoder_.end()) {
395 NOTREACHED() << "Missing picture buffer: " << id; 406 NOTREACHED() << "Missing picture buffer: " << id;
396 return; 407 return;
397 } 408 }
398 factories_->DeleteTexture(it->second.texture_id()); 409 factories_->DeleteTexture(it->second.texture_id());
399 picture_buffers_in_decoder_.erase(it); 410 picture_buffers_in_decoder_.erase(it);
400 } 411 }
401 412
402 void GpuVideoDecoder::PictureReady(const media::Picture& picture) { 413 void GpuVideoDecoder::PictureReady(const media::Picture& picture) {
403 if (!gvd_loop_proxy_->BelongsToCurrentThread()) { 414 if (!gvd_loop_proxy_->BelongsToCurrentThread()) {
404 gvd_loop_proxy_->PostTask(FROM_HERE, base::Bind( 415 gvd_loop_proxy_->PostTask(FROM_HERE, base::Bind(
405 &GpuVideoDecoder::PictureReady, this, picture)); 416 &GpuVideoDecoder::PictureReady, weak_this_, picture));
406 return; 417 return;
407 } 418 }
408 std::map<int32, PictureBuffer>::iterator it = 419 std::map<int32, PictureBuffer>::iterator it =
409 picture_buffers_in_decoder_.find(picture.picture_buffer_id()); 420 picture_buffers_in_decoder_.find(picture.picture_buffer_id());
410 if (it == picture_buffers_in_decoder_.end()) { 421 if (it == picture_buffers_in_decoder_.end()) {
411 NOTREACHED() << "Missing picture buffer: " << picture.picture_buffer_id(); 422 NOTREACHED() << "Missing picture buffer: " << picture.picture_buffer_id();
412 NotifyError(VideoDecodeAccelerator::PLATFORM_FAILURE); 423 NotifyError(VideoDecodeAccelerator::PLATFORM_FAILURE);
413 return; 424 return;
414 } 425 }
415 const PictureBuffer& pb = it->second; 426 const PictureBuffer& pb = it->second;
416 427
417 // Update frame's timestamp. 428 // Update frame's timestamp.
418 base::TimeDelta timestamp; 429 base::TimeDelta timestamp;
419 gfx::Rect visible_rect; 430 gfx::Rect visible_rect;
420 gfx::Size natural_size; 431 gfx::Size natural_size;
421 GetBufferData(picture.bitstream_buffer_id(), &timestamp, &visible_rect, 432 GetBufferData(picture.bitstream_buffer_id(), &timestamp, &visible_rect,
422 &natural_size); 433 &natural_size);
423 DCHECK(decoder_texture_target_); 434 DCHECK(decoder_texture_target_);
424 scoped_refptr<VideoFrame> frame( 435 scoped_refptr<VideoFrame> frame(
425 VideoFrame::WrapNativeTexture( 436 VideoFrame::WrapNativeTexture(
426 pb.texture_id(), decoder_texture_target_, pb.size(), visible_rect, 437 pb.texture_id(), decoder_texture_target_, pb.size(), visible_rect,
427 natural_size, timestamp, 438 natural_size, timestamp,
428 base::Bind(&Factories::ReadPixels, factories_, pb.texture_id(), 439 base::Bind(&Factories::ReadPixels, factories_, pb.texture_id(),
429 decoder_texture_target_, 440 decoder_texture_target_,
430 gfx::Size(visible_rect.width(), visible_rect.height())), 441 gfx::Size(visible_rect.width(), visible_rect.height())),
431 base::Bind(&GpuVideoDecoder::ReusePictureBuffer, this, 442 base::Bind(&GpuVideoDecoder::ReusePictureBuffer, weak_this_,
432 picture.picture_buffer_id()))); 443 picture.picture_buffer_id())));
433 CHECK_GT(available_pictures_, 0); 444 CHECK_GT(available_pictures_, 0);
434 available_pictures_--; 445 available_pictures_--;
435 446
436 EnqueueFrameAndTriggerFrameDelivery(frame); 447 EnqueueFrameAndTriggerFrameDelivery(frame);
437 } 448 }
438 449
439 void GpuVideoDecoder::EnqueueFrameAndTriggerFrameDelivery( 450 void GpuVideoDecoder::EnqueueFrameAndTriggerFrameDelivery(
440 const scoped_refptr<VideoFrame>& frame) { 451 const scoped_refptr<VideoFrame>& frame) {
441 DCHECK(gvd_loop_proxy_->BelongsToCurrentThread()); 452 DCHECK(gvd_loop_proxy_->BelongsToCurrentThread());
(...skipping 11 matching lines...) Expand all
453 if (pending_read_cb_.is_null()) 464 if (pending_read_cb_.is_null())
454 return; 465 return;
455 466
456 base::ResetAndReturn(&pending_read_cb_).Run(kOk, ready_video_frames_.front()); 467 base::ResetAndReturn(&pending_read_cb_).Run(kOk, ready_video_frames_.front());
457 ready_video_frames_.pop_front(); 468 ready_video_frames_.pop_front();
458 } 469 }
459 470
460 void GpuVideoDecoder::ReusePictureBuffer(int64 picture_buffer_id) { 471 void GpuVideoDecoder::ReusePictureBuffer(int64 picture_buffer_id) {
461 if (!gvd_loop_proxy_->BelongsToCurrentThread()) { 472 if (!gvd_loop_proxy_->BelongsToCurrentThread()) {
462 gvd_loop_proxy_->PostTask(FROM_HERE, base::Bind( 473 gvd_loop_proxy_->PostTask(FROM_HERE, base::Bind(
463 &GpuVideoDecoder::ReusePictureBuffer, this, picture_buffer_id)); 474 &GpuVideoDecoder::ReusePictureBuffer, weak_this_, picture_buffer_id));
464 return; 475 return;
465 } 476 }
466 CHECK_GE(available_pictures_, 0); 477 CHECK_GE(available_pictures_, 0);
467 available_pictures_++; 478 available_pictures_++;
468 479
469 if (!vda_.get()) 480 if (!vda_.get())
470 return; 481 return;
471 vda_loop_proxy_->PostTask(FROM_HERE, base::Bind( 482 vda_loop_proxy_->PostTask(FROM_HERE, base::Bind(
472 &VideoDecodeAccelerator::ReusePictureBuffer, weak_vda_, 483 &VideoDecodeAccelerator::ReusePictureBuffer, weak_vda_,
473 picture_buffer_id)); 484 picture_buffer_id));
(...skipping 14 matching lines...) Expand all
488 } 499 }
489 500
490 void GpuVideoDecoder::PutSHM(SHMBuffer* shm_buffer) { 501 void GpuVideoDecoder::PutSHM(SHMBuffer* shm_buffer) {
491 DCHECK(gvd_loop_proxy_->BelongsToCurrentThread()); 502 DCHECK(gvd_loop_proxy_->BelongsToCurrentThread());
492 available_shm_segments_.push_back(shm_buffer); 503 available_shm_segments_.push_back(shm_buffer);
493 } 504 }
494 505
495 void GpuVideoDecoder::NotifyEndOfBitstreamBuffer(int32 id) { 506 void GpuVideoDecoder::NotifyEndOfBitstreamBuffer(int32 id) {
496 if (!gvd_loop_proxy_->BelongsToCurrentThread()) { 507 if (!gvd_loop_proxy_->BelongsToCurrentThread()) {
497 gvd_loop_proxy_->PostTask(FROM_HERE, base::Bind( 508 gvd_loop_proxy_->PostTask(FROM_HERE, base::Bind(
498 &GpuVideoDecoder::NotifyEndOfBitstreamBuffer, this, id)); 509 &GpuVideoDecoder::NotifyEndOfBitstreamBuffer, weak_this_, id));
499 return; 510 return;
500 } 511 }
501 512
502 std::map<int32, BufferPair>::iterator it = 513 std::map<int32, BufferPair>::iterator it =
503 bitstream_buffers_in_decoder_.find(id); 514 bitstream_buffers_in_decoder_.find(id);
504 if (it == bitstream_buffers_in_decoder_.end()) { 515 if (it == bitstream_buffers_in_decoder_.end()) {
505 NotifyError(VideoDecodeAccelerator::PLATFORM_FAILURE); 516 NotifyError(VideoDecodeAccelerator::PLATFORM_FAILURE);
506 NOTREACHED() << "Missing bitstream buffer: " << id; 517 NOTREACHED() << "Missing bitstream buffer: " << id;
507 return; 518 return;
508 } 519 }
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
540 DestroyTextures(); 551 DestroyTextures();
541 } 552 }
542 553
543 void GpuVideoDecoder::EnsureDemuxOrDecode() { 554 void GpuVideoDecoder::EnsureDemuxOrDecode() {
544 DCHECK(gvd_loop_proxy_->BelongsToCurrentThread()); 555 DCHECK(gvd_loop_proxy_->BelongsToCurrentThread());
545 if (demuxer_read_in_progress_) 556 if (demuxer_read_in_progress_)
546 return; 557 return;
547 demuxer_read_in_progress_ = true; 558 demuxer_read_in_progress_ = true;
548 gvd_loop_proxy_->PostTask(FROM_HERE, base::Bind( 559 gvd_loop_proxy_->PostTask(FROM_HERE, base::Bind(
549 &DemuxerStream::Read, demuxer_stream_.get(), 560 &DemuxerStream::Read, demuxer_stream_.get(),
550 base::Bind(&GpuVideoDecoder::RequestBufferDecode, this))); 561 base::Bind(&GpuVideoDecoder::RequestBufferDecode, weak_this_)));
551 } 562 }
552 563
553 void GpuVideoDecoder::NotifyFlushDone() { 564 void GpuVideoDecoder::NotifyFlushDone() {
554 if (!gvd_loop_proxy_->BelongsToCurrentThread()) { 565 if (!gvd_loop_proxy_->BelongsToCurrentThread()) {
555 gvd_loop_proxy_->PostTask(FROM_HERE, base::Bind( 566 gvd_loop_proxy_->PostTask(FROM_HERE, base::Bind(
556 &GpuVideoDecoder::NotifyFlushDone, this)); 567 &GpuVideoDecoder::NotifyFlushDone, weak_this_));
557 return; 568 return;
558 } 569 }
559 DCHECK_EQ(state_, kDrainingDecoder); 570 DCHECK_EQ(state_, kDrainingDecoder);
560 state_ = kDecoderDrained; 571 state_ = kDecoderDrained;
561 EnqueueFrameAndTriggerFrameDelivery(VideoFrame::CreateEmptyFrame()); 572 EnqueueFrameAndTriggerFrameDelivery(VideoFrame::CreateEmptyFrame());
562 } 573 }
563 574
564 void GpuVideoDecoder::NotifyResetDone() { 575 void GpuVideoDecoder::NotifyResetDone() {
565 if (!gvd_loop_proxy_->BelongsToCurrentThread()) { 576 if (!gvd_loop_proxy_->BelongsToCurrentThread()) {
566 gvd_loop_proxy_->PostTask(FROM_HERE, base::Bind( 577 gvd_loop_proxy_->PostTask(FROM_HERE, base::Bind(
567 &GpuVideoDecoder::NotifyResetDone, this)); 578 &GpuVideoDecoder::NotifyResetDone, weak_this_));
568 return; 579 return;
569 } 580 }
570 581
571 if (!vda_.get()) 582 if (!vda_.get())
572 return; 583 return;
573 584
574 DCHECK(ready_video_frames_.empty()); 585 DCHECK(ready_video_frames_.empty());
575 586
576 // This needs to happen after the Reset() on vda_ is done to ensure pictures 587 // This needs to happen after the Reset() on vda_ is done to ensure pictures
577 // delivered during the reset can find their time data. 588 // delivered during the reset can find their time data.
578 input_buffer_data_.clear(); 589 input_buffer_data_.clear();
579 590
580 if (!pending_reset_cb_.is_null()) 591 if (!pending_reset_cb_.is_null())
581 base::ResetAndReturn(&pending_reset_cb_).Run(); 592 base::ResetAndReturn(&pending_reset_cb_).Run();
582 593
583 if (!pending_read_cb_.is_null()) 594 if (!pending_read_cb_.is_null())
584 EnqueueFrameAndTriggerFrameDelivery(VideoFrame::CreateEmptyFrame()); 595 EnqueueFrameAndTriggerFrameDelivery(VideoFrame::CreateEmptyFrame());
585 } 596 }
586 597
587 void GpuVideoDecoder::NotifyError(media::VideoDecodeAccelerator::Error error) { 598 void GpuVideoDecoder::NotifyError(media::VideoDecodeAccelerator::Error error) {
588 if (!gvd_loop_proxy_->BelongsToCurrentThread()) { 599 if (!gvd_loop_proxy_->BelongsToCurrentThread()) {
589 gvd_loop_proxy_->PostTask(FROM_HERE, base::Bind( 600 gvd_loop_proxy_->PostTask(FROM_HERE, base::Bind(
590 &GpuVideoDecoder::NotifyError, this, error)); 601 &GpuVideoDecoder::NotifyError, weak_this_, error));
591 return; 602 return;
592 } 603 }
593 if (!vda_.get()) 604 if (!vda_.get())
594 return; 605 return;
595 606
596 DLOG(ERROR) << "VDA Error: " << error; 607 DLOG(ERROR) << "VDA Error: " << error;
597 DestroyVDA(); 608 DestroyVDA();
598 609
599 error_occured_ = true; 610 error_occured_ = true;
600 611
601 if (!pending_read_cb_.is_null()) { 612 if (!pending_read_cb_.is_null()) {
602 base::ResetAndReturn(&pending_read_cb_).Run(kDecodeError, NULL); 613 base::ResetAndReturn(&pending_read_cb_).Run(kDecodeError, NULL);
603 return; 614 return;
604 } 615 }
605 } 616 }
606 617
607 } // namespace media 618 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698