OLD | NEW |
---|---|
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 19 matching lines...) Expand all Loading... | |
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::BufferTimeData::BufferTimeData( | 39 GpuVideoDecoder::BufferTimeData::BufferTimeData( |
40 int32 bbid, base::TimeDelta ts, base::TimeDelta dur) | 40 int32 bbid, base::TimeDelta ts) |
41 : bitstream_buffer_id(bbid), timestamp(ts), duration(dur) { | 41 : bitstream_buffer_id(bbid), timestamp(ts) { |
42 } | 42 } |
43 | 43 |
44 GpuVideoDecoder::BufferTimeData::~BufferTimeData() {} | 44 GpuVideoDecoder::BufferTimeData::~BufferTimeData() {} |
45 | 45 |
46 GpuVideoDecoder::GpuVideoDecoder( | 46 GpuVideoDecoder::GpuVideoDecoder( |
47 MessageLoop* message_loop, | 47 MessageLoop* message_loop, |
48 MessageLoop* vda_loop, | 48 MessageLoop* vda_loop, |
49 const scoped_refptr<Factories>& factories) | 49 const scoped_refptr<Factories>& factories) |
50 : gvd_loop_proxy_(message_loop->message_loop_proxy()), | 50 : gvd_loop_proxy_(message_loop->message_loop_proxy()), |
51 vda_loop_proxy_(vda_loop->message_loop_proxy()), | 51 vda_loop_proxy_(vda_loop->message_loop_proxy()), |
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
156 return; | 156 return; |
157 } | 157 } |
158 | 158 |
159 demuxer_stream_ = stream; | 159 demuxer_stream_ = stream; |
160 statistics_cb_ = statistics_cb; | 160 statistics_cb_ = statistics_cb; |
161 | 161 |
162 if (config.codec() == kCodecH264) | 162 if (config.codec() == kCodecH264) |
163 demuxer_stream_->EnableBitstreamConverter(); | 163 demuxer_stream_->EnableBitstreamConverter(); |
164 | 164 |
165 natural_size_ = config.natural_size(); | 165 natural_size_ = config.natural_size(); |
166 config_frame_duration_ = GetFrameDuration(config); | |
167 | 166 |
168 DVLOG(1) << "GpuVideoDecoder::Initialize() succeeded."; | 167 DVLOG(1) << "GpuVideoDecoder::Initialize() succeeded."; |
169 vda_loop_proxy_->PostTaskAndReply( | 168 vda_loop_proxy_->PostTaskAndReply( |
170 FROM_HERE, | 169 FROM_HERE, |
171 base::Bind(&GpuVideoDecoder::SetVDA, this, vda), | 170 base::Bind(&GpuVideoDecoder::SetVDA, this, vda), |
172 base::Bind(status_cb, PIPELINE_OK)); | 171 base::Bind(status_cb, PIPELINE_OK)); |
173 } | 172 } |
174 | 173 |
175 void GpuVideoDecoder::SetVDA(VideoDecodeAccelerator* vda) { | 174 void GpuVideoDecoder::SetVDA(VideoDecodeAccelerator* vda) { |
176 DCHECK(vda_loop_proxy_->BelongsToCurrentThread()); | 175 DCHECK(vda_loop_proxy_->BelongsToCurrentThread()); |
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
267 bitstream_buffer.id(), BufferPair(shm_buffer, buffer))).second; | 266 bitstream_buffer.id(), BufferPair(shm_buffer, buffer))).second; |
268 DCHECK(inserted); | 267 DCHECK(inserted); |
269 RecordBufferTimeData(bitstream_buffer, *buffer); | 268 RecordBufferTimeData(bitstream_buffer, *buffer); |
270 | 269 |
271 vda_loop_proxy_->PostTask(FROM_HERE, base::Bind( | 270 vda_loop_proxy_->PostTask(FROM_HERE, base::Bind( |
272 &VideoDecodeAccelerator::Decode, weak_vda_, bitstream_buffer)); | 271 &VideoDecodeAccelerator::Decode, weak_vda_, bitstream_buffer)); |
273 } | 272 } |
274 | 273 |
275 void GpuVideoDecoder::RecordBufferTimeData( | 274 void GpuVideoDecoder::RecordBufferTimeData( |
276 const BitstreamBuffer& bitstream_buffer, const Buffer& buffer) { | 275 const BitstreamBuffer& bitstream_buffer, const Buffer& buffer) { |
277 base::TimeDelta duration = buffer.GetDuration(); | |
278 if (duration == base::TimeDelta()) | |
279 duration = config_frame_duration_; | |
280 input_buffer_time_data_.push_front(BufferTimeData( | 276 input_buffer_time_data_.push_front(BufferTimeData( |
281 bitstream_buffer.id(), buffer.GetTimestamp(), duration)); | 277 bitstream_buffer.id(), buffer.GetTimestamp())); |
282 // Why this value? Because why not. avformat.h:MAX_REORDER_DELAY is 16, but | 278 // Why this value? Because why not. avformat.h:MAX_REORDER_DELAY is 16, but |
283 // that's too small for some pathological B-frame test videos. The cost of | 279 // that's too small for some pathological B-frame test videos. The cost of |
284 // using too-high a value is low (192 bits per extra slot). | 280 // using too-high a value is low (192 bits per extra slot). |
285 static const size_t kMaxInputBufferTimeDataSize = 128; | 281 static const size_t kMaxInputBufferTimeDataSize = 128; |
286 // Pop from the back of the list, because that's the oldest and least likely | 282 // Pop from the back of the list, because that's the oldest and least likely |
287 // to be useful in the future data. | 283 // to be useful in the future data. |
288 if (input_buffer_time_data_.size() > kMaxInputBufferTimeDataSize) | 284 if (input_buffer_time_data_.size() > kMaxInputBufferTimeDataSize) |
289 input_buffer_time_data_.pop_back(); | 285 input_buffer_time_data_.pop_back(); |
290 } | 286 } |
291 | 287 |
292 void GpuVideoDecoder::GetBufferTimeData( | 288 void GpuVideoDecoder::GetBufferTimeData( |
Ami GONE FROM CHROMIUM
2012/07/31 18:13:52
this could just return the timedelta now
acolwell GONE FROM CHROMIUM
2012/07/31 18:41:24
Done.
| |
293 int32 id, base::TimeDelta* timestamp, base::TimeDelta* duration) { | 289 int32 id, base::TimeDelta* timestamp) { |
294 // If all else fails later, at least we can set a default duration if there | |
295 // was one in the config. | |
296 *duration = config_frame_duration_; | |
297 for (std::list<BufferTimeData>::const_iterator it = | 290 for (std::list<BufferTimeData>::const_iterator it = |
298 input_buffer_time_data_.begin(); it != input_buffer_time_data_.end(); | 291 input_buffer_time_data_.begin(); it != input_buffer_time_data_.end(); |
299 ++it) { | 292 ++it) { |
300 if (it->bitstream_buffer_id != id) | 293 if (it->bitstream_buffer_id != id) |
301 continue; | 294 continue; |
302 *timestamp = it->timestamp; | 295 *timestamp = it->timestamp; |
303 *duration = it->duration; | |
304 return; | 296 return; |
305 } | 297 } |
306 NOTREACHED() << "Missing bitstreambuffer id: " << id; | 298 NOTREACHED() << "Missing bitstreambuffer id: " << id; |
307 } | 299 } |
308 | 300 |
309 const gfx::Size& GpuVideoDecoder::natural_size() { | 301 const gfx::Size& GpuVideoDecoder::natural_size() { |
310 return natural_size_; | 302 return natural_size_; |
311 } | 303 } |
312 | 304 |
313 bool GpuVideoDecoder::HasAlpha() const { | 305 bool GpuVideoDecoder::HasAlpha() const { |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
387 picture_buffers_in_decoder_.find(picture.picture_buffer_id()); | 379 picture_buffers_in_decoder_.find(picture.picture_buffer_id()); |
388 if (it == picture_buffers_in_decoder_.end()) { | 380 if (it == picture_buffers_in_decoder_.end()) { |
389 NOTREACHED() << "Missing picture buffer: " << picture.picture_buffer_id(); | 381 NOTREACHED() << "Missing picture buffer: " << picture.picture_buffer_id(); |
390 NotifyError(VideoDecodeAccelerator::PLATFORM_FAILURE); | 382 NotifyError(VideoDecodeAccelerator::PLATFORM_FAILURE); |
391 return; | 383 return; |
392 } | 384 } |
393 const PictureBuffer& pb = it->second; | 385 const PictureBuffer& pb = it->second; |
394 | 386 |
395 // Update frame's timestamp. | 387 // Update frame's timestamp. |
396 base::TimeDelta timestamp; | 388 base::TimeDelta timestamp; |
397 base::TimeDelta duration; | 389 GetBufferTimeData(picture.bitstream_buffer_id(), ×tamp); |
398 GetBufferTimeData(picture.bitstream_buffer_id(), ×tamp, &duration); | |
399 | 390 |
400 DCHECK(decoder_texture_target_); | 391 DCHECK(decoder_texture_target_); |
401 scoped_refptr<VideoFrame> frame(VideoFrame::WrapNativeTexture( | 392 scoped_refptr<VideoFrame> frame(VideoFrame::WrapNativeTexture( |
402 pb.texture_id(), decoder_texture_target_, pb.size().width(), | 393 pb.texture_id(), decoder_texture_target_, pb.size().width(), |
403 pb.size().height(), timestamp, duration, | 394 pb.size().height(), timestamp, |
404 base::Bind(&GpuVideoDecoder::ReusePictureBuffer, this, | 395 base::Bind(&GpuVideoDecoder::ReusePictureBuffer, this, |
405 picture.picture_buffer_id()))); | 396 picture.picture_buffer_id()))); |
406 | 397 |
407 EnqueueFrameAndTriggerFrameDelivery(frame); | 398 EnqueueFrameAndTriggerFrameDelivery(frame); |
408 } | 399 } |
409 | 400 |
410 void GpuVideoDecoder::EnqueueFrameAndTriggerFrameDelivery( | 401 void GpuVideoDecoder::EnqueueFrameAndTriggerFrameDelivery( |
411 const scoped_refptr<VideoFrame>& frame) { | 402 const scoped_refptr<VideoFrame>& frame) { |
412 DCHECK(gvd_loop_proxy_->BelongsToCurrentThread()); | 403 DCHECK(gvd_loop_proxy_->BelongsToCurrentThread()); |
413 | 404 |
(...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
567 | 558 |
568 error_occured_ = true; | 559 error_occured_ = true; |
569 | 560 |
570 if (!pending_read_cb_.is_null()) { | 561 if (!pending_read_cb_.is_null()) { |
571 base::ResetAndReturn(&pending_read_cb_).Run(kDecodeError, NULL); | 562 base::ResetAndReturn(&pending_read_cb_).Run(kDecodeError, NULL); |
572 return; | 563 return; |
573 } | 564 } |
574 } | 565 } |
575 | 566 |
576 } // namespace media | 567 } // namespace media |
OLD | NEW |