blob: 93ed6dab45ae225ed24c60ede577ca9f1f7c27a1 [file] [log] [blame]
Elad Alonde3360e2019-03-06 21:14:54 +01001/*
2 * Copyright (c) 2019 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
11#ifndef API_VIDEO_CODECS_VP8_FRAME_BUFFER_CONTROLLER_H_
12#define API_VIDEO_CODECS_VP8_FRAME_BUFFER_CONTROLLER_H_
13
14#include <vector>
15
16#include "api/video_codecs/vp8_frame_config.h"
17
18namespace webrtc {
19
20// Some notes on the prerequisites of the TemporalLayers interface.
21// * Vp8FrameBufferController is not thread safe, synchronization is the
22// caller's responsibility.
23// * The encoder is assumed to encode all frames in order, and callbacks to
24// PopulateCodecSpecific() / FrameEncoded() must happen in the same order.
25//
26// This means that in the case of pipelining encoders, it is OK to have a chain
27// of calls such as this:
28// - UpdateLayerConfig(timestampA)
29// - UpdateLayerConfig(timestampB)
30// - PopulateCodecSpecific(timestampA, ...)
31// - UpdateLayerConfig(timestampC)
32// - OnEncodeDone(timestampA, 1234, ...)
33// - UpdateLayerConfig(timestampC)
34// - OnEncodeDone(timestampB, 0, ...)
35// - OnEncodeDone(timestampC, 1234, ...)
36// Note that UpdateLayerConfig() for a new frame can happen before
37// FrameEncoded() for a previous one, but calls themselves must be both
38// synchronized (e.g. run on a task queue) and in order (per type).
39
40struct CodecSpecificInfo;
41
42struct Vp8EncoderConfig {
43 static constexpr size_t kMaxPeriodicity = 16;
44 static constexpr size_t kMaxLayers = 5;
45
46 // Number of active temporal layers. Set to 0 if not used.
47 uint32_t ts_number_layers;
48 // Arrays of length |ts_number_layers|, indicating (cumulative) target bitrate
49 // and rate decimator (e.g. 4 if every 4th frame is in the given layer) for
50 // each active temporal layer, starting with temporal id 0.
51 uint32_t ts_target_bitrate[kMaxLayers];
52 uint32_t ts_rate_decimator[kMaxLayers];
53
54 // The periodicity of the temporal pattern. Set to 0 if not used.
55 uint32_t ts_periodicity;
56 // Array of length |ts_periodicity| indicating the sequence of temporal id's
57 // to assign to incoming frames.
58 uint32_t ts_layer_id[kMaxPeriodicity];
59
60 // Target bitrate, in bps.
61 uint32_t rc_target_bitrate;
62
63 // Clamp QP to min/max. Use 0 to disable clamping.
64 uint32_t rc_min_quantizer;
65 uint32_t rc_max_quantizer;
66};
67
68// This interface defines a way of delegating the logic of buffer management.
69class Vp8FrameBufferController {
70 public:
71 virtual ~Vp8FrameBufferController() = default;
72
73 // If this method returns true, the encoder is free to drop frames for
74 // instance in an effort to uphold encoding bitrate.
75 // If this return false, the encoder must not drop any frames unless:
76 // 1. Requested to do so via Vp8FrameConfig.drop_frame
77 // 2. The frame to be encoded is requested to be a keyframe
78 // 3. The encoded detected a large overshoot and decided to drop and then
79 // re-encode the image at a low bitrate. In this case the encoder should
80 // call OnEncodeDone() once with size = 0 to indicate drop, and then call
81 // OnEncodeDone() again when the frame has actually been encoded.
82 virtual bool SupportsEncoderFrameDropping() const = 0;
83
84 // New target bitrate, per temporal layer.
85 virtual void OnRatesUpdated(const std::vector<uint32_t>& bitrates_bps,
86 int framerate_fps) = 0;
87
88 // Called by the encoder before encoding a frame. |cfg| contains the current
89 // configuration. If the TemporalLayers instance wishes any part of that
90 // to be changed before the encode step, |cfg| should be changed and then
91 // return true. If false is returned, the encoder will proceed without
92 // updating the configuration.
93 virtual bool UpdateConfiguration(Vp8EncoderConfig* cfg) = 0;
94
95 // Returns the recommended VP8 encode flags needed, and moves the temporal
96 // pattern to the next frame.
97 // The timestamp may be used as both a time and a unique identifier, and so
98 // the caller must make sure no two frames use the same timestamp.
99 // The timestamp uses a 90kHz RTP clock.
100 // After calling this method, first call the actual encoder with the provided
101 // frame configuration, and then OnEncodeDone() below.
102 virtual Vp8FrameConfig UpdateLayerConfig(uint32_t rtp_timestamp) = 0;
103
104 // Called after the encode step is done. |rtp_timestamp| must match the
105 // parameter use in the UpdateLayerConfig() call.
106 // |is_keyframe| must be true iff the encoder decided to encode this frame as
107 // a keyframe.
108 // If the encoder decided to drop this frame, |size_bytes| must be set to 0,
109 // otherwise it should indicate the size in bytes of the encoded frame.
110 // If |size_bytes| > 0, and |info| is not null, the TemporalLayers
111 // instance my update |info| with codec specific data such as temporal id.
112 // Some fields of this struct may have already been populated by the encoder,
113 // check before overwriting.
114 // If |size_bytes| > 0, |qp| should indicate the frame-level QP this frame was
115 // encoded at. If the encoder does not support extracting this, |qp| should be
116 // set to 0.
117 virtual void OnEncodeDone(uint32_t rtp_timestamp,
118 size_t size_bytes,
119 bool is_keyframe,
120 int qp,
121 CodecSpecificInfo* info) = 0;
122};
123
124} // namespace webrtc
125
126#endif // API_VIDEO_CODECS_VP8_FRAME_BUFFER_CONTROLLER_H_