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

Side by Side Diff: media/gpu/android_video_decode_accelerator.cc

Issue 2000833003: Don't reset the codec state for a flush; this kills the frames. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Defer reset. Created 4 years, 7 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
« no previous file with comments | « media/gpu/android_video_decode_accelerator.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « media/gpu/android_video_decode_accelerator.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698