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

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

Issue 9639005: HW video decode support for --enable-threaded-compositing (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: CR response. Created 8 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/message_loop.h" 8 #include "base/message_loop.h"
9 #include "base/stl_util.h" 9 #include "base/stl_util.h"
10 #include "media/base/demuxer_stream.h" 10 #include "media/base/demuxer_stream.h"
(...skipping 24 matching lines...) Expand all
35 35
36 GpuVideoDecoder::BufferTimeData::BufferTimeData( 36 GpuVideoDecoder::BufferTimeData::BufferTimeData(
37 int32 bbid, base::TimeDelta ts, base::TimeDelta dur) 37 int32 bbid, base::TimeDelta ts, base::TimeDelta dur)
38 : bitstream_buffer_id(bbid), timestamp(ts), duration(dur) { 38 : bitstream_buffer_id(bbid), timestamp(ts), duration(dur) {
39 } 39 }
40 40
41 GpuVideoDecoder::BufferTimeData::~BufferTimeData() {} 41 GpuVideoDecoder::BufferTimeData::~BufferTimeData() {}
42 42
43 GpuVideoDecoder::GpuVideoDecoder( 43 GpuVideoDecoder::GpuVideoDecoder(
44 MessageLoop* message_loop, 44 MessageLoop* message_loop,
45 MessageLoop* vda_loop,
45 const scoped_refptr<Factories>& factories) 46 const scoped_refptr<Factories>& factories)
46 : gvd_loop_proxy_(message_loop->message_loop_proxy()), 47 : gvd_loop_proxy_(message_loop->message_loop_proxy()),
47 render_loop_proxy_(base::MessageLoopProxy::current()), 48 vda_loop_proxy_(vda_loop->message_loop_proxy()),
48 factories_(factories), 49 factories_(factories),
49 state_(kNormal), 50 state_(kNormal),
50 demuxer_read_in_progress_(false), 51 demuxer_read_in_progress_(false),
51 decoder_texture_target_(0), 52 decoder_texture_target_(0),
52 next_picture_buffer_id_(0), 53 next_picture_buffer_id_(0),
53 next_bitstream_buffer_id_(0), 54 next_bitstream_buffer_id_(0),
54 shutting_down_(false) { 55 shutting_down_(false) {
55 DCHECK(gvd_loop_proxy_ && factories_); 56 DCHECK(gvd_loop_proxy_ && factories_);
56 } 57 }
57 58
(...skipping 16 matching lines...) Expand all
74 void GpuVideoDecoder::Stop(const base::Closure& callback) { 75 void GpuVideoDecoder::Stop(const base::Closure& callback) {
75 if (!gvd_loop_proxy_->BelongsToCurrentThread()) { 76 if (!gvd_loop_proxy_->BelongsToCurrentThread()) {
76 gvd_loop_proxy_->PostTask(FROM_HERE, base::Bind( 77 gvd_loop_proxy_->PostTask(FROM_HERE, base::Bind(
77 &GpuVideoDecoder::Stop, this, callback)); 78 &GpuVideoDecoder::Stop, this, callback));
78 return; 79 return;
79 } 80 }
80 if (!vda_) { 81 if (!vda_) {
81 callback.Run(); 82 callback.Run();
82 return; 83 return;
83 } 84 }
84 render_loop_proxy_->PostTask(FROM_HERE, base::Bind( 85 vda_loop_proxy_->PostTask(FROM_HERE, base::Bind(
85 &VideoDecodeAccelerator::Destroy, vda_)); 86 &VideoDecodeAccelerator::Destroy, vda_));
86 vda_ = NULL; 87 vda_ = NULL;
87 callback.Run(); 88 callback.Run();
88 } 89 }
89 90
90 void GpuVideoDecoder::Seek(base::TimeDelta time, const FilterStatusCB& cb) { 91 void GpuVideoDecoder::Seek(base::TimeDelta time, const FilterStatusCB& cb) {
91 if (!gvd_loop_proxy_->BelongsToCurrentThread()) { 92 if (!gvd_loop_proxy_->BelongsToCurrentThread()) {
92 gvd_loop_proxy_->PostTask(FROM_HERE, base::Bind( 93 gvd_loop_proxy_->PostTask(FROM_HERE, base::Bind(
93 &GpuVideoDecoder::Seek, this, time, cb)); 94 &GpuVideoDecoder::Seek, this, time, cb));
94 return; 95 return;
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
129 // us, so we fulfill such a read here. 130 // us, so we fulfill such a read here.
130 if (!pending_read_cb_.is_null()) 131 if (!pending_read_cb_.is_null())
131 EnqueueFrameAndTriggerFrameDelivery(VideoFrame::CreateEmptyFrame()); 132 EnqueueFrameAndTriggerFrameDelivery(VideoFrame::CreateEmptyFrame());
132 // Immediate fire the callback instead of waiting for the reset to complete 133 // Immediate fire the callback instead of waiting for the reset to complete
133 // (which will happen after PipelineImpl::Stop() completes). 134 // (which will happen after PipelineImpl::Stop() completes).
134 callback.Run(); 135 callback.Run();
135 } else { 136 } else {
136 pending_reset_cb_ = callback; 137 pending_reset_cb_ = callback;
137 } 138 }
138 139
139 render_loop_proxy_->PostTask(FROM_HERE, base::Bind( 140 vda_loop_proxy_->PostTask(FROM_HERE, base::Bind(
140 &VideoDecodeAccelerator::Reset, vda_)); 141 &VideoDecodeAccelerator::Reset, vda_));
141 } 142 }
142 143
143 void GpuVideoDecoder::Initialize(DemuxerStream* demuxer_stream, 144 void GpuVideoDecoder::Initialize(DemuxerStream* demuxer_stream,
144 const PipelineStatusCB& callback, 145 const PipelineStatusCB& callback,
145 const StatisticsCallback& stats_callback) { 146 const StatisticsCallback& stats_callback) {
146 if (!gvd_loop_proxy_->BelongsToCurrentThread()) { 147 if (!gvd_loop_proxy_->BelongsToCurrentThread()) {
147 gvd_loop_proxy_->PostTask(FROM_HERE, base::Bind( 148 gvd_loop_proxy_->PostTask(FROM_HERE, base::Bind(
148 &GpuVideoDecoder::Initialize, this, 149 &GpuVideoDecoder::Initialize, this,
149 make_scoped_refptr(demuxer_stream), callback, stats_callback)); 150 make_scoped_refptr(demuxer_stream), callback, stats_callback));
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
237 } 238 }
238 239
239 if (!vda_) { 240 if (!vda_) {
240 EnqueueFrameAndTriggerFrameDelivery(VideoFrame::CreateEmptyFrame()); 241 EnqueueFrameAndTriggerFrameDelivery(VideoFrame::CreateEmptyFrame());
241 return; 242 return;
242 } 243 }
243 244
244 if (buffer->IsEndOfStream()) { 245 if (buffer->IsEndOfStream()) {
245 if (state_ == kNormal) { 246 if (state_ == kNormal) {
246 state_ = kDrainingDecoder; 247 state_ = kDrainingDecoder;
247 render_loop_proxy_->PostTask(FROM_HERE, base::Bind( 248 vda_loop_proxy_->PostTask(FROM_HERE, base::Bind(
248 &VideoDecodeAccelerator::Flush, vda_)); 249 &VideoDecodeAccelerator::Flush, vda_));
249 } 250 }
250 return; 251 return;
251 } 252 }
252 253
253 size_t size = buffer->GetDataSize(); 254 size_t size = buffer->GetDataSize();
254 SHMBuffer* shm_buffer = GetSHM(size); 255 SHMBuffer* shm_buffer = GetSHM(size);
255 memcpy(shm_buffer->shm->memory(), buffer->GetData(), size); 256 memcpy(shm_buffer->shm->memory(), buffer->GetData(), size);
256 BitstreamBuffer bitstream_buffer( 257 BitstreamBuffer bitstream_buffer(
257 next_bitstream_buffer_id_++, shm_buffer->shm->handle(), size); 258 next_bitstream_buffer_id_++, shm_buffer->shm->handle(), size);
258 bool inserted = bitstream_buffers_in_decoder_.insert(std::make_pair( 259 bool inserted = bitstream_buffers_in_decoder_.insert(std::make_pair(
259 bitstream_buffer.id(), BufferPair(shm_buffer, buffer))).second; 260 bitstream_buffer.id(), BufferPair(shm_buffer, buffer))).second;
260 DCHECK(inserted); 261 DCHECK(inserted);
261 RecordBufferTimeData(bitstream_buffer, *buffer); 262 RecordBufferTimeData(bitstream_buffer, *buffer);
262 263
263 render_loop_proxy_->PostTask(FROM_HERE, base::Bind( 264 vda_loop_proxy_->PostTask(FROM_HERE, base::Bind(
264 &VideoDecodeAccelerator::Decode, vda_, bitstream_buffer)); 265 &VideoDecodeAccelerator::Decode, vda_, bitstream_buffer));
265 } 266 }
266 267
267 void GpuVideoDecoder::RecordBufferTimeData( 268 void GpuVideoDecoder::RecordBufferTimeData(
268 const BitstreamBuffer& bitstream_buffer, const Buffer& buffer) { 269 const BitstreamBuffer& bitstream_buffer, const Buffer& buffer) {
269 base::TimeDelta duration = buffer.GetDuration(); 270 base::TimeDelta duration = buffer.GetDuration();
270 if (duration == base::TimeDelta()) 271 if (duration == base::TimeDelta())
271 duration = config_frame_duration_; 272 duration = config_frame_duration_;
272 input_buffer_time_data_.push_front(BufferTimeData( 273 input_buffer_time_data_.push_front(BufferTimeData(
273 bitstream_buffer.id(), buffer.GetTimestamp(), duration)); 274 bitstream_buffer.id(), buffer.GetTimestamp(), duration));
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
338 return; 339 return;
339 340
340 std::vector<PictureBuffer> picture_buffers; 341 std::vector<PictureBuffer> picture_buffers;
341 for (size_t i = 0; i < texture_ids.size(); ++i) { 342 for (size_t i = 0; i < texture_ids.size(); ++i) {
342 picture_buffers.push_back(PictureBuffer( 343 picture_buffers.push_back(PictureBuffer(
343 next_picture_buffer_id_++, size, texture_ids[i])); 344 next_picture_buffer_id_++, size, texture_ids[i]));
344 bool inserted = picture_buffers_in_decoder_.insert(std::make_pair( 345 bool inserted = picture_buffers_in_decoder_.insert(std::make_pair(
345 picture_buffers.back().id(), picture_buffers.back())).second; 346 picture_buffers.back().id(), picture_buffers.back())).second;
346 DCHECK(inserted); 347 DCHECK(inserted);
347 } 348 }
348 render_loop_proxy_->PostTask(FROM_HERE, base::Bind( 349 vda_loop_proxy_->PostTask(FROM_HERE, base::Bind(
349 &VideoDecodeAccelerator::AssignPictureBuffers, vda_, picture_buffers)); 350 &VideoDecodeAccelerator::AssignPictureBuffers, vda_, picture_buffers));
350 } 351 }
351 352
352 void GpuVideoDecoder::DismissPictureBuffer(int32 id) { 353 void GpuVideoDecoder::DismissPictureBuffer(int32 id) {
353 if (!gvd_loop_proxy_->BelongsToCurrentThread()) { 354 if (!gvd_loop_proxy_->BelongsToCurrentThread()) {
354 gvd_loop_proxy_->PostTask(FROM_HERE, base::Bind( 355 gvd_loop_proxy_->PostTask(FROM_HERE, base::Bind(
355 &GpuVideoDecoder::DismissPictureBuffer, this, id)); 356 &GpuVideoDecoder::DismissPictureBuffer, this, id));
356 return; 357 return;
357 } 358 }
358 std::map<int32, PictureBuffer>::iterator it = 359 std::map<int32, PictureBuffer>::iterator it =
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
419 } 420 }
420 421
421 void GpuVideoDecoder::ReusePictureBuffer(int64 picture_buffer_id) { 422 void GpuVideoDecoder::ReusePictureBuffer(int64 picture_buffer_id) {
422 if (!gvd_loop_proxy_->BelongsToCurrentThread()) { 423 if (!gvd_loop_proxy_->BelongsToCurrentThread()) {
423 gvd_loop_proxy_->PostTask(FROM_HERE, base::Bind( 424 gvd_loop_proxy_->PostTask(FROM_HERE, base::Bind(
424 &GpuVideoDecoder::ReusePictureBuffer, this, picture_buffer_id)); 425 &GpuVideoDecoder::ReusePictureBuffer, this, picture_buffer_id));
425 return; 426 return;
426 } 427 }
427 if (!vda_) 428 if (!vda_)
428 return; 429 return;
429 render_loop_proxy_->PostTask(FROM_HERE, base::Bind( 430 vda_loop_proxy_->PostTask(FROM_HERE, base::Bind(
430 &VideoDecodeAccelerator::ReusePictureBuffer, vda_, picture_buffer_id)); 431 &VideoDecodeAccelerator::ReusePictureBuffer, vda_, picture_buffer_id));
431 } 432 }
432 433
433 GpuVideoDecoder::SHMBuffer* GpuVideoDecoder::GetSHM(size_t min_size) { 434 GpuVideoDecoder::SHMBuffer* GpuVideoDecoder::GetSHM(size_t min_size) {
434 DCHECK(gvd_loop_proxy_->BelongsToCurrentThread()); 435 DCHECK(gvd_loop_proxy_->BelongsToCurrentThread());
435 if (available_shm_segments_.empty() || 436 if (available_shm_segments_.empty() ||
436 available_shm_segments_.back()->size < min_size) { 437 available_shm_segments_.back()->size < min_size) {
437 size_t size_to_allocate = std::max(min_size, kSharedMemorySegmentBytes); 438 size_t size_to_allocate = std::max(min_size, kSharedMemorySegmentBytes);
438 base::SharedMemory* shm = factories_->CreateSharedMemory(size_to_allocate); 439 base::SharedMemory* shm = factories_->CreateSharedMemory(size_to_allocate);
439 DCHECK(shm); 440 DCHECK(shm);
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
523 if (!pending_read_cb_.is_null()) 524 if (!pending_read_cb_.is_null())
524 EnqueueFrameAndTriggerFrameDelivery(VideoFrame::CreateEmptyFrame()); 525 EnqueueFrameAndTriggerFrameDelivery(VideoFrame::CreateEmptyFrame());
525 } 526 }
526 527
527 void GpuVideoDecoder::NotifyError(media::VideoDecodeAccelerator::Error error) { 528 void GpuVideoDecoder::NotifyError(media::VideoDecodeAccelerator::Error error) {
528 if (!gvd_loop_proxy_->BelongsToCurrentThread()) { 529 if (!gvd_loop_proxy_->BelongsToCurrentThread()) {
529 gvd_loop_proxy_->PostTask(FROM_HERE, base::Bind( 530 gvd_loop_proxy_->PostTask(FROM_HERE, base::Bind(
530 &GpuVideoDecoder::NotifyError, this, error)); 531 &GpuVideoDecoder::NotifyError, this, error));
531 return; 532 return;
532 } 533 }
534 if (!vda_)
535 return;
533 vda_ = NULL; 536 vda_ = NULL;
534 DLOG(ERROR) << "VDA Error: " << error; 537 DLOG(ERROR) << "VDA Error: " << error;
535 if (host()) 538 if (host())
536 host()->SetError(PIPELINE_ERROR_DECODE); 539 host()->SetError(PIPELINE_ERROR_DECODE);
537 } 540 }
538 541
539 } // namespace media 542 } // namespace media
OLDNEW
« content/renderer/render_view_impl.cc ('K') | « media/filters/gpu_video_decoder.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698