blob: 76680ede3351b1620a9a2986bc176e2ff41cb07f [file] [log] [blame]
// Copyright 2017 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_MEDIARECORDER_VPX_ENCODER_H_
#define THIRD_PARTY_BLINK_RENDERER_MODULES_MEDIARECORDER_VPX_ENCODER_H_
#include "base/memory/weak_ptr.h"
#include "base/task/sequenced_task_runner.h"
#include "base/time/time.h"
#include "third_party/blink/renderer/modules/mediarecorder/video_track_recorder.h"
#include "third_party/blink/renderer/platform/wtf/vector.h"
#include "third_party/libvpx/source/libvpx/vpx/vp8cx.h"
#include "third_party/libvpx/source/libvpx/vpx/vpx_encoder.h"
namespace blink {
// Class encapsulating all libvpx interactions for VP8/VP9 encoding.
class VpxEncoder final : public VideoTrackRecorder::Encoder {
public:
// Originally from remoting/codec/scoped_vpx_codec.h.
// TODO(mcasas): Refactor into a common location.
struct VpxCodecDeleter {
void operator()(vpx_codec_ctx_t* codec);
};
typedef std::unique_ptr<vpx_codec_ctx_t, VpxCodecDeleter>
ScopedVpxCodecCtxPtr;
VpxEncoder(scoped_refptr<base::SequencedTaskRunner> encoding_task_runner,
bool use_vp9,
const VideoTrackRecorder::OnEncodedVideoCB& on_encoded_video_cb,
uint32_t bits_per_second,
bool is_screencast,
const VideoTrackRecorder::OnErrorCB on_error_cb);
VpxEncoder(const VpxEncoder&) = delete;
VpxEncoder& operator=(const VpxEncoder&) = delete;
base::WeakPtr<Encoder> GetWeakPtr() override {
return weak_factory_.GetWeakPtr();
}
private:
// VideoTrackRecorder::Encoder implementation.
void EncodeFrame(scoped_refptr<media::VideoFrame> frame,
base::TimeTicks capture_timestamp,
bool request_keyframe) override;
bool CanEncodeAlphaChannel() const override;
[[nodiscard]] bool ConfigureEncoder(const gfx::Size& size,
vpx_codec_enc_cfg_t* codec_config,
ScopedVpxCodecCtxPtr* encoder);
void DoEncode(vpx_codec_ctx_t* const encoder,
const gfx::Size& frame_size,
const uint8_t* data,
const uint8_t* y_plane,
int y_stride,
const uint8_t* u_plane,
int u_stride,
const uint8_t* v_plane,
int v_stride,
const base::TimeDelta& duration,
bool force_keyframe,
std::string& output_data,
bool* const keyframe,
vpx_img_fmt_t img_fmt);
// Returns true if |codec_config| has been filled in at least once.
bool IsInitialized(const vpx_codec_enc_cfg_t& codec_config) const;
// Estimate the frame duration from |frame| and |last_frame_timestamp_|.
base::TimeDelta EstimateFrameDuration(const media::VideoFrame& frame);
// Force usage of VP9 for encoding, instead of VP8 which is the default.
const bool use_vp9_;
const bool is_screencast_;
const VideoTrackRecorder::OnErrorCB on_error_cb_;
// VPx internal objects: configuration and encoder. |encoder_| is a special
// scoped pointer to guarantee proper destruction, particularly when
// reconfiguring due to parameters change. Only used on
// VideoTrackRecorder::Encoder::encoding_thread_.
vpx_codec_enc_cfg_t codec_config_;
ScopedVpxCodecCtxPtr encoder_;
vpx_codec_enc_cfg_t alpha_codec_config_;
ScopedVpxCodecCtxPtr alpha_encoder_;
Vector<uint8_t> alpha_dummy_planes_;
size_t v_plane_offset_;
size_t u_plane_stride_;
size_t v_plane_stride_;
bool last_frame_had_alpha_ = false;
// The |media::VideoFrame::timestamp()| of the last encoded frame. This is
// used to predict the duration of the next frame.
base::TimeDelta last_frame_timestamp_;
base::WeakPtrFactory<VpxEncoder> weak_factory_{this};
};
} // namespace blink
#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_MEDIARECORDER_VPX_ENCODER_H_