Break FrameConfig out of Vp8TemporalLayers
FrameConfig is not specific to temporal layers. Anything that can control referenced/updated buffers could potentially use it. Bug: webrtc:10259 Change-Id: I04ed177ee884693798c3b69e35fd4255ce1e9062 Reviewed-on: https://webrtc-review.googlesource.com/c/120355 Reviewed-by: Erik Språng <sprang@webrtc.org> Commit-Queue: Elad Alon <eladalon@webrtc.org> Cr-Commit-Position: refs/heads/master@{#26448}
This commit is contained in:
@ -28,12 +28,15 @@ rtc_source_set("video_codecs_api") {
|
||||
"video_encoder_config.cc",
|
||||
"video_encoder_config.h",
|
||||
"video_encoder_factory.h",
|
||||
"vp8_frame_config.cc",
|
||||
"vp8_frame_config.h",
|
||||
"vp8_temporal_layers.h",
|
||||
]
|
||||
|
||||
deps = [
|
||||
"..:scoped_refptr",
|
||||
"../..:webrtc_common",
|
||||
"../../modules/video_coding:codec_globals_headers",
|
||||
"../../rtc_base:checks",
|
||||
"../../rtc_base:rtc_base_approved",
|
||||
"../../rtc_base/system:rtc_export",
|
||||
|
||||
77
api/video_codecs/vp8_frame_config.cc
Normal file
77
api/video_codecs/vp8_frame_config.cc
Normal file
@ -0,0 +1,77 @@
|
||||
/*
|
||||
* Copyright (c) 2019 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.
|
||||
*/
|
||||
|
||||
#include "api/video_codecs/vp8_frame_config.h"
|
||||
|
||||
#include "modules/video_coding/codecs/interface/common_constants.h"
|
||||
#include "rtc_base/checks.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
Vp8FrameConfig::Vp8FrameConfig() : Vp8FrameConfig(kNone, kNone, kNone, false) {}
|
||||
|
||||
Vp8FrameConfig::Vp8FrameConfig(BufferFlags last,
|
||||
BufferFlags golden,
|
||||
BufferFlags arf)
|
||||
: Vp8FrameConfig(last, golden, arf, false) {}
|
||||
|
||||
Vp8FrameConfig::Vp8FrameConfig(BufferFlags last,
|
||||
BufferFlags golden,
|
||||
BufferFlags arf,
|
||||
FreezeEntropy)
|
||||
: Vp8FrameConfig(last, golden, arf, true) {}
|
||||
|
||||
Vp8FrameConfig::Vp8FrameConfig(BufferFlags last,
|
||||
BufferFlags golden,
|
||||
BufferFlags arf,
|
||||
bool freeze_entropy)
|
||||
: drop_frame(last == BufferFlags::kNone && golden == BufferFlags::kNone &&
|
||||
arf == BufferFlags::kNone),
|
||||
last_buffer_flags(last),
|
||||
golden_buffer_flags(golden),
|
||||
arf_buffer_flags(arf),
|
||||
encoder_layer_id(0),
|
||||
packetizer_temporal_idx(kNoTemporalIdx),
|
||||
layer_sync(false),
|
||||
freeze_entropy(freeze_entropy),
|
||||
first_reference(Vp8BufferReference::kNone),
|
||||
second_reference(Vp8BufferReference::kNone) {}
|
||||
|
||||
bool Vp8FrameConfig::References(Buffer buffer) const {
|
||||
switch (buffer) {
|
||||
case Buffer::kLast:
|
||||
return (last_buffer_flags & kReference) != 0;
|
||||
case Buffer::kGolden:
|
||||
return (golden_buffer_flags & kReference) != 0;
|
||||
case Buffer::kArf:
|
||||
return (arf_buffer_flags & kReference) != 0;
|
||||
case Buffer::kCount:
|
||||
break;
|
||||
}
|
||||
RTC_NOTREACHED();
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Vp8FrameConfig::Updates(Buffer buffer) const {
|
||||
switch (buffer) {
|
||||
case Buffer::kLast:
|
||||
return (last_buffer_flags & kUpdate) != 0;
|
||||
case Buffer::kGolden:
|
||||
return (golden_buffer_flags & kUpdate) != 0;
|
||||
case Buffer::kArf:
|
||||
return (arf_buffer_flags & kUpdate) != 0;
|
||||
case Buffer::kCount:
|
||||
break;
|
||||
}
|
||||
RTC_NOTREACHED();
|
||||
return false;
|
||||
}
|
||||
|
||||
} // namespace webrtc
|
||||
92
api/video_codecs/vp8_frame_config.h
Normal file
92
api/video_codecs/vp8_frame_config.h
Normal file
@ -0,0 +1,92 @@
|
||||
/*
|
||||
* Copyright (c) 2019 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 API_VIDEO_CODECS_VP8_FRAME_CONFIG_H_
|
||||
#define API_VIDEO_CODECS_VP8_FRAME_CONFIG_H_
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
struct Vp8FrameConfig {
|
||||
enum BufferFlags : int {
|
||||
kNone = 0,
|
||||
kReference = 1,
|
||||
kUpdate = 2,
|
||||
kReferenceAndUpdate = kReference | kUpdate,
|
||||
};
|
||||
|
||||
enum FreezeEntropy { kFreezeEntropy };
|
||||
|
||||
// Defined bit-maskable reference to the three buffers available in VP8.
|
||||
enum class Vp8BufferReference : uint8_t {
|
||||
kNone = 0,
|
||||
kLast = 1,
|
||||
kGolden = 2,
|
||||
kAltref = 4
|
||||
};
|
||||
|
||||
Vp8FrameConfig();
|
||||
|
||||
Vp8FrameConfig(BufferFlags last, BufferFlags golden, BufferFlags arf);
|
||||
Vp8FrameConfig(BufferFlags last,
|
||||
BufferFlags golden,
|
||||
BufferFlags arf,
|
||||
FreezeEntropy);
|
||||
|
||||
enum class Buffer : int { kLast = 0, kGolden = 1, kArf = 2, kCount };
|
||||
|
||||
bool References(Buffer buffer) const;
|
||||
|
||||
bool Updates(Buffer buffer) const;
|
||||
|
||||
bool drop_frame;
|
||||
BufferFlags last_buffer_flags;
|
||||
BufferFlags golden_buffer_flags;
|
||||
BufferFlags arf_buffer_flags;
|
||||
|
||||
// The encoder layer ID is used to utilize the correct bitrate allocator
|
||||
// inside the encoder. It does not control references nor determine which
|
||||
// "actual" temporal layer this is. The packetizer temporal index determines
|
||||
// which layer the encoded frame should be packetized into.
|
||||
// Normally these are the same, but current temporal-layer strategies for
|
||||
// screenshare use one bitrate allocator for all layers, but attempt to
|
||||
// packetize / utilize references to split a stream into multiple layers,
|
||||
// with different quantizer settings, to hit target bitrate.
|
||||
// TODO(sprang): Screenshare layers are being reconsidered at the time of
|
||||
// writing, we might be able to remove this distinction, and have a temporal
|
||||
// layer imply both (the normal case).
|
||||
int encoder_layer_id;
|
||||
// TODO(eladalon/sprang): Move out of this class.
|
||||
int packetizer_temporal_idx;
|
||||
|
||||
// TODO(eladalon/sprang): Move out of this class.
|
||||
bool layer_sync;
|
||||
|
||||
bool freeze_entropy;
|
||||
|
||||
// Indicates in which order the encoder should search the reference buffers
|
||||
// when doing motion prediction. Set to kNone to use unspecified order. Any
|
||||
// buffer indicated here must not have the corresponding no_ref bit set.
|
||||
// If all three buffers can be reference, the one not listed here should be
|
||||
// searched last.
|
||||
Vp8BufferReference first_reference;
|
||||
Vp8BufferReference second_reference;
|
||||
|
||||
private:
|
||||
Vp8FrameConfig(BufferFlags last,
|
||||
BufferFlags golden,
|
||||
BufferFlags arf,
|
||||
bool freeze_entropy);
|
||||
};
|
||||
|
||||
} // namespace webrtc
|
||||
|
||||
#endif // API_VIDEO_CODECS_VP8_FRAME_CONFIG_H_
|
||||
@ -14,7 +14,7 @@
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
#include "rtc_base/checks.h"
|
||||
#include "api/video_codecs/vp8_frame_config.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
@ -72,111 +72,16 @@ struct Vp8EncoderConfig {
|
||||
uint32_t rc_max_quantizer;
|
||||
};
|
||||
|
||||
// Defined bit-maskable reference to the three buffers available in VP8.
|
||||
enum class Vp8BufferReference : uint8_t {
|
||||
kNone = 0,
|
||||
kLast = 1,
|
||||
kGolden = 2,
|
||||
kAltref = 4
|
||||
};
|
||||
|
||||
// This interface defines a way of getting the encoder settings needed to
|
||||
// realize a temporal layer structure.
|
||||
class Vp8TemporalLayers {
|
||||
public:
|
||||
enum BufferFlags : int {
|
||||
kNone = 0,
|
||||
kReference = 1,
|
||||
kUpdate = 2,
|
||||
kReferenceAndUpdate = kReference | kUpdate,
|
||||
};
|
||||
enum FreezeEntropy { kFreezeEntropy };
|
||||
|
||||
struct FrameConfig {
|
||||
FrameConfig();
|
||||
|
||||
FrameConfig(BufferFlags last, BufferFlags golden, BufferFlags arf);
|
||||
FrameConfig(BufferFlags last,
|
||||
BufferFlags golden,
|
||||
BufferFlags arf,
|
||||
FreezeEntropy);
|
||||
|
||||
enum class Buffer : int { kLast = 0, kGolden = 1, kArf = 2, kCount };
|
||||
|
||||
bool References(Buffer buffer) const {
|
||||
switch (buffer) {
|
||||
case Buffer::kLast:
|
||||
return (last_buffer_flags & kReference) != 0;
|
||||
case Buffer::kGolden:
|
||||
return (golden_buffer_flags & kReference) != 0;
|
||||
case Buffer::kArf:
|
||||
return (arf_buffer_flags & kReference) != 0;
|
||||
case Buffer::kCount:
|
||||
break;
|
||||
}
|
||||
RTC_NOTREACHED();
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Updates(Buffer buffer) const {
|
||||
switch (buffer) {
|
||||
case Buffer::kLast:
|
||||
return (last_buffer_flags & kUpdate) != 0;
|
||||
case Buffer::kGolden:
|
||||
return (golden_buffer_flags & kUpdate) != 0;
|
||||
case Buffer::kArf:
|
||||
return (arf_buffer_flags & kUpdate) != 0;
|
||||
case Buffer::kCount:
|
||||
break;
|
||||
}
|
||||
RTC_NOTREACHED();
|
||||
return false;
|
||||
}
|
||||
|
||||
bool drop_frame;
|
||||
BufferFlags last_buffer_flags;
|
||||
BufferFlags golden_buffer_flags;
|
||||
BufferFlags arf_buffer_flags;
|
||||
|
||||
// The encoder layer ID is used to utilize the correct bitrate allocator
|
||||
// inside the encoder. It does not control references nor determine which
|
||||
// "actual" temporal layer this is. The packetizer temporal index determines
|
||||
// which layer the encoded frame should be packetized into.
|
||||
// Normally these are the same, but current temporal-layer strategies for
|
||||
// screenshare use one bitrate allocator for all layers, but attempt to
|
||||
// packetize / utilize references to split a stream into multiple layers,
|
||||
// with different quantizer settings, to hit target bitrate.
|
||||
// TODO(pbos): Screenshare layers are being reconsidered at the time of
|
||||
// writing, we might be able to remove this distinction, and have a temporal
|
||||
// layer imply both (the normal case).
|
||||
int encoder_layer_id;
|
||||
int packetizer_temporal_idx;
|
||||
|
||||
bool layer_sync;
|
||||
|
||||
bool freeze_entropy;
|
||||
|
||||
// Indicates in which order the encoder should search the reference buffers
|
||||
// when doing motion prediction. Set to kNone to use unspecified order. Any
|
||||
// buffer indicated here must not have the corresponding no_ref bit set.
|
||||
// If all three buffers can be reference, the one not listed here should be
|
||||
// searched last.
|
||||
Vp8BufferReference first_reference;
|
||||
Vp8BufferReference second_reference;
|
||||
|
||||
private:
|
||||
FrameConfig(BufferFlags last,
|
||||
BufferFlags golden,
|
||||
BufferFlags arf,
|
||||
bool freeze_entropy);
|
||||
};
|
||||
|
||||
virtual ~Vp8TemporalLayers() = default;
|
||||
|
||||
// If this method returns true, the encoder is free to drop frames for
|
||||
// instance in an effort to uphold encoding bitrate.
|
||||
// If this return false, the encoder must not drop any frames unless:
|
||||
// 1. Requested to do so via FrameConfig.drop_frame
|
||||
// 1. Requested to do so via Vp8FrameConfig.drop_frame
|
||||
// 2. The frame to be encoded is requested to be a keyframe
|
||||
// 3. The encoded detected a large overshoot and decided to drop and then
|
||||
// re-encode the image at a low bitrate. In this case the encoder should
|
||||
@ -202,7 +107,7 @@ class Vp8TemporalLayers {
|
||||
// The timestamp uses a 90kHz RTP clock.
|
||||
// After calling this method, first call the actual encoder with the provided
|
||||
// frame configuration, and then OnEncodeDone() below.
|
||||
virtual FrameConfig UpdateLayerConfig(uint32_t rtp_timestamp) = 0;
|
||||
virtual Vp8FrameConfig UpdateLayerConfig(uint32_t rtp_timestamp) = 0;
|
||||
|
||||
// Called after the encode step is done. |rtp_timestamp| must match the
|
||||
// parameter use in the UpdateLayerConfig() call.
|
||||
|
||||
Reference in New Issue
Block a user