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, |
| 22 FrameStatistics* frame_statistics, |
21 const base::Closure& request_data_cb, | 23 const base::Closure& request_data_cb, |
22 const base::Closure& starvation_cb, | 24 const base::Closure& starvation_cb, |
23 const base::Closure& decoder_drained_cb, | 25 const base::Closure& decoder_drained_cb, |
24 const base::Closure& stop_done_cb, | 26 const base::Closure& stop_done_cb, |
25 const base::Closure& waiting_for_decryption_key_cb, | 27 const base::Closure& waiting_for_decryption_key_cb, |
26 const base::Closure& error_cb, | 28 const base::Closure& error_cb, |
27 const SetTimeCallback& update_current_time_cb, | 29 const SetTimeCallback& update_current_time_cb, |
28 const VideoSizeChangedCallback& video_size_changed_cb, | 30 const VideoSizeChangedCallback& video_size_changed_cb, |
29 const base::Closure& codec_created_cb) | 31 const base::Closure& codec_created_cb) |
30 : MediaCodecDecoder(media_task_runner, | 32 : MediaCodecDecoder("VideoDecoder", |
| 33 media_task_runner, |
| 34 frame_statistics, |
31 request_data_cb, | 35 request_data_cb, |
32 starvation_cb, | 36 starvation_cb, |
33 decoder_drained_cb, | 37 decoder_drained_cb, |
34 stop_done_cb, | 38 stop_done_cb, |
35 waiting_for_decryption_key_cb, | 39 waiting_for_decryption_key_cb, |
36 error_cb, | 40 error_cb), |
37 "VideoDecoder"), | |
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 221 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
269 DCHECK_EQ(kRenderNow, render_mode); | 272 DCHECK_EQ(kRenderNow, render_mode); |
270 DCHECK_NE(kNoTimestamp(), start_pts_); // start_pts_ must be set | 273 DCHECK_NE(kNoTimestamp(), start_pts_); // start_pts_ must be set |
271 | 274 |
272 base::TimeDelta time_to_render = | 275 base::TimeDelta time_to_render = |
273 pts - (base::TimeTicks::Now() - start_time_ticks_ + start_pts_); | 276 pts - (base::TimeTicks::Now() - start_time_ticks_ + start_pts_); |
274 | 277 |
275 DVLOG(2) << class_name() << "::" << __FUNCTION__ << " pts:" << pts | 278 DVLOG(2) << class_name() << "::" << __FUNCTION__ << " pts:" << pts |
276 << " ticks delta:" << (base::TimeTicks::Now() - start_time_ticks_) | 279 << " ticks delta:" << (base::TimeTicks::Now() - start_time_ticks_) |
277 << " time_to_render:" << time_to_render; | 280 << " time_to_render:" << time_to_render; |
278 | 281 |
| 282 const bool render = (size > 0); |
| 283 |
| 284 if (render) |
| 285 frame_statistics_->IncrementFrameCount(); |
| 286 |
279 if (time_to_render < base::TimeDelta()) { | 287 if (time_to_render < base::TimeDelta()) { |
| 288 if (render) { |
| 289 DVLOG(2) << class_name() << "::" << __FUNCTION__ |
| 290 << " LATE FRAME delay:" << (-1) * time_to_render; |
| 291 |
| 292 frame_statistics_->IncrementLateFrameCount(); |
| 293 } |
| 294 |
280 // Skip late frames | 295 // Skip late frames |
281 ReleaseOutputBuffer(buffer_index, pts, false, update_time, eos_encountered); | 296 ReleaseOutputBuffer(buffer_index, pts, false, update_time, eos_encountered); |
282 return; | 297 return; |
283 } | 298 } |
284 | 299 |
285 delayed_buffers_.insert(buffer_index); | 300 delayed_buffers_.insert(buffer_index); |
286 | 301 |
287 const bool render = (size > 0); | |
288 decoder_thread_.task_runner()->PostDelayedTask( | 302 decoder_thread_.task_runner()->PostDelayedTask( |
289 FROM_HERE, base::Bind(&MediaCodecVideoDecoder::ReleaseOutputBuffer, | 303 FROM_HERE, base::Bind(&MediaCodecVideoDecoder::ReleaseOutputBuffer, |
290 base::Unretained(this), buffer_index, pts, render, | 304 base::Unretained(this), buffer_index, pts, render, |
291 update_time, eos_encountered), | 305 update_time, eos_encountered), |
292 time_to_render); | 306 time_to_render); |
293 } | 307 } |
294 | 308 |
295 int MediaCodecVideoDecoder::NumDelayedRenderTasks() const { | 309 int MediaCodecVideoDecoder::NumDelayedRenderTasks() const { |
296 DCHECK(decoder_thread_.task_runner()->BelongsToCurrentThread()); | 310 DCHECK(decoder_thread_.task_runner()->BelongsToCurrentThread()); |
297 | 311 |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
338 | 352 |
339 // |update_current_time_cb_| might be null if there is audio stream. | 353 // |update_current_time_cb_| might be null if there is audio stream. |
340 // Do not update current time for stand-alone EOS frames. | 354 // Do not update current time for stand-alone EOS frames. |
341 if (!update_current_time_cb_.is_null() && update_time) { | 355 if (!update_current_time_cb_.is_null() && update_time) { |
342 media_task_runner_->PostTask( | 356 media_task_runner_->PostTask( |
343 FROM_HERE, base::Bind(update_current_time_cb_, pts, pts, false)); | 357 FROM_HERE, base::Bind(update_current_time_cb_, pts, pts, false)); |
344 } | 358 } |
345 } | 359 } |
346 | 360 |
347 } // namespace media | 361 } // namespace media |
OLD | NEW |