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

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

Issue 10824141: Remove VideoDecoder::natural_size() & added VideoFrame::natural_size(). (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Minor cleanup Created 8 years, 4 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 18 matching lines...) Expand all
29 29
30 GpuVideoDecoder::SHMBuffer::~SHMBuffer() {} 30 GpuVideoDecoder::SHMBuffer::~SHMBuffer() {}
31 31
32 GpuVideoDecoder::BufferPair::BufferPair( 32 GpuVideoDecoder::BufferPair::BufferPair(
33 SHMBuffer* s, const scoped_refptr<DecoderBuffer>& b) 33 SHMBuffer* s, const scoped_refptr<DecoderBuffer>& b)
34 : shm_buffer(s), buffer(b) { 34 : shm_buffer(s), buffer(b) {
35 } 35 }
36 36
37 GpuVideoDecoder::BufferPair::~BufferPair() {} 37 GpuVideoDecoder::BufferPair::~BufferPair() {}
38 38
39 GpuVideoDecoder::BufferData::BufferData(
40 int32 bbid, base::TimeDelta ts, const gfx::Size& ns)
41 : bitstream_buffer_id(bbid), timestamp(ts), natural_size(ns) {
42 }
43
44 GpuVideoDecoder::BufferData::~BufferData() {}
45
39 GpuVideoDecoder::GpuVideoDecoder( 46 GpuVideoDecoder::GpuVideoDecoder(
40 MessageLoop* message_loop, 47 MessageLoop* message_loop,
41 MessageLoop* vda_loop, 48 MessageLoop* vda_loop,
42 const scoped_refptr<Factories>& factories) 49 const scoped_refptr<Factories>& factories)
43 : gvd_loop_proxy_(message_loop->message_loop_proxy()), 50 : gvd_loop_proxy_(message_loop->message_loop_proxy()),
44 vda_loop_proxy_(vda_loop->message_loop_proxy()), 51 vda_loop_proxy_(vda_loop->message_loop_proxy()),
45 factories_(factories), 52 factories_(factories),
46 state_(kNormal), 53 state_(kNormal),
47 demuxer_read_in_progress_(false), 54 demuxer_read_in_progress_(false),
48 decoder_texture_target_(0), 55 decoder_texture_target_(0),
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after
148 status_cb.Run(DECODER_ERROR_NOT_SUPPORTED); 155 status_cb.Run(DECODER_ERROR_NOT_SUPPORTED);
149 return; 156 return;
150 } 157 }
151 158
152 demuxer_stream_ = stream; 159 demuxer_stream_ = stream;
153 statistics_cb_ = statistics_cb; 160 statistics_cb_ = statistics_cb;
154 161
155 if (config.codec() == kCodecH264) 162 if (config.codec() == kCodecH264)
156 demuxer_stream_->EnableBitstreamConverter(); 163 demuxer_stream_->EnableBitstreamConverter();
157 164
158 natural_size_ = config.natural_size();
159
160 DVLOG(1) << "GpuVideoDecoder::Initialize() succeeded."; 165 DVLOG(1) << "GpuVideoDecoder::Initialize() succeeded.";
161 vda_loop_proxy_->PostTaskAndReply( 166 vda_loop_proxy_->PostTaskAndReply(
162 FROM_HERE, 167 FROM_HERE,
163 base::Bind(&GpuVideoDecoder::SetVDA, this, vda), 168 base::Bind(&GpuVideoDecoder::SetVDA, this, vda),
164 base::Bind(status_cb, PIPELINE_OK)); 169 base::Bind(status_cb, PIPELINE_OK));
165 } 170 }
166 171
167 void GpuVideoDecoder::SetVDA(VideoDecodeAccelerator* vda) { 172 void GpuVideoDecoder::SetVDA(VideoDecodeAccelerator* vda) {
168 DCHECK(vda_loop_proxy_->BelongsToCurrentThread()); 173 DCHECK(vda_loop_proxy_->BelongsToCurrentThread());
169 vda_.reset(vda); 174 vda_.reset(vda);
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
220 &GpuVideoDecoder::RequestBufferDecode, this, status, buffer)); 225 &GpuVideoDecoder::RequestBufferDecode, this, status, buffer));
221 return; 226 return;
222 } 227 }
223 demuxer_read_in_progress_ = false; 228 demuxer_read_in_progress_ = false;
224 229
225 if (status != DemuxerStream::kOk) { 230 if (status != DemuxerStream::kOk) {
226 if (pending_read_cb_.is_null()) 231 if (pending_read_cb_.is_null())
227 return; 232 return;
228 233
229 // TODO(acolwell): Add support for reinitializing the decoder when 234 // TODO(acolwell): Add support for reinitializing the decoder when
230 // |status| == kConfigChanged. For now we just trigger a decode error. 235 // |status| == kConfigChanged. For now we just trigger a decode error.
Ami GONE FROM CHROMIUM 2012/08/02 17:34:45 Do we still need this? IOW if the decoders don't m
acolwell GONE FROM CHROMIUM 2012/08/02 20:20:21 No. We still need this because the decoders hold s
231 DecoderStatus decoder_status = 236 DecoderStatus decoder_status =
232 (status == DemuxerStream::kAborted) ? kOk : kDecodeError; 237 (status == DemuxerStream::kAborted) ? kOk : kDecodeError;
233 gvd_loop_proxy_->PostTask(FROM_HERE, base::Bind( 238 gvd_loop_proxy_->PostTask(FROM_HERE, base::Bind(
234 pending_read_cb_, decoder_status, scoped_refptr<VideoFrame>())); 239 pending_read_cb_, decoder_status, scoped_refptr<VideoFrame>()));
235 pending_read_cb_.Reset(); 240 pending_read_cb_.Reset();
236 return; 241 return;
237 } 242 }
238 243
239 if (!vda_.get()) { 244 if (!vda_.get()) {
240 EnqueueFrameAndTriggerFrameDelivery(VideoFrame::CreateEmptyFrame()); 245 EnqueueFrameAndTriggerFrameDelivery(VideoFrame::CreateEmptyFrame());
(...skipping 10 matching lines...) Expand all
251 } 256 }
252 257
253 size_t size = buffer->GetDataSize(); 258 size_t size = buffer->GetDataSize();
254 SHMBuffer* shm_buffer = GetSHM(size); 259 SHMBuffer* shm_buffer = GetSHM(size);
255 memcpy(shm_buffer->shm->memory(), buffer->GetData(), size); 260 memcpy(shm_buffer->shm->memory(), buffer->GetData(), size);
256 BitstreamBuffer bitstream_buffer( 261 BitstreamBuffer bitstream_buffer(
257 next_bitstream_buffer_id_++, shm_buffer->shm->handle(), size); 262 next_bitstream_buffer_id_++, shm_buffer->shm->handle(), size);
258 bool inserted = bitstream_buffers_in_decoder_.insert(std::make_pair( 263 bool inserted = bitstream_buffers_in_decoder_.insert(std::make_pair(
259 bitstream_buffer.id(), BufferPair(shm_buffer, buffer))).second; 264 bitstream_buffer.id(), BufferPair(shm_buffer, buffer))).second;
260 DCHECK(inserted); 265 DCHECK(inserted);
261 RecordBufferTimeData(bitstream_buffer, *buffer); 266 RecordBufferData(bitstream_buffer, *buffer);
262 267
263 vda_loop_proxy_->PostTask(FROM_HERE, base::Bind( 268 vda_loop_proxy_->PostTask(FROM_HERE, base::Bind(
264 &VideoDecodeAccelerator::Decode, weak_vda_, bitstream_buffer)); 269 &VideoDecodeAccelerator::Decode, weak_vda_, bitstream_buffer));
265 } 270 }
266 271
267 void GpuVideoDecoder::RecordBufferTimeData( 272 void GpuVideoDecoder::RecordBufferData(
268 const BitstreamBuffer& bitstream_buffer, const Buffer& buffer) { 273 const BitstreamBuffer& bitstream_buffer, const Buffer& buffer) {
269 input_buffer_time_data_.push_front(BufferTimeData( 274 input_buffer_data_.push_front(BufferData(
270 bitstream_buffer.id(), buffer.GetTimestamp())); 275 bitstream_buffer.id(), buffer.GetTimestamp(),
276 demuxer_stream_->video_decoder_config().natural_size()));
271 // Why this value? Because why not. avformat.h:MAX_REORDER_DELAY is 16, but 277 // Why this value? Because why not. avformat.h:MAX_REORDER_DELAY is 16, but
272 // that's too small for some pathological B-frame test videos. The cost of 278 // that's too small for some pathological B-frame test videos. The cost of
273 // using too-high a value is low (192 bits per extra slot). 279 // using too-high a value is low (192 bits per extra slot).
274 static const size_t kMaxInputBufferTimeDataSize = 128; 280 static const size_t kMaxInputBufferDataSize = 128;
275 // Pop from the back of the list, because that's the oldest and least likely 281 // Pop from the back of the list, because that's the oldest and least likely
276 // to be useful in the future data. 282 // to be useful in the future data.
277 if (input_buffer_time_data_.size() > kMaxInputBufferTimeDataSize) 283 if (input_buffer_data_.size() > kMaxInputBufferDataSize)
278 input_buffer_time_data_.pop_back(); 284 input_buffer_data_.pop_back();
279 } 285 }
280 286
281 base::TimeDelta GpuVideoDecoder::GetBufferTimestamp(int32 id) { 287 void GpuVideoDecoder::GetBufferData(int32 id, base::TimeDelta* timestamp,
282 for (std::list<BufferTimeData>::const_iterator it = 288 gfx::Size* natural_size) {
283 input_buffer_time_data_.begin(); it != input_buffer_time_data_.end(); 289 for (std::list<BufferData>::const_iterator it =
290 input_buffer_data_.begin(); it != input_buffer_data_.end();
284 ++it) { 291 ++it) {
285 if (it->first == id) 292 if (it->bitstream_buffer_id != id)
286 return it->second; 293 continue;
294 *timestamp = it->timestamp;
295 *natural_size = it->natural_size;
296 return;
287 } 297 }
288 NOTREACHED() << "Missing bitstreambuffer id: " << id; 298 NOTREACHED() << "Missing bitstreambuffer id: " << id;
289 return kNoTimestamp();
290 }
291
292 const gfx::Size& GpuVideoDecoder::natural_size() {
293 return natural_size_;
294 } 299 }
295 300
296 bool GpuVideoDecoder::HasAlpha() const { 301 bool GpuVideoDecoder::HasAlpha() const {
297 return true; 302 return true;
298 } 303 }
299 304
300 void GpuVideoDecoder::PrepareForShutdownHack() { 305 void GpuVideoDecoder::PrepareForShutdownHack() {
301 if (!gvd_loop_proxy_->BelongsToCurrentThread()) { 306 if (!gvd_loop_proxy_->BelongsToCurrentThread()) {
302 gvd_loop_proxy_->PostTask(FROM_HERE, base::Bind( 307 gvd_loop_proxy_->PostTask(FROM_HERE, base::Bind(
303 &GpuVideoDecoder::PrepareForShutdownHack, this)); 308 &GpuVideoDecoder::PrepareForShutdownHack, this));
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
369 std::map<int32, PictureBuffer>::iterator it = 374 std::map<int32, PictureBuffer>::iterator it =
370 picture_buffers_in_decoder_.find(picture.picture_buffer_id()); 375 picture_buffers_in_decoder_.find(picture.picture_buffer_id());
371 if (it == picture_buffers_in_decoder_.end()) { 376 if (it == picture_buffers_in_decoder_.end()) {
372 NOTREACHED() << "Missing picture buffer: " << picture.picture_buffer_id(); 377 NOTREACHED() << "Missing picture buffer: " << picture.picture_buffer_id();
373 NotifyError(VideoDecodeAccelerator::PLATFORM_FAILURE); 378 NotifyError(VideoDecodeAccelerator::PLATFORM_FAILURE);
374 return; 379 return;
375 } 380 }
376 const PictureBuffer& pb = it->second; 381 const PictureBuffer& pb = it->second;
377 382
378 // Update frame's timestamp. 383 // Update frame's timestamp.
379 base::TimeDelta timestamp = GetBufferTimestamp(picture.bitstream_buffer_id()); 384 base::TimeDelta timestamp;
385 gfx::Size natural_size;
386 GetBufferData(picture.bitstream_buffer_id(), &timestamp, &natural_size);
380 DCHECK(decoder_texture_target_); 387 DCHECK(decoder_texture_target_);
381 scoped_refptr<VideoFrame> frame(VideoFrame::WrapNativeTexture( 388 scoped_refptr<VideoFrame> frame(VideoFrame::WrapNativeTexture(
382 pb.texture_id(), decoder_texture_target_, pb.size().width(), 389 pb.texture_id(), decoder_texture_target_, pb.size(), natural_size,
383 pb.size().height(), timestamp, 390 timestamp,
384 base::Bind(&GpuVideoDecoder::ReusePictureBuffer, this, 391 base::Bind(&GpuVideoDecoder::ReusePictureBuffer, this,
385 picture.picture_buffer_id()))); 392 picture.picture_buffer_id())));
386 393
387 EnqueueFrameAndTriggerFrameDelivery(frame); 394 EnqueueFrameAndTriggerFrameDelivery(frame);
388 } 395 }
389 396
390 void GpuVideoDecoder::EnqueueFrameAndTriggerFrameDelivery( 397 void GpuVideoDecoder::EnqueueFrameAndTriggerFrameDelivery(
391 const scoped_refptr<VideoFrame>& frame) { 398 const scoped_refptr<VideoFrame>& frame) {
392 DCHECK(gvd_loop_proxy_->BelongsToCurrentThread()); 399 DCHECK(gvd_loop_proxy_->BelongsToCurrentThread());
393 400
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after
518 return; 525 return;
519 } 526 }
520 527
521 if (!vda_.get()) 528 if (!vda_.get())
522 return; 529 return;
523 530
524 DCHECK(ready_video_frames_.empty()); 531 DCHECK(ready_video_frames_.empty());
525 532
526 // This needs to happen after the Reset() on vda_ is done to ensure pictures 533 // This needs to happen after the Reset() on vda_ is done to ensure pictures
527 // delivered during the reset can find their time data. 534 // delivered during the reset can find their time data.
528 input_buffer_time_data_.clear(); 535 input_buffer_data_.clear();
529 536
530 if (!pending_reset_cb_.is_null()) 537 if (!pending_reset_cb_.is_null())
531 base::ResetAndReturn(&pending_reset_cb_).Run(); 538 base::ResetAndReturn(&pending_reset_cb_).Run();
532 539
533 if (!pending_read_cb_.is_null()) 540 if (!pending_read_cb_.is_null())
534 EnqueueFrameAndTriggerFrameDelivery(VideoFrame::CreateEmptyFrame()); 541 EnqueueFrameAndTriggerFrameDelivery(VideoFrame::CreateEmptyFrame());
535 } 542 }
536 543
537 void GpuVideoDecoder::NotifyError(media::VideoDecodeAccelerator::Error error) { 544 void GpuVideoDecoder::NotifyError(media::VideoDecodeAccelerator::Error error) {
538 if (!gvd_loop_proxy_->BelongsToCurrentThread()) { 545 if (!gvd_loop_proxy_->BelongsToCurrentThread()) {
539 gvd_loop_proxy_->PostTask(FROM_HERE, base::Bind( 546 gvd_loop_proxy_->PostTask(FROM_HERE, base::Bind(
540 &GpuVideoDecoder::NotifyError, this, error)); 547 &GpuVideoDecoder::NotifyError, this, error));
541 return; 548 return;
542 } 549 }
543 if (!vda_.get()) 550 if (!vda_.get())
544 return; 551 return;
545 vda_loop_proxy_->DeleteSoon(FROM_HERE, vda_.release()); 552 vda_loop_proxy_->DeleteSoon(FROM_HERE, vda_.release());
546 DLOG(ERROR) << "VDA Error: " << error; 553 DLOG(ERROR) << "VDA Error: " << error;
547 554
548 error_occured_ = true; 555 error_occured_ = true;
549 556
550 if (!pending_read_cb_.is_null()) { 557 if (!pending_read_cb_.is_null()) {
551 base::ResetAndReturn(&pending_read_cb_).Run(kDecodeError, NULL); 558 base::ResetAndReturn(&pending_read_cb_).Run(kDecodeError, NULL);
552 return; 559 return;
553 } 560 }
554 } 561 }
555 562
556 } // namespace media 563 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698