Files
platform-external-webrtc/webrtc/modules/video_coding/include/video_coding.h
Erik Språng 08127a9449 Reland #2 of Issue 2434073003: Extract bitrate allocation ...
This is yet another reland of https://codereview.webrtc.org/2434073003/
including two fixes:

1. SimulcastRateAllocator did not handle the screenshare settings properly for numSimulcastStreams = 1. Additional test case was added for that.
2. In VideoSender, when rate allocation is updated after setting a new VideoCodec config, only update the state of the EncoderParameters, but don't actually run SetRateAllocation on the encoder itself. This caused some problems upstreams.

Please review only the changes after patch set 1.

Original description:

Extract bitrate allocation of spatial/temporal layers out of codec impl.

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
R=stefan@webrtc.org

Review URL: https://codereview.webrtc.org/2510583002 .

Cr-Commit-Position: refs/heads/master@{#15105}
2016-11-16 15:41:45 +00:00

479 lines
19 KiB
C++

/*
* Copyright (c) 2012 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_MODULES_VIDEO_CODING_INCLUDE_VIDEO_CODING_H_
#define WEBRTC_MODULES_VIDEO_CODING_INCLUDE_VIDEO_CODING_H_
#if defined(WEBRTC_WIN)
// This is a workaround on Windows due to the fact that some Windows
// headers define CreateEvent as a macro to either CreateEventW or CreateEventA.
// This can cause problems since we use that name as well and could
// declare them as one thing here whereas in another place a windows header
// may have been included and then implementing CreateEvent() causes compilation
// errors. So for consistency, we include the main windows header here.
#include <windows.h>
#endif
#include "webrtc/modules/include/module.h"
#include "webrtc/modules/include/module_common_types.h"
#include "webrtc/modules/video_coding/include/video_coding_defines.h"
#include "webrtc/system_wrappers/include/event_wrapper.h"
#include "webrtc/video_frame.h"
namespace webrtc {
class Clock;
class EncodedImageCallback;
// TODO(pbos): Remove VCMQMSettingsCallback completely. This might be done by
// removing the VCM and use VideoSender/VideoReceiver as a public interface
// directly.
class VCMQMSettingsCallback;
class VideoBitrateAllocator;
class VideoEncoder;
class VideoDecoder;
struct CodecSpecificInfo;
class EventFactory {
public:
virtual ~EventFactory() {}
virtual EventWrapper* CreateEvent() = 0;
};
class EventFactoryImpl : public EventFactory {
public:
virtual ~EventFactoryImpl() {}
virtual EventWrapper* CreateEvent() { return EventWrapper::Create(); }
};
// Used to indicate which decode with errors mode should be used.
enum VCMDecodeErrorMode {
kNoErrors, // Never decode with errors. Video will freeze
// if nack is disabled.
kSelectiveErrors, // Frames that are determined decodable in
// VCMSessionInfo may be decoded with missing
// packets. As not all incomplete frames will be
// decodable, video will freeze if nack is disabled.
kWithErrors // Release frames as needed. Errors may be
// introduced as some encoded frames may not be
// complete.
};
class VideoCodingModule : public Module {
public:
enum SenderNackMode { kNackNone, kNackAll, kNackSelective };
enum ReceiverRobustness { kNone, kHardNack, kSoftNack, kReferenceSelection };
static VideoCodingModule* Create(Clock* clock, EventFactory* event_factory);
static VideoCodingModule* Create(
Clock* clock,
VCMQMSettingsCallback* qm_settings_callback,
NackSender* nack_sender,
KeyFrameRequestSender* keyframe_request_sender,
EncodedImageCallback* pre_decode_image_callback);
static VideoCodingModule* Create(
Clock* clock,
EventFactory* event_factory,
NackSender* nack_sender,
KeyFrameRequestSender* keyframe_request_sender);
// Get supported codec settings using codec type
//
// Input:
// - codecType : The codec type to get settings for
// - codec : Memory where the codec settings will be stored
//
// Return value : VCM_OK, on success
// VCM_PARAMETER_ERROR if codec not supported
static void Codec(VideoCodecType codecType, VideoCodec* codec);
/*
* Sender
*/
// Registers a codec to be used for encoding. Calling this
// API multiple times overwrites any previously registered codecs.
//
// NOTE: Must be called on the thread that constructed the VCM instance.
//
// Input:
// - sendCodec : Settings for the codec to be registered.
// - numberOfCores : The number of cores the codec is allowed
// to use.
// - maxPayloadSize : The maximum size each payload is allowed
// to have. Usually MTU - overhead.
//
// Return value : VCM_OK, on success.
// < 0, on error.
virtual int32_t RegisterSendCodec(const VideoCodec* sendCodec,
uint32_t numberOfCores,
uint32_t maxPayloadSize) = 0;
// Register an external encoder object. This can not be used together with
// external decoder callbacks.
//
// Input:
// - externalEncoder : Encoder object to be used for encoding frames
// inserted
// with the AddVideoFrame API.
// - payloadType : The payload type bound which this encoder is bound
// to.
//
// Return value : VCM_OK, on success.
// < 0, on error.
// TODO(pbos): Remove return type when unused elsewhere.
virtual int32_t RegisterExternalEncoder(VideoEncoder* externalEncoder,
uint8_t payloadType,
bool internalSource = false) = 0;
// API to get currently configured encoder target bitrate in bits/s.
//
// Return value : 0, on success.
// < 0, on error.
virtual int Bitrate(unsigned int* bitrate) const = 0;
// API to get currently configured encoder target frame rate.
//
// Return value : 0, on success.
// < 0, on error.
virtual int FrameRate(unsigned int* framerate) const = 0;
// Sets the parameters describing the send channel. These parameters are
// inputs to the
// Media Optimization inside the VCM and also specifies the target bit rate
// for the
// encoder. Bit rate used by NACK should already be compensated for by the
// user.
//
// Input:
// - target_bitrate : The target bitrate for VCM in bits/s.
// - lossRate : Fractions of lost packets the past second.
// (loss rate in percent = 100 * packetLoss /
// 255)
// - rtt : Current round-trip time in ms.
//
// Return value : VCM_OK, on success.
// < 0, on error.
virtual int32_t SetChannelParameters(uint32_t target_bitrate,
uint8_t lossRate,
int64_t rtt) = 0;
// Sets the parameters describing the receive channel. These parameters are
// inputs to the
// Media Optimization inside the VCM.
//
// Input:
// - rtt : Current round-trip time in ms.
// with the most amount available bandwidth in
// a conference
// scenario
//
// Return value : VCM_OK, on success.
// < 0, on error.
virtual int32_t SetReceiveChannelParameters(int64_t rtt) = 0;
// Deprecated: This method currently does not have any effect.
// Register a video protection callback which will be called to deliver
// the requested FEC rate and NACK status (on/off).
// TODO(perkj): Remove once no projects use it.
virtual int32_t RegisterProtectionCallback(
VCMProtectionCallback* protection) = 0;
// Enable or disable a video protection method.
//
// Input:
// - videoProtection : The method to enable or disable.
// - enable : True if the method should be enabled, false if
// it should be disabled.
//
// Return value : VCM_OK, on success.
// < 0, on error.
virtual int32_t SetVideoProtection(VCMVideoProtection videoProtection,
bool enable) = 0;
// Add one raw video frame to the encoder. This function does all the
// necessary
// processing, then decides what frame type to encode, or if the frame should
// be
// dropped. If the frame should be encoded it passes the frame to the encoder
// before it returns.
//
// Input:
// - videoFrame : Video frame to encode.
// - codecSpecificInfo : Extra codec information, e.g., pre-parsed
// in-band signaling.
//
// Return value : VCM_OK, on success.
// < 0, on error.
virtual int32_t AddVideoFrame(
const VideoFrame& videoFrame,
const CodecSpecificInfo* codecSpecificInfo = NULL) = 0;
// Next frame encoded should be an intra frame (keyframe).
//
// Return value : VCM_OK, on success.
// < 0, on error.
virtual int32_t IntraFrameRequest(size_t stream_index) = 0;
// Frame Dropper enable. Can be used to disable the frame dropping when the
// encoder
// over-uses its bit rate. This API is designed to be used when the encoded
// frames
// are supposed to be stored to an AVI file, or when the I420 codec is used
// and the
// target bit rate shouldn't affect the frame rate.
//
// Input:
// - enable : True to enable the setting, false to disable it.
//
// Return value : VCM_OK, on success.
// < 0, on error.
virtual int32_t EnableFrameDropper(bool enable) = 0;
/*
* Receiver
*/
// Register possible receive codecs, can be called multiple times for
// different codecs.
// The module will automatically switch between registered codecs depending on
// the
// payload type of incoming frames. The actual decoder will be created when
// needed.
//
// Input:
// - receiveCodec : Settings for the codec to be registered.
// - numberOfCores : Number of CPU cores that the decoder is allowed
// to use.
// - requireKeyFrame : Set this to true if you don't want any delta
// frames
// to be decoded until the first key frame has been
// decoded.
//
// Return value : VCM_OK, on success.
// < 0, on error.
virtual int32_t RegisterReceiveCodec(const VideoCodec* receiveCodec,
int32_t numberOfCores,
bool requireKeyFrame = false) = 0;
// Register an externally defined decoder/renderer object. Can be a decoder
// only or a
// decoder coupled with a renderer. Note that RegisterReceiveCodec must be
// called to
// be used for decoding incoming streams.
//
// Input:
// - externalDecoder : The external decoder/renderer object.
// - payloadType : The payload type which this decoder should
// be
// registered to.
//
virtual void RegisterExternalDecoder(VideoDecoder* externalDecoder,
uint8_t payloadType) = 0;
// Register a receive callback. Will be called whenever there is a new frame
// ready
// for rendering.
//
// Input:
// - receiveCallback : The callback object to be used by the
// module when a
// frame is ready for rendering.
// De-register with a NULL pointer.
//
// Return value : VCM_OK, on success.
// < 0, on error.
virtual int32_t RegisterReceiveCallback(
VCMReceiveCallback* receiveCallback) = 0;
// Register a receive statistics callback which will be called to deliver
// information
// about the video stream received by the receiving side of the VCM, for
// instance the
// average frame rate and bit rate.
//
// Input:
// - receiveStats : The callback object to register.
//
// Return value : VCM_OK, on success.
// < 0, on error.
virtual int32_t RegisterReceiveStatisticsCallback(
VCMReceiveStatisticsCallback* receiveStats) = 0;
// Register a decoder timing callback which will be called to deliver
// information about the timing of the decoder in the receiving side of the
// VCM, for instance the current and maximum frame decode latency.
//
// Input:
// - decoderTiming : The callback object to register.
//
// Return value : VCM_OK, on success.
// < 0, on error.
virtual int32_t RegisterDecoderTimingCallback(
VCMDecoderTimingCallback* decoderTiming) = 0;
// Register a frame type request callback. This callback will be called when
// the
// module needs to request specific frame types from the send side.
//
// Input:
// - frameTypeCallback : The callback object to be used by the
// module when
// requesting a specific type of frame from
// the send side.
// De-register with a NULL pointer.
//
// Return value : VCM_OK, on success.
// < 0, on error.
virtual int32_t RegisterFrameTypeCallback(
VCMFrameTypeCallback* frameTypeCallback) = 0;
// Registers a callback which is called whenever the receive side of the VCM
// encounters holes in the packet sequence and needs packets to be
// retransmitted.
//
// Input:
// - callback : The callback to be registered in the VCM.
//
// Return value : VCM_OK, on success.
// <0, on error.
virtual int32_t RegisterPacketRequestCallback(
VCMPacketRequestCallback* callback) = 0;
// Waits for the next frame in the jitter buffer to become complete
// (waits no longer than maxWaitTimeMs), then passes it to the decoder for
// decoding.
// Should be called as often as possible to get the most out of the decoder.
//
// Return value : VCM_OK, on success.
// < 0, on error.
virtual int32_t Decode(uint16_t maxWaitTimeMs = 200) = 0;
// API to get the codec which is currently used for decoding by the module.
//
// Input:
// - currentReceiveCodec : Settings for the codec to be registered.
//
// Return value : VCM_OK, on success.
// < 0, on error.
virtual int32_t ReceiveCodec(VideoCodec* currentReceiveCodec) const = 0;
// API to get the codec type currently used for decoding by the module.
//
// Return value : codecy type, on success.
// kVideoCodecUnknown, on error or if no receive codec is
// registered
virtual VideoCodecType ReceiveCodec() const = 0;
// Insert a parsed packet into the receiver side of the module. Will be placed
// in the
// jitter buffer waiting for the frame to become complete. Returns as soon as
// the packet
// has been placed in the jitter buffer.
//
// Input:
// - incomingPayload : Payload of the packet.
// - payloadLength : Length of the payload.
// - rtpInfo : The parsed header.
//
// Return value : VCM_OK, on success.
// < 0, on error.
virtual int32_t IncomingPacket(const uint8_t* incomingPayload,
size_t payloadLength,
const WebRtcRTPHeader& rtpInfo) = 0;
// Minimum playout delay (Used for lip-sync). This is the minimum delay
// required
// to sync with audio. Not included in VideoCodingModule::Delay()
// Defaults to 0 ms.
//
// Input:
// - minPlayoutDelayMs : Additional delay in ms.
//
// Return value : VCM_OK, on success.
// < 0, on error.
virtual int32_t SetMinimumPlayoutDelay(uint32_t minPlayoutDelayMs) = 0;
// Set the time required by the renderer to render a frame.
//
// Input:
// - timeMS : The time in ms required by the renderer to render a
// frame.
//
// Return value : VCM_OK, on success.
// < 0, on error.
virtual int32_t SetRenderDelay(uint32_t timeMS) = 0;
// The total delay desired by the VCM. Can be less than the minimum
// delay set with SetMinimumPlayoutDelay.
//
// Return value : Total delay in ms, on success.
// < 0, on error.
virtual int32_t Delay() const = 0;
// Returns the number of packets discarded by the jitter buffer due to being
// too late. This can include duplicated packets which arrived after the
// frame was sent to the decoder. Therefore packets which were prematurely
// NACKed will be counted.
virtual uint32_t DiscardedPackets() const = 0;
// Robustness APIs
// Set the receiver robustness mode. The mode decides how the receiver
// responds to losses in the stream. The type of counter-measure (soft or
// hard NACK, dual decoder, RPS, etc.) is selected through the
// robustnessMode parameter. The errorMode parameter decides if it is
// allowed to display frames corrupted by losses. Note that not all
// combinations of the two parameters are feasible. An error will be
// returned for invalid combinations.
// Input:
// - robustnessMode : selected robustness mode.
// - errorMode : selected error mode.
//
// Return value : VCM_OK, on success;
// < 0, on error.
virtual int SetReceiverRobustnessMode(ReceiverRobustness robustnessMode,
VCMDecodeErrorMode errorMode) = 0;
// Set the decode error mode. The mode decides which errors (if any) are
// allowed in decodable frames. Note that setting decode_error_mode to
// anything other than kWithErrors without enabling nack will cause
// long-term freezes (resulting from frequent key frame requests) if
// packet loss occurs.
virtual void SetDecodeErrorMode(VCMDecodeErrorMode decode_error_mode) = 0;
// Sets the maximum number of sequence numbers that we are allowed to NACK
// and the oldest sequence number that we will consider to NACK. If a
// sequence number older than |max_packet_age_to_nack| is missing
// a key frame will be requested. A key frame will also be requested if the
// time of incomplete or non-continuous frames in the jitter buffer is above
// |max_incomplete_time_ms|.
virtual void SetNackSettings(size_t max_nack_list_size,
int max_packet_age_to_nack,
int max_incomplete_time_ms) = 0;
// Setting a desired delay to the VCM receiver. Video rendering will be
// delayed by at least desired_delay_ms.
virtual int SetMinReceiverDelay(int desired_delay_ms) = 0;
virtual void RegisterPostEncodeImageCallback(
EncodedImageCallback* post_encode_callback) = 0;
// Releases pending decode calls, permitting faster thread shutdown.
virtual void TriggerDecoderShutdown() = 0;
};
} // namespace webrtc
#endif // WEBRTC_MODULES_VIDEO_CODING_INCLUDE_VIDEO_CODING_H_