Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2013 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/gpu/android_video_decode_accelerator.h" | 5 #include "media/gpu/android_video_decode_accelerator.h" |
| 6 | 6 |
| 7 #include <stddef.h> | 7 #include <stddef.h> |
| 8 | 8 |
| 9 #include <memory> | 9 #include <memory> |
| 10 | 10 |
| (...skipping 365 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 376 get_gles2_decoder_cb_(get_gles2_decoder_cb), | 376 get_gles2_decoder_cb_(get_gles2_decoder_cb), |
| 377 state_(NO_ERROR), | 377 state_(NO_ERROR), |
| 378 picturebuffers_requested_(false), | 378 picturebuffers_requested_(false), |
| 379 drain_type_(DRAIN_TYPE_NONE), | 379 drain_type_(DRAIN_TYPE_NONE), |
| 380 media_drm_bridge_cdm_context_(nullptr), | 380 media_drm_bridge_cdm_context_(nullptr), |
| 381 cdm_registration_id_(0), | 381 cdm_registration_id_(0), |
| 382 pending_input_buf_index_(-1), | 382 pending_input_buf_index_(-1), |
| 383 error_sequence_token_(0), | 383 error_sequence_token_(0), |
| 384 defer_errors_(false), | 384 defer_errors_(false), |
| 385 deferred_initialization_pending_(false), | 385 deferred_initialization_pending_(false), |
| 386 codec_needs_reset_(false), | |
| 386 weak_this_factory_(this) {} | 387 weak_this_factory_(this) {} |
| 387 | 388 |
| 388 AndroidVideoDecodeAccelerator::~AndroidVideoDecodeAccelerator() { | 389 AndroidVideoDecodeAccelerator::~AndroidVideoDecodeAccelerator() { |
| 389 DCHECK(thread_checker_.CalledOnValidThread()); | 390 DCHECK(thread_checker_.CalledOnValidThread()); |
| 390 g_avda_timer.Pointer()->StopTimer(this); | 391 g_avda_timer.Pointer()->StopTimer(this); |
| 391 g_avda_timer.Pointer()->StopThread(this); | 392 g_avda_timer.Pointer()->StopThread(this); |
| 392 | 393 |
| 393 #if defined(ENABLE_MOJO_MEDIA_IN_GPU_PROCESS) | 394 #if defined(ENABLE_MOJO_MEDIA_IN_GPU_PROCESS) |
| 394 if (!media_drm_bridge_cdm_context_) | 395 if (!media_drm_bridge_cdm_context_) |
| 395 return; | 396 return; |
| (...skipping 497 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 893 | 894 |
| 894 // Connect the PictureBuffer to the decoded frame, via whatever mechanism the | 895 // Connect the PictureBuffer to the decoded frame, via whatever mechanism the |
| 895 // strategy likes. | 896 // strategy likes. |
| 896 strategy_->UseCodecBufferForPictureBuffer(codec_buffer_index, i->second); | 897 strategy_->UseCodecBufferForPictureBuffer(codec_buffer_index, i->second); |
| 897 } | 898 } |
| 898 | 899 |
| 899 void AndroidVideoDecodeAccelerator::Decode( | 900 void AndroidVideoDecodeAccelerator::Decode( |
| 900 const media::BitstreamBuffer& bitstream_buffer) { | 901 const media::BitstreamBuffer& bitstream_buffer) { |
| 901 DCHECK(thread_checker_.CalledOnValidThread()); | 902 DCHECK(thread_checker_.CalledOnValidThread()); |
| 902 | 903 |
| 904 // If we previously deferred a codec restart, take care of it now. This can | |
| 905 // happen on older devices where configuration changes require a codec reset. | |
| 906 if (codec_needs_reset_) | |
| 907 ResetCodecState(base::Closure()); | |
|
Tima Vaisburd
2016/05/21 06:40:31
Did you mean ConfigureMediaCodecAsynchronously() ?
DaleCurtis
2016/05/24 00:35:29
ResetCodecState() does all the necessary things: C
| |
| 908 | |
| 903 if (bitstream_buffer.id() >= 0 && bitstream_buffer.size() > 0) { | 909 if (bitstream_buffer.id() >= 0 && bitstream_buffer.size() > 0) { |
| 904 DecodeBuffer(bitstream_buffer); | 910 DecodeBuffer(bitstream_buffer); |
| 905 return; | 911 return; |
| 906 } | 912 } |
| 907 | 913 |
| 908 if (base::SharedMemory::IsHandleValid(bitstream_buffer.handle())) | 914 if (base::SharedMemory::IsHandleValid(bitstream_buffer.handle())) |
| 909 base::SharedMemory::CloseHandle(bitstream_buffer.handle()); | 915 base::SharedMemory::CloseHandle(bitstream_buffer.handle()); |
| 910 | 916 |
| 911 if (bitstream_buffer.id() < 0) { | 917 if (bitstream_buffer.id() < 0) { |
| 912 POST_ERROR(INVALID_ARGUMENT, | 918 POST_ERROR(INVALID_ARGUMENT, |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 981 if (i == output_picture_buffers_.end()) { | 987 if (i == output_picture_buffers_.end()) { |
| 982 POST_ERROR(PLATFORM_FAILURE, "Can't find PictureBuffer id " | 988 POST_ERROR(PLATFORM_FAILURE, "Can't find PictureBuffer id " |
| 983 << picture_buffer_id); | 989 << picture_buffer_id); |
| 984 return; | 990 return; |
| 985 } | 991 } |
| 986 | 992 |
| 987 strategy_->ReuseOnePictureBuffer(i->second); | 993 strategy_->ReuseOnePictureBuffer(i->second); |
| 988 DoIOTask(true); | 994 DoIOTask(true); |
| 989 } | 995 } |
| 990 | 996 |
| 991 void AndroidVideoDecodeAccelerator::Flush() { | 997 void AndroidVideoDecodeAccelerator::Flush() { |
|
Tima Vaisburd
2016/05/21 06:40:31
Is this flush() exists solely for the purpose to
| |
| 992 DVLOG(1) << __FUNCTION__; | 998 DVLOG(1) << __FUNCTION__; |
| 993 DCHECK(thread_checker_.CalledOnValidThread()); | 999 DCHECK(thread_checker_.CalledOnValidThread()); |
| 994 | 1000 |
| 995 if (state_ == SURFACE_DESTROYED) | 1001 if (state_ == SURFACE_DESTROYED) |
| 996 NotifyFlushDone(); | 1002 NotifyFlushDone(); |
| 997 else | 1003 else |
| 998 StartCodecDrain(DRAIN_FOR_FLUSH); | 1004 StartCodecDrain(DRAIN_FOR_FLUSH); |
| 999 } | 1005 } |
| 1000 | 1006 |
| 1001 void AndroidVideoDecodeAccelerator::ConfigureMediaCodecAsynchronously() { | 1007 void AndroidVideoDecodeAccelerator::ConfigureMediaCodecAsynchronously() { |
| (...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1172 // shm block been deleted. Check that it is safe to flush the coec, i.e. | 1178 // shm block been deleted. Check that it is safe to flush the coec, i.e. |
| 1173 // |pending_bitstream_buffers_| is empty. | 1179 // |pending_bitstream_buffers_| is empty. |
| 1174 // TODO(timav): keep shm block for that buffer and remove this restriction. | 1180 // TODO(timav): keep shm block for that buffer and remove this restriction. |
| 1175 DCHECK(pending_bitstream_buffers_.empty()); | 1181 DCHECK(pending_bitstream_buffers_.empty()); |
| 1176 pending_input_buf_index_ = -1; | 1182 pending_input_buf_index_ = -1; |
| 1177 } | 1183 } |
| 1178 | 1184 |
| 1179 const bool did_codec_error_happen = state_ == ERROR; | 1185 const bool did_codec_error_happen = state_ == ERROR; |
| 1180 state_ = NO_ERROR; | 1186 state_ = NO_ERROR; |
| 1181 | 1187 |
| 1188 // When codec is not in error state we can quickly reset (internally calls | |
| 1189 // flush()) for JB-MR2 and beyond. Prior to JB-MR2, flush() had several bugs | |
| 1190 // (b/8125974, b/8347958) so we must delete the MediaCodec and create a new | |
| 1191 // one. The full reconfigure is much slower and may cause visible freezing if | |
| 1192 // done mid-stream. | |
| 1193 const bool codec_requires_reset_for_config_changes = | |
|
chcunningham
2016/05/21 00:25:33
It used to be that
api >= 18 -> quick flush
api <
DaleCurtis
2016/05/24 00:35:29
Actually, this needs to always reset since once we
| |
| 1194 base::android::BuildInfo::GetInstance()->sdk_int() < 18; | |
| 1195 | |
| 1196 // Don't reset the codec if there's no error and we're only flushing. On older | |
| 1197 // JellyBean devices we'll defer the reset until we get another Decode() call | |
| 1198 // so that we don't prematurely nuke the last few frames of video. | |
| 1199 codec_needs_reset_ = false; | |
| 1200 if (drain_type_ == DRAIN_FOR_FLUSH && !did_codec_error_happen) { | |
| 1201 codec_needs_reset_ = codec_requires_reset_for_config_changes; | |
| 1202 if (!done_cb.is_null()) | |
| 1203 done_cb.Run(); | |
| 1204 return; | |
| 1205 } | |
| 1206 | |
| 1182 // We might increment error_sequence_token here to cancel any delayed errors, | 1207 // We might increment error_sequence_token here to cancel any delayed errors, |
| 1183 // but right now it's unclear that it's safe to do so. If we are in an error | 1208 // but right now it's unclear that it's safe to do so. If we are in an error |
| 1184 // state because of a codec error, then it would be okay. Otherwise, it's | 1209 // state because of a codec error, then it would be okay. Otherwise, it's |
| 1185 // less obvious that we are exiting the error state. Since deferred errors | 1210 // less obvious that we are exiting the error state. Since deferred errors |
| 1186 // are only intended for fullscreen transitions right now, we take the more | 1211 // are only intended for fullscreen transitions right now, we take the more |
| 1187 // conservative approach and let the errors post. | 1212 // conservative approach and let the errors post. |
| 1188 // TODO(liberato): revisit this once we sort out the error state a bit more. | 1213 // TODO(liberato): revisit this once we sort out the error state a bit more. |
| 1189 | 1214 if (!did_codec_error_happen && !codec_requires_reset_for_config_changes) { |
| 1190 // When codec is not in error state we can quickly reset (internally calls | |
| 1191 // flush()) for JB-MR2 and beyond. Prior to JB-MR2, flush() had several bugs | |
| 1192 // (b/8125974, b/8347958) so we must delete the MediaCodec and create a new | |
| 1193 // one. The full reconfigure is much slower and may cause visible freezing if | |
| 1194 // done mid-stream. | |
| 1195 if (!did_codec_error_happen && | |
| 1196 base::android::BuildInfo::GetInstance()->sdk_int() >= 18) { | |
| 1197 DVLOG(3) << __FUNCTION__ << " Doing fast MediaCodec reset (flush)."; | 1215 DVLOG(3) << __FUNCTION__ << " Doing fast MediaCodec reset (flush)."; |
| 1198 media_codec_->Reset(); | 1216 media_codec_->Reset(); |
| 1199 // Since we just flushed all the output buffers, make sure that nothing is | 1217 // Since we just flushed all the output buffers, make sure that nothing is |
| 1200 // using them. | 1218 // using them. |
| 1201 strategy_->CodecChanged(media_codec_.get()); | 1219 strategy_->CodecChanged(media_codec_.get()); |
| 1202 } else { | 1220 } else { |
| 1203 DVLOG(3) << __FUNCTION__ | 1221 DVLOG(3) << __FUNCTION__ |
| 1204 << " Deleting the MediaCodec and creating a new one."; | 1222 << " Deleting the MediaCodec and creating a new one."; |
| 1205 g_avda_timer.Pointer()->StopTimer(this); | 1223 g_avda_timer.Pointer()->StopTimer(this); |
| 1206 // Changing the codec will also notify the strategy to forget about any | 1224 // Changing the codec will also notify the strategy to forget about any |
| (...skipping 387 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1594 if (media::MediaCodecUtil::IsSurfaceViewOutputSupported()) { | 1612 if (media::MediaCodecUtil::IsSurfaceViewOutputSupported()) { |
| 1595 capabilities.flags |= media::VideoDecodeAccelerator::Capabilities:: | 1613 capabilities.flags |= media::VideoDecodeAccelerator::Capabilities:: |
| 1596 SUPPORTS_EXTERNAL_OUTPUT_SURFACE; | 1614 SUPPORTS_EXTERNAL_OUTPUT_SURFACE; |
| 1597 } | 1615 } |
| 1598 } | 1616 } |
| 1599 | 1617 |
| 1600 return capabilities; | 1618 return capabilities; |
| 1601 } | 1619 } |
| 1602 | 1620 |
| 1603 } // namespace media | 1621 } // namespace media |
| OLD | NEW |