#include "media/gpu/android/codec_image_group.h"
#include "base/functional/bind.h"
#include "base/task/sequenced_task_runner.h"
#include "media/gpu/android/codec_surface_bundle.h"
namespace media {
CodecImageGroup::CodecImageGroup(
scoped_refptr<base::SequencedTaskRunner> task_runner,
scoped_refptr<CodecSurfaceBundle> surface_bundle,
scoped_refptr<gpu::RefCountedLock> drdc_lock)
: gpu::RefCountedLockHelperDrDc(std::move(drdc_lock)),
surface_bundle_(std::move(surface_bundle)),
task_runner_(std::move(task_runner)) {
if (surface_bundle_->overlay()) {
surface_bundle_->overlay()->AddSurfaceDestroyedCallback(base::BindOnce(
[](scoped_refptr<base::SequencedTaskRunner> task_runner,
base::OnceCallback<void(AndroidOverlay*)> cb,
AndroidOverlay* overlay) -> void {
task_runner->PostTask(FROM_HERE,
base::BindOnce(std::move(cb), overlay));
},
task_runner_,
base::BindOnce(&CodecImageGroup::OnSurfaceDestroyed,
weak_this_factory_.GetWeakPtr())));
}
}
CodecImageGroup::~CodecImageGroup() {
DCHECK(images_.empty());
CHECK(task_runner_->RunsTasksInCurrentSequence());
}
void CodecImageGroup::AddCodecImage(CodecImage* image) {
CHECK(task_runner_->RunsTasksInCurrentSequence());
if (!surface_bundle_) {
base::AutoLockMaybe auto_lock(GetDrDcLockPtr());
image->ReleaseCodecBuffer();
return;
}
images_.insert(image);
image->AddUnusedCB(
base::BindOnce(&CodecImageGroup::OnCodecImageUnused, this));
}
void CodecImageGroup::OnCodecImageUnused(CodecImage* image) {
CHECK(task_runner_->RunsTasksInCurrentSequence());
images_.erase(image);
}
void CodecImageGroup::OnSurfaceDestroyed(AndroidOverlay* overlay) {
CHECK(task_runner_->RunsTasksInCurrentSequence());
for (CodecImage* image : images_) {
base::AutoLockMaybe auto_lock(GetDrDcLockPtr());
image->ReleaseCodecBuffer();
}
surface_bundle_ = nullptr;
}
}