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

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

Issue 2707703002: Group AVDA output surface into AVDASurfaceBundle. (Closed)
Patch Set: minor fixes after testing Created 3 years, 10 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
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 224 matching lines...) Expand 10 before | Expand all | Expand 10 after
235 state_(WAITING_FOR_SURFACE), 235 state_(WAITING_FOR_SURFACE),
236 picturebuffers_requested_(false), 236 picturebuffers_requested_(false),
237 picture_buffer_manager_(this), 237 picture_buffer_manager_(this),
238 media_drm_bridge_cdm_context_(nullptr), 238 media_drm_bridge_cdm_context_(nullptr),
239 cdm_registration_id_(0), 239 cdm_registration_id_(0),
240 pending_input_buf_index_(-1), 240 pending_input_buf_index_(-1),
241 during_initialize_(false), 241 during_initialize_(false),
242 deferred_initialization_pending_(false), 242 deferred_initialization_pending_(false),
243 codec_needs_reset_(false), 243 codec_needs_reset_(false),
244 defer_surface_creation_(false), 244 defer_surface_creation_(false),
245 last_release_task_type_(TaskType::AUTO_CODEC),
246 weak_this_factory_(this) {} 245 weak_this_factory_(this) {}
247 246
248 AndroidVideoDecodeAccelerator::~AndroidVideoDecodeAccelerator() { 247 AndroidVideoDecodeAccelerator::~AndroidVideoDecodeAccelerator() {
249 DCHECK(thread_checker_.CalledOnValidThread()); 248 DCHECK(thread_checker_.CalledOnValidThread());
250 GetManager()->StopTimer(this); 249 GetManager()->StopTimer(this);
251 codec_allocator_->StopThread(this); 250 codec_allocator_->StopThread(this);
252 251
253 #if defined(ENABLE_MOJO_MEDIA_IN_GPU_PROCESS) 252 #if defined(ENABLE_MOJO_MEDIA_IN_GPU_PROCESS)
254 if (!media_drm_bridge_cdm_context_) 253 if (!media_drm_bridge_cdm_context_)
255 return; 254 return;
(...skipping 26 matching lines...) Expand all
282 return false; 281 return false;
283 } 282 }
284 283
285 DCHECK(client); 284 DCHECK(client);
286 client_ = client; 285 client_ = client;
287 config_ = config; 286 config_ = config;
288 codec_config_ = new CodecConfig(); 287 codec_config_ = new CodecConfig();
289 codec_config_->codec = VideoCodecProfileToVideoCodec(config.profile); 288 codec_config_->codec = VideoCodecProfileToVideoCodec(config.profile);
290 codec_config_->initial_expected_coded_size = 289 codec_config_->initial_expected_coded_size =
291 config.initial_expected_coded_size; 290 config.initial_expected_coded_size;
291 incoming_bundle_ = new AVDASurfaceBundle(config_.surface_id);
292 292
293 if (codec_config_->codec != kCodecVP8 && codec_config_->codec != kCodecVP9 && 293 if (codec_config_->codec != kCodecVP8 && codec_config_->codec != kCodecVP9 &&
294 #if BUILDFLAG(ENABLE_HEVC_DEMUXING) 294 #if BUILDFLAG(ENABLE_HEVC_DEMUXING)
295 codec_config_->codec != kCodecHEVC && 295 codec_config_->codec != kCodecHEVC &&
296 #endif 296 #endif
297 codec_config_->codec != kCodecH264) { 297 codec_config_->codec != kCodecH264) {
298 DLOG(ERROR) << "Unsupported profile: " << GetProfileName(config.profile); 298 DLOG(ERROR) << "Unsupported profile: " << GetProfileName(config.profile);
299 return false; 299 return false;
300 } 300 }
301 301
(...skipping 22 matching lines...) Expand all
324 // SetSurface() can't be called before Initialize(), so we pick up our first 324 // SetSurface() can't be called before Initialize(), so we pick up our first
325 // surface ID from the codec configuration. 325 // surface ID from the codec configuration.
326 DCHECK(!pending_surface_id_); 326 DCHECK(!pending_surface_id_);
327 327
328 // We signaled that we support deferred initialization, so see if the client 328 // We signaled that we support deferred initialization, so see if the client
329 // does also. 329 // does also.
330 deferred_initialization_pending_ = config.is_deferred_initialization_allowed; 330 deferred_initialization_pending_ = config.is_deferred_initialization_allowed;
331 331
332 // If we're low on resources, we may decide to defer creation of the surface 332 // If we're low on resources, we may decide to defer creation of the surface
333 // until the codec is actually used. 333 // until the codec is actually used.
334 if (ShouldDeferSurfaceCreation(codec_allocator_, config_.surface_id, 334 if (ShouldDeferSurfaceCreation(codec_allocator_, surface_id(),
335 codec_config_->codec)) { 335 codec_config_->codec)) {
336 // We should never be here if a SurfaceView is required. 336 // We should never be here if a SurfaceView is required.
337 DCHECK_EQ(config_.surface_id, SurfaceManager::kNoSurfaceID); 337 DCHECK_EQ(surface_id(), SurfaceManager::kNoSurfaceID);
338 defer_surface_creation_ = true; 338 defer_surface_creation_ = true;
339 } 339 }
340 340
341 if (!codec_allocator_->StartThread(this)) { 341 if (!codec_allocator_->StartThread(this)) {
342 LOG(ERROR) << "Unable to start thread"; 342 LOG(ERROR) << "Unable to start thread";
343 return false; 343 return false;
344 } 344 }
345 345
346 // For encrypted media, start by initializing the CDM. Otherwise, start with 346 // For encrypted media, start by initializing the CDM. Otherwise, start with
347 // the surface. 347 // the surface.
348 if (config_.is_encrypted()) { 348 if (config_.is_encrypted()) {
349 if (!deferred_initialization_pending_) { 349 if (!deferred_initialization_pending_) {
350 DLOG(ERROR) 350 DLOG(ERROR)
351 << "Deferred initialization must be used for encrypted streams"; 351 << "Deferred initialization must be used for encrypted streams";
352 return false; 352 return false;
353 } 353 }
354 InitializeCdm(); 354 InitializeCdm();
355 } else { 355 } else {
356 StartSurfaceCreation(); 356 StartSurfaceCreation();
357 } 357 }
358 358
359 // Fail / complete / defer initialization. 359 // Fail / complete / defer initialization.
360 return state_ != ERROR; 360 return state_ != ERROR;
361 } 361 }
362 362
363 void AndroidVideoDecodeAccelerator::StartSurfaceCreation() { 363 void AndroidVideoDecodeAccelerator::StartSurfaceCreation() {
364 // We might be called during Initialize, during deferred initialization, or 364 // We might be called during Initialize, during deferred initialization, or
365 // afterwards (::Decode, for deferred surface init, UpdateSurface). 365 // afterwards (::Decode, for deferred surface init, UpdateSurface).
366 DCHECK(incoming_bundle_);
366 367
367 // If surface creation is deferred, then do nothing except signal that init 368 // If surface creation is deferred, then do nothing except signal that init
368 // is complete, if needed. We might still fail to get a surface or codec, 369 // is complete, if needed. We might still fail to get a surface or codec,
369 // which would normally be an init error. Since we're deferring init until a 370 // which would normally be an init error. Since we're deferring init until a
370 // decode to save resources, though, we're signaling success now. If we're 371 // decode to save resources, though, we're signaling success now. If we're
371 // wrong, then decoding might fail when we might have been able to use a 372 // wrong, then decoding might fail when we might have been able to use a
372 // fallback renderer in WMPI if we failed init. 373 // fallback renderer in WMPI if we failed init.
373 if (defer_surface_creation_) { 374 if (defer_surface_creation_) {
374 if (deferred_initialization_pending_) 375 if (deferred_initialization_pending_)
375 NotifyInitializationSucceeded(); 376 NotifyInitializationSucceeded();
376 377
377 return; 378 return;
378 } 379 }
379 380
380 if (!codec_allocator_->AllocateSurface(this, config_.surface_id)) { 381 if (!codec_allocator_->AllocateSurface(this, incoming_bundle_->surface_id)) {
381 // We have to wait for some other AVDA instance to free up the surface. 382 // We have to wait for some other AVDA instance to free up the surface.
382 // OnSurfaceAvailable will be called when it's available. 383 // OnSurfaceAvailable will be called when it's available.
383 // Note that if we aren't deferring init, then we'll signal success, and 384 // Note that if we aren't deferring init, then we'll signal success, and
384 // if we fail later then it will fail decoding instead. However, since 385 // if we fail later then it will fail decoding instead. However, since
385 // nobody that provides a SurfaceView requires sync init, it doesn't matter. 386 // nobody that provides a SurfaceView requires sync init, it doesn't matter.
386 state_ = WAITING_FOR_SURFACE; 387 state_ = WAITING_FOR_SURFACE;
387 return; 388 return;
388 } 389 }
389 390
390 // We now own the surface, so finish initialization. 391 // We now own the surface, so finish initialization.
391 InitializePictureBufferManager(); 392 InitializePictureBufferManager();
392 } 393 }
393 394
394 void AndroidVideoDecodeAccelerator::OnSurfaceAvailable(bool success) { 395 void AndroidVideoDecodeAccelerator::OnSurfaceAvailable(bool success) {
395 DCHECK(!defer_surface_creation_); 396 DCHECK(!defer_surface_creation_);
396 DCHECK_EQ(state_, WAITING_FOR_SURFACE); 397 DCHECK_EQ(state_, WAITING_FOR_SURFACE);
398 DCHECK(incoming_bundle_);
397 399
398 if (!success) { 400 if (!success) {
399 NOTIFY_ERROR(PLATFORM_FAILURE, "Surface is not available"); 401 NOTIFY_ERROR(PLATFORM_FAILURE, "Surface is not available");
402 incoming_bundle_ = nullptr;
400 return; 403 return;
401 } 404 }
402 405
403 InitializePictureBufferManager(); 406 InitializePictureBufferManager();
404 } 407 }
405 408
406 void AndroidVideoDecodeAccelerator::InitializePictureBufferManager() { 409 void AndroidVideoDecodeAccelerator::InitializePictureBufferManager() {
407 DCHECK(!defer_surface_creation_); 410 DCHECK(!defer_surface_creation_);
411 DCHECK(incoming_bundle_);
408 412
409 if (!make_context_current_cb_.Run()) { 413 if (!make_context_current_cb_.Run()) {
410 NOTIFY_ERROR(PLATFORM_FAILURE, 414 NOTIFY_ERROR(PLATFORM_FAILURE,
411 "Failed to make this decoder's GL context current"); 415 "Failed to make this decoder's GL context current");
412 return; 416 return;
413 } 417 }
414 418
415 codec_config_->surface = 419 // Move |incoming_bundle_| to |codec_config_|. Our caller must set up an
416 picture_buffer_manager_.Initialize(config_.surface_id); 420 // incoming bundle properly, since we don't want to accidentally overwrite
417 codec_config_->surface_texture = picture_buffer_manager_.surface_texture(); 421 // |surface_bundle| for a codec that's being released elsewhere.
418 if (codec_config_->surface.IsEmpty()) { 422 incoming_bundle_->surface = picture_buffer_manager_.Initialize(surface_id());
423 incoming_bundle_->surface_texture = picture_buffer_manager_.surface_texture();
424 if (incoming_bundle_->surface.IsEmpty()) {
419 NOTIFY_ERROR(PLATFORM_FAILURE, "Codec surface is empty"); 425 NOTIFY_ERROR(PLATFORM_FAILURE, "Codec surface is empty");
426 incoming_bundle_ = nullptr;
420 return; 427 return;
421 } 428 }
422 429
423 // If we have a media codec, then setSurface. If that doesn't work, then we 430 // If we have a media codec, then SetSurface. If that doesn't work, then we
424 // do not try to allocate a new codec; we might not be at a keyframe, etc. 431 // do not try to allocate a new codec; we might not be at a keyframe, etc.
425 // If we get here with a codec, then we must setSurface. 432 // If we get here with a codec, then we must setSurface.
426 if (media_codec_) { 433 if (media_codec_) {
427 // TODO(liberato): fail on api check? 434 // TODO(liberato): fail on api check?
428 if (!media_codec_->SetSurface(codec_config_->surface.j_surface().obj())) { 435 if (!media_codec_->SetSurface(
436 incoming_bundle_->surface.j_surface().obj())) {
429 NOTIFY_ERROR(PLATFORM_FAILURE, "MediaCodec failed to switch surfaces."); 437 NOTIFY_ERROR(PLATFORM_FAILURE, "MediaCodec failed to switch surfaces.");
438 // We're not going to use |incoming_bundle_|.
439 } else {
440 // We've switched surfaces, so replace |surface_bundle|.
441 codec_config_->surface_bundle = incoming_bundle_;
442 state_ = NO_ERROR;
watk 2017/02/22 20:38:55 I don't think we should be changing state_ here?
liberato (no reviews please) 2017/02/23 18:18:46 it can be WAITING_FOR_SURFACE if it came through O
430 } 443 }
444 incoming_bundle_ = nullptr;
431 return; 445 return;
432 } 446 }
433 447
448 // We're going to create a codec with |incoming_bundle_|. It might fail, but
449 // either way, we're done with any previous bundle. Note that, since we
450 // never get here after init (i.e., we never change surfaces without using
451 // SetSurface), there shouldn't be any previous bundle. However, this is the
452 // right thing to do even if we can switch.
453 codec_config_->surface_bundle = incoming_bundle_;
454 incoming_bundle_ = nullptr;
455
434 // If the client doesn't support deferred initialization (WebRTC), then we 456 // If the client doesn't support deferred initialization (WebRTC), then we
435 // should complete it now and return a meaningful result. Note that it would 457 // should complete it now and return a meaningful result. Note that it would
436 // be nice if we didn't have to worry about starting codec configuration at 458 // be nice if we didn't have to worry about starting codec configuration at
437 // all (::Initialize or the wrapper can do it), but then they have to remember 459 // all (::Initialize or the wrapper can do it), but then they have to remember
438 // not to start codec config if we have to wait for the cdm. It's somewhat 460 // not to start codec config if we have to wait for the cdm. It's somewhat
439 // clearer for us to handle both cases. 461 // clearer for us to handle both cases.
440 // For this to be a case for sync configuration, we must be called from 462 // For this to be a case for sync configuration, we must be called from
441 // Initialize(), and the client must not want deferred init. Note that having 463 // Initialize(), and the client must not want deferred init. Note that having
442 // |deferred_initialization_pending_| false by itself isn't enough; if we're 464 // |deferred_initialization_pending_| false by itself isn't enough; if we're
443 // deferring surface creation, then we'll finish deferred init before asking 465 // deferring surface creation, then we'll finish deferred init before asking
(...skipping 727 matching lines...) Expand 10 before | Expand all | Expand 10 after
1171 bitstreams_notified_in_advance_.clear(); 1193 bitstreams_notified_in_advance_.clear();
1172 1194
1173 picture_buffer_manager_.ReleaseCodecBuffers(output_picture_buffers_); 1195 picture_buffer_manager_.ReleaseCodecBuffers(output_picture_buffers_);
1174 StartCodecDrain(DRAIN_FOR_RESET); 1196 StartCodecDrain(DRAIN_FOR_RESET);
1175 } 1197 }
1176 1198
1177 void AndroidVideoDecodeAccelerator::SetSurface(int32_t surface_id) { 1199 void AndroidVideoDecodeAccelerator::SetSurface(int32_t surface_id) {
1178 DVLOG(1) << __func__; 1200 DVLOG(1) << __func__;
1179 DCHECK(thread_checker_.CalledOnValidThread()); 1201 DCHECK(thread_checker_.CalledOnValidThread());
1180 1202
1181 if (surface_id == config_.surface_id) { 1203 if (surface_id == this->surface_id()) {
watk 2017/02/22 20:38:55 remove this->
liberato (no reviews please) 2017/02/23 18:18:46 can't. |surface_id| shadows the method.
1182 pending_surface_id_.reset(); 1204 pending_surface_id_.reset();
1183 return; 1205 return;
1184 } 1206 }
1185 1207
1186 // Surface changes never take effect immediately, they will be handled during 1208 // Surface changes never take effect immediately, they will be handled during
1187 // DequeOutput() once we get to a good switch point or immediately during an 1209 // DequeOutput() once we get to a good switch point or immediately during an
1188 // OnSurfaceDestroyed() call. 1210 // OnSurfaceDestroyed() call.
1189 pending_surface_id_ = surface_id; 1211 pending_surface_id_ = surface_id;
1190 } 1212 }
1191 1213
(...skipping 15 matching lines...) Expand all
1207 1229
1208 // Note that async codec construction might still be in progress. In that 1230 // Note that async codec construction might still be in progress. In that
1209 // case, the codec will be deleted when it completes once we invalidate all 1231 // case, the codec will be deleted when it completes once we invalidate all
1210 // our weak refs. 1232 // our weak refs.
1211 weak_this_factory_.InvalidateWeakPtrs(); 1233 weak_this_factory_.InvalidateWeakPtrs();
1212 GetManager()->StopTimer(this); 1234 GetManager()->StopTimer(this);
1213 ReleaseCodec(); 1235 ReleaseCodec();
1214 1236
1215 // We no longer care about |surface_id|, in case we did before. It's okay 1237 // We no longer care about |surface_id|, in case we did before. It's okay
1216 // if we have no surface and/or weren't the owner or a waiter. 1238 // if we have no surface and/or weren't the owner or a waiter.
1217 codec_allocator_->DeallocateSurface(this, config_.surface_id); 1239 codec_allocator_->DeallocateSurface(this, surface_id());
watk 2017/02/22 20:38:55 If we have an incoming SurfaceBundle, we don't wan
liberato (no reviews please) 2017/02/23 18:18:46 having |incoming_bundle_| implies that there is no
1218
1219 // Hop the SurfaceTexture release call through the task runner used last time
1220 // we released a codec. This ensures that we release the surface texture after
1221 // the codec it's attached to (if any) is released. It's not sufficient to use
1222 // |codec_config_->task_type| because that might have changed since we
1223 // released the codec this surface was attached to.
1224 if (codec_config_->surface_texture) {
1225 codec_allocator_->TaskRunnerFor(last_release_task_type_)
1226 ->PostTaskAndReply(
1227 FROM_HERE, base::Bind(&base::DoNothing),
1228 base::Bind(&gl::SurfaceTexture::ReleaseSurfaceTexture,
1229 codec_config_->surface_texture));
1230 }
1231 1240
1232 delete this; 1241 delete this;
1233 } 1242 }
1234 1243
1235 bool AndroidVideoDecodeAccelerator::TryToSetupDecodeOnSeparateThread( 1244 bool AndroidVideoDecodeAccelerator::TryToSetupDecodeOnSeparateThread(
1236 const base::WeakPtr<Client>& decode_client, 1245 const base::WeakPtr<Client>& decode_client,
1237 const scoped_refptr<base::SingleThreadTaskRunner>& decode_task_runner) { 1246 const scoped_refptr<base::SingleThreadTaskRunner>& decode_task_runner) {
1238 return false; 1247 return false;
1239 } 1248 }
1240 1249
(...skipping 20 matching lines...) Expand all
1261 1270
1262 // If the API is available avoid having to restart the decoder in order to 1271 // If the API is available avoid having to restart the decoder in order to
1263 // leave fullscreen. If we don't clear the surface immediately during this 1272 // leave fullscreen. If we don't clear the surface immediately during this
1264 // callback, the MediaCodec will throw an error as the surface is destroyed. 1273 // callback, the MediaCodec will throw an error as the surface is destroyed.
1265 if (base::android::BuildInfo::GetInstance()->sdk_int() >= 23) { 1274 if (base::android::BuildInfo::GetInstance()->sdk_int() >= 23) {
1266 // Since we can't wait for a transition, we must invalidate all outstanding 1275 // Since we can't wait for a transition, we must invalidate all outstanding
1267 // picture buffers to avoid putting the GL system in a broken state. 1276 // picture buffers to avoid putting the GL system in a broken state.
1268 picture_buffer_manager_.ReleaseCodecBuffers(output_picture_buffers_); 1277 picture_buffer_manager_.ReleaseCodecBuffers(output_picture_buffers_);
1269 1278
1270 // Switch away from the surface being destroyed to a surface texture. 1279 // Switch away from the surface being destroyed to a surface texture.
1271 DCHECK_NE(config_.surface_id, SurfaceManager::kNoSurfaceID); 1280 DCHECK_NE(surface_id(), SurfaceManager::kNoSurfaceID);
1272 1281
1273 // The leaving fullscreen notification may come in before this point. 1282 // The leaving fullscreen notification may come in before this point.
1274 if (pending_surface_id_) 1283 if (pending_surface_id_)
1275 DCHECK_EQ(pending_surface_id_.value(), SurfaceManager::kNoSurfaceID); 1284 DCHECK_EQ(pending_surface_id_.value(), SurfaceManager::kNoSurfaceID);
1276 1285
1277 pending_surface_id_ = SurfaceManager::kNoSurfaceID; 1286 pending_surface_id_ = SurfaceManager::kNoSurfaceID;
1278 UpdateSurface(); 1287 UpdateSurface();
1279 // Switching to a SurfaceTexture should never need to wait. If it does, 1288 // Switching to a SurfaceTexture should never need to wait. If it does,
1280 // then the codec might still be using the destroyed surface, which is bad. 1289 // then the codec might still be using the destroyed surface, which is bad.
1281 DCHECK_NE(state_, WAITING_FOR_SURFACE); 1290 DCHECK_NE(state_, WAITING_FOR_SURFACE);
(...skipping 257 matching lines...) Expand 10 before | Expand all | Expand 10 after
1539 bool AndroidVideoDecodeAccelerator::IsMediaCodecSoftwareDecodingForbidden() 1548 bool AndroidVideoDecodeAccelerator::IsMediaCodecSoftwareDecodingForbidden()
1540 const { 1549 const {
1541 // Prevent MediaCodec from using its internal software decoders when we have 1550 // Prevent MediaCodec from using its internal software decoders when we have
1542 // more secure and up to date versions in the renderer process. 1551 // more secure and up to date versions in the renderer process.
1543 return !config_.is_encrypted() && (codec_config_->codec == kCodecVP8 || 1552 return !config_.is_encrypted() && (codec_config_->codec == kCodecVP8 ||
1544 codec_config_->codec == kCodecVP9); 1553 codec_config_->codec == kCodecVP9);
1545 } 1554 }
1546 1555
1547 bool AndroidVideoDecodeAccelerator::UpdateSurface() { 1556 bool AndroidVideoDecodeAccelerator::UpdateSurface() {
1548 DCHECK(pending_surface_id_); 1557 DCHECK(pending_surface_id_);
1549 DCHECK_NE(config_.surface_id, pending_surface_id_.value()); 1558 DCHECK_NE(surface_id(), pending_surface_id_.value());
1550 DCHECK(config_.surface_id == SurfaceManager::kNoSurfaceID || 1559 DCHECK(surface_id() == SurfaceManager::kNoSurfaceID ||
1551 pending_surface_id_.value() == SurfaceManager::kNoSurfaceID); 1560 pending_surface_id_.value() == SurfaceManager::kNoSurfaceID);
1552 1561
1553 const int previous_surface_id = config_.surface_id; 1562 const int previous_surface_id = surface_id();
1554 const int new_surface_id = pending_surface_id_.value(); 1563 const int new_surface_id = pending_surface_id_.value();
1555 pending_surface_id_.reset(); 1564 pending_surface_id_.reset();
1556 1565
1557 // Start surface creation. Note that if we're called via surfaceDestroyed, 1566 // Start surface creation. Note that if we're called via surfaceDestroyed,
1558 // then this must complete synchronously or it will DCHECK. Otherwise, we 1567 // then this must complete synchronously or it will DCHECK. Otherwise, we
1559 // might still be using the destroyed surface. We don't enforce this, but 1568 // might still be using the destroyed surface. We don't enforce this, but
1560 // it's worth remembering that there are cases where it's required. 1569 // it's worth remembering that there are cases where it's required.
1561 config_.surface_id = new_surface_id; 1570 // Note that we don't re-use |surface_bundle|, since the codec is using it!
1571 incoming_bundle_ = new AVDASurfaceBundle(new_surface_id);
1562 StartSurfaceCreation(); 1572 StartSurfaceCreation();
1563 if (state_ == ERROR) { 1573 if (state_ == ERROR) {
1564 // This might be called from OnSurfaceDestroyed(), so we have to release the 1574 // This might be called from OnSurfaceDestroyed(), so we have to release the
1565 // MediaCodec if we failed to switch the surface. We reset the surface ID 1575 // MediaCodec if we failed to switch the surface. We reset the surface ID
1566 // to the previous one, since failures never result in the codec using the 1576 // to the previous one, since failures never result in the codec using the
1567 // new surface. This is only guaranteed because of how OnCodecConfigured 1577 // new surface. This is only guaranteed because of how OnCodecConfigured
1568 // works. If it could fail after getting a codec, then this assumption 1578 // works. If it could fail after getting a codec, then this assumption
1569 // wouldn't be necessarily true anymore. 1579 // wouldn't be necessarily true anymore.
1570 // Also note that we might not have switched surfaces yet, which is also bad 1580 // Also note that we might not have switched surfaces yet, which is also bad
1571 // for OnSurfaceDestroyed, because of WAITING_FOR_SURFACE. Shouldn't 1581 // for OnSurfaceDestroyed, because of WAITING_FOR_SURFACE. Shouldn't
1572 // happen with SurfaceTexture, and OnSurfaceDestroyed checks for it. 1582 // happen with SurfaceTexture, and OnSurfaceDestroyed checks for it. In
1573 config_.surface_id = previous_surface_id; 1583 // either case, we definitely should not still have an incoming bundle; it
1584 // should have been dropped.
1585 DCHECK(!incoming_bundle_);
1574 ReleaseCodec(); 1586 ReleaseCodec();
1587 // We no longer own the new surface.
1575 codec_allocator_->DeallocateSurface(this, new_surface_id); 1588 codec_allocator_->DeallocateSurface(this, new_surface_id);
1576 } 1589 }
1577 1590
1578 // Regardless of whether we succeeded, we no longer own the previous surface. 1591 // Regardless of whether we succeeded, we no longer own the previous surface.
1592 // It would be nice if the outgoing surface bundle did this.
1593 // TODO(liberato): It could, but the CVV implementation of AndroidOverlay
1594 // will do it too when the bundle holding it is dropped. We'll do it this way
1595 // until then, just to minimize changes.
1579 codec_allocator_->DeallocateSurface(this, previous_surface_id); 1596 codec_allocator_->DeallocateSurface(this, previous_surface_id);
1580 1597
1581 return state_ != ERROR; 1598 return state_ != ERROR;
1582 } 1599 }
1583 1600
1584 void AndroidVideoDecodeAccelerator::ReleaseCodec() { 1601 void AndroidVideoDecodeAccelerator::ReleaseCodec() {
1585 if (!media_codec_) 1602 if (!media_codec_)
1586 return; 1603 return;
1587 1604
1588 picture_buffer_manager_.CodecChanged(nullptr); 1605 picture_buffer_manager_.CodecChanged(nullptr);
1589 codec_allocator_->ReleaseMediaCodec( 1606 codec_allocator_->ReleaseMediaCodec(std::move(media_codec_),
1590 std::move(media_codec_), codec_config_->task_type, config_.surface_id); 1607 codec_config_->task_type,
1591 last_release_task_type_ = codec_config_->task_type; 1608 codec_config_->surface_bundle);
1592 } 1609 }
1593 1610
1594 } // namespace media 1611 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698