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

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

Issue 2116573002: Release MediaCodec on another thread more often. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 5 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 1070 matching lines...) Expand 10 before | Expand all | Expand 10 after
1081 DCHECK_NE(state_, WAITING_FOR_CODEC); 1081 DCHECK_NE(state_, WAITING_FOR_CODEC);
1082 1082
1083 state_ = WAITING_FOR_CODEC; 1083 state_ = WAITING_FOR_CODEC;
1084 1084
1085 // Tell the strategy that we're changing codecs. The codec itself could be 1085 // Tell the strategy that we're changing codecs. The codec itself could be
1086 // used normally, since we don't replace it until we're back on the main 1086 // used normally, since we don't replace it until we're back on the main
1087 // thread. However, if we're using an output surface, then the incoming codec 1087 // thread. However, if we're using an output surface, then the incoming codec
1088 // might access that surface while the main thread is drawing. Telling the 1088 // might access that surface while the main thread is drawing. Telling the
1089 // strategy to forget the codec avoids this. 1089 // strategy to forget the codec avoids this.
1090 if (media_codec_) { 1090 if (media_codec_) {
1091 media_codec_.reset(); 1091 ReleaseMediaCodec();
1092 strategy_->CodecChanged(nullptr); 1092 strategy_->CodecChanged(nullptr);
1093 } 1093 }
1094 1094
1095 // Choose whether to autodetect the codec type. 1095 // Choose whether to autodetect the codec type. Note that we do this after
1096 // releasing any outgoing codec, so that |codec_config_| still matches the
1097 // outgoing codec for ReleaseMediaCodec().
1096 codec_config_->allow_autodetection_ = 1098 codec_config_->allow_autodetection_ =
1097 g_avda_timer.Pointer()->IsCodecAutodetectionProbablySafe(); 1099 g_avda_timer.Pointer()->IsCodecAutodetectionProbablySafe();
1098 codec_config_->notify_completion_ = codec_config_->allow_autodetection_; 1100 codec_config_->notify_completion_ = codec_config_->allow_autodetection_;
1099 if (codec_config_->allow_autodetection_) 1101 if (codec_config_->allow_autodetection_)
1100 g_avda_timer.Pointer()->OnAsyncCodecAutodetectionStarted(); 1102 g_avda_timer.Pointer()->OnAsyncCodecAutodetectionStarted();
1101 1103
1102 // If we're not trying autodetection, then use the main thread. The original 1104 // If we're not trying autodetection, then use the main thread. The original
1103 // might be blocked. 1105 // might be blocked.
1104 scoped_refptr<base::SingleThreadTaskRunner> task_runner = 1106 scoped_refptr<base::SingleThreadTaskRunner> task_runner =
1105 codec_config_->allow_autodetection_ 1107 codec_config_->allow_autodetection_
(...skipping 13 matching lines...) Expand all
1119 state_ = WAITING_FOR_CODEC; 1121 state_ = WAITING_FOR_CODEC;
1120 1122
1121 // Decide whether to allow autodetection or not. Since we're on the main 1123 // Decide whether to allow autodetection or not. Since we're on the main
1122 // thread, and this request is unordered with respect to pending async config 1124 // thread, and this request is unordered with respect to pending async config
1123 // attempts, don't record it. It may break book-keeping, and there's not 1125 // attempts, don't record it. It may break book-keeping, and there's not
1124 // much we can do anyway. 1126 // much we can do anyway.
1125 codec_config_->allow_autodetection_ = 1127 codec_config_->allow_autodetection_ =
1126 g_avda_timer.Pointer()->IsCodecAutodetectionProbablySafe(); 1128 g_avda_timer.Pointer()->IsCodecAutodetectionProbablySafe();
1127 codec_config_->notify_completion_ = false; 1129 codec_config_->notify_completion_ = false;
1128 1130
1131 ReleaseMediaCodec();
1129 std::unique_ptr<VideoCodecBridge> media_codec = 1132 std::unique_ptr<VideoCodecBridge> media_codec =
1130 ConfigureMediaCodecOnAnyThread(codec_config_); 1133 ConfigureMediaCodecOnAnyThread(codec_config_);
1131 OnCodecConfigured(std::move(media_codec)); 1134 OnCodecConfigured(std::move(media_codec));
1132 return !!media_codec_; 1135 return !!media_codec_;
1133 } 1136 }
1134 1137
1135 std::unique_ptr<VideoCodecBridge> 1138 std::unique_ptr<VideoCodecBridge>
1136 AndroidVideoDecodeAccelerator::ConfigureMediaCodecOnAnyThread( 1139 AndroidVideoDecodeAccelerator::ConfigureMediaCodecOnAnyThread(
1137 scoped_refptr<CodecConfig> codec_config) { 1140 scoped_refptr<CodecConfig> codec_config) {
1138 TRACE_EVENT0("media", "AVDA::ConfigureMediaCodec"); 1141 TRACE_EVENT0("media", "AVDA::ConfigureMediaCodec");
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
1176 NotifyInitializationComplete(state_ == SURFACE_DESTROYED ? true 1179 NotifyInitializationComplete(state_ == SURFACE_DESTROYED ? true
1177 : !!media_codec); 1180 : !!media_codec);
1178 deferred_initialization_pending_ = false; 1181 deferred_initialization_pending_ = false;
1179 } 1182 }
1180 1183
1181 // If |state_| changed to SURFACE_DESTROYED while we were configuring a codec, 1184 // If |state_| changed to SURFACE_DESTROYED while we were configuring a codec,
1182 // then the codec is already invalid so we return early and drop it. 1185 // then the codec is already invalid so we return early and drop it.
1183 if (state_ == SURFACE_DESTROYED) 1186 if (state_ == SURFACE_DESTROYED)
1184 return; 1187 return;
1185 1188
1189 DCHECK(!media_codec_);
1186 media_codec_ = std::move(media_codec); 1190 media_codec_ = std::move(media_codec);
1187 strategy_->CodecChanged(media_codec_.get()); 1191 strategy_->CodecChanged(media_codec_.get());
1188 if (!media_codec_) { 1192 if (!media_codec_) {
1189 POST_ERROR(PLATFORM_FAILURE, "Failed to create MediaCodec."); 1193 POST_ERROR(PLATFORM_FAILURE, "Failed to create MediaCodec.");
1190 return; 1194 return;
1191 } 1195 }
1192 1196
1193 state_ = NO_ERROR; 1197 state_ = NO_ERROR;
1194 1198
1195 ManageTimer(true); 1199 ManageTimer(true);
(...skipping 209 matching lines...) Expand 10 before | Expand all | Expand 10 after
1405 // We no longer care about |surface_id|, in case we did before. It's okay 1409 // We no longer care about |surface_id|, in case we did before. It's okay
1406 // if we have no surface and/or weren't the owner or a waiter. 1410 // if we have no surface and/or weren't the owner or a waiter.
1407 manager->DeallocateSurface(config_.surface_id, this); 1411 manager->DeallocateSurface(config_.surface_id, this);
1408 1412
1409 // Note that async codec construction might still be in progress. In that 1413 // Note that async codec construction might still be in progress. In that
1410 // case, the codec will be deleted when it completes once we invalidate all 1414 // case, the codec will be deleted when it completes once we invalidate all
1411 // our weak refs. 1415 // our weak refs.
1412 weak_this_factory_.InvalidateWeakPtrs(); 1416 weak_this_factory_.InvalidateWeakPtrs();
1413 if (media_codec_) { 1417 if (media_codec_) {
1414 manager->StopTimer(this); 1418 manager->StopTimer(this);
1415 // If codec construction is broken, then we can't release this codec if it's 1419 ReleaseMediaCodec();
1416 // backed by hardware, else it may hang too. Post it to the construction
1417 // thread, and it'll get freed if things start working. If things are
1418 // already working, then it'll be freed soon.
1419 //
1420 // We require software codecs when |allow_autodetection_| is false, so use
1421 // the stored value as a proxy for whether the MediaCodec is software backed
1422 // or not.
1423 if (!codec_config_->allow_autodetection_) {
1424 media_codec_.reset();
1425 } else {
1426 manager->ConstructionTaskRunner()->DeleteSoon(FROM_HERE,
1427 media_codec_.release());
1428 }
1429 } 1420 }
1430 delete this; 1421 delete this;
1431 } 1422 }
1432 1423
1433 bool AndroidVideoDecodeAccelerator::TryToSetupDecodeOnSeparateThread( 1424 bool AndroidVideoDecodeAccelerator::TryToSetupDecodeOnSeparateThread(
1434 const base::WeakPtr<Client>& decode_client, 1425 const base::WeakPtr<Client>& decode_client,
1435 const scoped_refptr<base::SingleThreadTaskRunner>& decode_task_runner) { 1426 const scoped_refptr<base::SingleThreadTaskRunner>& decode_task_runner) {
1436 return false; 1427 return false;
1437 } 1428 }
1438 1429
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
1506 DVLOG(1) << __FUNCTION__ << " surface_id: " << surface_id; 1497 DVLOG(1) << __FUNCTION__ << " surface_id: " << surface_id;
1507 1498
1508 if (surface_id != config_.surface_id) 1499 if (surface_id != config_.surface_id)
1509 return; 1500 return;
1510 1501
1511 // If we're currently asynchronously configuring a codec, it will be destroyed 1502 // If we're currently asynchronously configuring a codec, it will be destroyed
1512 // when configuration completes and it notices that |state_| has changed to 1503 // when configuration completes and it notices that |state_| has changed to
1513 // SURFACE_DESTROYED. 1504 // SURFACE_DESTROYED.
1514 state_ = SURFACE_DESTROYED; 1505 state_ = SURFACE_DESTROYED;
1515 if (media_codec_) { 1506 if (media_codec_) {
1516 media_codec_.reset(); 1507 ReleaseMediaCodec();
1517 strategy_->CodecChanged(media_codec_.get()); 1508 strategy_->CodecChanged(media_codec_.get());
1518 } 1509 }
1519 // If we're draining, signal completion now because the drain can no longer 1510 // If we're draining, signal completion now because the drain can no longer
1520 // proceed. 1511 // proceed.
1521 if (drain_type_ != DRAIN_TYPE_NONE) 1512 if (drain_type_ != DRAIN_TYPE_NONE)
1522 OnDrainCompleted(); 1513 OnDrainCompleted();
1523 } 1514 }
1524 1515
1525 void AndroidVideoDecodeAccelerator::OnFrameAvailable() { 1516 void AndroidVideoDecodeAccelerator::OnFrameAvailable() {
1526 // Remember: this may be on any thread. 1517 // Remember: this may be on any thread.
(...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after
1662 } else { 1653 } else {
1663 most_recent_work_ = now; 1654 most_recent_work_ = now;
1664 } 1655 }
1665 1656
1666 if (should_be_running) 1657 if (should_be_running)
1667 g_avda_timer.Pointer()->StartTimer(this); 1658 g_avda_timer.Pointer()->StartTimer(this);
1668 else 1659 else
1669 g_avda_timer.Pointer()->StopTimer(this); 1660 g_avda_timer.Pointer()->StopTimer(this);
1670 } 1661 }
1671 1662
1663 void AndroidVideoDecodeAccelerator::ReleaseMediaCodec() {
1664 if (!media_codec_)
1665 return;
1666
1667 // If codec construction is broken, then we can't release this codec if it's
1668 // backed by hardware, else it may hang too. Post it to the construction
1669 // thread, and it'll get freed if things start working. If things are
1670 // already working, then it'll be freed soon.
1671 //
1672 // We require software codecs when |allow_autodetection_| is false, so use
1673 // the stored value as a proxy for whether the MediaCodec is software backed
1674 // or not.
1675 if (!codec_config_->allow_autodetection_) {
1676 media_codec_.reset();
1677 } else {
1678 g_avda_timer.Pointer()->ConstructionTaskRunner()->DeleteSoon(
1679 FROM_HERE, media_codec_.release());
1680 }
1681 }
1682
1672 // static 1683 // static
1673 bool AndroidVideoDecodeAccelerator::UseDeferredRenderingStrategy( 1684 bool AndroidVideoDecodeAccelerator::UseDeferredRenderingStrategy(
1674 const gpu::GpuPreferences& gpu_preferences) { 1685 const gpu::GpuPreferences& gpu_preferences) {
1675 return true; 1686 return true;
1676 } 1687 }
1677 1688
1678 // static 1689 // static
1679 bool AndroidVideoDecodeAccelerator::UseTextureCopyForDeferredStrategy( 1690 bool AndroidVideoDecodeAccelerator::UseTextureCopyForDeferredStrategy(
1680 const gpu::GpuPreferences& gpu_preferences) { 1691 const gpu::GpuPreferences& gpu_preferences) {
1681 // http://crbug.com/582170 1692 // http://crbug.com/582170
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
1754 // http://crbug.com/582170 1765 // http://crbug.com/582170
1755 capabilities.flags |= media::VideoDecodeAccelerator::Capabilities:: 1766 capabilities.flags |= media::VideoDecodeAccelerator::Capabilities::
1756 SUPPORTS_EXTERNAL_OUTPUT_SURFACE; 1767 SUPPORTS_EXTERNAL_OUTPUT_SURFACE;
1757 } 1768 }
1758 } 1769 }
1759 1770
1760 return capabilities; 1771 return capabilities;
1761 } 1772 }
1762 1773
1763 } // namespace media 1774 } // 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