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

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: Fixes 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
« no previous file with comments | « media/filters/gpu_video_decoder.h ('k') | media/filters/pipeline_integration_test_base.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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/task_runner_util.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 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
154 return; 158 return;
155 } 159 }
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 PostTaskAndReplyWithResult(
165 FROM_HERE, 169 vda_loop_proxy_, FROM_HERE,
166 base::Bind(&GpuVideoDecoder::SetVDA, this, vda), 170 base::Bind(&VideoDecodeAccelerator::AsWeakPtr, base::Unretained(vda)),
167 base::Bind(status_cb, PIPELINE_OK)); 171 base::Bind(&GpuVideoDecoder::SetVDA, weak_this_, status_cb, vda));
168 } 172 }
169 173
170 void GpuVideoDecoder::SetVDA(VideoDecodeAccelerator* vda) { 174 void GpuVideoDecoder::SetVDA(
171 DCHECK(vda_loop_proxy_->BelongsToCurrentThread()); 175 const PipelineStatusCB& status_cb,
176 VideoDecodeAccelerator* vda,
177 base::WeakPtr<VideoDecodeAccelerator> weak_vda) {
178 DCHECK(gvd_loop_proxy_->BelongsToCurrentThread());
172 DCHECK(!vda_.get()); 179 DCHECK(!vda_.get());
173 vda_.reset(vda); 180 vda_.reset(vda);
174 weak_vda_ = vda->AsWeakPtr(); 181 weak_vda_ = weak_vda;
182 status_cb.Run(PIPELINE_OK);
175 } 183 }
176 184
177 void GpuVideoDecoder::DestroyTextures() { 185 void GpuVideoDecoder::DestroyTextures() {
178 for (std::map<int32, PictureBuffer>::iterator it = 186 for (std::map<int32, PictureBuffer>::iterator it =
179 picture_buffers_in_decoder_.begin(); 187 picture_buffers_in_decoder_.begin();
180 it != picture_buffers_in_decoder_.end(); ++it) { 188 it != picture_buffers_in_decoder_.end(); ++it) {
181 factories_->DeleteTexture(it->second.texture_id()); 189 factories_->DeleteTexture(it->second.texture_id());
182 } 190 }
183 picture_buffers_in_decoder_.clear(); 191 picture_buffers_in_decoder_.clear();
184 } 192 }
185 193
186 void GpuVideoDecoder::DestroyVDA() { 194 void GpuVideoDecoder::DestroyVDA() {
187 DCHECK(gvd_loop_proxy_->BelongsToCurrentThread()); 195 DCHECK(gvd_loop_proxy_->BelongsToCurrentThread());
188 VideoDecodeAccelerator* vda ALLOW_UNUSED = vda_.release(); 196 VideoDecodeAccelerator* vda ALLOW_UNUSED = vda_.release();
189 // Tricky: |this| needs to stay alive until after VDA::Destroy is actually 197
190 // called, not just posted, so we take an artificial ref to |this| and release 198 // Note: I don't think it's possible to guarantee that VDA *won't* call us
scherkus (not reviewing) 2013/03/28 02:00:01 FYI It's a bit late in the day, but I'm not sure
Ami GONE FROM CHROMIUM 2013/03/29 23:55:19 Yes, this is the key point of this CL :) Today GVD
scherkus (not reviewing) 2013/04/05 01:18:30 I'd prefer to not mess around w/ transferring owne
191 // it as |reply| after VDA::Destroy() returns. 199 // after GVD has been destroyed.
192 AddRef(); 200 //
193 vda_loop_proxy_->PostTaskAndReply( 201 // Example:
194 FROM_HERE, 202 // * VDA runs on render thread
195 base::Bind(&VideoDecodeAccelerator::Destroy, weak_vda_), 203 // * WMPI is blocking render thread on Stop()
196 base::Bind(&GpuVideoDecoder::Release, this)); 204 // * GVD receives Stop() on media thread
205 // * GVD posts VDA::Destroy() to render thread
206 // * GVD completes Stop() and WMPI becomes unblocked
207 // * WMPI + GVD are destroyed
208 // * VDA executes pending work on GVD on render thread
209 // * -- boom --
210 vda_loop_proxy_->PostTask(FROM_HERE, base::Bind(
211 &VideoDecodeAccelerator::Destroy, weak_vda_));
197 212
198 DestroyTextures(); 213 DestroyTextures();
199 } 214 }
200 215
201 void GpuVideoDecoder::Read(const ReadCB& read_cb) { 216 void GpuVideoDecoder::Read(const ReadCB& read_cb) {
202 DCHECK(gvd_loop_proxy_->BelongsToCurrentThread()); 217 DCHECK(gvd_loop_proxy_->BelongsToCurrentThread());
203 DCHECK(pending_reset_cb_.is_null()); 218 DCHECK(pending_reset_cb_.is_null());
204 DCHECK(pending_read_cb_.is_null()); 219 DCHECK(pending_read_cb_.is_null());
205 pending_read_cb_ = BindToCurrentLoop(read_cb); 220 pending_read_cb_ = BindToCurrentLoop(read_cb);
206 221
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
238 return bitstream_buffers_in_decoder_.size() < kMaxInFlightDecodes; 253 return bitstream_buffers_in_decoder_.size() < kMaxInFlightDecodes;
239 } 254 }
240 255
241 void GpuVideoDecoder::RequestBufferDecode( 256 void GpuVideoDecoder::RequestBufferDecode(
242 DemuxerStream::Status status, 257 DemuxerStream::Status status,
243 const scoped_refptr<DecoderBuffer>& buffer) { 258 const scoped_refptr<DecoderBuffer>& buffer) {
244 DCHECK_EQ(status != DemuxerStream::kOk, !buffer) << status; 259 DCHECK_EQ(status != DemuxerStream::kOk, !buffer) << status;
245 260
246 if (!gvd_loop_proxy_->BelongsToCurrentThread()) { 261 if (!gvd_loop_proxy_->BelongsToCurrentThread()) {
247 gvd_loop_proxy_->PostTask(FROM_HERE, base::Bind( 262 gvd_loop_proxy_->PostTask(FROM_HERE, base::Bind(
248 &GpuVideoDecoder::RequestBufferDecode, this, status, buffer)); 263 &GpuVideoDecoder::RequestBufferDecode, weak_this_, status, buffer));
249 return; 264 return;
250 } 265 }
251 demuxer_read_in_progress_ = false; 266 demuxer_read_in_progress_ = false;
252 267
253 if (status != DemuxerStream::kOk) { 268 if (status != DemuxerStream::kOk) {
254 if (pending_read_cb_.is_null()) 269 if (pending_read_cb_.is_null())
255 return; 270 return;
256 271
257 // TODO(acolwell): Add support for reinitializing the decoder when 272 // TODO(acolwell): Add support for reinitializing the decoder when
258 // |status| == kConfigChanged. For now we just trigger a decode error. 273 // |status| == kConfigChanged. For now we just trigger a decode error.
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
344 359
345 void GpuVideoDecoder::NotifyInitializeDone() { 360 void GpuVideoDecoder::NotifyInitializeDone() {
346 NOTREACHED() << "GpuVideoDecodeAcceleratorHost::Initialize is synchronous!"; 361 NOTREACHED() << "GpuVideoDecodeAcceleratorHost::Initialize is synchronous!";
347 } 362 }
348 363
349 void GpuVideoDecoder::ProvidePictureBuffers(uint32 count, 364 void GpuVideoDecoder::ProvidePictureBuffers(uint32 count,
350 const gfx::Size& size, 365 const gfx::Size& size,
351 uint32 texture_target) { 366 uint32 texture_target) {
352 if (!gvd_loop_proxy_->BelongsToCurrentThread()) { 367 if (!gvd_loop_proxy_->BelongsToCurrentThread()) {
353 gvd_loop_proxy_->PostTask(FROM_HERE, base::Bind( 368 gvd_loop_proxy_->PostTask(FROM_HERE, base::Bind(
354 &GpuVideoDecoder::ProvidePictureBuffers, this, count, size, 369 &GpuVideoDecoder::ProvidePictureBuffers, weak_this_, count, size,
355 texture_target)); 370 texture_target));
356 return; 371 return;
357 } 372 }
358 373
359 std::vector<uint32> texture_ids; 374 std::vector<uint32> texture_ids;
360 decoder_texture_target_ = texture_target; 375 decoder_texture_target_ = texture_target;
361 if (!factories_->CreateTextures( 376 if (!factories_->CreateTextures(
362 count, size, &texture_ids, decoder_texture_target_)) { 377 count, size, &texture_ids, decoder_texture_target_)) {
363 NotifyError(VideoDecodeAccelerator::PLATFORM_FAILURE); 378 NotifyError(VideoDecodeAccelerator::PLATFORM_FAILURE);
364 return; 379 return;
(...skipping 14 matching lines...) Expand all
379 DCHECK(inserted); 394 DCHECK(inserted);
380 } 395 }
381 vda_loop_proxy_->PostTask(FROM_HERE, base::Bind( 396 vda_loop_proxy_->PostTask(FROM_HERE, base::Bind(
382 &VideoDecodeAccelerator::AssignPictureBuffers, weak_vda_, 397 &VideoDecodeAccelerator::AssignPictureBuffers, weak_vda_,
383 picture_buffers)); 398 picture_buffers));
384 } 399 }
385 400
386 void GpuVideoDecoder::DismissPictureBuffer(int32 id) { 401 void GpuVideoDecoder::DismissPictureBuffer(int32 id) {
387 if (!gvd_loop_proxy_->BelongsToCurrentThread()) { 402 if (!gvd_loop_proxy_->BelongsToCurrentThread()) {
388 gvd_loop_proxy_->PostTask(FROM_HERE, base::Bind( 403 gvd_loop_proxy_->PostTask(FROM_HERE, base::Bind(
389 &GpuVideoDecoder::DismissPictureBuffer, this, id)); 404 &GpuVideoDecoder::DismissPictureBuffer, weak_this_, id));
390 return; 405 return;
391 } 406 }
392 std::map<int32, PictureBuffer>::iterator it = 407 std::map<int32, PictureBuffer>::iterator it =
393 picture_buffers_in_decoder_.find(id); 408 picture_buffers_in_decoder_.find(id);
394 if (it == picture_buffers_in_decoder_.end()) { 409 if (it == picture_buffers_in_decoder_.end()) {
395 NOTREACHED() << "Missing picture buffer: " << id; 410 NOTREACHED() << "Missing picture buffer: " << id;
396 return; 411 return;
397 } 412 }
398 factories_->DeleteTexture(it->second.texture_id()); 413 factories_->DeleteTexture(it->second.texture_id());
399 picture_buffers_in_decoder_.erase(it); 414 picture_buffers_in_decoder_.erase(it);
400 } 415 }
401 416
402 void GpuVideoDecoder::PictureReady(const media::Picture& picture) { 417 void GpuVideoDecoder::PictureReady(const media::Picture& picture) {
403 if (!gvd_loop_proxy_->BelongsToCurrentThread()) { 418 if (!gvd_loop_proxy_->BelongsToCurrentThread()) {
404 gvd_loop_proxy_->PostTask(FROM_HERE, base::Bind( 419 gvd_loop_proxy_->PostTask(FROM_HERE, base::Bind(
405 &GpuVideoDecoder::PictureReady, this, picture)); 420 &GpuVideoDecoder::PictureReady, weak_this_, picture));
406 return; 421 return;
407 } 422 }
408 std::map<int32, PictureBuffer>::iterator it = 423 std::map<int32, PictureBuffer>::iterator it =
409 picture_buffers_in_decoder_.find(picture.picture_buffer_id()); 424 picture_buffers_in_decoder_.find(picture.picture_buffer_id());
410 if (it == picture_buffers_in_decoder_.end()) { 425 if (it == picture_buffers_in_decoder_.end()) {
411 NOTREACHED() << "Missing picture buffer: " << picture.picture_buffer_id(); 426 NOTREACHED() << "Missing picture buffer: " << picture.picture_buffer_id();
412 NotifyError(VideoDecodeAccelerator::PLATFORM_FAILURE); 427 NotifyError(VideoDecodeAccelerator::PLATFORM_FAILURE);
413 return; 428 return;
414 } 429 }
415 const PictureBuffer& pb = it->second; 430 const PictureBuffer& pb = it->second;
416 431
417 // Update frame's timestamp. 432 // Update frame's timestamp.
418 base::TimeDelta timestamp; 433 base::TimeDelta timestamp;
419 gfx::Rect visible_rect; 434 gfx::Rect visible_rect;
420 gfx::Size natural_size; 435 gfx::Size natural_size;
421 GetBufferData(picture.bitstream_buffer_id(), &timestamp, &visible_rect, 436 GetBufferData(picture.bitstream_buffer_id(), &timestamp, &visible_rect,
422 &natural_size); 437 &natural_size);
423 DCHECK(decoder_texture_target_); 438 DCHECK(decoder_texture_target_);
424 scoped_refptr<VideoFrame> frame( 439 scoped_refptr<VideoFrame> frame(
425 VideoFrame::WrapNativeTexture( 440 VideoFrame::WrapNativeTexture(
426 pb.texture_id(), decoder_texture_target_, pb.size(), visible_rect, 441 pb.texture_id(), decoder_texture_target_, pb.size(), visible_rect,
427 natural_size, timestamp, 442 natural_size, timestamp,
428 base::Bind(&Factories::ReadPixels, factories_, pb.texture_id(), 443 base::Bind(&Factories::ReadPixels, factories_, pb.texture_id(),
429 decoder_texture_target_, 444 decoder_texture_target_,
430 gfx::Size(visible_rect.width(), visible_rect.height())), 445 gfx::Size(visible_rect.width(), visible_rect.height())),
431 base::Bind(&GpuVideoDecoder::ReusePictureBuffer, this, 446 BindToCurrentLoop(base::Bind(
432 picture.picture_buffer_id()))); 447 &GpuVideoDecoder::ReusePictureBuffer, weak_this_,
448 picture.picture_buffer_id()))));
433 CHECK_GT(available_pictures_, 0); 449 CHECK_GT(available_pictures_, 0);
434 available_pictures_--; 450 available_pictures_--;
435 451
436 EnqueueFrameAndTriggerFrameDelivery(frame); 452 EnqueueFrameAndTriggerFrameDelivery(frame);
437 } 453 }
438 454
439 void GpuVideoDecoder::EnqueueFrameAndTriggerFrameDelivery( 455 void GpuVideoDecoder::EnqueueFrameAndTriggerFrameDelivery(
440 const scoped_refptr<VideoFrame>& frame) { 456 const scoped_refptr<VideoFrame>& frame) {
441 DCHECK(gvd_loop_proxy_->BelongsToCurrentThread()); 457 DCHECK(gvd_loop_proxy_->BelongsToCurrentThread());
442 458
443 // During a pending vda->Reset(), we don't accumulate frames. Drop it on the 459 // During a pending vda->Reset(), we don't accumulate frames. Drop it on the
444 // floor and return. 460 // floor and return.
445 if (!pending_reset_cb_.is_null()) 461 if (!pending_reset_cb_.is_null())
446 return; 462 return;
447 463
448 if (frame) 464 if (frame)
449 ready_video_frames_.push_back(frame); 465 ready_video_frames_.push_back(frame);
450 else 466 else
451 DCHECK(!ready_video_frames_.empty()); 467 DCHECK(!ready_video_frames_.empty());
452 468
453 if (pending_read_cb_.is_null()) 469 if (pending_read_cb_.is_null())
454 return; 470 return;
455 471
456 base::ResetAndReturn(&pending_read_cb_).Run(kOk, ready_video_frames_.front()); 472 base::ResetAndReturn(&pending_read_cb_).Run(kOk, ready_video_frames_.front());
457 ready_video_frames_.pop_front(); 473 ready_video_frames_.pop_front();
458 } 474 }
459 475
460 void GpuVideoDecoder::ReusePictureBuffer(int64 picture_buffer_id) { 476 void GpuVideoDecoder::ReusePictureBuffer(int64 picture_buffer_id) {
461 if (!gvd_loop_proxy_->BelongsToCurrentThread()) { 477 DCHECK(gvd_loop_proxy_->BelongsToCurrentThread());
462 gvd_loop_proxy_->PostTask(FROM_HERE, base::Bind(
463 &GpuVideoDecoder::ReusePictureBuffer, this, picture_buffer_id));
464 return;
465 }
466 CHECK_GE(available_pictures_, 0); 478 CHECK_GE(available_pictures_, 0);
467 available_pictures_++; 479 available_pictures_++;
468 480
469 if (!vda_.get()) 481 if (!vda_.get())
470 return; 482 return;
471 vda_loop_proxy_->PostTask(FROM_HERE, base::Bind( 483 vda_loop_proxy_->PostTask(FROM_HERE, base::Bind(
472 &VideoDecodeAccelerator::ReusePictureBuffer, weak_vda_, 484 &VideoDecodeAccelerator::ReusePictureBuffer, weak_vda_,
473 picture_buffer_id)); 485 picture_buffer_id));
474 } 486 }
475 487
(...skipping 12 matching lines...) Expand all
488 } 500 }
489 501
490 void GpuVideoDecoder::PutSHM(SHMBuffer* shm_buffer) { 502 void GpuVideoDecoder::PutSHM(SHMBuffer* shm_buffer) {
491 DCHECK(gvd_loop_proxy_->BelongsToCurrentThread()); 503 DCHECK(gvd_loop_proxy_->BelongsToCurrentThread());
492 available_shm_segments_.push_back(shm_buffer); 504 available_shm_segments_.push_back(shm_buffer);
493 } 505 }
494 506
495 void GpuVideoDecoder::NotifyEndOfBitstreamBuffer(int32 id) { 507 void GpuVideoDecoder::NotifyEndOfBitstreamBuffer(int32 id) {
496 if (!gvd_loop_proxy_->BelongsToCurrentThread()) { 508 if (!gvd_loop_proxy_->BelongsToCurrentThread()) {
497 gvd_loop_proxy_->PostTask(FROM_HERE, base::Bind( 509 gvd_loop_proxy_->PostTask(FROM_HERE, base::Bind(
498 &GpuVideoDecoder::NotifyEndOfBitstreamBuffer, this, id)); 510 &GpuVideoDecoder::NotifyEndOfBitstreamBuffer, weak_this_, id));
499 return; 511 return;
500 } 512 }
501 513
502 std::map<int32, BufferPair>::iterator it = 514 std::map<int32, BufferPair>::iterator it =
503 bitstream_buffers_in_decoder_.find(id); 515 bitstream_buffers_in_decoder_.find(id);
504 if (it == bitstream_buffers_in_decoder_.end()) { 516 if (it == bitstream_buffers_in_decoder_.end()) {
505 NotifyError(VideoDecodeAccelerator::PLATFORM_FAILURE); 517 NotifyError(VideoDecodeAccelerator::PLATFORM_FAILURE);
506 NOTREACHED() << "Missing bitstream buffer: " << id; 518 NOTREACHED() << "Missing bitstream buffer: " << id;
507 return; 519 return;
508 } 520 }
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
540 DestroyTextures(); 552 DestroyTextures();
541 } 553 }
542 554
543 void GpuVideoDecoder::EnsureDemuxOrDecode() { 555 void GpuVideoDecoder::EnsureDemuxOrDecode() {
544 DCHECK(gvd_loop_proxy_->BelongsToCurrentThread()); 556 DCHECK(gvd_loop_proxy_->BelongsToCurrentThread());
545 if (demuxer_read_in_progress_) 557 if (demuxer_read_in_progress_)
546 return; 558 return;
547 demuxer_read_in_progress_ = true; 559 demuxer_read_in_progress_ = true;
548 gvd_loop_proxy_->PostTask(FROM_HERE, base::Bind( 560 gvd_loop_proxy_->PostTask(FROM_HERE, base::Bind(
549 &DemuxerStream::Read, demuxer_stream_.get(), 561 &DemuxerStream::Read, demuxer_stream_.get(),
550 base::Bind(&GpuVideoDecoder::RequestBufferDecode, this))); 562 base::Bind(&GpuVideoDecoder::RequestBufferDecode, weak_this_)));
551 } 563 }
552 564
553 void GpuVideoDecoder::NotifyFlushDone() { 565 void GpuVideoDecoder::NotifyFlushDone() {
554 if (!gvd_loop_proxy_->BelongsToCurrentThread()) { 566 if (!gvd_loop_proxy_->BelongsToCurrentThread()) {
555 gvd_loop_proxy_->PostTask(FROM_HERE, base::Bind( 567 gvd_loop_proxy_->PostTask(FROM_HERE, base::Bind(
556 &GpuVideoDecoder::NotifyFlushDone, this)); 568 &GpuVideoDecoder::NotifyFlushDone, weak_this_));
557 return; 569 return;
558 } 570 }
559 DCHECK_EQ(state_, kDrainingDecoder); 571 DCHECK_EQ(state_, kDrainingDecoder);
560 state_ = kDecoderDrained; 572 state_ = kDecoderDrained;
561 EnqueueFrameAndTriggerFrameDelivery(VideoFrame::CreateEmptyFrame()); 573 EnqueueFrameAndTriggerFrameDelivery(VideoFrame::CreateEmptyFrame());
562 } 574 }
563 575
564 void GpuVideoDecoder::NotifyResetDone() { 576 void GpuVideoDecoder::NotifyResetDone() {
565 if (!gvd_loop_proxy_->BelongsToCurrentThread()) { 577 if (!gvd_loop_proxy_->BelongsToCurrentThread()) {
566 gvd_loop_proxy_->PostTask(FROM_HERE, base::Bind( 578 gvd_loop_proxy_->PostTask(FROM_HERE, base::Bind(
567 &GpuVideoDecoder::NotifyResetDone, this)); 579 &GpuVideoDecoder::NotifyResetDone, weak_this_));
568 return; 580 return;
569 } 581 }
570 582
571 if (!vda_.get()) 583 if (!vda_.get())
572 return; 584 return;
573 585
574 DCHECK(ready_video_frames_.empty()); 586 DCHECK(ready_video_frames_.empty());
575 587
576 // This needs to happen after the Reset() on vda_ is done to ensure pictures 588 // This needs to happen after the Reset() on vda_ is done to ensure pictures
577 // delivered during the reset can find their time data. 589 // delivered during the reset can find their time data.
578 input_buffer_data_.clear(); 590 input_buffer_data_.clear();
579 591
580 if (!pending_reset_cb_.is_null()) 592 if (!pending_reset_cb_.is_null())
581 base::ResetAndReturn(&pending_reset_cb_).Run(); 593 base::ResetAndReturn(&pending_reset_cb_).Run();
582 594
583 if (!pending_read_cb_.is_null()) 595 if (!pending_read_cb_.is_null())
584 EnqueueFrameAndTriggerFrameDelivery(VideoFrame::CreateEmptyFrame()); 596 EnqueueFrameAndTriggerFrameDelivery(VideoFrame::CreateEmptyFrame());
585 } 597 }
586 598
587 void GpuVideoDecoder::NotifyError(media::VideoDecodeAccelerator::Error error) { 599 void GpuVideoDecoder::NotifyError(media::VideoDecodeAccelerator::Error error) {
588 if (!gvd_loop_proxy_->BelongsToCurrentThread()) { 600 if (!gvd_loop_proxy_->BelongsToCurrentThread()) {
589 gvd_loop_proxy_->PostTask(FROM_HERE, base::Bind( 601 gvd_loop_proxy_->PostTask(FROM_HERE, base::Bind(
590 &GpuVideoDecoder::NotifyError, this, error)); 602 &GpuVideoDecoder::NotifyError, weak_this_, error));
591 return; 603 return;
592 } 604 }
593 if (!vda_.get()) 605 if (!vda_.get())
594 return; 606 return;
595 607
596 DLOG(ERROR) << "VDA Error: " << error; 608 DLOG(ERROR) << "VDA Error: " << error;
597 DestroyVDA(); 609 DestroyVDA();
598 610
599 error_occured_ = true; 611 error_occured_ = true;
600 612
601 if (!pending_read_cb_.is_null()) { 613 if (!pending_read_cb_.is_null()) {
602 base::ResetAndReturn(&pending_read_cb_).Run(kDecodeError, NULL); 614 base::ResetAndReturn(&pending_read_cb_).Run(kDecodeError, NULL);
603 return; 615 return;
604 } 616 }
605 } 617 }
606 618
607 } // namespace media 619 } // namespace media
OLDNEW
« no previous file with comments | « media/filters/gpu_video_decoder.h ('k') | media/filters/pipeline_integration_test_base.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698