#ifndef MEDIA_GPU_CHROMEOS_IMAGE_PROCESSOR_H_
#define MEDIA_GPU_CHROMEOS_IMAGE_PROCESSOR_H_
#include <stdint.h>
#include <map>
#include <optional>
#include <utility>
#include <vector>
#include "base/functional/callback_forward.h"
#include "base/memory/scoped_refptr.h"
#include "base/memory/weak_ptr.h"
#include "base/sequence_checker.h"
#include "base/task/sequenced_task_runner.h"
#include "media/base/video_frame.h"
#include "media/gpu/chromeos/fourcc.h"
#include "media/gpu/chromeos/frame_resource.h"
#include "media/gpu/chromeos/image_processor_backend.h"
#include "media/gpu/media_gpu_export.h"
#include "ui/gfx/native_pixmap_handle.h"
namespace media {
class MEDIA_GPU_EXPORT ImageProcessor {
public:
struct PixelLayoutCandidate {
Fourcc fourcc;
gfx::Size size;
uint64_t modifier = gfx::NativePixmapHandle::kNoModifier;
bool operator==(const PixelLayoutCandidate& candidate) const {
return this->fourcc == candidate.fourcc && this->size == candidate.size &&
this->modifier == candidate.modifier;
}
};
using PortConfig = ImageProcessorBackend::PortConfig;
using OutputMode = ImageProcessorBackend::OutputMode;
using ErrorCB = ImageProcessorBackend::ErrorCB;
using FrameReadyCB = ImageProcessorBackend::FrameReadyCB;
using FrameResourceReadyCB = ImageProcessorBackend::FrameResourceReadyCB;
using LegacyFrameResourceReadyCB =
ImageProcessorBackend::LegacyFrameResourceReadyCB;
using CreateBackendCB =
base::RepeatingCallback<std::unique_ptr<ImageProcessorBackend>(
const PortConfig& input_config,
const PortConfig& output_config,
OutputMode output_mode,
ErrorCB error_cb)>;
static std::unique_ptr<ImageProcessor> Create(
CreateBackendCB create_backend_cb,
const PortConfig& input_config,
const PortConfig& output_config,
OutputMode output_mode,
ErrorCB error_cb,
scoped_refptr<base::SequencedTaskRunner> client_task_runner);
ImageProcessor() = delete;
ImageProcessor(const ImageProcessor&) = delete;
ImageProcessor& operator=(const ImageProcessor&) = delete;
virtual ~ImageProcessor();
virtual const PortConfig& input_config() const;
virtual const PortConfig& output_config() const;
OutputMode output_mode() const { return backend_->output_mode(); }
std::string backend_type() const { return backend_->type(); }
bool Process(scoped_refptr<FrameResource> frame,
LegacyFrameResourceReadyCB cb);
bool Process(scoped_refptr<VideoFrame> input_frame,
scoped_refptr<VideoFrame> output_frame,
FrameReadyCB cb);
bool Process(scoped_refptr<FrameResource> input_frame,
scoped_refptr<FrameResource> output_frame,
FrameResourceReadyCB cb);
bool Reset();
bool needs_linear_output_buffers() const {
return needs_linear_output_buffers_;
}
bool SupportsIncoherentBufs() const {
return backend_ && backend_->supports_incoherent_buffers();
}
protected:
struct ClientCallback {
ClientCallback(FrameReadyCB ready_cb);
ClientCallback(FrameResourceReadyCB frame_resource_ready_cb);
ClientCallback(LegacyFrameResourceReadyCB legacy_frame_resource_ready_cb);
ClientCallback(ClientCallback&&);
~ClientCallback();
FrameReadyCB ready_cb;
FrameResourceReadyCB frame_resource_ready_cb;
LegacyFrameResourceReadyCB legacy_frame_resource_ready_cb;
};
ImageProcessor(std::unique_ptr<ImageProcessorBackend> backend,
scoped_refptr<base::SequencedTaskRunner> client_task_runner,
scoped_refptr<base::SequencedTaskRunner> backend_task_runner);
static void OnProcessDoneThunk(
scoped_refptr<base::SequencedTaskRunner> task_runner,
std::optional<base::WeakPtr<ImageProcessor>> weak_this,
int cb_index,
scoped_refptr<VideoFrame> frame);
static void OnProcessFrameResourceDoneThunk(
scoped_refptr<base::SequencedTaskRunner> task_runner,
std::optional<base::WeakPtr<ImageProcessor>> weak_this,
int cb_index,
scoped_refptr<FrameResource> frame);
static void OnProcessFrameResourceLegacyDoneThunk(
scoped_refptr<base::SequencedTaskRunner> task_runner,
std::optional<base::WeakPtr<ImageProcessor>> weak_this,
int cb_index,
size_t buffer_id,
scoped_refptr<FrameResource> frame);
void OnProcessDone(int cb_index, scoped_refptr<VideoFrame> frame);
void OnProcessFrameResourceDone(int cb_index,
scoped_refptr<FrameResource> frame);
void OnProcessFrameResourceLegacyDone(int cb_index,
size_t buffer_id,
scoped_refptr<FrameResource> frame);
int StoreCallback(ClientCallback cb);
std::unique_ptr<ImageProcessorBackend> backend_;
std::map<int , ClientCallback > pending_cbs_;
int next_cb_index_ = 0;
scoped_refptr<base::SequencedTaskRunner> client_task_runner_;
SEQUENCE_CHECKER(client_sequence_checker_);
scoped_refptr<base::SequencedTaskRunner> backend_task_runner_;
const bool needs_linear_output_buffers_;
base::WeakPtr<ImageProcessor> weak_this_;
base::WeakPtrFactory<ImageProcessor> weak_this_factory_{this};
};
}
#endif