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

Unified Diff: media/gpu/avda_codec_allocator.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 side-by-side diff with in-line comments
Download patch
Index: media/gpu/avda_codec_allocator.cc
diff --git a/media/gpu/avda_codec_allocator.cc b/media/gpu/avda_codec_allocator.cc
index bbf96156ea4d85280e8bba9b69dbbd319f80b7c0..52bde7bb28bb582a9ff3f683fc3a5944339ba666 100644
--- a/media/gpu/avda_codec_allocator.cc
+++ b/media/gpu/avda_codec_allocator.cc
@@ -41,6 +41,11 @@ void DeleteMediaCodecAndSignal(std::unique_ptr<VideoCodecBridge> codec,
done_event->Signal();
}
+void DropReferenceToSurfaceBundle(
+ scoped_refptr<AVDASurfaceBundle> surface_bundle) {
+ // Do nothing. Let |surface_bundle| go out of scope.
+}
+
} // namespace
CodecConfig::CodecConfig() {}
@@ -248,8 +253,8 @@ std::unique_ptr<VideoCodecBridge> AVDACodecAllocator::CreateMediaCodecSync(
std::unique_ptr<VideoCodecBridge> codec(VideoCodecBridge::CreateDecoder(
codec_config->codec, codec_config->needs_protected_surface,
codec_config->initial_expected_coded_size,
- codec_config->surface.j_surface().obj(), media_crypto, codec_config->csd0,
- codec_config->csd1, true, require_software_codec));
+ codec_config->surface_bundle->surface.j_surface().obj(), media_crypto,
+ codec_config->csd0, codec_config->csd1, true, require_software_codec));
return codec;
}
@@ -257,55 +262,89 @@ std::unique_ptr<VideoCodecBridge> AVDACodecAllocator::CreateMediaCodecSync(
void AVDACodecAllocator::CreateMediaCodecAsync(
base::WeakPtr<AVDACodecAllocatorClient> client,
scoped_refptr<CodecConfig> codec_config) {
+ // Allocate the codec on the appropriate thread, and reply to this one with
+ // the result. If |client| is gone by then, we handle cleanup.
base::PostTaskAndReplyWithResult(
TaskRunnerFor(codec_config->task_type).get(), FROM_HERE,
base::Bind(&AVDACodecAllocator::CreateMediaCodecSync,
base::Unretained(this), codec_config),
- base::Bind(&AVDACodecAllocatorClient::OnCodecConfigured, client));
+ base::Bind(&AVDACodecAllocator::ForwardOrDropCodec,
+ base::Unretained(this), client, codec_config->task_type,
+ codec_config->surface_bundle));
+}
+
+void AVDACodecAllocator::ForwardOrDropCodec(
+ base::WeakPtr<AVDACodecAllocatorClient> client,
+ TaskType task_type,
+ scoped_refptr<AVDASurfaceBundle> surface_bundle,
+ std::unique_ptr<VideoCodecBridge> media_codec) {
+ if (!client) {
+ // |client| has been destroyed. Free |media_codec| on the right thread.
+ // Note that this also preserves |surface_bundle| until |media_codec| has
+ // been released, in case our ref to it is the last one.
+ ReleaseMediaCodec(std::move(media_codec), task_type, surface_bundle);
+ return;
+ }
+
+ // The client is still around, so (presumably) it has a reference to
+ // |surface_bundle| already.
watk 2017/02/22 20:38:56 This comment seems out of place. It seems to be ju
liberato (no reviews please) 2017/02/23 18:18:46 Done.
+ client->OnCodecConfigured(std::move(media_codec));
}
void AVDACodecAllocator::ReleaseMediaCodec(
std::unique_ptr<VideoCodecBridge> media_codec,
TaskType task_type,
- int surface_id) {
+ const scoped_refptr<AVDASurfaceBundle>& surface_bundle) {
DCHECK(thread_checker_.CalledOnValidThread());
DCHECK(media_codec);
- // No need to track the release if it's a SurfaceTexture.
- if (surface_id == SurfaceManager::kNoSurfaceID) {
- TaskRunnerFor(task_type)->PostTask(
+ // No need to track the release if it's a SurfaceTexture. We still forward
+ // the reference to |surface_bundle|, though, so that the SurfaceTexture
+ // lasts at least as long as the codec.
+ if (surface_bundle->surface_id == SurfaceManager::kNoSurfaceID) {
+ TaskRunnerFor(task_type)->PostTaskAndReply(
FROM_HERE, base::Bind(&DeleteMediaCodecAndSignal,
- base::Passed(std::move(media_codec)), nullptr));
+ base::Passed(std::move(media_codec)), nullptr),
+ base::Bind(&DropReferenceToSurfaceBundle, surface_bundle));
return;
}
+ DCHECK(!surface_bundle->surface_texture);
pending_codec_releases_.emplace(
- std::piecewise_construct, std::forward_as_tuple(surface_id),
+ std::piecewise_construct,
+ std::forward_as_tuple(surface_bundle->surface_id),
std::forward_as_tuple(base::WaitableEvent::ResetPolicy::MANUAL,
base::WaitableEvent::InitialState::NOT_SIGNALED));
base::WaitableEvent* released =
- &pending_codec_releases_.find(surface_id)->second;
+ &pending_codec_releases_.find(surface_bundle->surface_id)->second;
+ // Note that we forward |surface_bundle|, too, so that the surface outlasts
+ // the codec. This doesn't matter so much for CVV surfaces, since they don't
+ // auto-release when they're dropped. However, for surface owners, this will
+ // become important, so we still handle it. Plus, it makes sense.
TaskRunnerFor(task_type)->PostTaskAndReply(
FROM_HERE, base::Bind(&DeleteMediaCodecAndSignal,
base::Passed(std::move(media_codec)), released),
base::Bind(&AVDACodecAllocator::OnMediaCodecAndSurfaceReleased,
- base::Unretained(this), surface_id));
+ base::Unretained(this), surface_bundle));
}
-void AVDACodecAllocator::OnMediaCodecAndSurfaceReleased(int surface_id) {
+void AVDACodecAllocator::OnMediaCodecAndSurfaceReleased(
+ scoped_refptr<AVDASurfaceBundle> surface_bundle) {
DCHECK(thread_checker_.CalledOnValidThread());
- pending_codec_releases_.erase(surface_id);
- if (!surface_owners_.count(surface_id))
+ pending_codec_releases_.erase(surface_bundle->surface_id);
+ if (!surface_owners_.count(surface_bundle->surface_id))
return;
- OwnerRecord& record = surface_owners_[surface_id];
+ OwnerRecord& record = surface_owners_[surface_bundle->surface_id];
if (!record.owner && record.waiter) {
record.owner = record.waiter;
record.waiter = nullptr;
record.owner->OnSurfaceAvailable(true);
}
+
+ // Also note that |surface_bundle| lasted at least as long as the codec.
}
// Returns a hint about whether the construction thread has hung for

Powered by Google App Engine
This is Rietveld 408576698