| 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 262 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 273 | 273 |
| 274 if (config.output_mode != Config::OutputMode::ALLOCATE) { | 274 if (config.output_mode != Config::OutputMode::ALLOCATE) { |
| 275 DLOG(ERROR) << "Only ALLOCATE OutputMode is supported by this VDA"; | 275 DLOG(ERROR) << "Only ALLOCATE OutputMode is supported by this VDA"; |
| 276 return false; | 276 return false; |
| 277 } | 277 } |
| 278 | 278 |
| 279 DCHECK(client); | 279 DCHECK(client); |
| 280 client_ = client; | 280 client_ = client; |
| 281 config_ = config; | 281 config_ = config; |
| 282 codec_config_ = new CodecConfig(); | 282 codec_config_ = new CodecConfig(); |
| 283 codec_config_->codec_ = VideoCodecProfileToVideoCodec(config.profile); | 283 codec_config_->codec = VideoCodecProfileToVideoCodec(config.profile); |
| 284 codec_config_->initial_expected_coded_size_ = | 284 codec_config_->initial_expected_coded_size = |
| 285 config.initial_expected_coded_size; | 285 config.initial_expected_coded_size; |
| 286 | 286 |
| 287 if (codec_config_->codec_ != kCodecVP8 && | 287 if (codec_config_->codec != kCodecVP8 && codec_config_->codec != kCodecVP9 && |
| 288 codec_config_->codec_ != kCodecVP9 && | |
| 289 #if BUILDFLAG(ENABLE_HEVC_DEMUXING) | 288 #if BUILDFLAG(ENABLE_HEVC_DEMUXING) |
| 290 codec_config_->codec_ != kCodecHEVC && | 289 codec_config_->codec != kCodecHEVC && |
| 291 #endif | 290 #endif |
| 292 codec_config_->codec_ != kCodecH264) { | 291 codec_config_->codec != kCodecH264) { |
| 293 DLOG(ERROR) << "Unsupported profile: " << config.profile; | 292 DLOG(ERROR) << "Unsupported profile: " << config.profile; |
| 294 return false; | 293 return false; |
| 295 } | 294 } |
| 296 | 295 |
| 297 if (codec_config_->codec_ == kCodecH264) { | 296 if (codec_config_->codec == kCodecH264) { |
| 298 codec_config_->csd0_ = config.sps; | 297 codec_config_->csd0 = config.sps; |
| 299 codec_config_->csd1_ = config.pps; | 298 codec_config_->csd1 = config.pps; |
| 300 } | 299 } |
| 301 | 300 |
| 302 // Only use MediaCodec for VP8/9 if it's likely backed by hardware | 301 // Only use MediaCodec for VP8/9 if it's likely backed by hardware |
| 303 // or if the stream is encrypted. | 302 // or if the stream is encrypted. |
| 304 if (IsMediaCodecSoftwareDecodingForbidden() && | 303 if (IsMediaCodecSoftwareDecodingForbidden() && |
| 305 VideoCodecBridge::IsKnownUnaccelerated(codec_config_->codec_, | 304 VideoCodecBridge::IsKnownUnaccelerated(codec_config_->codec, |
| 306 MEDIA_CODEC_DECODER)) { | 305 MEDIA_CODEC_DECODER)) { |
| 307 DVLOG(1) << "Initialization failed: " | 306 DVLOG(1) << "Initialization failed: " |
| 308 << (codec_config_->codec_ == kCodecVP8 ? "vp8" : "vp9") | 307 << (codec_config_->codec == kCodecVP8 ? "vp8" : "vp9") |
| 309 << " is not hardware accelerated"; | 308 << " is not hardware accelerated"; |
| 310 return false; | 309 return false; |
| 311 } | 310 } |
| 312 | 311 |
| 313 auto gles_decoder = get_gles2_decoder_cb_.Run(); | 312 auto gles_decoder = get_gles2_decoder_cb_.Run(); |
| 314 if (!gles_decoder) { | 313 if (!gles_decoder) { |
| 315 DLOG(ERROR) << "Failed to get gles2 decoder instance."; | 314 DLOG(ERROR) << "Failed to get gles2 decoder instance."; |
| 316 return false; | 315 return false; |
| 317 } | 316 } |
| 318 | 317 |
| 319 // SetSurface() can't be called before Initialize(), so we pick up our first | 318 // SetSurface() can't be called before Initialize(), so we pick up our first |
| 320 // surface ID from the codec configuration. | 319 // surface ID from the codec configuration. |
| 321 DCHECK(!pending_surface_id_); | 320 DCHECK(!pending_surface_id_); |
| 322 | 321 |
| 323 // If we're low on resources, we may decide to defer creation of the surface | 322 // If we're low on resources, we may decide to defer creation of the surface |
| 324 // until the codec is actually used. | 323 // until the codec is actually used. |
| 325 if (ShouldDeferSurfaceCreation(config_.surface_id, codec_config_->codec_)) { | 324 if (ShouldDeferSurfaceCreation(config_.surface_id, codec_config_->codec)) { |
| 326 DCHECK(!deferred_initialization_pending_); | 325 DCHECK(!deferred_initialization_pending_); |
| 327 // We should never be here if a SurfaceView is required. | 326 // We should never be here if a SurfaceView is required. |
| 328 DCHECK_EQ(config_.surface_id, SurfaceManager::kNoSurfaceID); | 327 DCHECK_EQ(config_.surface_id, SurfaceManager::kNoSurfaceID); |
| 329 defer_surface_creation_ = true; | 328 defer_surface_creation_ = true; |
| 330 NotifyInitializationComplete(true); | 329 NotifyInitializationComplete(true); |
| 331 return true; | 330 return true; |
| 332 } | 331 } |
| 333 | 332 |
| 334 // We signaled that we support deferred initialization, so see if the client | 333 // We signaled that we support deferred initialization, so see if the client |
| 335 // does also. | 334 // does also. |
| (...skipping 23 matching lines...) Expand all Loading... |
| 359 deferred_initialization_pending_ = false; | 358 deferred_initialization_pending_ = false; |
| 360 } | 359 } |
| 361 } | 360 } |
| 362 | 361 |
| 363 bool AndroidVideoDecodeAccelerator::InitializePictureBufferManager() { | 362 bool AndroidVideoDecodeAccelerator::InitializePictureBufferManager() { |
| 364 if (!make_context_current_cb_.Run()) { | 363 if (!make_context_current_cb_.Run()) { |
| 365 LOG(ERROR) << "Failed to make this decoder's GL context current."; | 364 LOG(ERROR) << "Failed to make this decoder's GL context current."; |
| 366 return false; | 365 return false; |
| 367 } | 366 } |
| 368 | 367 |
| 369 codec_config_->surface_ = | 368 codec_config_->surface = |
| 370 picture_buffer_manager_.Initialize(config_.surface_id); | 369 picture_buffer_manager_.Initialize(config_.surface_id); |
| 371 if (codec_config_->surface_.IsEmpty()) | 370 if (codec_config_->surface.IsEmpty()) |
| 372 return false; | 371 return false; |
| 373 | 372 |
| 374 if (!AVDACodecAllocator::Instance()->StartThread(this)) | 373 if (!AVDACodecAllocator::Instance()->StartThread(this)) |
| 375 return false; | 374 return false; |
| 376 | 375 |
| 377 // If we are encrypted, then we aren't able to create the codec yet. | 376 // If we are encrypted, then we aren't able to create the codec yet. |
| 378 if (config_.is_encrypted) { | 377 if (config_.is_encrypted) { |
| 379 InitializeCdm(); | 378 InitializeCdm(); |
| 380 return true; | 379 return true; |
| 381 } | 380 } |
| (...skipping 491 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 873 } | 872 } |
| 874 | 873 |
| 875 void AndroidVideoDecodeAccelerator::ConfigureMediaCodecAsynchronously() { | 874 void AndroidVideoDecodeAccelerator::ConfigureMediaCodecAsynchronously() { |
| 876 DCHECK(thread_checker_.CalledOnValidThread()); | 875 DCHECK(thread_checker_.CalledOnValidThread()); |
| 877 | 876 |
| 878 DCHECK_NE(state_, WAITING_FOR_CODEC); | 877 DCHECK_NE(state_, WAITING_FOR_CODEC); |
| 879 state_ = WAITING_FOR_CODEC; | 878 state_ = WAITING_FOR_CODEC; |
| 880 | 879 |
| 881 if (media_codec_) { | 880 if (media_codec_) { |
| 882 AVDACodecAllocator::Instance()->ReleaseMediaCodec( | 881 AVDACodecAllocator::Instance()->ReleaseMediaCodec( |
| 883 std::move(media_codec_), codec_config_->task_type_, config_.surface_id); | 882 std::move(media_codec_), codec_config_->task_type, config_.surface_id); |
| 884 picture_buffer_manager_.CodecChanged(nullptr); | 883 picture_buffer_manager_.CodecChanged(nullptr); |
| 885 } | 884 } |
| 886 | 885 |
| 887 base::Optional<TaskType> task_type = | 886 base::Optional<TaskType> task_type = |
| 888 AVDACodecAllocator::Instance()->TaskTypeForAllocation(); | 887 AVDACodecAllocator::Instance()->TaskTypeForAllocation(); |
| 889 if (!task_type) { | 888 if (!task_type) { |
| 890 // If there is no free thread, then just fail. | 889 // If there is no free thread, then just fail. |
| 891 OnCodecConfigured(nullptr); | 890 OnCodecConfigured(nullptr); |
| 892 return; | 891 return; |
| 893 } | 892 } |
| 894 | 893 |
| 895 // If autodetection is disallowed, fall back to Chrome's software decoders | 894 // If autodetection is disallowed, fall back to Chrome's software decoders |
| 896 // instead of using the software decoders provided by MediaCodec. | 895 // instead of using the software decoders provided by MediaCodec. |
| 897 if (task_type == TaskType::SW_CODEC && | 896 if (task_type == TaskType::SW_CODEC && |
| 898 IsMediaCodecSoftwareDecodingForbidden()) { | 897 IsMediaCodecSoftwareDecodingForbidden()) { |
| 899 OnCodecConfigured(nullptr); | 898 OnCodecConfigured(nullptr); |
| 900 return; | 899 return; |
| 901 } | 900 } |
| 902 | 901 |
| 903 codec_config_->task_type_ = task_type.value(); | 902 codec_config_->task_type = task_type.value(); |
| 904 AVDACodecAllocator::Instance()->CreateMediaCodecAsync( | 903 AVDACodecAllocator::Instance()->CreateMediaCodecAsync( |
| 905 weak_this_factory_.GetWeakPtr(), codec_config_); | 904 weak_this_factory_.GetWeakPtr(), codec_config_); |
| 906 } | 905 } |
| 907 | 906 |
| 908 bool AndroidVideoDecodeAccelerator::ConfigureMediaCodecSynchronously() { | 907 bool AndroidVideoDecodeAccelerator::ConfigureMediaCodecSynchronously() { |
| 909 DCHECK(thread_checker_.CalledOnValidThread()); | 908 DCHECK(thread_checker_.CalledOnValidThread()); |
| 910 DCHECK(!media_codec_); | 909 DCHECK(!media_codec_); |
| 911 DCHECK_NE(state_, WAITING_FOR_CODEC); | 910 DCHECK_NE(state_, WAITING_FOR_CODEC); |
| 912 state_ = WAITING_FOR_CODEC; | 911 state_ = WAITING_FOR_CODEC; |
| 913 | 912 |
| 914 base::Optional<TaskType> task_type = | 913 base::Optional<TaskType> task_type = |
| 915 AVDACodecAllocator::Instance()->TaskTypeForAllocation(); | 914 AVDACodecAllocator::Instance()->TaskTypeForAllocation(); |
| 916 if (!task_type) { | 915 if (!task_type) { |
| 917 // If there is no free thread, then just fail. | 916 // If there is no free thread, then just fail. |
| 918 OnCodecConfigured(nullptr); | 917 OnCodecConfigured(nullptr); |
| 919 return false; | 918 return false; |
| 920 } | 919 } |
| 921 | 920 |
| 922 codec_config_->task_type_ = task_type.value(); | 921 codec_config_->task_type = task_type.value(); |
| 923 std::unique_ptr<VideoCodecBridge> media_codec = | 922 std::unique_ptr<VideoCodecBridge> media_codec = |
| 924 AVDACodecAllocator::Instance()->CreateMediaCodecSync(codec_config_); | 923 AVDACodecAllocator::Instance()->CreateMediaCodecSync(codec_config_); |
| 925 OnCodecConfigured(std::move(media_codec)); | 924 OnCodecConfigured(std::move(media_codec)); |
| 926 return !!media_codec_; | 925 return !!media_codec_; |
| 927 } | 926 } |
| 928 | 927 |
| 929 void AndroidVideoDecodeAccelerator::OnCodecConfigured( | 928 void AndroidVideoDecodeAccelerator::OnCodecConfigured( |
| 930 std::unique_ptr<VideoCodecBridge> media_codec) { | 929 std::unique_ptr<VideoCodecBridge> media_codec) { |
| 931 DCHECK(thread_checker_.CalledOnValidThread()); | 930 DCHECK(thread_checker_.CalledOnValidThread()); |
| 932 DCHECK(state_ == WAITING_FOR_CODEC || state_ == SURFACE_DESTROYED); | 931 DCHECK(state_ == WAITING_FOR_CODEC || state_ == SURFACE_DESTROYED); |
| (...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1095 weak_this_factory_.GetWeakPtr(), bitstream_buffer_id)); | 1094 weak_this_factory_.GetWeakPtr(), bitstream_buffer_id)); |
| 1096 } | 1095 } |
| 1097 } | 1096 } |
| 1098 TRACE_COUNTER1("media", "AVDA::PendingBitstreamBufferCount", 0); | 1097 TRACE_COUNTER1("media", "AVDA::PendingBitstreamBufferCount", 0); |
| 1099 bitstreams_notified_in_advance_.clear(); | 1098 bitstreams_notified_in_advance_.clear(); |
| 1100 | 1099 |
| 1101 picture_buffer_manager_.ReleaseCodecBuffers(output_picture_buffers_); | 1100 picture_buffer_manager_.ReleaseCodecBuffers(output_picture_buffers_); |
| 1102 | 1101 |
| 1103 // Some VP8 files require complete MediaCodec drain before we can call | 1102 // Some VP8 files require complete MediaCodec drain before we can call |
| 1104 // MediaCodec.flush() or MediaCodec.reset(). http://crbug.com/598963. | 1103 // MediaCodec.flush() or MediaCodec.reset(). http://crbug.com/598963. |
| 1105 if (media_codec_ && codec_config_->codec_ == kCodecVP8 && | 1104 if (media_codec_ && codec_config_->codec == kCodecVP8 && |
| 1106 !bitstream_buffers_in_decoder_.empty()) { | 1105 !bitstream_buffers_in_decoder_.empty()) { |
| 1107 // Postpone ResetCodecState() after the drain. | 1106 // Postpone ResetCodecState() after the drain. |
| 1108 StartCodecDrain(DRAIN_FOR_RESET); | 1107 StartCodecDrain(DRAIN_FOR_RESET); |
| 1109 } else { | 1108 } else { |
| 1110 ResetCodecState(); | 1109 ResetCodecState(); |
| 1111 base::ThreadTaskRunnerHandle::Get()->PostTask( | 1110 base::ThreadTaskRunnerHandle::Get()->PostTask( |
| 1112 FROM_HERE, base::Bind(&AndroidVideoDecodeAccelerator::NotifyResetDone, | 1111 FROM_HERE, base::Bind(&AndroidVideoDecodeAccelerator::NotifyResetDone, |
| 1113 weak_this_factory_.GetWeakPtr())); | 1112 weak_this_factory_.GetWeakPtr())); |
| 1114 } | 1113 } |
| 1115 } | 1114 } |
| (...skipping 17 matching lines...) Expand all Loading... |
| 1133 DVLOG(1) << __FUNCTION__; | 1132 DVLOG(1) << __FUNCTION__; |
| 1134 DCHECK(thread_checker_.CalledOnValidThread()); | 1133 DCHECK(thread_checker_.CalledOnValidThread()); |
| 1135 | 1134 |
| 1136 picture_buffer_manager_.Destroy(output_picture_buffers_); | 1135 picture_buffer_manager_.Destroy(output_picture_buffers_); |
| 1137 | 1136 |
| 1138 client_ = nullptr; | 1137 client_ = nullptr; |
| 1139 | 1138 |
| 1140 // Some VP8 files require a complete MediaCodec drain before we can call | 1139 // Some VP8 files require a complete MediaCodec drain before we can call |
| 1141 // MediaCodec.flush() or MediaCodec.release(). http://crbug.com/598963. In | 1140 // MediaCodec.flush() or MediaCodec.release(). http://crbug.com/598963. In |
| 1142 // that case, postpone ActualDestroy() until after the drain. | 1141 // that case, postpone ActualDestroy() until after the drain. |
| 1143 if (media_codec_ && codec_config_->codec_ == kCodecVP8) { | 1142 if (media_codec_ && codec_config_->codec == kCodecVP8) { |
| 1144 // Clear |pending_bitstream_records_|. | 1143 // Clear |pending_bitstream_records_|. |
| 1145 while (!pending_bitstream_records_.empty()) | 1144 while (!pending_bitstream_records_.empty()) |
| 1146 pending_bitstream_records_.pop(); | 1145 pending_bitstream_records_.pop(); |
| 1147 | 1146 |
| 1148 StartCodecDrain(DRAIN_FOR_DESTROY); | 1147 StartCodecDrain(DRAIN_FOR_DESTROY); |
| 1149 } else { | 1148 } else { |
| 1150 ActualDestroy(); | 1149 ActualDestroy(); |
| 1151 } | 1150 } |
| 1152 } | 1151 } |
| 1153 | 1152 |
| 1154 void AndroidVideoDecodeAccelerator::ActualDestroy() { | 1153 void AndroidVideoDecodeAccelerator::ActualDestroy() { |
| 1155 DVLOG(1) << __FUNCTION__; | 1154 DVLOG(1) << __FUNCTION__; |
| 1156 DCHECK(thread_checker_.CalledOnValidThread()); | 1155 DCHECK(thread_checker_.CalledOnValidThread()); |
| 1157 | 1156 |
| 1158 // Note that async codec construction might still be in progress. In that | 1157 // Note that async codec construction might still be in progress. In that |
| 1159 // case, the codec will be deleted when it completes once we invalidate all | 1158 // case, the codec will be deleted when it completes once we invalidate all |
| 1160 // our weak refs. | 1159 // our weak refs. |
| 1161 weak_this_factory_.InvalidateWeakPtrs(); | 1160 weak_this_factory_.InvalidateWeakPtrs(); |
| 1162 g_avda_manager.Get().StopTimer(this); | 1161 g_avda_manager.Get().StopTimer(this); |
| 1163 if (media_codec_) { | 1162 if (media_codec_) { |
| 1164 AVDACodecAllocator::Instance()->ReleaseMediaCodec( | 1163 AVDACodecAllocator::Instance()->ReleaseMediaCodec( |
| 1165 std::move(media_codec_), codec_config_->task_type_, config_.surface_id); | 1164 std::move(media_codec_), codec_config_->task_type, config_.surface_id); |
| 1166 } | 1165 } |
| 1167 | 1166 |
| 1168 // We no longer care about |surface_id|, in case we did before. It's okay | 1167 // We no longer care about |surface_id|, in case we did before. It's okay |
| 1169 // if we have no surface and/or weren't the owner or a waiter. | 1168 // if we have no surface and/or weren't the owner or a waiter. |
| 1170 AVDACodecAllocator::Instance()->DeallocateSurface(this, config_.surface_id); | 1169 AVDACodecAllocator::Instance()->DeallocateSurface(this, config_.surface_id); |
| 1171 | 1170 |
| 1172 delete this; | 1171 delete this; |
| 1173 } | 1172 } |
| 1174 | 1173 |
| 1175 bool AndroidVideoDecodeAccelerator::TryToSetupDecodeOnSeparateThread( | 1174 bool AndroidVideoDecodeAccelerator::TryToSetupDecodeOnSeparateThread( |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1211 UpdateSurface(); | 1210 UpdateSurface(); |
| 1212 return; | 1211 return; |
| 1213 } | 1212 } |
| 1214 | 1213 |
| 1215 // If we're currently asynchronously configuring a codec, it will be destroyed | 1214 // If we're currently asynchronously configuring a codec, it will be destroyed |
| 1216 // when configuration completes and it notices that |state_| has changed to | 1215 // when configuration completes and it notices that |state_| has changed to |
| 1217 // SURFACE_DESTROYED. | 1216 // SURFACE_DESTROYED. |
| 1218 state_ = SURFACE_DESTROYED; | 1217 state_ = SURFACE_DESTROYED; |
| 1219 if (media_codec_) { | 1218 if (media_codec_) { |
| 1220 AVDACodecAllocator::Instance()->ReleaseMediaCodec( | 1219 AVDACodecAllocator::Instance()->ReleaseMediaCodec( |
| 1221 std::move(media_codec_), codec_config_->task_type_, config_.surface_id); | 1220 std::move(media_codec_), codec_config_->task_type, config_.surface_id); |
| 1222 picture_buffer_manager_.CodecChanged(nullptr); | 1221 picture_buffer_manager_.CodecChanged(nullptr); |
| 1223 } | 1222 } |
| 1224 | 1223 |
| 1225 // If we're draining, signal completion now because the drain can no longer | 1224 // If we're draining, signal completion now because the drain can no longer |
| 1226 // proceed. | 1225 // proceed. |
| 1227 if (drain_type_ != DRAIN_TYPE_NONE) | 1226 if (drain_type_ != DRAIN_TYPE_NONE) |
| 1228 OnDrainCompleted(); | 1227 OnDrainCompleted(); |
| 1229 } | 1228 } |
| 1230 | 1229 |
| 1231 void AndroidVideoDecodeAccelerator::InitializeCdm() { | 1230 void AndroidVideoDecodeAccelerator::InitializeCdm() { |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1277 NotifyInitializationComplete(false); | 1276 NotifyInitializationComplete(false); |
| 1278 return; | 1277 return; |
| 1279 } | 1278 } |
| 1280 | 1279 |
| 1281 DCHECK(!media_crypto->is_null()); | 1280 DCHECK(!media_crypto->is_null()); |
| 1282 | 1281 |
| 1283 // We assume this is a part of the initialization process, thus MediaCodec | 1282 // We assume this is a part of the initialization process, thus MediaCodec |
| 1284 // is not created yet. | 1283 // is not created yet. |
| 1285 DCHECK(!media_codec_); | 1284 DCHECK(!media_codec_); |
| 1286 | 1285 |
| 1287 codec_config_->media_crypto_ = std::move(media_crypto); | 1286 codec_config_->media_crypto = std::move(media_crypto); |
| 1288 codec_config_->needs_protected_surface_ = needs_protected_surface; | 1287 codec_config_->needs_protected_surface = needs_protected_surface; |
| 1289 | 1288 |
| 1290 // After receiving |media_crypto_| we can configure MediaCodec. | 1289 // After receiving |media_crypto_| we can configure MediaCodec. |
| 1291 ConfigureMediaCodecAsynchronously(); | 1290 ConfigureMediaCodecAsynchronously(); |
| 1292 } | 1291 } |
| 1293 | 1292 |
| 1294 void AndroidVideoDecodeAccelerator::OnKeyAdded() { | 1293 void AndroidVideoDecodeAccelerator::OnKeyAdded() { |
| 1295 DVLOG(1) << __FUNCTION__; | 1294 DVLOG(1) << __FUNCTION__; |
| 1296 | 1295 |
| 1297 if (state_ == WAITING_FOR_KEY) | 1296 if (state_ == WAITING_FOR_KEY) |
| 1298 state_ = NO_ERROR; | 1297 state_ = NO_ERROR; |
| (...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1447 } | 1446 } |
| 1448 #endif | 1447 #endif |
| 1449 | 1448 |
| 1450 return capabilities; | 1449 return capabilities; |
| 1451 } | 1450 } |
| 1452 | 1451 |
| 1453 bool AndroidVideoDecodeAccelerator::IsMediaCodecSoftwareDecodingForbidden() | 1452 bool AndroidVideoDecodeAccelerator::IsMediaCodecSoftwareDecodingForbidden() |
| 1454 const { | 1453 const { |
| 1455 // Prevent MediaCodec from using its internal software decoders when we have | 1454 // Prevent MediaCodec from using its internal software decoders when we have |
| 1456 // more secure and up to date versions in the renderer process. | 1455 // more secure and up to date versions in the renderer process. |
| 1457 return !config_.is_encrypted && (codec_config_->codec_ == kCodecVP8 || | 1456 return !config_.is_encrypted && (codec_config_->codec == kCodecVP8 || |
| 1458 codec_config_->codec_ == kCodecVP9); | 1457 codec_config_->codec == kCodecVP9); |
| 1459 } | 1458 } |
| 1460 | 1459 |
| 1461 bool AndroidVideoDecodeAccelerator::UpdateSurface() { | 1460 bool AndroidVideoDecodeAccelerator::UpdateSurface() { |
| 1462 DCHECK(pending_surface_id_); | 1461 DCHECK(pending_surface_id_); |
| 1463 DCHECK_NE(config_.surface_id, pending_surface_id_.value()); | 1462 DCHECK_NE(config_.surface_id, pending_surface_id_.value()); |
| 1464 DCHECK(config_.surface_id == SurfaceManager::kNoSurfaceID || | 1463 DCHECK(config_.surface_id == SurfaceManager::kNoSurfaceID || |
| 1465 pending_surface_id_.value() == SurfaceManager::kNoSurfaceID); | 1464 pending_surface_id_.value() == SurfaceManager::kNoSurfaceID); |
| 1466 | 1465 |
| 1467 const int previous_surface_id = config_.surface_id; | 1466 const int previous_surface_id = config_.surface_id; |
| 1468 const int new_surface_id = pending_surface_id_.value(); | 1467 const int new_surface_id = pending_surface_id_.value(); |
| 1469 pending_surface_id_.reset(); | 1468 pending_surface_id_.reset(); |
| 1470 bool success = true; | 1469 bool success = true; |
| 1471 | 1470 |
| 1472 // TODO(watk): Fix this so we can wait for the new surface to be allocated. | 1471 // TODO(watk): Fix this so we can wait for the new surface to be allocated. |
| 1473 if (!AVDACodecAllocator::Instance()->AllocateSurface(this, new_surface_id)) { | 1472 if (!AVDACodecAllocator::Instance()->AllocateSurface(this, new_surface_id)) { |
| 1474 NOTIFY_ERROR(PLATFORM_FAILURE, "Failed to allocate the new surface"); | 1473 NOTIFY_ERROR(PLATFORM_FAILURE, "Failed to allocate the new surface"); |
| 1475 success = false; | 1474 success = false; |
| 1476 } | 1475 } |
| 1477 | 1476 |
| 1478 // Ensure the current context is active when switching surfaces; we may need | 1477 // Ensure the current context is active when switching surfaces; we may need |
| 1479 // to create a new texture. | 1478 // to create a new texture. |
| 1480 if (success && !make_context_current_cb_.Run()) { | 1479 if (success && !make_context_current_cb_.Run()) { |
| 1481 NOTIFY_ERROR(PLATFORM_FAILURE, | 1480 NOTIFY_ERROR(PLATFORM_FAILURE, |
| 1482 "Failed to make this decoder's GL context current when " | 1481 "Failed to make this decoder's GL context current when " |
| 1483 "switching surfaces."); | 1482 "switching surfaces."); |
| 1484 success = false; | 1483 success = false; |
| 1485 } | 1484 } |
| 1486 | 1485 |
| 1487 if (success) { | 1486 if (success) { |
| 1488 codec_config_->surface_ = | 1487 codec_config_->surface = picture_buffer_manager_.Initialize(new_surface_id); |
| 1489 picture_buffer_manager_.Initialize(new_surface_id); | 1488 if (codec_config_->surface.IsEmpty()) { |
| 1490 if (codec_config_->surface_.IsEmpty()) { | |
| 1491 NOTIFY_ERROR(PLATFORM_FAILURE, "Failed to switch surfaces."); | 1489 NOTIFY_ERROR(PLATFORM_FAILURE, "Failed to switch surfaces."); |
| 1492 success = false; | 1490 success = false; |
| 1493 } | 1491 } |
| 1494 } | 1492 } |
| 1495 | 1493 |
| 1496 if (success && media_codec_ && | 1494 if (success && media_codec_ && |
| 1497 !media_codec_->SetSurface(codec_config_->surface_.j_surface().obj())) { | 1495 !media_codec_->SetSurface(codec_config_->surface.j_surface().obj())) { |
| 1498 NOTIFY_ERROR(PLATFORM_FAILURE, "MediaCodec failed to switch surfaces."); | 1496 NOTIFY_ERROR(PLATFORM_FAILURE, "MediaCodec failed to switch surfaces."); |
| 1499 success = false; | 1497 success = false; |
| 1500 } | 1498 } |
| 1501 | 1499 |
| 1502 if (success) { | 1500 if (success) { |
| 1503 config_.surface_id = new_surface_id; | 1501 config_.surface_id = new_surface_id; |
| 1504 } else { | 1502 } else { |
| 1505 // This might be called from OnSurfaceDestroyed(), so we have to release the | 1503 // This might be called from OnSurfaceDestroyed(), so we have to release the |
| 1506 // MediaCodec if we failed to switch the surface. | 1504 // MediaCodec if we failed to switch the surface. |
| 1507 if (media_codec_) { | 1505 if (media_codec_) { |
| 1508 AVDACodecAllocator::Instance()->ReleaseMediaCodec( | 1506 AVDACodecAllocator::Instance()->ReleaseMediaCodec( |
| 1509 std::move(media_codec_), codec_config_->task_type_, | 1507 std::move(media_codec_), codec_config_->task_type, |
| 1510 previous_surface_id); | 1508 previous_surface_id); |
| 1511 picture_buffer_manager_.CodecChanged(nullptr); | 1509 picture_buffer_manager_.CodecChanged(nullptr); |
| 1512 } | 1510 } |
| 1513 AVDACodecAllocator::Instance()->DeallocateSurface(this, new_surface_id); | 1511 AVDACodecAllocator::Instance()->DeallocateSurface(this, new_surface_id); |
| 1514 } | 1512 } |
| 1515 | 1513 |
| 1516 // Regardless of whether we succeeded, we no longer own the previous surface. | 1514 // Regardless of whether we succeeded, we no longer own the previous surface. |
| 1517 AVDACodecAllocator::Instance()->DeallocateSurface(this, previous_surface_id); | 1515 AVDACodecAllocator::Instance()->DeallocateSurface(this, previous_surface_id); |
| 1518 | 1516 |
| 1519 return success; | 1517 return success; |
| 1520 } | 1518 } |
| 1521 | 1519 |
| 1522 } // namespace media | 1520 } // namespace media |
| OLD | NEW |