Refactoring temporal layers implementation and adding VideoCodecMode for easier control of codec settings.

Review URL: https://webrtc-codereview.appspot.com/1105007

git-svn-id: http://webrtc.googlecode.com/svn/trunk@3528 4adac7df-926f-26a2-2b94-8c16560cd09d
This commit is contained in:
stefan@webrtc.org 2013-02-18 14:40:18 +00:00
parent 3897255b63
commit eb91792cfd
20 changed files with 322 additions and 148 deletions

View File

@ -566,6 +566,11 @@ struct SimulcastStream
unsigned int qpMax; // minimum quality unsigned int qpMax; // minimum quality
}; };
enum VideoCodecMode {
kRealtimeVideo,
kScreensharing
};
// Common video codec properties // Common video codec properties
struct VideoCodec struct VideoCodec
{ {
@ -586,6 +591,8 @@ struct VideoCodec
unsigned int qpMax; unsigned int qpMax;
unsigned char numberOfSimulcastStreams; unsigned char numberOfSimulcastStreams;
SimulcastStream simulcastStream[kMaxSimulcastStreams]; SimulcastStream simulcastStream[kMaxSimulcastStreams];
VideoCodecMode mode;
}; };
// Bandwidth over-use detector options. These are used to drive // Bandwidth over-use detector options. These are used to drive

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. /* Copyright (c) 2013 The WebRTC project authors. All Rights Reserved.
* *
* Use of this source code is governed by a BSD-style license * 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 * that can be found in the LICENSE file in the root of the source
@ -7,26 +7,27 @@
* be found in the AUTHORS file in the root of the source tree. * be found in the AUTHORS file in the root of the source tree.
*/ */
#include "temporal_layers.h" #include "webrtc/modules/video_coding/codecs/vp8/default_temporal_layers.h"
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <cassert> #include <cassert>
#include "modules/interface/module_common_types.h" #include "webrtc/modules/interface/module_common_types.h"
#include "modules/video_coding/codecs/interface/video_codec_interface.h" #include "webrtc/modules/video_coding/codecs/interface/video_codec_interface.h"
#include "modules/video_coding/codecs/vp8/include/vp8_common_types.h" #include "webrtc/modules/video_coding/codecs/vp8/include/vp8_common_types.h"
#include "vpx/vpx_encoder.h" #include "vpx/vpx_encoder.h"
#include "vpx/vp8cx.h" #include "vpx/vp8cx.h"
namespace webrtc { namespace webrtc {
TemporalLayers::TemporalLayers(int numberOfTemporalLayers) DefaultTemporalLayers::DefaultTemporalLayers(int numberOfTemporalLayers,
uint8_t initial_tl0_pic_idx)
: number_of_temporal_layers_(numberOfTemporalLayers), : number_of_temporal_layers_(numberOfTemporalLayers),
temporal_ids_length_(0), temporal_ids_length_(0),
temporal_pattern_length_(0), temporal_pattern_length_(0),
tl0_pic_idx_(rand()), tl0_pic_idx_(initial_tl0_pic_idx),
pattern_idx_(255), pattern_idx_(255),
timestamp_(0), timestamp_(0),
last_base_layer_sync_(false) { last_base_layer_sync_(false) {
@ -35,7 +36,8 @@ TemporalLayers::TemporalLayers(int numberOfTemporalLayers)
memset(temporal_pattern_, 0, sizeof(temporal_pattern_)); memset(temporal_pattern_, 0, sizeof(temporal_pattern_));
} }
bool TemporalLayers::ConfigureBitrates(int bitrateKbit, bool DefaultTemporalLayers::ConfigureBitrates(int bitrateKbit,
int framerate,
vpx_codec_enc_cfg_t* cfg) { vpx_codec_enc_cfg_t* cfg) {
switch (number_of_temporal_layers_) { switch (number_of_temporal_layers_) {
case 0: case 0:
@ -156,7 +158,7 @@ bool TemporalLayers::ConfigureBitrates(int bitrateKbit,
return true; return true;
} }
int TemporalLayers::EncodeFlags() { int DefaultTemporalLayers::EncodeFlags(uint32_t timestamp) {
assert(number_of_temporal_layers_ > 0); assert(number_of_temporal_layers_ > 0);
assert(kMaxTemporalPattern >= temporal_pattern_length_); assert(kMaxTemporalPattern >= temporal_pattern_length_);
assert(0 < temporal_pattern_length_); assert(0 < temporal_pattern_length_);
@ -228,7 +230,8 @@ int TemporalLayers::EncodeFlags() {
return flags; return flags;
} }
void TemporalLayers::PopulateCodecSpecific(bool base_layer_sync, void DefaultTemporalLayers::PopulateCodecSpecific(
bool base_layer_sync,
CodecSpecificInfoVP8 *vp8_info, CodecSpecificInfoVP8 *vp8_info,
uint32_t timestamp) { uint32_t timestamp) {
assert(number_of_temporal_layers_ > 0); assert(number_of_temporal_layers_ > 0);

View File

@ -0,0 +1,87 @@
/* Copyright (c) 2013 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.
*/
/*
* This file defines classes for doing temporal layers with VP8.
*/
#ifndef WEBRTC_MODULES_VIDEO_CODING_CODECS_VP8_DEFAULT_TEMPORAL_LAYERS_H_
#define WEBRTC_MODULES_VIDEO_CODING_CODECS_VP8_DEFAULT_TEMPORAL_LAYERS_H_
#include "webrtc/modules/video_coding/codecs/vp8/temporal_layers.h"
namespace webrtc {
class DefaultTemporalLayers : public TemporalLayers {
public:
DefaultTemporalLayers(int number_of_temporal_layers,
uint8_t initial_tl0_pic_idx);
virtual ~DefaultTemporalLayers() {}
// Returns the recommended VP8 encode flags needed. May refresh the decoder
// and/or update the reference buffers.
virtual int EncodeFlags(uint32_t timestamp);
virtual bool ConfigureBitrates(int bitrate_kbit,
int framerate,
vpx_codec_enc_cfg_t* cfg);
virtual void PopulateCodecSpecific(bool base_layer_sync,
CodecSpecificInfoVP8* vp8_info,
uint32_t timestamp);
virtual void FrameEncoded(unsigned int size, uint32_t timestamp) {}
private:
enum TemporalReferences {
// For 1 layer case: reference all (last, golden, and alt ref), but only
// update last.
kTemporalUpdateLastRefAll = 12,
// First base layer frame for 3 temporal layers, which updates last and
// golden with alt ref dependency.
kTemporalUpdateLastAndGoldenRefAltRef = 11,
// First enhancement layer with alt ref dependency.
kTemporalUpdateGoldenRefAltRef = 10,
// First enhancement layer with alt ref dependency.
kTemporalUpdateGoldenWithoutDependencyRefAltRef = 9,
// Base layer with alt ref dependency.
kTemporalUpdateLastRefAltRef = 8,
// Highest enhacement layer without dependency on golden with alt ref
// dependency.
kTemporalUpdateNoneNoRefGoldenRefAltRef = 7,
// Second layer and last frame in cycle, for 2 layers.
kTemporalUpdateNoneNoRefAltref = 6,
// Highest enhancement layer.
kTemporalUpdateNone = 5,
// Second enhancement layer.
kTemporalUpdateAltref = 4,
// Second enhancement layer without dependency on previous frames in
// the second enhancement layer.
kTemporalUpdateAltrefWithoutDependency = 3,
// First enhancement layer.
kTemporalUpdateGolden = 2,
// First enhancement layer without dependency on previous frames in
// the first enhancement layer.
kTemporalUpdateGoldenWithoutDependency = 1,
// Base layer.
kTemporalUpdateLast = 0,
};
enum { kMaxTemporalPattern = 16 };
int number_of_temporal_layers_;
int temporal_ids_length_;
int temporal_ids_[kMaxTemporalPattern];
int temporal_pattern_length_;
TemporalReferences temporal_pattern_[kMaxTemporalPattern];
uint8_t tl0_pic_idx_;
uint8_t pattern_idx_;
uint32_t timestamp_;
bool last_base_layer_sync_;
};
} // namespace webrtc
#endif // WEBRTC_MODULES_VIDEO_CODING_CODECS_VP8_DEFAULT_TEMPORAL_LAYERS_H_

View File

@ -10,8 +10,8 @@
#include "gtest/gtest.h" #include "gtest/gtest.h"
#include "temporal_layers.h" #include "webrtc/modules/video_coding/codecs/interface/video_codec_interface.h"
#include "video_codec_interface.h" #include "webrtc/modules/video_coding/codecs/vp8/default_temporal_layers.h"
#include "vpx/vpx_encoder.h" #include "vpx/vpx_encoder.h"
#include "vpx/vp8cx.h" #include "vpx/vp8cx.h"
@ -63,10 +63,10 @@ enum {
}; };
TEST(TemporalLayersTest, 2Layers) { TEST(TemporalLayersTest, 2Layers) {
TemporalLayers tl(2); DefaultTemporalLayers tl(2, 0);
vpx_codec_enc_cfg_t cfg; vpx_codec_enc_cfg_t cfg;
CodecSpecificInfoVP8 vp8_info; CodecSpecificInfoVP8 vp8_info;
tl.ConfigureBitrates(500, &cfg); tl.ConfigureBitrates(500, 30, &cfg);
int expected_flags[16] = { kTemporalUpdateLastAndGoldenRefAltRef, int expected_flags[16] = { kTemporalUpdateLastAndGoldenRefAltRef,
kTemporalUpdateGoldenWithoutDependencyRefAltRef, kTemporalUpdateGoldenWithoutDependencyRefAltRef,
@ -92,19 +92,21 @@ TEST(TemporalLayersTest, 2Layers) {
{ false, true, false, false, false, false, false, false, { false, true, false, false, false, false, false, false,
false, true, false, false, false, false, false, false }; false, true, false, false, false, false, false, false };
uint32_t timestamp = 0;
for (int i = 0; i < 16; ++i) { for (int i = 0; i < 16; ++i) {
EXPECT_EQ(expected_flags[i], tl.EncodeFlags()); EXPECT_EQ(expected_flags[i], tl.EncodeFlags(timestamp));
tl.PopulateCodecSpecific(false, &vp8_info, 0); tl.PopulateCodecSpecific(false, &vp8_info, 0);
EXPECT_EQ(expected_temporal_idx[i], vp8_info.temporalIdx); EXPECT_EQ(expected_temporal_idx[i], vp8_info.temporalIdx);
EXPECT_EQ(expected_layer_sync[i], vp8_info.layerSync); EXPECT_EQ(expected_layer_sync[i], vp8_info.layerSync);
timestamp += 3000;
} }
} }
TEST(TemporalLayersTest, 3Layers) { TEST(TemporalLayersTest, 3Layers) {
TemporalLayers tl(3); DefaultTemporalLayers tl(3, 0);
vpx_codec_enc_cfg_t cfg; vpx_codec_enc_cfg_t cfg;
CodecSpecificInfoVP8 vp8_info; CodecSpecificInfoVP8 vp8_info;
tl.ConfigureBitrates(500, &cfg); tl.ConfigureBitrates(500, 30, &cfg);
int expected_flags[16] = { kTemporalUpdateLastAndGoldenRefAltRef, int expected_flags[16] = { kTemporalUpdateLastAndGoldenRefAltRef,
kTemporalUpdateNoneNoRefGolden, kTemporalUpdateNoneNoRefGolden,
@ -130,19 +132,21 @@ TEST(TemporalLayersTest, 3Layers) {
{ false, true, true, false, false, false, false, false, { false, true, true, false, false, false, false, false,
false, true, true, false, false, false, false, false }; false, true, true, false, false, false, false, false };
unsigned int timestamp = 0;
for (int i = 0; i < 16; ++i) { for (int i = 0; i < 16; ++i) {
EXPECT_EQ(expected_flags[i], tl.EncodeFlags()); EXPECT_EQ(expected_flags[i], tl.EncodeFlags(timestamp));
tl.PopulateCodecSpecific(false, &vp8_info, 0); tl.PopulateCodecSpecific(false, &vp8_info, 0);
EXPECT_EQ(expected_temporal_idx[i], vp8_info.temporalIdx); EXPECT_EQ(expected_temporal_idx[i], vp8_info.temporalIdx);
EXPECT_EQ(expected_layer_sync[i], vp8_info.layerSync); EXPECT_EQ(expected_layer_sync[i], vp8_info.layerSync);
timestamp += 3000;
} }
} }
TEST(TemporalLayersTest, 4Layers) { TEST(TemporalLayersTest, 4Layers) {
TemporalLayers tl(4); DefaultTemporalLayers tl(4, 0);
vpx_codec_enc_cfg_t cfg; vpx_codec_enc_cfg_t cfg;
CodecSpecificInfoVP8 vp8_info; CodecSpecificInfoVP8 vp8_info;
tl.ConfigureBitrates(500, &cfg); tl.ConfigureBitrates(500, 30, &cfg);
int expected_flags[16] = { int expected_flags[16] = {
kTemporalUpdateLast, kTemporalUpdateLast,
kTemporalUpdateNone, kTemporalUpdateNone,
@ -168,19 +172,21 @@ TEST(TemporalLayersTest, 4Layers) {
{ false, true, true, true, true, true, false, true, { false, true, true, true, true, true, false, true,
false, true, false, true, false, true, false, true }; false, true, false, true, false, true, false, true };
uint32_t timestamp = 0;
for (int i = 0; i < 16; ++i) { for (int i = 0; i < 16; ++i) {
EXPECT_EQ(expected_flags[i], tl.EncodeFlags()); EXPECT_EQ(expected_flags[i], tl.EncodeFlags(timestamp));
tl.PopulateCodecSpecific(false, &vp8_info, 0); tl.PopulateCodecSpecific(false, &vp8_info, 0);
EXPECT_EQ(expected_temporal_idx[i], vp8_info.temporalIdx); EXPECT_EQ(expected_temporal_idx[i], vp8_info.temporalIdx);
EXPECT_EQ(expected_layer_sync[i], vp8_info.layerSync); EXPECT_EQ(expected_layer_sync[i], vp8_info.layerSync);
timestamp += 3000;
} }
} }
TEST(TemporalLayersTest, KeyFrame) { TEST(TemporalLayersTest, KeyFrame) {
TemporalLayers tl(3); DefaultTemporalLayers tl(3, 0);
vpx_codec_enc_cfg_t cfg; vpx_codec_enc_cfg_t cfg;
CodecSpecificInfoVP8 vp8_info; CodecSpecificInfoVP8 vp8_info;
tl.ConfigureBitrates(500, &cfg); tl.ConfigureBitrates(500, 30, &cfg);
int expected_flags[8] = { int expected_flags[8] = {
kTemporalUpdateLastAndGoldenRefAltRef, kTemporalUpdateLastAndGoldenRefAltRef,
@ -195,13 +201,15 @@ TEST(TemporalLayersTest, KeyFrame) {
int expected_temporal_idx[8] = int expected_temporal_idx[8] =
{ 0, 0, 0, 0, 0, 0, 0, 2}; { 0, 0, 0, 0, 0, 0, 0, 2};
uint32_t timestamp = 0;
for (int i = 0; i < 7; ++i) { for (int i = 0; i < 7; ++i) {
EXPECT_EQ(expected_flags[i], tl.EncodeFlags()); EXPECT_EQ(expected_flags[i], tl.EncodeFlags(timestamp));
tl.PopulateCodecSpecific(true, &vp8_info, 0); tl.PopulateCodecSpecific(true, &vp8_info, 0);
EXPECT_EQ(expected_temporal_idx[i], vp8_info.temporalIdx); EXPECT_EQ(expected_temporal_idx[i], vp8_info.temporalIdx);
EXPECT_EQ(true, vp8_info.layerSync); EXPECT_EQ(true, vp8_info.layerSync);
timestamp += 3000;
} }
EXPECT_EQ(expected_flags[7], tl.EncodeFlags()); EXPECT_EQ(expected_flags[7], tl.EncodeFlags(timestamp));
tl.PopulateCodecSpecific(false, &vp8_info, 0); tl.PopulateCodecSpecific(false, &vp8_info, 0);
EXPECT_EQ(expected_temporal_idx[7], vp8_info.temporalIdx); EXPECT_EQ(expected_temporal_idx[7], vp8_info.temporalIdx);
EXPECT_EQ(true, vp8_info.layerSync); EXPECT_EQ(true, vp8_info.layerSync);

View File

@ -7,14 +7,15 @@
* be found in the AUTHORS file in the root of the source tree. * be found in the AUTHORS file in the root of the source tree.
*/ */
/* /*
* This file defines classes for doing temporal layers with VP8. * This file defines the interface for doing temporal layers with VP8.
*/ */
#ifndef WEBRTC_MODULES_VIDEO_CODING_CODECS_VP8_TEMPORAL_LAYERS_H_ #ifndef WEBRTC_MODULES_VIDEO_CODING_CODECS_VP8_TEMPORAL_LAYERS_H_
#define WEBRTC_MODULES_VIDEO_CODING_CODECS_VP8_TEMPORAL_LAYERS_H_ #define WEBRTC_MODULES_VIDEO_CODING_CODECS_VP8_TEMPORAL_LAYERS_H_
#include <typedefs.h> #include "webrtc/common_video/interface/video_image.h"
#include "webrtc/typedefs.h"
// VPX forward declaration // libvpx forward declaration.
typedef struct vpx_codec_enc_cfg vpx_codec_enc_cfg_t; typedef struct vpx_codec_enc_cfg vpx_codec_enc_cfg_t;
namespace webrtc { namespace webrtc {
@ -23,64 +24,23 @@ struct CodecSpecificInfoVP8;
class TemporalLayers { class TemporalLayers {
public: public:
TemporalLayers(int number_of_temporal_layers); virtual ~TemporalLayers() {}
// Returns the recommended VP8 encode flags needed. May refresh the decoder // Returns the recommended VP8 encode flags needed. May refresh the decoder
// and/or update the reference buffers. // and/or update the reference buffers.
int EncodeFlags(); virtual int EncodeFlags(uint32_t timestamp) = 0;
bool ConfigureBitrates(int bitrate_kbit, vpx_codec_enc_cfg_t* cfg); virtual bool ConfigureBitrates(int bitrate_kbit,
int framerate,
vpx_codec_enc_cfg_t* cfg) = 0;
void PopulateCodecSpecific(bool base_layer_sync, virtual void PopulateCodecSpecific(bool base_layer_sync,
CodecSpecificInfoVP8* vp8_info, CodecSpecificInfoVP8* vp8_info,
uint32_t timestamp); uint32_t timestamp) = 0;
private: virtual void FrameEncoded(unsigned int size, uint32_t timestamp) = 0;
enum TemporalReferences {
// For 1 layer case: reference all (last, golden, and alt ref), but only
// update last.
kTemporalUpdateLastRefAll = 12,
// First base layer frame for 3 temporal layers, which updates last and
// golden with alt ref dependency.
kTemporalUpdateLastAndGoldenRefAltRef = 11,
// First enhancement layer with alt ref dependency.
kTemporalUpdateGoldenRefAltRef = 10,
// First enhancement layer with alt ref dependency.
kTemporalUpdateGoldenWithoutDependencyRefAltRef = 9,
// Base layer with alt ref dependency.
kTemporalUpdateLastRefAltRef = 8,
// Highest enhacement layer without dependency on golden with alt ref
// dependency.
kTemporalUpdateNoneNoRefGoldenRefAltRef = 7,
// Second layer and last frame in cycle, for 2 layers.
kTemporalUpdateNoneNoRefAltref = 6,
// Highest enhancement layer.
kTemporalUpdateNone = 5,
// Second enhancement layer.
kTemporalUpdateAltref = 4,
// Second enhancement layer without dependency on previous frames in
// the second enhancement layer.
kTemporalUpdateAltrefWithoutDependency = 3,
// First enhancement layer.
kTemporalUpdateGolden = 2,
// First enhancement layer without dependency on previous frames in
// the first enhancement layer.
kTemporalUpdateGoldenWithoutDependency = 1,
// Base layer.
kTemporalUpdateLast = 0,
}; };
enum { kMaxTemporalPattern = 16 };
int number_of_temporal_layers_;
int temporal_ids_length_;
int temporal_ids_[kMaxTemporalPattern];
int temporal_pattern_length_;
TemporalReferences temporal_pattern_[kMaxTemporalPattern];
uint8_t tl0_pic_idx_;
uint8_t pattern_idx_;
uint32_t timestamp_;
bool last_base_layer_sync_;
};
} // namespace webrtc } // namespace webrtc
#endif // WEBRTC_MODULES_VIDEO_CODING_CODECS_VP8_TEMPORAL_LAYERS_H_ #endif // WEBRTC_MODULES_VIDEO_CODING_CODECS_VP8_TEMPORAL_LAYERS_H_

View File

@ -25,8 +25,9 @@
'target_name': 'webrtc_vp8', 'target_name': 'webrtc_vp8',
'type': 'static_library', 'type': 'static_library',
'dependencies': [ 'dependencies': [
'<(webrtc_root)/system_wrappers/source/system_wrappers.gyp:system_wrappers',
'<(webrtc_root)/common_video/common_video.gyp:common_video', '<(webrtc_root)/common_video/common_video.gyp:common_video',
'<(webrtc_root)/modules/video_coding/utility/video_coding_utility.gyp:video_coding_utility',
'<(webrtc_root)/system_wrappers/source/system_wrappers.gyp:system_wrappers',
], ],
'include_dirs': [ 'include_dirs': [
'include', 'include',
@ -54,8 +55,9 @@
}], }],
['use_temporal_layers==1', { ['use_temporal_layers==1', {
'sources': [ 'sources': [
'default_temporal_layers.cc',
'default_temporal_layers.h',
'temporal_layers.h', 'temporal_layers.h',
'temporal_layers.cc',
], ],
}], }],
], ],
@ -113,8 +115,8 @@
'<(DEPTH)/third_party/libvpx/source/libvpx', '<(DEPTH)/third_party/libvpx/source/libvpx',
], ],
'sources': [ 'sources': [
'default_temporal_layers_unittest.cc',
'reference_picture_selection_unittest.cc', 'reference_picture_selection_unittest.cc',
'temporal_layers_unittest.cc',
], ],
'conditions': [ 'conditions': [
['build_libvpx==1', { ['build_libvpx==1', {

View File

@ -25,8 +25,8 @@
#include "webrtc/common_video/libyuv/include/webrtc_libyuv.h" #include "webrtc/common_video/libyuv/include/webrtc_libyuv.h"
#include "webrtc/modules/interface/module_common_types.h" #include "webrtc/modules/interface/module_common_types.h"
#include "webrtc/modules/video_coding/codecs/vp8/default_temporal_layers.h"
#include "webrtc/modules/video_coding/codecs/vp8/reference_picture_selection.h" #include "webrtc/modules/video_coding/codecs/vp8/reference_picture_selection.h"
#include "webrtc/modules/video_coding/codecs/vp8/temporal_layers.h"
#include "webrtc/system_wrappers/interface/tick_util.h" #include "webrtc/system_wrappers/interface/tick_util.h"
#include "webrtc/system_wrappers/interface/trace_event.h" #include "webrtc/system_wrappers/interface/trace_event.h"
@ -113,7 +113,7 @@ int VP8EncoderImpl::SetRates(uint32_t new_bitrate_kbit,
config_->rc_target_bitrate = new_bitrate_kbit; // in kbit/s config_->rc_target_bitrate = new_bitrate_kbit; // in kbit/s
#if WEBRTC_LIBVPX_VERSION >= 971 #if WEBRTC_LIBVPX_VERSION >= 971
temporal_layers_->ConfigureBitrates(new_bitrate_kbit, config_); temporal_layers_->ConfigureBitrates(new_bitrate_kbit, new_framerate, config_);
#endif #endif
codec_.maxFramerate = new_framerate; codec_.maxFramerate = new_framerate;
@ -163,7 +163,7 @@ int VP8EncoderImpl::InitEncode(const VideoCodec* inst,
int num_temporal_layers = inst->codecSpecific.VP8.numberOfTemporalLayers > 1 ? int num_temporal_layers = inst->codecSpecific.VP8.numberOfTemporalLayers > 1 ?
inst->codecSpecific.VP8.numberOfTemporalLayers : 1; inst->codecSpecific.VP8.numberOfTemporalLayers : 1;
assert(temporal_layers_ == NULL); assert(temporal_layers_ == NULL);
temporal_layers_ = new TemporalLayers(num_temporal_layers); temporal_layers_ = new DefaultTemporalLayers(num_temporal_layers, rand());
#endif #endif
// random start 16 bits is enough. // random start 16 bits is enough.
picture_id_ = static_cast<uint16_t>(rand()) & 0x7FFF; picture_id_ = static_cast<uint16_t>(rand()) & 0x7FFF;
@ -190,7 +190,8 @@ int VP8EncoderImpl::InitEncode(const VideoCodec* inst,
config_->rc_target_bitrate = inst->startBitrate; // in kbit/s config_->rc_target_bitrate = inst->startBitrate; // in kbit/s
#if WEBRTC_LIBVPX_VERSION >= 971 #if WEBRTC_LIBVPX_VERSION >= 971
temporal_layers_->ConfigureBitrates(inst->startBitrate, config_); temporal_layers_->ConfigureBitrates(inst->startBitrate, inst->maxFramerate,
config_);
#endif #endif
// setting the time base of the codec // setting the time base of the codec
config_->g_timebase.num = 1; config_->g_timebase.num = 1;
@ -365,7 +366,7 @@ int VP8EncoderImpl::Encode(const I420VideoFrame& input_image,
int flags = 0; int flags = 0;
#if WEBRTC_LIBVPX_VERSION >= 971 #if WEBRTC_LIBVPX_VERSION >= 971
flags |= temporal_layers_->EncodeFlags(); flags |= temporal_layers_->EncodeFlags(input_image.timestamp());
#endif #endif
bool send_keyframe = (frame_type == kKeyFrame); bool send_keyframe = (frame_type == kKeyFrame);
if (send_keyframe) { if (send_keyframe) {

View File

@ -23,9 +23,7 @@ LOCAL_SRC_FILES := \
content_metrics_processing.cc \ content_metrics_processing.cc \
decoding_state.cc \ decoding_state.cc \
encoded_frame.cc \ encoded_frame.cc \
exp_filter.cc \
frame_buffer.cc \ frame_buffer.cc \
frame_dropper.cc \
generic_decoder.cc \ generic_decoder.cc \
generic_encoder.cc \ generic_encoder.cc \
inter_frame_delay.cc \ inter_frame_delay.cc \
@ -57,6 +55,7 @@ LOCAL_C_INCLUDES := \
$(LOCAL_PATH)/../../../.. \ $(LOCAL_PATH)/../../../.. \
$(LOCAL_PATH)/../../../../common_video/vplib/main/interface \ $(LOCAL_PATH)/../../../../common_video/vplib/main/interface \
$(LOCAL_PATH)/../../../../common_video/interface \ $(LOCAL_PATH)/../../../../common_video/interface \
$(LOCAL_PATH)/../../utility/include \
$(LOCAL_PATH)/../../../../system_wrappers/interface $(LOCAL_PATH)/../../../../system_wrappers/interface
LOCAL_SHARED_LIBRARIES := \ LOCAL_SHARED_LIBRARIES := \

View File

@ -11,15 +11,14 @@
#ifndef WEBRTC_MODULES_VIDEO_CODING_MEDIA_OPT_UTIL_H_ #ifndef WEBRTC_MODULES_VIDEO_CODING_MEDIA_OPT_UTIL_H_
#define WEBRTC_MODULES_VIDEO_CODING_MEDIA_OPT_UTIL_H_ #define WEBRTC_MODULES_VIDEO_CODING_MEDIA_OPT_UTIL_H_
#include "typedefs.h"
#include "trace.h"
#include "exp_filter.h"
#include "internal_defines.h"
#include "qm_select.h"
#include <cmath> #include <cmath>
#include <cstdlib> #include <cstdlib>
#include "webrtc/modules/video_coding/utility/include/exp_filter.h"
#include "webrtc/modules/video_coding/main/source/internal_defines.h"
#include "webrtc/modules/video_coding/main/source/qm_select.h"
#include "webrtc/system_wrappers/interface/trace.h"
#include "webrtc/typedefs.h"
namespace webrtc namespace webrtc
{ {

View File

@ -8,11 +8,11 @@
* be found in the AUTHORS file in the root of the source tree. * be found in the AUTHORS file in the root of the source tree.
*/ */
#include "media_optimization.h" #include "webrtc/modules/video_coding/main/source/media_optimization.h"
#include "content_metrics_processing.h" #include "webrtc/modules/video_coding/utility/include/frame_dropper.h"
#include "frame_dropper.h" #include "webrtc/modules/video_coding/main/source/content_metrics_processing.h"
#include "qm_select.h" #include "webrtc/modules/video_coding/main/source/qm_select.h"
#include "webrtc/system_wrappers/interface/clock.h" #include "webrtc/system_wrappers/interface/clock.h"
namespace webrtc { namespace webrtc {
@ -45,7 +45,7 @@ _numLayers(0)
memset(_sendStatistics, 0, sizeof(_sendStatistics)); memset(_sendStatistics, 0, sizeof(_sendStatistics));
memset(_incomingFrameTimes, -1, sizeof(_incomingFrameTimes)); memset(_incomingFrameTimes, -1, sizeof(_incomingFrameTimes));
_frameDropper = new VCMFrameDropper(_id); _frameDropper = new FrameDropper;
_lossProtLogic = new VCMLossProtectionLogic(_clock->TimeInMilliseconds()); _lossProtLogic = new VCMLossProtectionLogic(_clock->TimeInMilliseconds());
_content = new VCMContentMetricsProcessing(); _content = new VCMContentMetricsProcessing();
_qmResolution = new VCMQmResolution(); _qmResolution = new VCMQmResolution();

View File

@ -24,8 +24,8 @@ enum { kBitrateMaxFrameSamples = 60 };
enum { kBitrateAverageWinMs = 1000 }; enum { kBitrateAverageWinMs = 1000 };
class Clock; class Clock;
class FrameDropper;
class VCMContentMetricsProcessing; class VCMContentMetricsProcessing;
class VCMFrameDropper;
struct VCMEncodedFrameSample struct VCMEncodedFrameSample
{ {
@ -170,7 +170,7 @@ private:
WebRtc_UWord16 _codecHeight; WebRtc_UWord16 _codecHeight;
float _userFrameRate; float _userFrameRate;
VCMFrameDropper* _frameDropper; FrameDropper* _frameDropper;
VCMLossProtectionLogic* _lossProtLogic; VCMLossProtectionLogic* _lossProtLogic;
WebRtc_UWord8 _fractionLost; WebRtc_UWord8 _fractionLost;

View File

@ -14,6 +14,7 @@
'dependencies': [ 'dependencies': [
'webrtc_i420', 'webrtc_i420',
'<(webrtc_root)/common_video/common_video.gyp:common_video', '<(webrtc_root)/common_video/common_video.gyp:common_video',
'<(webrtc_root)/modules/video_coding/utility/video_coding_utility.gyp:video_coding_utility',
'<(webrtc_root)/system_wrappers/source/system_wrappers.gyp:system_wrappers', '<(webrtc_root)/system_wrappers/source/system_wrappers.gyp:system_wrappers',
'<(webrtc_vp8_dir)/vp8.gyp:webrtc_vp8', '<(webrtc_vp8_dir)/vp8.gyp:webrtc_vp8',
], ],
@ -42,10 +43,8 @@
'encoded_frame.h', 'encoded_frame.h',
'er_tables_xor.h', 'er_tables_xor.h',
'event.h', 'event.h',
'exp_filter.h',
'fec_tables_xor.h', 'fec_tables_xor.h',
'frame_buffer.h', 'frame_buffer.h',
'frame_dropper.h',
'generic_decoder.h', 'generic_decoder.h',
'generic_encoder.h', 'generic_encoder.h',
'inter_frame_delay.h', 'inter_frame_delay.h',
@ -73,9 +72,7 @@
'content_metrics_processing.cc', 'content_metrics_processing.cc',
'decoding_state.cc', 'decoding_state.cc',
'encoded_frame.cc', 'encoded_frame.cc',
'exp_filter.cc',
'frame_buffer.cc', 'frame_buffer.cc',
'frame_dropper.cc',
'generic_decoder.cc', 'generic_decoder.cc',
'generic_encoder.cc', 'generic_encoder.cc',
'inter_frame_delay.cc', 'inter_frame_delay.cc',

View File

@ -0,0 +1,39 @@
# Copyright (c) 2013 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.
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
include $(LOCAL_PATH)/../../../../android-webrtc.mk
LOCAL_ARM_MODE := arm
LOCAL_MODULE_CLASS := STATIC_LIBRARIES
LOCAL_MODULE := libvideo_coding_utility
LOCAL_MODULE_TAGS := optional
LOCAL_CPP_EXTENSION := .cc
LOCAL_SRC_FILES := \
exp_filter.cc \
frame_dropper.cc \
# Flags passed to both C and C++ files.
LOCAL_CFLAGS := \
$(MY_WEBRTC_COMMON_DEFS)
LOCAL_C_INCLUDES := \
$(LOCAL_PATH)/../../../../system_wrappers/interface
LOCAL_SHARED_LIBRARIES := \
libcutils \
libdl \
libstlport
ifndef NDK_ROOT
include external/stlport/libstlport.mk
endif
include $(BUILD_STATIC_LIBRARY)

View File

@ -8,7 +8,7 @@
* be found in the AUTHORS file in the root of the source tree. * be found in the AUTHORS file in the root of the source tree.
*/ */
#include "exp_filter.h" #include "webrtc/modules/video_coding/utility/include/exp_filter.h"
#include <math.h> #include <math.h>

View File

@ -8,16 +8,15 @@
* be found in the AUTHORS file in the root of the source tree. * be found in the AUTHORS file in the root of the source tree.
*/ */
#include "frame_dropper.h" #include "webrtc/modules/video_coding/utility/include/frame_dropper.h"
#include "internal_defines.h"
#include "trace.h" #include "webrtc/system_wrappers/interface/trace.h"
namespace webrtc namespace webrtc
{ {
VCMFrameDropper::VCMFrameDropper(WebRtc_Word32 vcmId) FrameDropper::FrameDropper()
: :
_vcmId(vcmId),
_keyFrameSizeAvgKbits(0.9f), _keyFrameSizeAvgKbits(0.9f),
_keyFrameRatio(0.99f), _keyFrameRatio(0.99f),
_dropRatio(0.9f, 0.96f), _dropRatio(0.9f, 0.96f),
@ -27,7 +26,7 @@ _enabled(true)
} }
void void
VCMFrameDropper::Reset() FrameDropper::Reset()
{ {
_keyFrameRatio.Reset(0.99f); _keyFrameRatio.Reset(0.99f);
_keyFrameRatio.Apply(1.0f, 1.0f/300.0f); // 1 key frame every 10th second in 30 fps _keyFrameRatio.Apply(1.0f, 1.0f/300.0f); // 1 key frame every 10th second in 30 fps
@ -52,13 +51,13 @@ VCMFrameDropper::Reset()
} }
void void
VCMFrameDropper::Enable(bool enable) FrameDropper::Enable(bool enable)
{ {
_enabled = enable; _enabled = enable;
} }
void void
VCMFrameDropper::Fill(WebRtc_UWord32 frameSizeBytes, bool deltaFrame) FrameDropper::Fill(WebRtc_UWord32 frameSizeBytes, bool deltaFrame)
{ {
if (!_enabled) if (!_enabled)
{ {
@ -106,7 +105,7 @@ VCMFrameDropper::Fill(WebRtc_UWord32 frameSizeBytes, bool deltaFrame)
} }
void void
VCMFrameDropper::Leak(WebRtc_UWord32 inputFrameRate) FrameDropper::Leak(WebRtc_UWord32 inputFrameRate)
{ {
if (!_enabled) if (!_enabled)
{ {
@ -143,7 +142,7 @@ VCMFrameDropper::Leak(WebRtc_UWord32 inputFrameRate)
} }
void void
VCMFrameDropper::UpdateNack(WebRtc_UWord32 nackBytes) FrameDropper::UpdateNack(WebRtc_UWord32 nackBytes)
{ {
if (!_enabled) if (!_enabled)
{ {
@ -153,13 +152,13 @@ VCMFrameDropper::UpdateNack(WebRtc_UWord32 nackBytes)
} }
void void
VCMFrameDropper::FillBucket(float inKbits, float outKbits) FrameDropper::FillBucket(float inKbits, float outKbits)
{ {
_accumulator += (inKbits - outKbits); _accumulator += (inKbits - outKbits);
} }
void void
VCMFrameDropper::UpdateRatio() FrameDropper::UpdateRatio()
{ {
if (_accumulator > 1.3f * _accumulatorMax) if (_accumulator > 1.3f * _accumulatorMax)
{ {
@ -198,13 +197,12 @@ VCMFrameDropper::UpdateRatio()
_accumulator = 0.0f; _accumulator = 0.0f;
} }
_wasBelowMax = _accumulator < _accumulatorMax; _wasBelowMax = _accumulator < _accumulatorMax;
WEBRTC_TRACE(webrtc::kTraceDebug, webrtc::kTraceVideoCoding, VCMId(_vcmId), "FrameDropper: dropRatio = %f accumulator = %f, accumulatorMax = %f", _dropRatio.Value(), _accumulator, _accumulatorMax);
} }
// This function signals when to drop frames to the caller. It makes use of the dropRatio // This function signals when to drop frames to the caller. It makes use of the dropRatio
// to smooth out the drops over time. // to smooth out the drops over time.
bool bool
VCMFrameDropper::DropFrame() FrameDropper::DropFrame()
{ {
if (!_enabled) if (!_enabled)
{ {
@ -313,7 +311,7 @@ VCMFrameDropper::DropFrame()
} }
void void
VCMFrameDropper::SetRates(float bitRate, float incoming_frame_rate) FrameDropper::SetRates(float bitRate, float incoming_frame_rate)
{ {
// Bit rate of -1 means infinite bandwidth. // Bit rate of -1 means infinite bandwidth.
_accumulatorMax = bitRate * _windowSize; // bitRate * windowSize (in seconds) _accumulatorMax = bitRate * _windowSize; // bitRate * windowSize (in seconds)
@ -328,7 +326,7 @@ VCMFrameDropper::SetRates(float bitRate, float incoming_frame_rate)
} }
float float
VCMFrameDropper::ActualFrameRate(WebRtc_UWord32 inputFrameRate) const FrameDropper::ActualFrameRate(WebRtc_UWord32 inputFrameRate) const
{ {
if (!_enabled) if (!_enabled)
{ {
@ -340,7 +338,7 @@ VCMFrameDropper::ActualFrameRate(WebRtc_UWord32 inputFrameRate) const
// Put a cap on the accumulator, i.e., don't let it grow beyond some level. // Put a cap on the accumulator, i.e., don't let it grow beyond some level.
// This is a temporary fix for screencasting where very large frames from // This is a temporary fix for screencasting where very large frames from
// encoder will cause very slow response (too many frame drops). // encoder will cause very slow response (too many frame drops).
void VCMFrameDropper::CapAccumulator() { void FrameDropper::CapAccumulator() {
float max_accumulator = _targetBitRate * _cap_buffer_size; float max_accumulator = _targetBitRate * _cap_buffer_size;
if (_accumulator > max_accumulator) { if (_accumulator > max_accumulator) {
_accumulator = max_accumulator; _accumulator = max_accumulator;

View File

@ -8,8 +8,8 @@
* be found in the AUTHORS file in the root of the source tree. * be found in the AUTHORS file in the root of the source tree.
*/ */
#ifndef WEBRTC_MODULES_VIDEO_CODING_EXP_FILTER_H_ #ifndef WEBRTC_MODULES_VIDEO_CODING_UTILITY_INCLUDE_EXP_FILTER_H_
#define WEBRTC_MODULES_VIDEO_CODING_EXP_FILTER_H_ #define WEBRTC_MODULES_VIDEO_CODING_UTILITY_INCLUDE_EXP_FILTER_H_
namespace webrtc namespace webrtc
{ {
@ -55,4 +55,4 @@ private:
} // namespace webrtc } // namespace webrtc
#endif // WEBRTC_MODULES_VIDEO_CODING_EXP_FILTER_H_ #endif // WEBRTC_MODULES_VIDEO_CODING_UTILITY_INCLUDE_EXP_FILTER_H_

View File

@ -8,37 +8,36 @@
* be found in the AUTHORS file in the root of the source tree. * be found in the AUTHORS file in the root of the source tree.
*/ */
#ifndef WEBRTC_MODULES_VIDEO_CODING_FRAME_DROPPER_H_ #ifndef WEBRTC_MODULES_VIDEO_CODING_UTILITY_INCLUDE_FRAME_DROPPER_H_
#define WEBRTC_MODULES_VIDEO_CODING_FRAME_DROPPER_H_ #define WEBRTC_MODULES_VIDEO_CODING_UTILITY_INCLUDE_FRAME_DROPPER_H_
#include "exp_filter.h" #include "webrtc/modules/video_coding/utility/include/exp_filter.h"
#include "typedefs.h" #include "webrtc/typedefs.h"
namespace webrtc namespace webrtc
{ {
/******************************/
/* VCMFrameDropper class */
/****************************/
// The Frame Dropper implements a variant of the leaky bucket algorithm // The Frame Dropper implements a variant of the leaky bucket algorithm
// for keeping track of when to drop frames to avoid bit rate // for keeping track of when to drop frames to avoid bit rate
// over use when the encoder can't keep its bit rate. // over use when the encoder can't keep its bit rate.
class VCMFrameDropper class FrameDropper
{ {
public: public:
VCMFrameDropper(WebRtc_Word32 vcmId = 0); FrameDropper();
virtual ~FrameDropper() {}
// Resets the FrameDropper to its initial state. // Resets the FrameDropper to its initial state.
// This means that the frameRateWeight is set to its // This means that the frameRateWeight is set to its
// default value as well. // default value as well.
void Reset(); virtual void Reset();
void Enable(bool enable); virtual void Enable(bool enable);
// Answers the question if it's time to drop a frame // Answers the question if it's time to drop a frame
// if we want to reach a given frame rate. Must be // if we want to reach a given frame rate. Must be
// called for every frame. // called for every frame.
// //
// Return value : True if we should drop the current frame // Return value : True if we should drop the current frame
bool DropFrame(); virtual bool DropFrame();
// Updates the FrameDropper with the size of the latest encoded // Updates the FrameDropper with the size of the latest encoded
// frame. The FrameDropper calculates a new drop ratio (can be // frame. The FrameDropper calculates a new drop ratio (can be
// seen as the probability to drop a frame) and updates its // seen as the probability to drop a frame) and updates its
@ -49,9 +48,9 @@ public:
// returned from the encoder. // returned from the encoder.
// - deltaFrame : True if the encoder returned // - deltaFrame : True if the encoder returned
// a key frame. // a key frame.
void Fill(WebRtc_UWord32 frameSizeBytes, bool deltaFrame); virtual void Fill(WebRtc_UWord32 frameSizeBytes, bool deltaFrame);
void Leak(WebRtc_UWord32 inputFrameRate); virtual void Leak(WebRtc_UWord32 inputFrameRate);
void UpdateNack(WebRtc_UWord32 nackBytes); void UpdateNack(WebRtc_UWord32 nackBytes);
@ -60,12 +59,12 @@ public:
// //
// Input: // Input:
// - bitRate : The target bit rate // - bitRate : The target bit rate
void SetRates(float bitRate, float incoming_frame_rate); virtual void SetRates(float bitRate, float incoming_frame_rate);
// Return value : The current average frame rate produced // Return value : The current average frame rate produced
// if the DropFrame() function is used as // if the DropFrame() function is used as
// instruction of when to drop frames. // instruction of when to drop frames.
float ActualFrameRate(WebRtc_UWord32 inputFrameRate) const; virtual float ActualFrameRate(WebRtc_UWord32 inputFrameRate) const;
private: private:
@ -73,7 +72,6 @@ private:
void UpdateRatio(); void UpdateRatio();
void CapAccumulator(); void CapAccumulator();
WebRtc_Word32 _vcmId;
VCMExpFilter _keyFrameSizeAvgKbits; VCMExpFilter _keyFrameSizeAvgKbits;
VCMExpFilter _keyFrameRatio; VCMExpFilter _keyFrameRatio;
float _keyFrameSpreadFrames; float _keyFrameSpreadFrames;
@ -95,4 +93,4 @@ private:
} // namespace webrtc } // namespace webrtc
#endif // WEBRTC_MODULES_VIDEO_CODING_FRAME_DROPPER_H_ #endif // WEBRTC_MODULES_VIDEO_CODING_UTILITY_INCLUDE_FRAME_DROPPER_H_

View File

@ -0,0 +1,41 @@
/*
* Copyright (c) 2013 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_UTILITY_INCLUDE_MOCK_MOCK_FRAME_DROPPER_H_
#define WEBRTC_MODULES_VIDEO_CODING_UTILITY_INCLUDE_MOCK_MOCK_FRAME_DROPPER_H_
#include <string>
#include "gmock/gmock.h"
#include "webrtc/modules/video_coding/utility/include/frame_dropper.h"
#include "webrtc/typedefs.h"
namespace webrtc {
class MockFrameDropper : public FrameDropper {
public:
MOCK_METHOD0(Reset,
void());
MOCK_METHOD1(Enable,
void(bool enable));
MOCK_METHOD0(DropFrame,
bool());
MOCK_METHOD2(Fill,
void(WebRtc_UWord32 frameSizeBytes, bool deltaFrame));
MOCK_METHOD1(Leak,
void(WebRtc_UWord32 inputFrameRate));
MOCK_METHOD2(SetRates,
void(float bitRate, float incoming_frame_rate));
MOCK_CONST_METHOD1(ActualFrameRate,
float(WebRtc_UWord32 inputFrameRate));
};
} // namespace webrtc
#endif // WEBRTC_MODULES_VIDEO_CODING_UTILITY_INCLUDE_MOCK_MOCK_FRAME_DROPPER_H_

View File

@ -0,0 +1,28 @@
# Copyright (c) 2013 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.
{
'includes': [
'../../../build/common.gypi',
],
'targets': [
{
'target_name': 'video_coding_utility',
'type': 'static_library',
'dependencies': [
'<(webrtc_root)/system_wrappers/source/system_wrappers.gyp:system_wrappers',
],
'sources': [
'include/exp_filter.h',
'include/frame_dropper.h',
'exp_filter.cc',
'frame_dropper.cc',
],
},
], # targets
}

View File

@ -248,6 +248,12 @@ LOCAL_SRC_FILES := \
$(MY_LIBS_PATH)/libwebrtc_vp8.a $(MY_LIBS_PATH)/libwebrtc_vp8.a
include $(PREBUILT_STATIC_LIBRARY) include $(PREBUILT_STATIC_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := libvideo_coding_utility
LOCAL_SRC_FILES := \
$(MY_LIBS_PATH)/libvideo_coding_utility.a
include $(PREBUILT_STATIC_LIBRARY)
include $(CLEAR_VARS) include $(CLEAR_VARS)
LOCAL_MODULE := libjpeg_turbo LOCAL_MODULE := libjpeg_turbo
LOCAL_SRC_FILES := \ LOCAL_SRC_FILES := \
@ -348,6 +354,7 @@ LOCAL_STATIC_LIBRARIES := \
libyuv \ libyuv \
libwebrtc_i420 \ libwebrtc_i420 \
libwebrtc_vp8 \ libwebrtc_vp8 \
libvideo_coding_utility \
libsystem_wrappers \ libsystem_wrappers \
libjpeg_turbo \ libjpeg_turbo \
libaudioproc_debug_proto \ libaudioproc_debug_proto \