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 1070 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |