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

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

Issue 2629223003: media: Ensure MediaCodecs are released before attached SurfaceTextures (Closed)
Patch Set: Created 3 years, 11 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 | « no previous file | media/gpu/avda_codec_allocator.h » ('j') | media/gpu/avda_codec_allocator.h » ('J')
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 857 matching lines...) Expand 10 before | Expand all | Expand 10 after
868 } 868 }
869 869
870 void AndroidVideoDecodeAccelerator::ConfigureMediaCodecAsynchronously() { 870 void AndroidVideoDecodeAccelerator::ConfigureMediaCodecAsynchronously() {
871 DCHECK(thread_checker_.CalledOnValidThread()); 871 DCHECK(thread_checker_.CalledOnValidThread());
872 872
873 DCHECK_NE(state_, WAITING_FOR_CODEC); 873 DCHECK_NE(state_, WAITING_FOR_CODEC);
874 state_ = WAITING_FOR_CODEC; 874 state_ = WAITING_FOR_CODEC;
875 875
876 if (media_codec_) { 876 if (media_codec_) {
877 AVDACodecAllocator::Instance()->ReleaseMediaCodec( 877 AVDACodecAllocator::Instance()->ReleaseMediaCodec(
878 std::move(media_codec_), codec_config_->task_type, config_.surface_id); 878 std::move(media_codec_), codec_config_->task_type, config_.surface_id,
879 picture_buffer_manager_.surface_texture().get());
liberato (no reviews please) 2017/01/13 17:22:04 this looks a lot like the surface owner api. it s
879 picture_buffer_manager_.CodecChanged(nullptr); 880 picture_buffer_manager_.CodecChanged(nullptr);
880 } 881 }
881 882
882 base::Optional<TaskType> task_type = 883 base::Optional<TaskType> task_type =
883 AVDACodecAllocator::Instance()->TaskTypeForAllocation(); 884 AVDACodecAllocator::Instance()->TaskTypeForAllocation();
884 if (!task_type) { 885 if (!task_type) {
885 // If there is no free thread, then just fail. 886 // If there is no free thread, then just fail.
886 OnCodecConfigured(nullptr); 887 OnCodecConfigured(nullptr);
887 return; 888 return;
888 } 889 }
(...skipping 248 matching lines...) Expand 10 before | Expand all | Expand 10 after
1137 DVLOG(1) << __func__; 1138 DVLOG(1) << __func__;
1138 DCHECK(thread_checker_.CalledOnValidThread()); 1139 DCHECK(thread_checker_.CalledOnValidThread());
1139 1140
1140 // Note that async codec construction might still be in progress. In that 1141 // Note that async codec construction might still be in progress. In that
1141 // case, the codec will be deleted when it completes once we invalidate all 1142 // case, the codec will be deleted when it completes once we invalidate all
1142 // our weak refs. 1143 // our weak refs.
1143 weak_this_factory_.InvalidateWeakPtrs(); 1144 weak_this_factory_.InvalidateWeakPtrs();
1144 g_avda_manager.Get().StopTimer(this); 1145 g_avda_manager.Get().StopTimer(this);
1145 if (media_codec_) { 1146 if (media_codec_) {
1146 AVDACodecAllocator::Instance()->ReleaseMediaCodec( 1147 AVDACodecAllocator::Instance()->ReleaseMediaCodec(
1147 std::move(media_codec_), codec_config_->task_type, config_.surface_id); 1148 std::move(media_codec_), codec_config_->task_type, config_.surface_id,
1149 picture_buffer_manager_.surface_texture().get());
liberato (no reviews please) 2017/01/13 17:22:04 it's a little weird that we ask for the surface te
watk 2017/01/14 01:01:03 Agreed. I fixed this in the latest PS. Now Destroy
1148 } 1150 }
1149 1151
1150 // We no longer care about |surface_id|, in case we did before. It's okay 1152 // We no longer care about |surface_id|, in case we did before. It's okay
1151 // if we have no surface and/or weren't the owner or a waiter. 1153 // if we have no surface and/or weren't the owner or a waiter.
1152 AVDACodecAllocator::Instance()->DeallocateSurface(this, config_.surface_id); 1154 AVDACodecAllocator::Instance()->DeallocateSurface(this, config_.surface_id);
1153 1155
1156 if (picture_buffer_manager_.surface_texture()) {
1157 AVDACodecAllocator::Instance()->ReleaseSurfaceTexture(
1158 picture_buffer_manager_.surface_texture());
1159 }
1160
1154 delete this; 1161 delete this;
1155 } 1162 }
1156 1163
1157 bool AndroidVideoDecodeAccelerator::TryToSetupDecodeOnSeparateThread( 1164 bool AndroidVideoDecodeAccelerator::TryToSetupDecodeOnSeparateThread(
1158 const base::WeakPtr<Client>& decode_client, 1165 const base::WeakPtr<Client>& decode_client,
1159 const scoped_refptr<base::SingleThreadTaskRunner>& decode_task_runner) { 1166 const scoped_refptr<base::SingleThreadTaskRunner>& decode_task_runner) {
1160 return false; 1167 return false;
1161 } 1168 }
1162 1169
1163 const gfx::Size& AndroidVideoDecodeAccelerator::GetSize() const { 1170 const gfx::Size& AndroidVideoDecodeAccelerator::GetSize() const {
(...skipping 29 matching lines...) Expand all
1193 UpdateSurface(); 1200 UpdateSurface();
1194 return; 1201 return;
1195 } 1202 }
1196 1203
1197 // If we're currently asynchronously configuring a codec, it will be destroyed 1204 // If we're currently asynchronously configuring a codec, it will be destroyed
1198 // when configuration completes and it notices that |state_| has changed to 1205 // when configuration completes and it notices that |state_| has changed to
1199 // SURFACE_DESTROYED. 1206 // SURFACE_DESTROYED.
1200 state_ = SURFACE_DESTROYED; 1207 state_ = SURFACE_DESTROYED;
1201 if (media_codec_) { 1208 if (media_codec_) {
1202 AVDACodecAllocator::Instance()->ReleaseMediaCodec( 1209 AVDACodecAllocator::Instance()->ReleaseMediaCodec(
1203 std::move(media_codec_), codec_config_->task_type, config_.surface_id); 1210 std::move(media_codec_), codec_config_->task_type, config_.surface_id,
1211 picture_buffer_manager_.surface_texture().get());
1204 picture_buffer_manager_.CodecChanged(nullptr); 1212 picture_buffer_manager_.CodecChanged(nullptr);
1205 } 1213 }
1206 1214
1207 // If we're draining, signal completion now because the drain can no longer 1215 // If we're draining, signal completion now because the drain can no longer
1208 // proceed. 1216 // proceed.
1209 if (drain_type_) 1217 if (drain_type_)
1210 OnDrainCompleted(); 1218 OnDrainCompleted();
1211 } 1219 }
1212 1220
1213 void AndroidVideoDecodeAccelerator::InitializeCdm() { 1221 void AndroidVideoDecodeAccelerator::InitializeCdm() {
(...skipping 245 matching lines...) Expand 10 before | Expand all | Expand 10 after
1459 1467
1460 // Ensure the current context is active when switching surfaces; we may need 1468 // Ensure the current context is active when switching surfaces; we may need
1461 // to create a new texture. 1469 // to create a new texture.
1462 if (success && !make_context_current_cb_.Run()) { 1470 if (success && !make_context_current_cb_.Run()) {
1463 NOTIFY_ERROR(PLATFORM_FAILURE, 1471 NOTIFY_ERROR(PLATFORM_FAILURE,
1464 "Failed to make this decoder's GL context current when " 1472 "Failed to make this decoder's GL context current when "
1465 "switching surfaces."); 1473 "switching surfaces.");
1466 success = false; 1474 success = false;
1467 } 1475 }
1468 1476
1477 // Save the SurfaceTexture if any, so we can release it below.
1478 scoped_refptr<gl::SurfaceTexture> previous_surface_texture =
1479 picture_buffer_manager_.surface_texture();
1480 gl::ScopedJavaSurface new_surface;
1469 if (success) { 1481 if (success) {
1470 codec_config_->surface = picture_buffer_manager_.Initialize(new_surface_id); 1482 new_surface = picture_buffer_manager_.Initialize(new_surface_id);
1471 if (codec_config_->surface.IsEmpty()) { 1483 if (new_surface.IsEmpty()) {
1472 NOTIFY_ERROR(PLATFORM_FAILURE, "Failed to switch surfaces."); 1484 NOTIFY_ERROR(PLATFORM_FAILURE, "Failed to switch surfaces.");
1473 success = false; 1485 success = false;
1474 } 1486 }
1475 } 1487 }
1476 1488
1477 if (success && media_codec_ && 1489 if (success && media_codec_ &&
1478 !media_codec_->SetSurface(codec_config_->surface.j_surface().obj())) { 1490 !media_codec_->SetSurface(new_surface.j_surface().obj())) {
1479 NOTIFY_ERROR(PLATFORM_FAILURE, "MediaCodec failed to switch surfaces."); 1491 NOTIFY_ERROR(PLATFORM_FAILURE, "MediaCodec failed to switch surfaces.");
1480 success = false; 1492 success = false;
1481 } 1493 }
1482 1494
1483 if (success) { 1495 if (success) {
1484 config_.surface_id = new_surface_id; 1496 config_.surface_id = new_surface_id;
1497 codec_config_->surface = std::move(new_surface);
1485 } else { 1498 } else {
1486 // This might be called from OnSurfaceDestroyed(), so we have to release the 1499 // This might be called from OnSurfaceDestroyed(), so we have to release the
1487 // MediaCodec if we failed to switch the surface. 1500 // MediaCodec if we failed to switch the surface.
1488 if (media_codec_) { 1501 if (media_codec_) {
1489 AVDACodecAllocator::Instance()->ReleaseMediaCodec( 1502 AVDACodecAllocator::Instance()->ReleaseMediaCodec(
1490 std::move(media_codec_), codec_config_->task_type, 1503 std::move(media_codec_), codec_config_->task_type,
1491 previous_surface_id); 1504 previous_surface_id, previous_surface_texture.get());
1492 picture_buffer_manager_.CodecChanged(nullptr); 1505 picture_buffer_manager_.CodecChanged(nullptr);
1493 } 1506 }
1494 AVDACodecAllocator::Instance()->DeallocateSurface(this, new_surface_id); 1507 AVDACodecAllocator::Instance()->DeallocateSurface(this, new_surface_id);
1495 } 1508 }
1496 1509
1497 // Regardless of whether we succeeded, we no longer own the previous surface. 1510 // Regardless of whether we succeeded, we no longer own the previous surface.
1498 AVDACodecAllocator::Instance()->DeallocateSurface(this, previous_surface_id); 1511 AVDACodecAllocator::Instance()->DeallocateSurface(this, previous_surface_id);
1499 1512
1513 // Regardless of whether we succeded, we no longer want the previous
1514 // SurfaceTexture. This ensures it's released after its attached codec (if
1515 // applicable).
1516 if (previous_surface_texture) {
1517 AVDACodecAllocator::Instance()->ReleaseSurfaceTexture(
1518 previous_surface_texture);
1519 }
1520
1500 return success; 1521 return success;
1501 } 1522 }
1502 1523
1503 } // namespace media 1524 } // namespace media
OLDNEW
« no previous file with comments | « no previous file | media/gpu/avda_codec_allocator.h » ('j') | media/gpu/avda_codec_allocator.h » ('J')

Powered by Google App Engine
This is Rietveld 408576698