This CL makes a number of intervowen changes: * Add BitrateAllocation struct, that contains a codec independent view of how the target bitrate is distributed over spatial and temporal layers. * Adds the BitrateAllocator interface, which takes a bitrate and frame rate and produces a BitrateAllocation. * A default (non layered) implementation is added, and SimulcastRateAllocator is extended to fully handle VP8 allocation. This includes capturing TemporalLayer instances created by the encoder. * ViEEncoder now owns both the bitrate allocator and the temporal layer factories for VP8. This allows allocation to happen fully outside of the encoder implementation. This refactoring will make it possible for ViEEncoder to signal the full picture of target bitrates to the RTCP module. BUG=webrtc:6301 Review-Url: https://codereview.webrtc.org/2434073003 Cr-Commit-Position: refs/heads/master@{#14998}
223 lines
8.0 KiB
C++
223 lines
8.0 KiB
C++
/*
|
|
* Copyright (c) 2014 The WebRTC project authors. All Rights Reserved.
|
|
*
|
|
* Use of this source code is governed by a BSD-style license
|
|
* that can be found in the LICENSE file in the root of the source
|
|
* tree. An additional intellectual property rights grant can be found
|
|
* in the file PATENTS. All contributing project authors may
|
|
* be found in the AUTHORS file in the root of the source tree.
|
|
*/
|
|
|
|
#ifndef WEBRTC_VIDEO_ENCODER_H_
|
|
#define WEBRTC_VIDEO_ENCODER_H_
|
|
|
|
#include <memory>
|
|
#include <string>
|
|
#include <vector>
|
|
|
|
#include "webrtc/base/checks.h"
|
|
#include "webrtc/common_types.h"
|
|
#include "webrtc/typedefs.h"
|
|
#include "webrtc/video_frame.h"
|
|
|
|
namespace webrtc {
|
|
|
|
class RTPFragmentationHeader;
|
|
// TODO(pbos): Expose these through a public (root) header or change these APIs.
|
|
struct CodecSpecificInfo;
|
|
class VideoCodec;
|
|
|
|
class EncodedImageCallback {
|
|
public:
|
|
virtual ~EncodedImageCallback() {}
|
|
|
|
struct Result {
|
|
enum Error {
|
|
OK,
|
|
|
|
// Failed to send the packet.
|
|
ERROR_SEND_FAILED,
|
|
};
|
|
|
|
Result(Error error) : error(error) {}
|
|
Result(Error error, uint32_t frame_id) : error(error), frame_id(frame_id) {}
|
|
|
|
Error error;
|
|
|
|
// Frame ID assigned to the frame. The frame ID should be the same as the ID
|
|
// seen by the receiver for this frame. RTP timestamp of the frame is used
|
|
// as frame ID when RTP is used to send video. Must be used only when
|
|
// error=OK.
|
|
uint32_t frame_id = 0;
|
|
|
|
// Tells the encoder that the next frame is should be dropped.
|
|
bool drop_next_frame = false;
|
|
};
|
|
|
|
// Callback function which is called when an image has been encoded.
|
|
virtual Result OnEncodedImage(
|
|
const EncodedImage& encoded_image,
|
|
const CodecSpecificInfo* codec_specific_info,
|
|
const RTPFragmentationHeader* fragmentation) = 0;
|
|
};
|
|
|
|
class VideoEncoder {
|
|
public:
|
|
enum EncoderType {
|
|
kH264,
|
|
kVp8,
|
|
kVp9,
|
|
kUnsupportedCodec,
|
|
};
|
|
|
|
static VideoEncoder* Create(EncoderType codec_type);
|
|
// Returns true if this type of encoder can be created using
|
|
// VideoEncoder::Create.
|
|
static bool IsSupportedSoftware(EncoderType codec_type);
|
|
static EncoderType CodecToEncoderType(VideoCodecType codec_type);
|
|
|
|
static VideoCodecVP8 GetDefaultVp8Settings();
|
|
static VideoCodecVP9 GetDefaultVp9Settings();
|
|
static VideoCodecH264 GetDefaultH264Settings();
|
|
|
|
virtual ~VideoEncoder() {}
|
|
|
|
// Initialize the encoder with the information from the codecSettings
|
|
//
|
|
// Input:
|
|
// - codec_settings : Codec settings
|
|
// - number_of_cores : Number of cores available for the encoder
|
|
// - max_payload_size : The maximum size each payload is allowed
|
|
// to have. Usually MTU - overhead.
|
|
//
|
|
// Return value : Set bit rate if OK
|
|
// <0 - Errors:
|
|
// WEBRTC_VIDEO_CODEC_ERR_PARAMETER
|
|
// WEBRTC_VIDEO_CODEC_ERR_SIZE
|
|
// WEBRTC_VIDEO_CODEC_LEVEL_EXCEEDED
|
|
// WEBRTC_VIDEO_CODEC_MEMORY
|
|
// WEBRTC_VIDEO_CODEC_ERROR
|
|
virtual int32_t InitEncode(const VideoCodec* codec_settings,
|
|
int32_t number_of_cores,
|
|
size_t max_payload_size) = 0;
|
|
|
|
// Register an encode complete callback object.
|
|
//
|
|
// Input:
|
|
// - callback : Callback object which handles encoded images.
|
|
//
|
|
// Return value : WEBRTC_VIDEO_CODEC_OK if OK, < 0 otherwise.
|
|
virtual int32_t RegisterEncodeCompleteCallback(
|
|
EncodedImageCallback* callback) = 0;
|
|
|
|
// Free encoder memory.
|
|
// Return value : WEBRTC_VIDEO_CODEC_OK if OK, < 0 otherwise.
|
|
virtual int32_t Release() = 0;
|
|
|
|
// Encode an I420 image (as a part of a video stream). The encoded image
|
|
// will be returned to the user through the encode complete callback.
|
|
//
|
|
// Input:
|
|
// - frame : Image to be encoded
|
|
// - frame_types : Frame type to be generated by the encoder.
|
|
//
|
|
// Return value : WEBRTC_VIDEO_CODEC_OK if OK
|
|
// <0 - Errors:
|
|
// WEBRTC_VIDEO_CODEC_ERR_PARAMETER
|
|
// WEBRTC_VIDEO_CODEC_MEMORY
|
|
// WEBRTC_VIDEO_CODEC_ERROR
|
|
// WEBRTC_VIDEO_CODEC_TIMEOUT
|
|
virtual int32_t Encode(const VideoFrame& frame,
|
|
const CodecSpecificInfo* codec_specific_info,
|
|
const std::vector<FrameType>* frame_types) = 0;
|
|
|
|
// Inform the encoder of the new packet loss rate and the round-trip time of
|
|
// the network.
|
|
//
|
|
// Input:
|
|
// - packet_loss : Fraction lost
|
|
// (loss rate in percent = 100 * packetLoss / 255)
|
|
// - rtt : Round-trip time in milliseconds
|
|
// Return value : WEBRTC_VIDEO_CODEC_OK if OK
|
|
// <0 - Errors: WEBRTC_VIDEO_CODEC_ERROR
|
|
virtual int32_t SetChannelParameters(uint32_t packet_loss, int64_t rtt) = 0;
|
|
|
|
// Inform the encoder about the new target bit rate.
|
|
//
|
|
// Input:
|
|
// - bitrate : New target bit rate
|
|
// - framerate : The target frame rate
|
|
//
|
|
// Return value : WEBRTC_VIDEO_CODEC_OK if OK, < 0 otherwise.
|
|
virtual int32_t SetRates(uint32_t bitrate, uint32_t framerate) {
|
|
RTC_NOTREACHED() << "SetRate(uint32_t, uint32_t) is deprecated.";
|
|
return -1;
|
|
}
|
|
|
|
// Default fallback: Just use the sum of bitrates as the single target rate.
|
|
// TODO(sprang): Remove this default implementation when we remove SetRates().
|
|
virtual int32_t SetRateAllocation(const BitrateAllocation& allocation,
|
|
uint32_t framerate) {
|
|
return SetRates(allocation.get_sum_kbps(), framerate);
|
|
}
|
|
|
|
virtual int32_t SetPeriodicKeyFrames(bool enable) { return -1; }
|
|
virtual void OnDroppedFrame() {}
|
|
virtual bool SupportsNativeHandle() const { return false; }
|
|
virtual const char* ImplementationName() const { return "unknown"; }
|
|
};
|
|
|
|
// Class used to wrap external VideoEncoders to provide a fallback option on
|
|
// software encoding when a hardware encoder fails to encode a stream due to
|
|
// hardware restrictions, such as max resolution.
|
|
class VideoEncoderSoftwareFallbackWrapper : public VideoEncoder {
|
|
public:
|
|
VideoEncoderSoftwareFallbackWrapper(VideoCodecType codec_type,
|
|
webrtc::VideoEncoder* encoder);
|
|
|
|
int32_t InitEncode(const VideoCodec* codec_settings,
|
|
int32_t number_of_cores,
|
|
size_t max_payload_size) override;
|
|
|
|
int32_t RegisterEncodeCompleteCallback(
|
|
EncodedImageCallback* callback) override;
|
|
|
|
int32_t Release() override;
|
|
int32_t Encode(const VideoFrame& frame,
|
|
const CodecSpecificInfo* codec_specific_info,
|
|
const std::vector<FrameType>* frame_types) override;
|
|
int32_t SetChannelParameters(uint32_t packet_loss, int64_t rtt) override;
|
|
int32_t SetRateAllocation(const BitrateAllocation& bitrate_allocation,
|
|
uint32_t framerate) override;
|
|
void OnDroppedFrame() override;
|
|
bool SupportsNativeHandle() const override;
|
|
|
|
private:
|
|
bool InitFallbackEncoder();
|
|
|
|
// Settings used in the last InitEncode call and used if a dynamic fallback to
|
|
// software is required.
|
|
VideoCodec codec_settings_;
|
|
int32_t number_of_cores_;
|
|
size_t max_payload_size_;
|
|
|
|
// The last bitrate/framerate set, and a flag for noting they are set.
|
|
bool rates_set_;
|
|
BitrateAllocation bitrate_allocation_;
|
|
uint32_t framerate_;
|
|
|
|
// The last channel parameters set, and a flag for noting they are set.
|
|
bool channel_parameters_set_;
|
|
uint32_t packet_loss_;
|
|
int64_t rtt_;
|
|
|
|
const EncoderType encoder_type_;
|
|
webrtc::VideoEncoder* const encoder_;
|
|
|
|
std::unique_ptr<webrtc::VideoEncoder> fallback_encoder_;
|
|
std::string fallback_implementation_name_;
|
|
EncodedImageCallback* callback_;
|
|
};
|
|
} // namespace webrtc
|
|
#endif // WEBRTC_VIDEO_ENCODER_H_
|