OLD | NEW |
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 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/base/android/media_codec_video_decoder.h" | 5 #include "media/base/android/media_codec_video_decoder.h" |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
8 #include "base/logging.h" | 8 #include "base/logging.h" |
9 #include "media/base/android/media_codec_bridge.h" | 9 #include "media/base/android/media_codec_bridge.h" |
| 10 #include "media/base/android/media_statistics.h" |
10 #include "media/base/demuxer_stream.h" | 11 #include "media/base/demuxer_stream.h" |
11 #include "media/base/timestamp_constants.h" | 12 #include "media/base/timestamp_constants.h" |
12 | 13 |
13 namespace media { | 14 namespace media { |
14 | 15 |
15 namespace { | 16 namespace { |
16 const int kDelayForStandAloneEOS = 2; // milliseconds | 17 const int kDelayForStandAloneEOS = 2; // milliseconds |
17 } | 18 } |
18 | 19 |
19 MediaCodecVideoDecoder::MediaCodecVideoDecoder( | 20 MediaCodecVideoDecoder::MediaCodecVideoDecoder( |
20 const scoped_refptr<base::SingleThreadTaskRunner>& media_task_runner, | 21 const scoped_refptr<base::SingleThreadTaskRunner>& media_task_runner, |
21 const base::Closure& request_data_cb, | 22 const base::Closure& request_data_cb, |
22 const base::Closure& starvation_cb, | 23 const base::Closure& starvation_cb, |
23 const base::Closure& decoder_drained_cb, | 24 const base::Closure& decoder_drained_cb, |
24 const base::Closure& stop_done_cb, | 25 const base::Closure& stop_done_cb, |
25 const base::Closure& key_required_cb, | 26 const base::Closure& key_required_cb, |
26 const base::Closure& error_cb, | 27 const base::Closure& error_cb, |
27 const SetTimeCallback& update_current_time_cb, | 28 const SetTimeCallback& update_current_time_cb, |
28 const VideoSizeChangedCallback& video_size_changed_cb, | 29 const VideoSizeChangedCallback& video_size_changed_cb, |
29 const base::Closure& codec_created_cb) | 30 const base::Closure& codec_created_cb, |
| 31 FrameStatistics* frame_statistics) |
30 : MediaCodecDecoder(media_task_runner, | 32 : MediaCodecDecoder(media_task_runner, |
31 request_data_cb, | 33 request_data_cb, |
32 starvation_cb, | 34 starvation_cb, |
33 decoder_drained_cb, | 35 decoder_drained_cb, |
34 stop_done_cb, | 36 stop_done_cb, |
35 key_required_cb, | 37 key_required_cb, |
36 error_cb, | 38 error_cb, |
37 "VideoDecoder"), | 39 "VideoDecoder", |
| 40 frame_statistics), |
38 is_protected_surface_required_(false), | 41 is_protected_surface_required_(false), |
39 update_current_time_cb_(update_current_time_cb), | 42 update_current_time_cb_(update_current_time_cb), |
40 video_size_changed_cb_(video_size_changed_cb), | 43 video_size_changed_cb_(video_size_changed_cb), |
41 codec_created_cb_(codec_created_cb) { | 44 codec_created_cb_(codec_created_cb) { |
42 } | 45 } |
43 | 46 |
44 MediaCodecVideoDecoder::~MediaCodecVideoDecoder() { | 47 MediaCodecVideoDecoder::~MediaCodecVideoDecoder() { |
45 DCHECK(media_task_runner_->BelongsToCurrentThread()); | 48 DCHECK(media_task_runner_->BelongsToCurrentThread()); |
46 DVLOG(1) << "VideoDecoder::~VideoDecoder()"; | 49 DVLOG(1) << "VideoDecoder::~VideoDecoder()"; |
47 ReleaseDecoderResources(); | 50 ReleaseDecoderResources(); |
(...skipping 219 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
267 DCHECK_EQ(kRenderNow, render_mode); | 270 DCHECK_EQ(kRenderNow, render_mode); |
268 DCHECK_NE(kNoTimestamp(), start_pts_); // start_pts_ must be set | 271 DCHECK_NE(kNoTimestamp(), start_pts_); // start_pts_ must be set |
269 | 272 |
270 base::TimeDelta time_to_render = | 273 base::TimeDelta time_to_render = |
271 pts - (base::TimeTicks::Now() - start_time_ticks_ + start_pts_); | 274 pts - (base::TimeTicks::Now() - start_time_ticks_ + start_pts_); |
272 | 275 |
273 DVLOG(2) << class_name() << "::" << __FUNCTION__ << " pts:" << pts | 276 DVLOG(2) << class_name() << "::" << __FUNCTION__ << " pts:" << pts |
274 << " ticks delta:" << (base::TimeTicks::Now() - start_time_ticks_) | 277 << " ticks delta:" << (base::TimeTicks::Now() - start_time_ticks_) |
275 << " time_to_render:" << time_to_render; | 278 << " time_to_render:" << time_to_render; |
276 | 279 |
| 280 const bool render = (size > 0); |
| 281 |
| 282 if (render && frame_statistics_) |
| 283 frame_statistics_->AddFrame(); |
| 284 |
277 if (time_to_render < base::TimeDelta()) { | 285 if (time_to_render < base::TimeDelta()) { |
| 286 if (render && frame_statistics_) |
| 287 frame_statistics_->AddLateFrame((-1) * time_to_render); |
| 288 |
278 // Skip late frames | 289 // Skip late frames |
279 ReleaseOutputBuffer(buffer_index, pts, false, update_time, eos_encountered); | 290 ReleaseOutputBuffer(buffer_index, pts, false, update_time, eos_encountered); |
280 return; | 291 return; |
281 } | 292 } |
282 | 293 |
283 delayed_buffers_.insert(buffer_index); | 294 delayed_buffers_.insert(buffer_index); |
284 | 295 |
285 const bool render = (size > 0); | |
286 decoder_thread_.task_runner()->PostDelayedTask( | 296 decoder_thread_.task_runner()->PostDelayedTask( |
287 FROM_HERE, base::Bind(&MediaCodecVideoDecoder::ReleaseOutputBuffer, | 297 FROM_HERE, base::Bind(&MediaCodecVideoDecoder::ReleaseOutputBuffer, |
288 base::Unretained(this), buffer_index, pts, render, | 298 base::Unretained(this), buffer_index, pts, render, |
289 update_time, eos_encountered), | 299 update_time, eos_encountered), |
290 time_to_render); | 300 time_to_render); |
291 } | 301 } |
292 | 302 |
293 int MediaCodecVideoDecoder::NumDelayedRenderTasks() const { | 303 int MediaCodecVideoDecoder::NumDelayedRenderTasks() const { |
294 DCHECK(decoder_thread_.task_runner()->BelongsToCurrentThread()); | 304 DCHECK(decoder_thread_.task_runner()->BelongsToCurrentThread()); |
295 | 305 |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
336 | 346 |
337 // |update_current_time_cb_| might be null if there is audio stream. | 347 // |update_current_time_cb_| might be null if there is audio stream. |
338 // Do not update current time for stand-alone EOS frames. | 348 // Do not update current time for stand-alone EOS frames. |
339 if (!update_current_time_cb_.is_null() && update_time) { | 349 if (!update_current_time_cb_.is_null() && update_time) { |
340 media_task_runner_->PostTask( | 350 media_task_runner_->PostTask( |
341 FROM_HERE, base::Bind(update_current_time_cb_, pts, pts, false)); | 351 FROM_HERE, base::Bind(update_current_time_cb_, pts, pts, false)); |
342 } | 352 } |
343 } | 353 } |
344 | 354 |
345 } // namespace media | 355 } // namespace media |
OLD | NEW |