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

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

Issue 2707703002: Group AVDA output surface into AVDASurfaceBundle. (Closed)
Patch Set: rebased Created 3 years, 9 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') | media/gpu/avda_codec_allocator.h » ('j') | 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 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 21 matching lines...) Expand all
323 // SetSurface() can't be called before Initialize(), so we pick up our first 323 // SetSurface() can't be called before Initialize(), so we pick up our first
324 // surface ID from the codec configuration. 324 // surface ID from the codec configuration.
325 DCHECK(!pending_surface_id_); 325 DCHECK(!pending_surface_id_);
326 326
327 // We signaled that we support deferred initialization, so see if the client 327 // We signaled that we support deferred initialization, so see if the client
328 // does also. 328 // does also.
329 deferred_initialization_pending_ = config.is_deferred_initialization_allowed; 329 deferred_initialization_pending_ = config.is_deferred_initialization_allowed;
330 330
331 // If we're low on resources, we may decide to defer creation of the surface 331 // If we're low on resources, we may decide to defer creation of the surface
332 // until the codec is actually used. 332 // until the codec is actually used.
333 if (ShouldDeferSurfaceCreation(codec_allocator_, config_.surface_id, 333 if (ShouldDeferSurfaceCreation(codec_allocator_, surface_id(),
334 codec_config_->codec)) { 334 codec_config_->codec)) {
335 // We should never be here if a SurfaceView is required. 335 // We should never be here if a SurfaceView is required.
336 DCHECK_EQ(config_.surface_id, SurfaceManager::kNoSurfaceID); 336 DCHECK_EQ(surface_id(), SurfaceManager::kNoSurfaceID);
337 defer_surface_creation_ = true; 337 defer_surface_creation_ = true;
338 } 338 }
339 339
340 if (!codec_allocator_->StartThread(this)) { 340 if (!codec_allocator_->StartThread(this)) {
341 LOG(ERROR) << "Unable to start thread"; 341 LOG(ERROR) << "Unable to start thread";
342 return false; 342 return false;
343 } 343 }
344 344
345 // For encrypted media, start by initializing the CDM. Otherwise, start with 345 // For encrypted media, start by initializing the CDM. Otherwise, start with
346 // the surface. 346 // the surface.
347 if (config_.is_encrypted()) { 347 if (config_.is_encrypted()) {
348 if (!deferred_initialization_pending_) { 348 if (!deferred_initialization_pending_) {
349 DLOG(ERROR) 349 DLOG(ERROR)
350 << "Deferred initialization must be used for encrypted streams"; 350 << "Deferred initialization must be used for encrypted streams";
351 return false; 351 return false;
352 } 352 }
353 InitializeCdm(); 353 InitializeCdm();
354 } else { 354 } else {
355 StartSurfaceCreation(); 355 StartSurfaceCreation();
356 } 356 }
357 357
358 // Fail / complete / defer initialization. 358 // Fail / complete / defer initialization.
359 return state_ != ERROR; 359 return state_ != ERROR;
360 } 360 }
361 361
362 void AndroidVideoDecodeAccelerator::StartSurfaceCreation() { 362 void AndroidVideoDecodeAccelerator::StartSurfaceCreation() {
363 // We might be called during Initialize, during deferred initialization, or 363 // We might be called during Initialize, during deferred initialization, or
364 // afterwards (::Decode, for deferred surface init, UpdateSurface). 364 // afterwards (::Decode, for deferred surface init, UpdateSurface).
365 DCHECK(incoming_bundle_);
365 366
366 // If surface creation is deferred, then do nothing except signal that init 367 // If surface creation is deferred, then do nothing except signal that init
367 // is complete, if needed. We might still fail to get a surface or codec, 368 // is complete, if needed. We might still fail to get a surface or codec,
368 // which would normally be an init error. Since we're deferring init until a 369 // which would normally be an init error. Since we're deferring init until a
369 // decode to save resources, though, we're signaling success now. If we're 370 // decode to save resources, though, we're signaling success now. If we're
370 // wrong, then decoding might fail when we might have been able to use a 371 // wrong, then decoding might fail when we might have been able to use a
371 // fallback renderer in WMPI if we failed init. 372 // fallback renderer in WMPI if we failed init.
372 if (defer_surface_creation_) { 373 if (defer_surface_creation_) {
373 if (deferred_initialization_pending_) 374 if (deferred_initialization_pending_)
374 NotifyInitializationSucceeded(); 375 NotifyInitializationSucceeded();
375 376
376 return; 377 return;
377 } 378 }
378 379
379 if (!codec_allocator_->AllocateSurface(this, config_.surface_id)) { 380 if (!codec_allocator_->AllocateSurface(this, incoming_bundle_->surface_id)) {
380 // We have to wait for some other AVDA instance to free up the surface. 381 // We have to wait for some other AVDA instance to free up the surface.
381 // OnSurfaceAvailable will be called when it's available. 382 // OnSurfaceAvailable will be called when it's available.
382 // Note that if we aren't deferring init, then we'll signal success, and 383 // Note that if we aren't deferring init, then we'll signal success, and
383 // if we fail later then it will fail decoding instead. However, since 384 // if we fail later then it will fail decoding instead. However, since
384 // nobody that provides a SurfaceView requires sync init, it doesn't matter. 385 // nobody that provides a SurfaceView requires sync init, it doesn't matter.
385 state_ = WAITING_FOR_SURFACE; 386 state_ = WAITING_FOR_SURFACE;
386 return; 387 return;
387 } 388 }
388 389
389 // We now own the surface, so finish initialization. 390 // We now own the surface, so finish initialization.
390 InitializePictureBufferManager(); 391 InitializePictureBufferManager();
391 } 392 }
392 393
393 void AndroidVideoDecodeAccelerator::OnSurfaceAvailable(bool success) { 394 void AndroidVideoDecodeAccelerator::OnSurfaceAvailable(bool success) {
394 DCHECK(!defer_surface_creation_); 395 DCHECK(!defer_surface_creation_);
395 DCHECK_EQ(state_, WAITING_FOR_SURFACE); 396 DCHECK_EQ(state_, WAITING_FOR_SURFACE);
397 DCHECK(incoming_bundle_);
396 398
397 if (!success) { 399 if (!success) {
398 NOTIFY_ERROR(PLATFORM_FAILURE, "Surface is not available"); 400 NOTIFY_ERROR(PLATFORM_FAILURE, "Surface is not available");
401 incoming_bundle_ = nullptr;
399 return; 402 return;
400 } 403 }
401 404
402 InitializePictureBufferManager(); 405 InitializePictureBufferManager();
403 } 406 }
404 407
405 void AndroidVideoDecodeAccelerator::InitializePictureBufferManager() { 408 void AndroidVideoDecodeAccelerator::InitializePictureBufferManager() {
406 DCHECK(!defer_surface_creation_); 409 DCHECK(!defer_surface_creation_);
410 DCHECK(incoming_bundle_);
407 411
408 if (!make_context_current_cb_.Run()) { 412 if (!make_context_current_cb_.Run()) {
409 NOTIFY_ERROR(PLATFORM_FAILURE, 413 NOTIFY_ERROR(PLATFORM_FAILURE,
410 "Failed to make this decoder's GL context current"); 414 "Failed to make this decoder's GL context current");
411 return; 415 return;
412 } 416 }
413 417
414 codec_config_->surface = 418 // Move |incoming_bundle_| to |codec_config_|. Our caller must set up an
415 picture_buffer_manager_.Initialize(config_.surface_id); 419 // incoming bundle properly, since we don't want to accidentally overwrite
416 codec_config_->surface_texture = picture_buffer_manager_.surface_texture(); 420 // |surface_bundle| for a codec that's being released elsewhere.
417 if (codec_config_->surface.IsEmpty()) { 421 incoming_bundle_->surface = picture_buffer_manager_.Initialize(surface_id());
422 incoming_bundle_->surface_texture = picture_buffer_manager_.surface_texture();
423 if (incoming_bundle_->surface.IsEmpty()) {
418 NOTIFY_ERROR(PLATFORM_FAILURE, "Codec surface is empty"); 424 NOTIFY_ERROR(PLATFORM_FAILURE, "Codec surface is empty");
425 incoming_bundle_ = nullptr;
419 return; 426 return;
420 } 427 }
421 428
422 // If we have a media codec, then setSurface. If that doesn't work, then we 429 // If we have a media codec, then SetSurface. If that doesn't work, then we
423 // do not try to allocate a new codec; we might not be at a keyframe, etc. 430 // do not try to allocate a new codec; we might not be at a keyframe, etc.
424 // If we get here with a codec, then we must setSurface. 431 // If we get here with a codec, then we must setSurface.
425 if (media_codec_) { 432 if (media_codec_) {
426 // TODO(liberato): fail on api check? 433 // TODO(liberato): fail on api check?
427 if (!media_codec_->SetSurface(codec_config_->surface.j_surface().obj())) { 434 if (!media_codec_->SetSurface(
435 incoming_bundle_->surface.j_surface().obj())) {
428 NOTIFY_ERROR(PLATFORM_FAILURE, "MediaCodec failed to switch surfaces."); 436 NOTIFY_ERROR(PLATFORM_FAILURE, "MediaCodec failed to switch surfaces.");
437 // We're not going to use |incoming_bundle_|.
438 } else {
439 // We've switched surfaces, so replace |surface_bundle|.
440 codec_config_->surface_bundle = incoming_bundle_;
441 // We could be in WAITING_FOR_SURFACE, but we're not anymore.
442 state_ = NO_ERROR;
429 } 443 }
444 incoming_bundle_ = nullptr;
430 return; 445 return;
431 } 446 }
432 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
433 // If the client doesn't support deferred initialization (WebRTC), then we 456 // If the client doesn't support deferred initialization (WebRTC), then we
434 // 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
435 // 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
436 // 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
437 // 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
438 // clearer for us to handle both cases. 461 // clearer for us to handle both cases.
439 // 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
440 // 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
441 // |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
442 // 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
1170 bitstreams_notified_in_advance_.clear(); 1193 bitstreams_notified_in_advance_.clear();
1171 1194
1172 picture_buffer_manager_.ReleaseCodecBuffers(output_picture_buffers_); 1195 picture_buffer_manager_.ReleaseCodecBuffers(output_picture_buffers_);
1173 StartCodecDrain(DRAIN_FOR_RESET); 1196 StartCodecDrain(DRAIN_FOR_RESET);
1174 } 1197 }
1175 1198
1176 void AndroidVideoDecodeAccelerator::SetSurface(int32_t surface_id) { 1199 void AndroidVideoDecodeAccelerator::SetSurface(int32_t surface_id) {
1177 DVLOG(1) << __func__; 1200 DVLOG(1) << __func__;
1178 DCHECK(thread_checker_.CalledOnValidThread()); 1201 DCHECK(thread_checker_.CalledOnValidThread());
1179 1202
1180 if (surface_id == config_.surface_id) { 1203 if (surface_id == this->surface_id()) {
1181 pending_surface_id_.reset(); 1204 pending_surface_id_.reset();
1182 return; 1205 return;
1183 } 1206 }
1184 1207
1185 // Surface changes never take effect immediately, they will be handled during 1208 // Surface changes never take effect immediately, they will be handled during
1186 // 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
1187 // OnSurfaceDestroyed() call. 1210 // OnSurfaceDestroyed() call.
1188 pending_surface_id_ = surface_id; 1211 pending_surface_id_ = surface_id;
1189 } 1212 }
1190 1213
(...skipping 15 matching lines...) Expand all
1206 1229
1207 // 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
1208 // 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
1209 // our weak refs. 1232 // our weak refs.
1210 weak_this_factory_.InvalidateWeakPtrs(); 1233 weak_this_factory_.InvalidateWeakPtrs();
1211 GetManager()->StopTimer(this); 1234 GetManager()->StopTimer(this);
1212 ReleaseCodec(); 1235 ReleaseCodec();
1213 1236
1214 // 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
1215 // 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.
1216 codec_allocator_->DeallocateSurface(this, config_.surface_id); 1239 codec_allocator_->DeallocateSurface(this, surface_id());
1217
1218 // Hop the SurfaceTexture release call through the task runner used last time
1219 // we released a codec. This ensures that we release the surface texture after
1220 // the codec it's attached to (if any) is released. It's not sufficient to use
1221 // |codec_config_->task_type| because that might have changed since we
1222 // released the codec this surface was attached to.
1223 if (codec_config_->surface_texture) {
1224 codec_allocator_->TaskRunnerFor(last_release_task_type_)
1225 ->PostTaskAndReply(
1226 FROM_HERE, base::Bind(&base::DoNothing),
1227 base::Bind(&gl::SurfaceTexture::ReleaseSurfaceTexture,
1228 codec_config_->surface_texture));
1229 }
1230 1240
1231 delete this; 1241 delete this;
1232 } 1242 }
1233 1243
1234 bool AndroidVideoDecodeAccelerator::TryToSetupDecodeOnSeparateThread( 1244 bool AndroidVideoDecodeAccelerator::TryToSetupDecodeOnSeparateThread(
1235 const base::WeakPtr<Client>& decode_client, 1245 const base::WeakPtr<Client>& decode_client,
1236 const scoped_refptr<base::SingleThreadTaskRunner>& decode_task_runner) { 1246 const scoped_refptr<base::SingleThreadTaskRunner>& decode_task_runner) {
1237 return false; 1247 return false;
1238 } 1248 }
1239 1249
(...skipping 20 matching lines...) Expand all
1260 1270
1261 // 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
1262 // 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
1263 // 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.
1264 if (base::android::BuildInfo::GetInstance()->sdk_int() >= 23) { 1274 if (base::android::BuildInfo::GetInstance()->sdk_int() >= 23) {
1265 // 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
1266 // 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.
1267 picture_buffer_manager_.ReleaseCodecBuffers(output_picture_buffers_); 1277 picture_buffer_manager_.ReleaseCodecBuffers(output_picture_buffers_);
1268 1278
1269 // Switch away from the surface being destroyed to a surface texture. 1279 // Switch away from the surface being destroyed to a surface texture.
1270 DCHECK_NE(config_.surface_id, SurfaceManager::kNoSurfaceID); 1280 DCHECK_NE(surface_id(), SurfaceManager::kNoSurfaceID);
1271 1281
1272 // The leaving fullscreen notification may come in before this point. 1282 // The leaving fullscreen notification may come in before this point.
1273 if (pending_surface_id_) 1283 if (pending_surface_id_)
1274 DCHECK_EQ(pending_surface_id_.value(), SurfaceManager::kNoSurfaceID); 1284 DCHECK_EQ(pending_surface_id_.value(), SurfaceManager::kNoSurfaceID);
1275 1285
1276 pending_surface_id_ = SurfaceManager::kNoSurfaceID; 1286 pending_surface_id_ = SurfaceManager::kNoSurfaceID;
1277 UpdateSurface(); 1287 UpdateSurface();
1278 // 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,
1279 // 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.
1280 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
1538 bool AndroidVideoDecodeAccelerator::IsMediaCodecSoftwareDecodingForbidden() 1548 bool AndroidVideoDecodeAccelerator::IsMediaCodecSoftwareDecodingForbidden()
1539 const { 1549 const {
1540 // Prevent MediaCodec from using its internal software decoders when we have 1550 // Prevent MediaCodec from using its internal software decoders when we have
1541 // more secure and up to date versions in the renderer process. 1551 // more secure and up to date versions in the renderer process.
1542 return !config_.is_encrypted() && (codec_config_->codec == kCodecVP8 || 1552 return !config_.is_encrypted() && (codec_config_->codec == kCodecVP8 ||
1543 codec_config_->codec == kCodecVP9); 1553 codec_config_->codec == kCodecVP9);
1544 } 1554 }
1545 1555
1546 bool AndroidVideoDecodeAccelerator::UpdateSurface() { 1556 bool AndroidVideoDecodeAccelerator::UpdateSurface() {
1547 DCHECK(pending_surface_id_); 1557 DCHECK(pending_surface_id_);
1548 DCHECK_NE(config_.surface_id, pending_surface_id_.value()); 1558 DCHECK_NE(surface_id(), pending_surface_id_.value());
1549 DCHECK(config_.surface_id == SurfaceManager::kNoSurfaceID || 1559 DCHECK(surface_id() == SurfaceManager::kNoSurfaceID ||
1550 pending_surface_id_.value() == SurfaceManager::kNoSurfaceID); 1560 pending_surface_id_.value() == SurfaceManager::kNoSurfaceID);
1551 1561
1552 const int previous_surface_id = config_.surface_id; 1562 const int previous_surface_id = surface_id();
1553 const int new_surface_id = pending_surface_id_.value(); 1563 const int new_surface_id = pending_surface_id_.value();
1554 pending_surface_id_.reset(); 1564 pending_surface_id_.reset();
1555 1565
1556 // Start surface creation. Note that if we're called via surfaceDestroyed, 1566 // Start surface creation. Note that if we're called via surfaceDestroyed,
1557 // then this must complete synchronously or it will DCHECK. Otherwise, we 1567 // then this must complete synchronously or it will DCHECK. Otherwise, we
1558 // 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
1559 // 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.
1560 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);
1561 StartSurfaceCreation(); 1572 StartSurfaceCreation();
1562 if (state_ == ERROR) { 1573 if (state_ == ERROR) {
1563 // 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
1564 // 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
1565 // 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
1566 // new surface. This is only guaranteed because of how OnCodecConfigured 1577 // new surface. This is only guaranteed because of how OnCodecConfigured
1567 // 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
1568 // wouldn't be necessarily true anymore. 1579 // wouldn't be necessarily true anymore.
1569 // 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
1570 // for OnSurfaceDestroyed, because of WAITING_FOR_SURFACE. Shouldn't 1581 // for OnSurfaceDestroyed, because of WAITING_FOR_SURFACE. Shouldn't
1571 // happen with SurfaceTexture, and OnSurfaceDestroyed checks for it. 1582 // happen with SurfaceTexture, and OnSurfaceDestroyed checks for it. In
1572 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_);
1573 ReleaseCodec(); 1586 ReleaseCodec();
1587 // We no longer own the new surface.
1574 codec_allocator_->DeallocateSurface(this, new_surface_id); 1588 codec_allocator_->DeallocateSurface(this, new_surface_id);
1575 } 1589 }
1576 1590
1577 // 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 // This is the only case where we start a new incoming bundle, and we maintain
1593 // the property that |incoming_bundle_| is the one that we own, as documented
1594 // for surface_id().
1595 // It would be nice if the outgoing surface bundle did this.
1596 // TODO(liberato): It could, but the CVV implementation of AndroidOverlay
1597 // will do it too when the bundle holding it is dropped. We'll do it this way
1598 // until then, just to minimize changes.
1578 codec_allocator_->DeallocateSurface(this, previous_surface_id); 1599 codec_allocator_->DeallocateSurface(this, previous_surface_id);
1579 1600
1580 return state_ != ERROR; 1601 return state_ != ERROR;
1581 } 1602 }
1582 1603
1583 void AndroidVideoDecodeAccelerator::ReleaseCodec() { 1604 void AndroidVideoDecodeAccelerator::ReleaseCodec() {
1584 if (!media_codec_) 1605 if (!media_codec_)
1585 return; 1606 return;
1586 1607
1587 picture_buffer_manager_.CodecChanged(nullptr); 1608 picture_buffer_manager_.CodecChanged(nullptr);
1588 codec_allocator_->ReleaseMediaCodec( 1609 codec_allocator_->ReleaseMediaCodec(std::move(media_codec_),
1589 std::move(media_codec_), codec_config_->task_type, config_.surface_id); 1610 codec_config_->task_type,
1590 last_release_task_type_ = codec_config_->task_type; 1611 codec_config_->surface_bundle);
1591 } 1612 }
1592 1613
1593 } // namespace media 1614 } // namespace media
OLDNEW
« no previous file with comments | « media/gpu/android_video_decode_accelerator.h ('k') | media/gpu/avda_codec_allocator.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698