blob: e5dc14eb5d414f714621921024fcd6d02c30f031 [file] [log] [blame]
Erik Språng8abd56c2018-10-01 18:47:03 +02001/*
2 * Copyright (c) 2018 The WebRTC project authors. All Rights Reserved.
3 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
Erik Språng4529fbc2018-10-12 10:30:31 +020011#ifndef API_VIDEO_CODECS_VP8_TEMPORAL_LAYERS_H_
12#define API_VIDEO_CODECS_VP8_TEMPORAL_LAYERS_H_
Erik Språng8abd56c2018-10-01 18:47:03 +020013
14#include <memory>
15#include <vector>
16
Elad Alon411b49b2019-01-29 14:05:55 +010017#include "api/video_codecs/vp8_frame_config.h"
Elad Alonf5b216a2019-01-28 14:25:17 +010018
Erik Språng8abd56c2018-10-01 18:47:03 +020019namespace webrtc {
20
21// Some notes on the prerequisites of the TemporalLayers interface.
Erik Språng4529fbc2018-10-12 10:30:31 +020022// * Vp8TemporalLayers is not thread safe, synchronization is the caller's
23// responsibility.
Erik Språng8abd56c2018-10-01 18:47:03 +020024// * The encoder is assumed to encode all frames in order, and callbacks to
25// PopulateCodecSpecific() / FrameEncoded() must happen in the same order.
26//
27// This means that in the case of pipelining encoders, it is OK to have a chain
28// of calls such as this:
29// - UpdateLayerConfig(timestampA)
30// - UpdateLayerConfig(timestampB)
31// - PopulateCodecSpecific(timestampA, ...)
32// - UpdateLayerConfig(timestampC)
Erik Språng59021ba2018-10-03 11:05:16 +020033// - OnEncodeDone(timestampA, 1234, ...)
34// - UpdateLayerConfig(timestampC)
35// - OnEncodeDone(timestampB, 0, ...)
36// - OnEncodeDone(timestampC, 1234, ...)
Erik Språng8abd56c2018-10-01 18:47:03 +020037// Note that UpdateLayerConfig() for a new frame can happen before
38// FrameEncoded() for a previous one, but calls themselves must be both
39// synchronized (e.g. run on a task queue) and in order (per type).
40
Erik Språng4529fbc2018-10-12 10:30:31 +020041// Two different flavors of temporal layers are currently available:
42// kFixedPattern uses a fixed repeating pattern of 1-4 layers.
43// kBitrateDynamic can allocate frames dynamically to 1 or 2 layers, based on
44// the bitrate produced.
45enum class Vp8TemporalLayersType { kFixedPattern, kBitrateDynamic };
Erik Språng8abd56c2018-10-01 18:47:03 +020046
philipel9df33532019-03-04 16:37:50 +010047struct CodecSpecificInfo;
Erik Språng8abd56c2018-10-01 18:47:03 +020048
49struct Vp8EncoderConfig {
50 static constexpr size_t kMaxPeriodicity = 16;
51 static constexpr size_t kMaxLayers = 5;
52
53 // Number of active temporal layers. Set to 0 if not used.
54 uint32_t ts_number_layers;
55 // Arrays of length |ts_number_layers|, indicating (cumulative) target bitrate
56 // and rate decimator (e.g. 4 if every 4th frame is in the given layer) for
57 // each active temporal layer, starting with temporal id 0.
58 uint32_t ts_target_bitrate[kMaxLayers];
59 uint32_t ts_rate_decimator[kMaxLayers];
60
61 // The periodicity of the temporal pattern. Set to 0 if not used.
62 uint32_t ts_periodicity;
63 // Array of length |ts_periodicity| indicating the sequence of temporal id's
64 // to assign to incoming frames.
65 uint32_t ts_layer_id[kMaxPeriodicity];
66
67 // Target bitrate, in bps.
68 uint32_t rc_target_bitrate;
69
70 // Clamp QP to min/max. Use 0 to disable clamping.
71 uint32_t rc_min_quantizer;
72 uint32_t rc_max_quantizer;
73};
74
75// This interface defines a way of getting the encoder settings needed to
Erik Språng4529fbc2018-10-12 10:30:31 +020076// realize a temporal layer structure.
77class Vp8TemporalLayers {
Erik Språng8abd56c2018-10-01 18:47:03 +020078 public:
Erik Språng4529fbc2018-10-12 10:30:31 +020079 virtual ~Vp8TemporalLayers() = default;
Erik Språng8abd56c2018-10-01 18:47:03 +020080
Erik Språng59021ba2018-10-03 11:05:16 +020081 // If this method returns true, the encoder is free to drop frames for
82 // instance in an effort to uphold encoding bitrate.
83 // If this return false, the encoder must not drop any frames unless:
Elad Alon411b49b2019-01-29 14:05:55 +010084 // 1. Requested to do so via Vp8FrameConfig.drop_frame
Erik Språng59021ba2018-10-03 11:05:16 +020085 // 2. The frame to be encoded is requested to be a keyframe
86 // 3. The encoded detected a large overshoot and decided to drop and then
87 // re-encode the image at a low bitrate. In this case the encoder should
88 // call OnEncodeDone() once with size = 0 to indicate drop, and then call
89 // OnEncodeDone() again when the frame has actually been encoded.
Erik Språng8abd56c2018-10-01 18:47:03 +020090 virtual bool SupportsEncoderFrameDropping() const = 0;
91
92 // New target bitrate, per temporal layer.
93 virtual void OnRatesUpdated(const std::vector<uint32_t>& bitrates_bps,
94 int framerate_fps) = 0;
95
Erik Språng59021ba2018-10-03 11:05:16 +020096 // Called by the encoder before encoding a frame. |cfg| contains the current
97 // configuration. If the TemporalLayers instance wishes any part of that
98 // to be changed before the encode step, |cfg| should be changed and then
99 // return true. If false is returned, the encoder will proceed without
100 // updating the configuration.
Erik Språng8abd56c2018-10-01 18:47:03 +0200101 virtual bool UpdateConfiguration(Vp8EncoderConfig* cfg) = 0;
102
103 // Returns the recommended VP8 encode flags needed, and moves the temporal
104 // pattern to the next frame.
105 // The timestamp may be used as both a time and a unique identifier, and so
106 // the caller must make sure no two frames use the same timestamp.
107 // The timestamp uses a 90kHz RTP clock.
Erik Språng59021ba2018-10-03 11:05:16 +0200108 // After calling this method, first call the actual encoder with the provided
109 // frame configuration, and then OnEncodeDone() below.
Elad Alon411b49b2019-01-29 14:05:55 +0100110 virtual Vp8FrameConfig UpdateLayerConfig(uint32_t rtp_timestamp) = 0;
Erik Språng8abd56c2018-10-01 18:47:03 +0200111
Erik Språng59021ba2018-10-03 11:05:16 +0200112 // Called after the encode step is done. |rtp_timestamp| must match the
113 // parameter use in the UpdateLayerConfig() call.
114 // |is_keyframe| must be true iff the encoder decided to encode this frame as
115 // a keyframe.
116 // If the encoder decided to drop this frame, |size_bytes| must be set to 0,
117 // otherwise it should indicate the size in bytes of the encoded frame.
philipel9df33532019-03-04 16:37:50 +0100118 // If |size_bytes| > 0, and |info| is not null, the TemporalLayers
119 // instance my update |info| with codec specific data such as temporal id.
Erik Språng59021ba2018-10-03 11:05:16 +0200120 // Some fields of this struct may have already been populated by the encoder,
121 // check before overwriting.
122 // If |size_bytes| > 0, |qp| should indicate the frame-level QP this frame was
123 // encoded at. If the encoder does not support extracting this, |qp| should be
124 // set to 0.
125 virtual void OnEncodeDone(uint32_t rtp_timestamp,
Erik Språng8abd56c2018-10-01 18:47:03 +0200126 size_t size_bytes,
Erik Språng59021ba2018-10-03 11:05:16 +0200127 bool is_keyframe,
128 int qp,
philipel9df33532019-03-04 16:37:50 +0100129 CodecSpecificInfo* info) = 0;
Erik Språng8abd56c2018-10-01 18:47:03 +0200130};
131
132} // namespace webrtc
133
Erik Språng4529fbc2018-10-12 10:30:31 +0200134#endif // API_VIDEO_CODECS_VP8_TEMPORAL_LAYERS_H_