#ifndef MEDIA_GPU_ANDROID_CODEC_ALLOCATOR_H_
#define MEDIA_GPU_ANDROID_CODEC_ALLOCATOR_H_
#include <stddef.h>
#include <memory>
#include "base/containers/circular_deque.h"
#include "base/functional/callback.h"
#include "base/memory/raw_ptr.h"
#include "base/no_destructor.h"
#include "base/task/sequenced_task_runner.h"
#include "base/time/time.h"
#include "media/base/android/media_codec_bridge.h"
#include "media/base/android/media_codec_bridge_impl.h"
#include "media/gpu/media_gpu_export.h"
#include "ui/gl/android/scoped_java_surface.h"
namespace base {
class TickClock;
}
namespace media {
class MEDIA_GPU_EXPORT CodecAllocator {
public:
static constexpr gfx::Size kMinHardwareResolution{96, 96};
static CodecAllocator* GetInstance(
scoped_refptr<base::SequencedTaskRunner> task_runner);
CodecAllocator(const CodecAllocator&) = delete;
CodecAllocator& operator=(const CodecAllocator&) = delete;
using CodecFactoryCB =
base::RepeatingCallback<std::unique_ptr<MediaCodecBridge>(
const VideoCodecConfig& config)>;
using CodecCreatedCB =
base::OnceCallback<void(std::unique_ptr<MediaCodecBridge>)>;
virtual void CreateMediaCodecAsync(
CodecCreatedCB codec_created_cb,
std::unique_ptr<VideoCodecConfig> codec_config);
virtual void ReleaseMediaCodec(std::unique_ptr<MediaCodecBridge> codec,
base::OnceClosure codec_released_cb);
protected:
friend class base::NoDestructor<CodecAllocator>;
CodecAllocator(CodecFactoryCB factory_cb,
scoped_refptr<base::SequencedTaskRunner> task_runner);
virtual ~CodecAllocator();
private:
friend class CodecAllocatorTest;
void OnCodecCreated(base::TimeTicks start_time,
CodecCreatedCB codec_created_cb,
std::unique_ptr<MediaCodecBridge> codec);
void OnCodecReleased(base::TimeTicks start_time,
base::OnceClosure codec_released_cb);
bool IsPrimaryTaskRunnerLikelyHung() const;
base::SequencedTaskRunner* SelectCodecTaskRunner();
void CompletePendingOperation(base::TimeTicks start_time);
const scoped_refptr<base::SequencedTaskRunner> task_runner_;
const CodecFactoryCB factory_cb_;
raw_ptr<const base::TickClock> tick_clock_;
scoped_refptr<base::SequencedTaskRunner> primary_task_runner_;
scoped_refptr<base::SequencedTaskRunner> secondary_task_runner_;
base::circular_deque<base::TimeTicks> pending_operations_;
bool force_sw_codecs_ = false;
};
}
#endif