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

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

Issue 20136002: Reland r212023 "Rename VideoDecoder::ReadCB to VideoDecoder::DecodeCB." (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: fix content_browsertests failure. Created 7 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
« no previous file with comments | « media/filters/gpu_video_decoder.h ('k') | media/filters/video_frame_stream.h » ('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 <algorithm> 7 #include <algorithm>
8 8
9 #include "base/bind.h" 9 #include "base/bind.h"
10 #include "base/callback_helpers.h" 10 #include "base/callback_helpers.h"
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
67 67
68 void GpuVideoDecoder::Reset(const base::Closure& closure) { 68 void GpuVideoDecoder::Reset(const base::Closure& closure) {
69 DVLOG(3) << "Reset()"; 69 DVLOG(3) << "Reset()";
70 DCHECK(gvd_loop_proxy_->BelongsToCurrentThread()); 70 DCHECK(gvd_loop_proxy_->BelongsToCurrentThread());
71 71
72 if (state_ == kDrainingDecoder && !factories_->IsAborted()) { 72 if (state_ == kDrainingDecoder && !factories_->IsAborted()) {
73 gvd_loop_proxy_->PostTask(FROM_HERE, base::Bind( 73 gvd_loop_proxy_->PostTask(FROM_HERE, base::Bind(
74 &GpuVideoDecoder::Reset, weak_this_, closure)); 74 &GpuVideoDecoder::Reset, weak_this_, closure));
75 // NOTE: if we're deferring Reset() until a Flush() completes, return 75 // 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(). 76 // queued pictures to the VDA so they can be used to finish that Flush().
77 if (pending_read_cb_.is_null()) 77 if (pending_decode_cb_.is_null())
78 ready_video_frames_.clear(); 78 ready_video_frames_.clear();
79 return; 79 return;
80 } 80 }
81 81
82 // Throw away any already-decoded, not-yet-delivered frames. 82 // Throw away any already-decoded, not-yet-delivered frames.
83 ready_video_frames_.clear(); 83 ready_video_frames_.clear();
84 84
85 if (!vda_) { 85 if (!vda_) {
86 gvd_loop_proxy_->PostTask(FROM_HERE, closure); 86 gvd_loop_proxy_->PostTask(FROM_HERE, closure);
87 return; 87 return;
88 } 88 }
89 89
90 if (!pending_read_cb_.is_null()) 90 if (!pending_decode_cb_.is_null())
91 EnqueueFrameAndTriggerFrameDelivery(VideoFrame::CreateEmptyFrame()); 91 EnqueueFrameAndTriggerFrameDelivery(VideoFrame::CreateEmptyFrame());
92 92
93 DCHECK(pending_reset_cb_.is_null()); 93 DCHECK(pending_reset_cb_.is_null());
94 pending_reset_cb_ = BindToCurrentLoop(closure); 94 pending_reset_cb_ = BindToCurrentLoop(closure);
95 95
96 vda_->Reset(); 96 vda_->Reset();
97 } 97 }
98 98
99 void GpuVideoDecoder::Stop(const base::Closure& closure) { 99 void GpuVideoDecoder::Stop(const base::Closure& closure) {
100 DCHECK(gvd_loop_proxy_->BelongsToCurrentThread()); 100 DCHECK(gvd_loop_proxy_->BelongsToCurrentThread());
101 if (vda_) 101 if (vda_)
102 DestroyVDA(); 102 DestroyVDA();
103 if (!pending_read_cb_.is_null()) 103 if (!pending_decode_cb_.is_null())
104 EnqueueFrameAndTriggerFrameDelivery(VideoFrame::CreateEmptyFrame()); 104 EnqueueFrameAndTriggerFrameDelivery(VideoFrame::CreateEmptyFrame());
105 if (!pending_reset_cb_.is_null()) 105 if (!pending_reset_cb_.is_null())
106 base::ResetAndReturn(&pending_reset_cb_).Run(); 106 base::ResetAndReturn(&pending_reset_cb_).Run();
107 BindToCurrentLoop(closure).Run(); 107 BindToCurrentLoop(closure).Run();
108 } 108 }
109 109
110 static bool IsCodedSizeSupported(const gfx::Size& coded_size) { 110 static bool IsCodedSizeSupported(const gfx::Size& coded_size) {
111 // Only non-Windows, Ivy Bridge+ platforms can support more than 1920x1080. 111 // Only non-Windows, Ivy Bridge+ platforms can support more than 1920x1080.
112 // We test against 1088 to account for 16x16 macroblocks. 112 // We test against 1088 to account for 16x16 macroblocks.
113 if (coded_size.width() <= 1920 && coded_size.height() <= 1088) 113 if (coded_size.width() <= 1920 && coded_size.height() <= 1088)
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
181 void GpuVideoDecoder::DestroyVDA() { 181 void GpuVideoDecoder::DestroyVDA() {
182 DCHECK(gvd_loop_proxy_->BelongsToCurrentThread()); 182 DCHECK(gvd_loop_proxy_->BelongsToCurrentThread());
183 183
184 if (vda_) 184 if (vda_)
185 vda_.release()->Destroy(); 185 vda_.release()->Destroy();
186 186
187 DestroyTextures(); 187 DestroyTextures();
188 } 188 }
189 189
190 void GpuVideoDecoder::Decode(const scoped_refptr<DecoderBuffer>& buffer, 190 void GpuVideoDecoder::Decode(const scoped_refptr<DecoderBuffer>& buffer,
191 const ReadCB& read_cb) { 191 const DecodeCB& decode_cb) {
192 DCHECK(gvd_loop_proxy_->BelongsToCurrentThread()); 192 DCHECK(gvd_loop_proxy_->BelongsToCurrentThread());
193 DCHECK(pending_reset_cb_.is_null()); 193 DCHECK(pending_reset_cb_.is_null());
194 DCHECK(pending_read_cb_.is_null()); 194 DCHECK(pending_decode_cb_.is_null());
195 195
196 pending_read_cb_ = BindToCurrentLoop(read_cb); 196 pending_decode_cb_ = BindToCurrentLoop(decode_cb);
197 197
198 if (state_ == kError || !vda_) { 198 if (state_ == kError || !vda_) {
199 base::ResetAndReturn(&pending_read_cb_).Run(kDecodeError, NULL); 199 base::ResetAndReturn(&pending_decode_cb_).Run(kDecodeError, NULL);
200 return; 200 return;
201 } 201 }
202 202
203 switch (state_) { 203 switch (state_) {
204 case kDecoderDrained: 204 case kDecoderDrained:
205 if (!ready_video_frames_.empty()) { 205 if (!ready_video_frames_.empty()) {
206 EnqueueFrameAndTriggerFrameDelivery(NULL); 206 EnqueueFrameAndTriggerFrameDelivery(NULL);
207 return; 207 return;
208 } 208 }
209 state_ = kNormal; 209 state_ = kNormal;
(...skipping 14 matching lines...) Expand all
224 if (state_ == kNormal) { 224 if (state_ == kNormal) {
225 state_ = kDrainingDecoder; 225 state_ = kDrainingDecoder;
226 vda_->Flush(); 226 vda_->Flush();
227 } 227 }
228 return; 228 return;
229 } 229 }
230 230
231 size_t size = buffer->data_size(); 231 size_t size = buffer->data_size();
232 SHMBuffer* shm_buffer = GetSHM(size); 232 SHMBuffer* shm_buffer = GetSHM(size);
233 if (!shm_buffer) { 233 if (!shm_buffer) {
234 base::ResetAndReturn(&pending_read_cb_).Run(kDecodeError, NULL); 234 base::ResetAndReturn(&pending_decode_cb_).Run(kDecodeError, NULL);
235 return; 235 return;
236 } 236 }
237 237
238 memcpy(shm_buffer->shm->memory(), buffer->data(), size); 238 memcpy(shm_buffer->shm->memory(), buffer->data(), size);
239 BitstreamBuffer bitstream_buffer( 239 BitstreamBuffer bitstream_buffer(
240 next_bitstream_buffer_id_, shm_buffer->shm->handle(), size); 240 next_bitstream_buffer_id_, shm_buffer->shm->handle(), size);
241 // Mask against 30 bits, to avoid (undefined) wraparound on signed integer. 241 // Mask against 30 bits, to avoid (undefined) wraparound on signed integer.
242 next_bitstream_buffer_id_ = (next_bitstream_buffer_id_ + 1) & 0x3FFFFFFF; 242 next_bitstream_buffer_id_ = (next_bitstream_buffer_id_ + 1) & 0x3FFFFFFF;
243 bool inserted = bitstream_buffers_in_decoder_.insert(std::make_pair( 243 bool inserted = bitstream_buffers_in_decoder_.insert(std::make_pair(
244 bitstream_buffer.id(), BufferPair(shm_buffer, buffer))).second; 244 bitstream_buffer.id(), BufferPair(shm_buffer, buffer))).second;
245 DCHECK(inserted); 245 DCHECK(inserted);
246 RecordBufferData(bitstream_buffer, *buffer.get()); 246 RecordBufferData(bitstream_buffer, *buffer.get());
247 247
248 vda_->Decode(bitstream_buffer); 248 vda_->Decode(bitstream_buffer);
249 249
250 if (!ready_video_frames_.empty()) { 250 if (!ready_video_frames_.empty()) {
251 EnqueueFrameAndTriggerFrameDelivery(NULL); 251 EnqueueFrameAndTriggerFrameDelivery(NULL);
252 return; 252 return;
253 } 253 }
254 254
255 if (CanMoreDecodeWorkBeDone()) 255 if (CanMoreDecodeWorkBeDone())
256 base::ResetAndReturn(&pending_read_cb_).Run(kNotEnoughData, NULL); 256 base::ResetAndReturn(&pending_decode_cb_).Run(kNotEnoughData, NULL);
257 } 257 }
258 258
259 bool GpuVideoDecoder::CanMoreDecodeWorkBeDone() { 259 bool GpuVideoDecoder::CanMoreDecodeWorkBeDone() {
260 return bitstream_buffers_in_decoder_.size() < kMaxInFlightDecodes; 260 return bitstream_buffers_in_decoder_.size() < kMaxInFlightDecodes;
261 } 261 }
262 262
263 void GpuVideoDecoder::RecordBufferData(const BitstreamBuffer& bitstream_buffer, 263 void GpuVideoDecoder::RecordBufferData(const BitstreamBuffer& bitstream_buffer,
264 const DecoderBuffer& buffer) { 264 const DecoderBuffer& buffer) {
265 input_buffer_data_.push_front(BufferData(bitstream_buffer.id(), 265 input_buffer_data_.push_front(BufferData(bitstream_buffer.id(),
266 buffer.timestamp(), 266 buffer.timestamp(),
(...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after
436 // During a pending vda->Reset(), we don't accumulate frames. Drop it on the 436 // During a pending vda->Reset(), we don't accumulate frames. Drop it on the
437 // floor and return. 437 // floor and return.
438 if (!pending_reset_cb_.is_null()) 438 if (!pending_reset_cb_.is_null())
439 return; 439 return;
440 440
441 if (frame.get()) 441 if (frame.get())
442 ready_video_frames_.push_back(frame); 442 ready_video_frames_.push_back(frame);
443 else 443 else
444 DCHECK(!ready_video_frames_.empty()); 444 DCHECK(!ready_video_frames_.empty());
445 445
446 if (pending_read_cb_.is_null()) 446 if (pending_decode_cb_.is_null())
447 return; 447 return;
448 448
449 base::ResetAndReturn(&pending_read_cb_).Run(kOk, ready_video_frames_.front()); 449 base::ResetAndReturn(&pending_decode_cb_)
450 .Run(kOk, ready_video_frames_.front());
450 ready_video_frames_.pop_front(); 451 ready_video_frames_.pop_front();
451 } 452 }
452 453
453 void GpuVideoDecoder::ReusePictureBuffer(int64 picture_buffer_id, 454 void GpuVideoDecoder::ReusePictureBuffer(int64 picture_buffer_id,
454 uint32 sync_point) { 455 uint32 sync_point) {
455 DVLOG(3) << "ReusePictureBuffer(" << picture_buffer_id << ")"; 456 DVLOG(3) << "ReusePictureBuffer(" << picture_buffer_id << ")";
456 DCHECK(gvd_loop_proxy_->BelongsToCurrentThread()); 457 DCHECK(gvd_loop_proxy_->BelongsToCurrentThread());
457 458
458 if (!vda_) 459 if (!vda_)
459 return; 460 return;
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
511 if (it == bitstream_buffers_in_decoder_.end()) { 512 if (it == bitstream_buffers_in_decoder_.end()) {
512 NotifyError(VideoDecodeAccelerator::PLATFORM_FAILURE); 513 NotifyError(VideoDecodeAccelerator::PLATFORM_FAILURE);
513 NOTREACHED() << "Missing bitstream buffer: " << id; 514 NOTREACHED() << "Missing bitstream buffer: " << id;
514 return; 515 return;
515 } 516 }
516 517
517 PutSHM(it->second.shm_buffer); 518 PutSHM(it->second.shm_buffer);
518 bitstream_buffers_in_decoder_.erase(it); 519 bitstream_buffers_in_decoder_.erase(it);
519 520
520 if (pending_reset_cb_.is_null() && state_ != kDrainingDecoder && 521 if (pending_reset_cb_.is_null() && state_ != kDrainingDecoder &&
521 CanMoreDecodeWorkBeDone() && !pending_read_cb_.is_null()) { 522 CanMoreDecodeWorkBeDone() && !pending_decode_cb_.is_null()) {
522 base::ResetAndReturn(&pending_read_cb_).Run(kNotEnoughData, NULL); 523 base::ResetAndReturn(&pending_decode_cb_).Run(kNotEnoughData, NULL);
523 } 524 }
524 } 525 }
525 526
526 GpuVideoDecoder::~GpuVideoDecoder() { 527 GpuVideoDecoder::~GpuVideoDecoder() {
527 DCHECK(!vda_.get()); // Stop should have been already called. 528 DCHECK(!vda_.get()); // Stop should have been already called.
528 DCHECK(pending_read_cb_.is_null()); 529 DCHECK(pending_decode_cb_.is_null());
529 for (size_t i = 0; i < available_shm_segments_.size(); ++i) { 530 for (size_t i = 0; i < available_shm_segments_.size(); ++i) {
530 available_shm_segments_[i]->shm->Close(); 531 available_shm_segments_[i]->shm->Close();
531 delete available_shm_segments_[i]; 532 delete available_shm_segments_[i];
532 } 533 }
533 available_shm_segments_.clear(); 534 available_shm_segments_.clear();
534 for (std::map<int32, BufferPair>::iterator it = 535 for (std::map<int32, BufferPair>::iterator it =
535 bitstream_buffers_in_decoder_.begin(); 536 bitstream_buffers_in_decoder_.begin();
536 it != bitstream_buffers_in_decoder_.end(); ++it) { 537 it != bitstream_buffers_in_decoder_.end(); ++it) {
537 it->second.shm_buffer->shm->Close(); 538 it->second.shm_buffer->shm->Close();
538 } 539 }
(...skipping 15 matching lines...) Expand all
554 DCHECK(gvd_loop_proxy_->BelongsToCurrentThread()); 555 DCHECK(gvd_loop_proxy_->BelongsToCurrentThread());
555 DCHECK(ready_video_frames_.empty()); 556 DCHECK(ready_video_frames_.empty());
556 557
557 // This needs to happen after the Reset() on vda_ is done to ensure pictures 558 // This needs to happen after the Reset() on vda_ is done to ensure pictures
558 // delivered during the reset can find their time data. 559 // delivered during the reset can find their time data.
559 input_buffer_data_.clear(); 560 input_buffer_data_.clear();
560 561
561 if (!pending_reset_cb_.is_null()) 562 if (!pending_reset_cb_.is_null())
562 base::ResetAndReturn(&pending_reset_cb_).Run(); 563 base::ResetAndReturn(&pending_reset_cb_).Run();
563 564
564 if (!pending_read_cb_.is_null()) 565 if (!pending_decode_cb_.is_null())
565 EnqueueFrameAndTriggerFrameDelivery(VideoFrame::CreateEmptyFrame()); 566 EnqueueFrameAndTriggerFrameDelivery(VideoFrame::CreateEmptyFrame());
566 } 567 }
567 568
568 void GpuVideoDecoder::NotifyError(media::VideoDecodeAccelerator::Error error) { 569 void GpuVideoDecoder::NotifyError(media::VideoDecodeAccelerator::Error error) {
569 DCHECK(gvd_loop_proxy_->BelongsToCurrentThread()); 570 DCHECK(gvd_loop_proxy_->BelongsToCurrentThread());
570 if (!vda_) 571 if (!vda_)
571 return; 572 return;
572 573
573 DLOG(ERROR) << "VDA Error: " << error; 574 DLOG(ERROR) << "VDA Error: " << error;
574 DestroyVDA(); 575 DestroyVDA();
575 576
576 state_ = kError; 577 state_ = kError;
577 578
578 if (!pending_read_cb_.is_null()) { 579 if (!pending_decode_cb_.is_null()) {
579 base::ResetAndReturn(&pending_read_cb_).Run(kDecodeError, NULL); 580 base::ResetAndReturn(&pending_decode_cb_).Run(kDecodeError, NULL);
580 return; 581 return;
581 } 582 }
582 } 583 }
583 584
584 } // namespace media 585 } // namespace media
OLDNEW
« no previous file with comments | « media/filters/gpu_video_decoder.h ('k') | media/filters/video_frame_stream.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698