#ifndef MEDIA_CAST_ENCODING_EXTERNAL_VIDEO_ENCODER_H_
#define MEDIA_CAST_ENCODING_EXTERNAL_VIDEO_ENCODER_H_
#include <stddef.h>
#include <stdint.h>
#include <memory>
#include <string_view>
#include "base/containers/span.h"
#include "base/memory/raw_ref.h"
#include "base/memory/weak_ptr.h"
#include "base/task/single_thread_task_runner.h"
#include "media/cast/cast_environment.h"
#include "media/cast/encoding/size_adaptable_video_encoder_base.h"
#include "media/cast/encoding/video_encoder.h"
#include "media/video/video_encode_accelerator.h"
#include "ui/gfx/geometry/size.h"
namespace media {
class VideoEncoderMetricsProvider;
namespace cast {
class ExternalVideoEncoder final : public VideoEncoder {
public:
static bool IsSupported(const FrameSenderConfig& video_config);
ExternalVideoEncoder(
const scoped_refptr<CastEnvironment>& cast_environment,
const FrameSenderConfig& video_config,
VideoEncoderMetricsProvider& metrics_provider,
const gfx::Size& frame_size,
FrameId first_frame_id,
StatusChangeCallback status_change_cb,
const CreateVideoEncodeAcceleratorCallback& create_vea_cb);
ExternalVideoEncoder(const ExternalVideoEncoder&) = delete;
ExternalVideoEncoder& operator=(const ExternalVideoEncoder&) = delete;
~ExternalVideoEncoder() final;
bool EncodeVideoFrame(scoped_refptr<media::VideoFrame> video_frame,
base::TimeTicks reference_time,
FrameEncodedCallback frame_encoded_callback) final;
void SetBitRate(int new_bit_rate) final;
void GenerateKeyFrame() final;
private:
class VEAClientImpl;
void DestroyClientSoon();
void SetErrorToMetricsProvider(const media::EncoderStatus& encoder_status);
void OnCreateVideoEncodeAccelerator(
const FrameSenderConfig& video_config,
FrameId first_frame_id,
const StatusChangeCallback& status_change_cb,
scoped_refptr<base::SingleThreadTaskRunner> encoder_task_runner,
std::unique_ptr<media::VideoEncodeAccelerator> vea);
const scoped_refptr<CastEnvironment> cast_environment_;
raw_ref<VideoEncoderMetricsProvider> metrics_provider_;
const gfx::Size frame_size_;
int bit_rate_;
bool key_frame_requested_ = false;
scoped_refptr<VEAClientImpl> client_;
base::WeakPtrFactory<ExternalVideoEncoder> weak_factory_{this};
};
class SizeAdaptableExternalVideoEncoder final
: public SizeAdaptableVideoEncoderBase {
public:
SizeAdaptableExternalVideoEncoder(
const scoped_refptr<CastEnvironment>& cast_environment,
const FrameSenderConfig& video_config,
std::unique_ptr<VideoEncoderMetricsProvider> metrics_provider,
StatusChangeCallback status_change_cb,
const CreateVideoEncodeAcceleratorCallback& create_vea_cb);
SizeAdaptableExternalVideoEncoder(const SizeAdaptableExternalVideoEncoder&) =
delete;
SizeAdaptableExternalVideoEncoder& operator=(
const SizeAdaptableExternalVideoEncoder&) = delete;
~SizeAdaptableExternalVideoEncoder() final;
protected:
std::unique_ptr<VideoEncoder> CreateEncoder() final;
private:
const CreateVideoEncodeAcceleratorCallback create_vea_cb_;
};
class QuantizerEstimator {
public:
static constexpr int MIN_VPX_QUANTIZER = 4;
static constexpr int MAX_VPX_QUANTIZER = 63;
QuantizerEstimator();
QuantizerEstimator(const QuantizerEstimator&) = delete;
QuantizerEstimator& operator=(const QuantizerEstimator&) = delete;
~QuantizerEstimator();
void Reset();
std::optional<double> EstimateForKeyFrame(const VideoFrame& frame);
std::optional<double> EstimateForDeltaFrame(const VideoFrame& frame);
private:
static bool CanExamineFrame(const VideoFrame& frame);
static double ComputeEntropyFromHistogram(
base::span<const int> histogram,
size_t spanification_suspected_redundant_histogram_size,
int num_samples);
static double ToQuantizerEstimate(double shannon_entropy);
std::unique_ptr<uint8_t[]> last_frame_pixel_buffer_;
gfx::Size last_frame_size_;
};
}
}
#endif