diff --git a/webrtc/common_types.h b/webrtc/common_types.h index 3c79137d74..58ac57103f 100644 --- a/webrtc/common_types.h +++ b/webrtc/common_types.h @@ -566,6 +566,11 @@ struct SimulcastStream unsigned int qpMax; // minimum quality }; +enum VideoCodecMode { + kRealtimeVideo, + kScreensharing +}; + // Common video codec properties struct VideoCodec { @@ -586,6 +591,8 @@ struct VideoCodec unsigned int qpMax; unsigned char numberOfSimulcastStreams; SimulcastStream simulcastStream[kMaxSimulcastStreams]; + + VideoCodecMode mode; }; // Bandwidth over-use detector options. These are used to drive diff --git a/webrtc/modules/video_coding/codecs/vp8/temporal_layers.cc b/webrtc/modules/video_coding/codecs/vp8/default_temporal_layers.cc similarity index 91% rename from webrtc/modules/video_coding/codecs/vp8/temporal_layers.cc rename to webrtc/modules/video_coding/codecs/vp8/default_temporal_layers.cc index 2096eb5d9c..43020f737c 100644 --- a/webrtc/modules/video_coding/codecs/vp8/temporal_layers.cc +++ b/webrtc/modules/video_coding/codecs/vp8/default_temporal_layers.cc @@ -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 * 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. */ -#include "temporal_layers.h" +#include "webrtc/modules/video_coding/codecs/vp8/default_temporal_layers.h" #include #include #include -#include "modules/interface/module_common_types.h" -#include "modules/video_coding/codecs/interface/video_codec_interface.h" -#include "modules/video_coding/codecs/vp8/include/vp8_common_types.h" +#include "webrtc/modules/interface/module_common_types.h" +#include "webrtc/modules/video_coding/codecs/interface/video_codec_interface.h" +#include "webrtc/modules/video_coding/codecs/vp8/include/vp8_common_types.h" #include "vpx/vpx_encoder.h" #include "vpx/vp8cx.h" namespace webrtc { -TemporalLayers::TemporalLayers(int numberOfTemporalLayers) +DefaultTemporalLayers::DefaultTemporalLayers(int numberOfTemporalLayers, + uint8_t initial_tl0_pic_idx) : number_of_temporal_layers_(numberOfTemporalLayers), temporal_ids_length_(0), temporal_pattern_length_(0), - tl0_pic_idx_(rand()), + tl0_pic_idx_(initial_tl0_pic_idx), pattern_idx_(255), timestamp_(0), last_base_layer_sync_(false) { @@ -35,8 +36,9 @@ TemporalLayers::TemporalLayers(int numberOfTemporalLayers) memset(temporal_pattern_, 0, sizeof(temporal_pattern_)); } -bool TemporalLayers::ConfigureBitrates(int bitrateKbit, - vpx_codec_enc_cfg_t* cfg) { +bool DefaultTemporalLayers::ConfigureBitrates(int bitrateKbit, + int framerate, + vpx_codec_enc_cfg_t* cfg) { switch (number_of_temporal_layers_) { case 0: case 1: @@ -156,7 +158,7 @@ bool TemporalLayers::ConfigureBitrates(int bitrateKbit, return true; } -int TemporalLayers::EncodeFlags() { +int DefaultTemporalLayers::EncodeFlags(uint32_t timestamp) { assert(number_of_temporal_layers_ > 0); assert(kMaxTemporalPattern >= temporal_pattern_length_); assert(0 < temporal_pattern_length_); @@ -228,9 +230,10 @@ int TemporalLayers::EncodeFlags() { return flags; } -void TemporalLayers::PopulateCodecSpecific(bool base_layer_sync, - CodecSpecificInfoVP8 *vp8_info, - uint32_t timestamp) { +void DefaultTemporalLayers::PopulateCodecSpecific( + bool base_layer_sync, + CodecSpecificInfoVP8 *vp8_info, + uint32_t timestamp) { assert(number_of_temporal_layers_ > 0); assert(0 < temporal_ids_length_); diff --git a/webrtc/modules/video_coding/codecs/vp8/default_temporal_layers.h b/webrtc/modules/video_coding/codecs/vp8/default_temporal_layers.h new file mode 100644 index 0000000000..6918e45273 --- /dev/null +++ b/webrtc/modules/video_coding/codecs/vp8/default_temporal_layers.h @@ -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_ diff --git a/webrtc/modules/video_coding/codecs/vp8/temporal_layers_unittest.cc b/webrtc/modules/video_coding/codecs/vp8/default_temporal_layers_unittest.cc similarity index 89% rename from webrtc/modules/video_coding/codecs/vp8/temporal_layers_unittest.cc rename to webrtc/modules/video_coding/codecs/vp8/default_temporal_layers_unittest.cc index 5c57319fc3..fe8588ad67 100644 --- a/webrtc/modules/video_coding/codecs/vp8/temporal_layers_unittest.cc +++ b/webrtc/modules/video_coding/codecs/vp8/default_temporal_layers_unittest.cc @@ -10,8 +10,8 @@ #include "gtest/gtest.h" -#include "temporal_layers.h" -#include "video_codec_interface.h" +#include "webrtc/modules/video_coding/codecs/interface/video_codec_interface.h" +#include "webrtc/modules/video_coding/codecs/vp8/default_temporal_layers.h" #include "vpx/vpx_encoder.h" #include "vpx/vp8cx.h" @@ -63,10 +63,10 @@ enum { }; TEST(TemporalLayersTest, 2Layers) { - TemporalLayers tl(2); + DefaultTemporalLayers tl(2, 0); vpx_codec_enc_cfg_t cfg; CodecSpecificInfoVP8 vp8_info; - tl.ConfigureBitrates(500, &cfg); + tl.ConfigureBitrates(500, 30, &cfg); int expected_flags[16] = { kTemporalUpdateLastAndGoldenRefAltRef, kTemporalUpdateGoldenWithoutDependencyRefAltRef, @@ -92,19 +92,21 @@ TEST(TemporalLayersTest, 2Layers) { { 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) { - EXPECT_EQ(expected_flags[i], tl.EncodeFlags()); + EXPECT_EQ(expected_flags[i], tl.EncodeFlags(timestamp)); tl.PopulateCodecSpecific(false, &vp8_info, 0); EXPECT_EQ(expected_temporal_idx[i], vp8_info.temporalIdx); EXPECT_EQ(expected_layer_sync[i], vp8_info.layerSync); + timestamp += 3000; } } TEST(TemporalLayersTest, 3Layers) { - TemporalLayers tl(3); + DefaultTemporalLayers tl(3, 0); vpx_codec_enc_cfg_t cfg; CodecSpecificInfoVP8 vp8_info; - tl.ConfigureBitrates(500, &cfg); + tl.ConfigureBitrates(500, 30, &cfg); int expected_flags[16] = { kTemporalUpdateLastAndGoldenRefAltRef, kTemporalUpdateNoneNoRefGolden, @@ -130,19 +132,21 @@ TEST(TemporalLayersTest, 3Layers) { { 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) { - EXPECT_EQ(expected_flags[i], tl.EncodeFlags()); + EXPECT_EQ(expected_flags[i], tl.EncodeFlags(timestamp)); tl.PopulateCodecSpecific(false, &vp8_info, 0); EXPECT_EQ(expected_temporal_idx[i], vp8_info.temporalIdx); EXPECT_EQ(expected_layer_sync[i], vp8_info.layerSync); + timestamp += 3000; } } TEST(TemporalLayersTest, 4Layers) { - TemporalLayers tl(4); + DefaultTemporalLayers tl(4, 0); vpx_codec_enc_cfg_t cfg; CodecSpecificInfoVP8 vp8_info; - tl.ConfigureBitrates(500, &cfg); + tl.ConfigureBitrates(500, 30, &cfg); int expected_flags[16] = { kTemporalUpdateLast, kTemporalUpdateNone, @@ -168,19 +172,21 @@ TEST(TemporalLayersTest, 4Layers) { { false, true, true, true, true, true, false, true, false, true, false, true, false, true, false, true }; + uint32_t timestamp = 0; 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); EXPECT_EQ(expected_temporal_idx[i], vp8_info.temporalIdx); EXPECT_EQ(expected_layer_sync[i], vp8_info.layerSync); + timestamp += 3000; } } TEST(TemporalLayersTest, KeyFrame) { - TemporalLayers tl(3); + DefaultTemporalLayers tl(3, 0); vpx_codec_enc_cfg_t cfg; CodecSpecificInfoVP8 vp8_info; - tl.ConfigureBitrates(500, &cfg); + tl.ConfigureBitrates(500, 30, &cfg); int expected_flags[8] = { kTemporalUpdateLastAndGoldenRefAltRef, @@ -195,13 +201,15 @@ TEST(TemporalLayersTest, KeyFrame) { int expected_temporal_idx[8] = { 0, 0, 0, 0, 0, 0, 0, 2}; + uint32_t timestamp = 0; 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); EXPECT_EQ(expected_temporal_idx[i], vp8_info.temporalIdx); 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); EXPECT_EQ(expected_temporal_idx[7], vp8_info.temporalIdx); EXPECT_EQ(true, vp8_info.layerSync); diff --git a/webrtc/modules/video_coding/codecs/vp8/temporal_layers.h b/webrtc/modules/video_coding/codecs/vp8/temporal_layers.h index 463f95e4f1..71b1cd47ed 100644 --- a/webrtc/modules/video_coding/codecs/vp8/temporal_layers.h +++ b/webrtc/modules/video_coding/codecs/vp8/temporal_layers.h @@ -7,14 +7,15 @@ * 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_ #define WEBRTC_MODULES_VIDEO_CODING_CODECS_VP8_TEMPORAL_LAYERS_H_ -#include +#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; namespace webrtc { @@ -23,64 +24,23 @@ struct CodecSpecificInfoVP8; class TemporalLayers { public: - TemporalLayers(int number_of_temporal_layers); + virtual ~TemporalLayers() {} // Returns the recommended VP8 encode flags needed. May refresh the decoder // 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, - CodecSpecificInfoVP8* vp8_info, - uint32_t timestamp); + virtual void PopulateCodecSpecific(bool base_layer_sync, + CodecSpecificInfoVP8* vp8_info, + uint32_t timestamp) = 0; - 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_; + virtual void FrameEncoded(unsigned int size, uint32_t timestamp) = 0; }; + } // namespace webrtc #endif // WEBRTC_MODULES_VIDEO_CODING_CODECS_VP8_TEMPORAL_LAYERS_H_ diff --git a/webrtc/modules/video_coding/codecs/vp8/vp8.gyp b/webrtc/modules/video_coding/codecs/vp8/vp8.gyp index a53ea29d52..6ca057ed83 100644 --- a/webrtc/modules/video_coding/codecs/vp8/vp8.gyp +++ b/webrtc/modules/video_coding/codecs/vp8/vp8.gyp @@ -25,8 +25,9 @@ 'target_name': 'webrtc_vp8', 'type': 'static_library', 'dependencies': [ - '<(webrtc_root)/system_wrappers/source/system_wrappers.gyp:system_wrappers', '<(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', @@ -54,8 +55,9 @@ }], ['use_temporal_layers==1', { 'sources': [ + 'default_temporal_layers.cc', + 'default_temporal_layers.h', 'temporal_layers.h', - 'temporal_layers.cc', ], }], ], @@ -113,8 +115,8 @@ '<(DEPTH)/third_party/libvpx/source/libvpx', ], 'sources': [ + 'default_temporal_layers_unittest.cc', 'reference_picture_selection_unittest.cc', - 'temporal_layers_unittest.cc', ], 'conditions': [ ['build_libvpx==1', { diff --git a/webrtc/modules/video_coding/codecs/vp8/vp8_impl.cc b/webrtc/modules/video_coding/codecs/vp8/vp8_impl.cc index cda90914fe..c1e7e4a37e 100644 --- a/webrtc/modules/video_coding/codecs/vp8/vp8_impl.cc +++ b/webrtc/modules/video_coding/codecs/vp8/vp8_impl.cc @@ -25,8 +25,8 @@ #include "webrtc/common_video/libyuv/include/webrtc_libyuv.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/temporal_layers.h" #include "webrtc/system_wrappers/interface/tick_util.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 #if WEBRTC_LIBVPX_VERSION >= 971 - temporal_layers_->ConfigureBitrates(new_bitrate_kbit, config_); + temporal_layers_->ConfigureBitrates(new_bitrate_kbit, new_framerate, config_); #endif codec_.maxFramerate = new_framerate; @@ -163,7 +163,7 @@ int VP8EncoderImpl::InitEncode(const VideoCodec* inst, int num_temporal_layers = inst->codecSpecific.VP8.numberOfTemporalLayers > 1 ? inst->codecSpecific.VP8.numberOfTemporalLayers : 1; assert(temporal_layers_ == NULL); - temporal_layers_ = new TemporalLayers(num_temporal_layers); + temporal_layers_ = new DefaultTemporalLayers(num_temporal_layers, rand()); #endif // random start 16 bits is enough. picture_id_ = static_cast(rand()) & 0x7FFF; @@ -190,7 +190,8 @@ int VP8EncoderImpl::InitEncode(const VideoCodec* inst, config_->rc_target_bitrate = inst->startBitrate; // in kbit/s #if WEBRTC_LIBVPX_VERSION >= 971 - temporal_layers_->ConfigureBitrates(inst->startBitrate, config_); + temporal_layers_->ConfigureBitrates(inst->startBitrate, inst->maxFramerate, + config_); #endif // setting the time base of the codec config_->g_timebase.num = 1; @@ -365,7 +366,7 @@ int VP8EncoderImpl::Encode(const I420VideoFrame& input_image, int flags = 0; #if WEBRTC_LIBVPX_VERSION >= 971 - flags |= temporal_layers_->EncodeFlags(); + flags |= temporal_layers_->EncodeFlags(input_image.timestamp()); #endif bool send_keyframe = (frame_type == kKeyFrame); if (send_keyframe) { diff --git a/webrtc/modules/video_coding/main/source/Android.mk b/webrtc/modules/video_coding/main/source/Android.mk index 2ecf45d8fd..9ebdbed9a6 100644 --- a/webrtc/modules/video_coding/main/source/Android.mk +++ b/webrtc/modules/video_coding/main/source/Android.mk @@ -23,9 +23,7 @@ LOCAL_SRC_FILES := \ content_metrics_processing.cc \ decoding_state.cc \ encoded_frame.cc \ - exp_filter.cc \ frame_buffer.cc \ - frame_dropper.cc \ generic_decoder.cc \ generic_encoder.cc \ inter_frame_delay.cc \ @@ -57,6 +55,7 @@ LOCAL_C_INCLUDES := \ $(LOCAL_PATH)/../../../.. \ $(LOCAL_PATH)/../../../../common_video/vplib/main/interface \ $(LOCAL_PATH)/../../../../common_video/interface \ + $(LOCAL_PATH)/../../utility/include \ $(LOCAL_PATH)/../../../../system_wrappers/interface LOCAL_SHARED_LIBRARIES := \ diff --git a/webrtc/modules/video_coding/main/source/media_opt_util.h b/webrtc/modules/video_coding/main/source/media_opt_util.h index 7cf97fbf28..f4a8ba49fc 100644 --- a/webrtc/modules/video_coding/main/source/media_opt_util.h +++ b/webrtc/modules/video_coding/main/source/media_opt_util.h @@ -11,15 +11,14 @@ #ifndef 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 #include +#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 { diff --git a/webrtc/modules/video_coding/main/source/media_optimization.cc b/webrtc/modules/video_coding/main/source/media_optimization.cc index dd428b457f..8836fd8ab3 100644 --- a/webrtc/modules/video_coding/main/source/media_optimization.cc +++ b/webrtc/modules/video_coding/main/source/media_optimization.cc @@ -8,11 +8,11 @@ * 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 "frame_dropper.h" -#include "qm_select.h" +#include "webrtc/modules/video_coding/utility/include/frame_dropper.h" +#include "webrtc/modules/video_coding/main/source/content_metrics_processing.h" +#include "webrtc/modules/video_coding/main/source/qm_select.h" #include "webrtc/system_wrappers/interface/clock.h" namespace webrtc { @@ -45,7 +45,7 @@ _numLayers(0) memset(_sendStatistics, 0, sizeof(_sendStatistics)); memset(_incomingFrameTimes, -1, sizeof(_incomingFrameTimes)); - _frameDropper = new VCMFrameDropper(_id); + _frameDropper = new FrameDropper; _lossProtLogic = new VCMLossProtectionLogic(_clock->TimeInMilliseconds()); _content = new VCMContentMetricsProcessing(); _qmResolution = new VCMQmResolution(); diff --git a/webrtc/modules/video_coding/main/source/media_optimization.h b/webrtc/modules/video_coding/main/source/media_optimization.h index a642c5d1a0..e0d67b1c08 100644 --- a/webrtc/modules/video_coding/main/source/media_optimization.h +++ b/webrtc/modules/video_coding/main/source/media_optimization.h @@ -24,8 +24,8 @@ enum { kBitrateMaxFrameSamples = 60 }; enum { kBitrateAverageWinMs = 1000 }; class Clock; +class FrameDropper; class VCMContentMetricsProcessing; -class VCMFrameDropper; struct VCMEncodedFrameSample { @@ -170,7 +170,7 @@ private: WebRtc_UWord16 _codecHeight; float _userFrameRate; - VCMFrameDropper* _frameDropper; + FrameDropper* _frameDropper; VCMLossProtectionLogic* _lossProtLogic; WebRtc_UWord8 _fractionLost; diff --git a/webrtc/modules/video_coding/main/source/video_coding.gypi b/webrtc/modules/video_coding/main/source/video_coding.gypi index fab85ddb08..3f5eb355b6 100644 --- a/webrtc/modules/video_coding/main/source/video_coding.gypi +++ b/webrtc/modules/video_coding/main/source/video_coding.gypi @@ -14,6 +14,7 @@ 'dependencies': [ 'webrtc_i420', '<(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_vp8_dir)/vp8.gyp:webrtc_vp8', ], @@ -42,10 +43,8 @@ 'encoded_frame.h', 'er_tables_xor.h', 'event.h', - 'exp_filter.h', 'fec_tables_xor.h', 'frame_buffer.h', - 'frame_dropper.h', 'generic_decoder.h', 'generic_encoder.h', 'inter_frame_delay.h', @@ -73,9 +72,7 @@ 'content_metrics_processing.cc', 'decoding_state.cc', 'encoded_frame.cc', - 'exp_filter.cc', 'frame_buffer.cc', - 'frame_dropper.cc', 'generic_decoder.cc', 'generic_encoder.cc', 'inter_frame_delay.cc', diff --git a/webrtc/modules/video_coding/utility/Android.mk b/webrtc/modules/video_coding/utility/Android.mk new file mode 100644 index 0000000000..4af007c682 --- /dev/null +++ b/webrtc/modules/video_coding/utility/Android.mk @@ -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) diff --git a/webrtc/modules/video_coding/main/source/exp_filter.cc b/webrtc/modules/video_coding/utility/exp_filter.cc similarity index 94% rename from webrtc/modules/video_coding/main/source/exp_filter.cc rename to webrtc/modules/video_coding/utility/exp_filter.cc index 1d6f9a7c26..44f280bc24 100644 --- a/webrtc/modules/video_coding/main/source/exp_filter.cc +++ b/webrtc/modules/video_coding/utility/exp_filter.cc @@ -8,7 +8,7 @@ * 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 diff --git a/webrtc/modules/video_coding/main/source/frame_dropper.cc b/webrtc/modules/video_coding/utility/frame_dropper.cc similarity index 91% rename from webrtc/modules/video_coding/main/source/frame_dropper.cc rename to webrtc/modules/video_coding/utility/frame_dropper.cc index 09d031c6b6..b871022d3b 100644 --- a/webrtc/modules/video_coding/main/source/frame_dropper.cc +++ b/webrtc/modules/video_coding/utility/frame_dropper.cc @@ -8,16 +8,15 @@ * be found in the AUTHORS file in the root of the source tree. */ -#include "frame_dropper.h" -#include "internal_defines.h" -#include "trace.h" +#include "webrtc/modules/video_coding/utility/include/frame_dropper.h" + +#include "webrtc/system_wrappers/interface/trace.h" namespace webrtc { -VCMFrameDropper::VCMFrameDropper(WebRtc_Word32 vcmId) +FrameDropper::FrameDropper() : -_vcmId(vcmId), _keyFrameSizeAvgKbits(0.9f), _keyFrameRatio(0.99f), _dropRatio(0.9f, 0.96f), @@ -27,7 +26,7 @@ _enabled(true) } void -VCMFrameDropper::Reset() +FrameDropper::Reset() { _keyFrameRatio.Reset(0.99f); _keyFrameRatio.Apply(1.0f, 1.0f/300.0f); // 1 key frame every 10th second in 30 fps @@ -52,13 +51,13 @@ VCMFrameDropper::Reset() } void -VCMFrameDropper::Enable(bool enable) +FrameDropper::Enable(bool enable) { _enabled = enable; } void -VCMFrameDropper::Fill(WebRtc_UWord32 frameSizeBytes, bool deltaFrame) +FrameDropper::Fill(WebRtc_UWord32 frameSizeBytes, bool deltaFrame) { if (!_enabled) { @@ -106,7 +105,7 @@ VCMFrameDropper::Fill(WebRtc_UWord32 frameSizeBytes, bool deltaFrame) } void -VCMFrameDropper::Leak(WebRtc_UWord32 inputFrameRate) +FrameDropper::Leak(WebRtc_UWord32 inputFrameRate) { if (!_enabled) { @@ -143,7 +142,7 @@ VCMFrameDropper::Leak(WebRtc_UWord32 inputFrameRate) } void -VCMFrameDropper::UpdateNack(WebRtc_UWord32 nackBytes) +FrameDropper::UpdateNack(WebRtc_UWord32 nackBytes) { if (!_enabled) { @@ -153,13 +152,13 @@ VCMFrameDropper::UpdateNack(WebRtc_UWord32 nackBytes) } void -VCMFrameDropper::FillBucket(float inKbits, float outKbits) +FrameDropper::FillBucket(float inKbits, float outKbits) { _accumulator += (inKbits - outKbits); } void -VCMFrameDropper::UpdateRatio() +FrameDropper::UpdateRatio() { if (_accumulator > 1.3f * _accumulatorMax) { @@ -198,13 +197,12 @@ VCMFrameDropper::UpdateRatio() _accumulator = 0.0f; } _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 // to smooth out the drops over time. bool -VCMFrameDropper::DropFrame() +FrameDropper::DropFrame() { if (!_enabled) { @@ -313,7 +311,7 @@ VCMFrameDropper::DropFrame() } void -VCMFrameDropper::SetRates(float bitRate, float incoming_frame_rate) +FrameDropper::SetRates(float bitRate, float incoming_frame_rate) { // Bit rate of -1 means infinite bandwidth. _accumulatorMax = bitRate * _windowSize; // bitRate * windowSize (in seconds) @@ -328,7 +326,7 @@ VCMFrameDropper::SetRates(float bitRate, float incoming_frame_rate) } float -VCMFrameDropper::ActualFrameRate(WebRtc_UWord32 inputFrameRate) const +FrameDropper::ActualFrameRate(WebRtc_UWord32 inputFrameRate) const { 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. // This is a temporary fix for screencasting where very large frames from // encoder will cause very slow response (too many frame drops). -void VCMFrameDropper::CapAccumulator() { +void FrameDropper::CapAccumulator() { float max_accumulator = _targetBitRate * _cap_buffer_size; if (_accumulator > max_accumulator) { _accumulator = max_accumulator; diff --git a/webrtc/modules/video_coding/main/source/exp_filter.h b/webrtc/modules/video_coding/utility/include/exp_filter.h similarity index 88% rename from webrtc/modules/video_coding/main/source/exp_filter.h rename to webrtc/modules/video_coding/utility/include/exp_filter.h index 46d206a1f5..42fbe3f019 100644 --- a/webrtc/modules/video_coding/main/source/exp_filter.h +++ b/webrtc/modules/video_coding/utility/include/exp_filter.h @@ -8,8 +8,8 @@ * be found in the AUTHORS file in the root of the source tree. */ -#ifndef WEBRTC_MODULES_VIDEO_CODING_EXP_FILTER_H_ -#define WEBRTC_MODULES_VIDEO_CODING_EXP_FILTER_H_ +#ifndef WEBRTC_MODULES_VIDEO_CODING_UTILITY_INCLUDE_EXP_FILTER_H_ +#define WEBRTC_MODULES_VIDEO_CODING_UTILITY_INCLUDE_EXP_FILTER_H_ namespace webrtc { @@ -55,4 +55,4 @@ private: } // namespace webrtc -#endif // WEBRTC_MODULES_VIDEO_CODING_EXP_FILTER_H_ +#endif // WEBRTC_MODULES_VIDEO_CODING_UTILITY_INCLUDE_EXP_FILTER_H_ diff --git a/webrtc/modules/video_coding/main/source/frame_dropper.h b/webrtc/modules/video_coding/utility/include/frame_dropper.h similarity index 78% rename from webrtc/modules/video_coding/main/source/frame_dropper.h rename to webrtc/modules/video_coding/utility/include/frame_dropper.h index fdf024ca83..fd15dd0872 100644 --- a/webrtc/modules/video_coding/main/source/frame_dropper.h +++ b/webrtc/modules/video_coding/utility/include/frame_dropper.h @@ -8,37 +8,36 @@ * be found in the AUTHORS file in the root of the source tree. */ -#ifndef WEBRTC_MODULES_VIDEO_CODING_FRAME_DROPPER_H_ -#define WEBRTC_MODULES_VIDEO_CODING_FRAME_DROPPER_H_ +#ifndef WEBRTC_MODULES_VIDEO_CODING_UTILITY_INCLUDE_FRAME_DROPPER_H_ +#define WEBRTC_MODULES_VIDEO_CODING_UTILITY_INCLUDE_FRAME_DROPPER_H_ -#include "exp_filter.h" -#include "typedefs.h" +#include "webrtc/modules/video_coding/utility/include/exp_filter.h" +#include "webrtc/typedefs.h" namespace webrtc { -/******************************/ -/* VCMFrameDropper class */ -/****************************/ // The Frame Dropper implements a variant of the leaky bucket algorithm // for keeping track of when to drop frames to avoid bit rate // over use when the encoder can't keep its bit rate. -class VCMFrameDropper +class FrameDropper { public: - VCMFrameDropper(WebRtc_Word32 vcmId = 0); + FrameDropper(); + virtual ~FrameDropper() {} + // Resets the FrameDropper to its initial state. // This means that the frameRateWeight is set to its // 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 // if we want to reach a given frame rate. Must be // called for every 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 // frame. The FrameDropper calculates a new drop ratio (can be // seen as the probability to drop a frame) and updates its @@ -49,9 +48,9 @@ public: // returned from the encoder. // - deltaFrame : True if the encoder returned // 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); @@ -60,12 +59,12 @@ public: // // Input: // - 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 // if the DropFrame() function is used as // instruction of when to drop frames. - float ActualFrameRate(WebRtc_UWord32 inputFrameRate) const; + virtual float ActualFrameRate(WebRtc_UWord32 inputFrameRate) const; private: @@ -73,7 +72,6 @@ private: void UpdateRatio(); void CapAccumulator(); - WebRtc_Word32 _vcmId; VCMExpFilter _keyFrameSizeAvgKbits; VCMExpFilter _keyFrameRatio; float _keyFrameSpreadFrames; @@ -95,4 +93,4 @@ private: } // namespace webrtc -#endif // WEBRTC_MODULES_VIDEO_CODING_FRAME_DROPPER_H_ +#endif // WEBRTC_MODULES_VIDEO_CODING_UTILITY_INCLUDE_FRAME_DROPPER_H_ diff --git a/webrtc/modules/video_coding/utility/include/mock/mock_frame_dropper.h b/webrtc/modules/video_coding/utility/include/mock/mock_frame_dropper.h new file mode 100644 index 0000000000..e8a6acc575 --- /dev/null +++ b/webrtc/modules/video_coding/utility/include/mock/mock_frame_dropper.h @@ -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 + +#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_ diff --git a/webrtc/modules/video_coding/utility/video_coding_utility.gyp b/webrtc/modules/video_coding/utility/video_coding_utility.gyp new file mode 100644 index 0000000000..24f88800e9 --- /dev/null +++ b/webrtc/modules/video_coding/utility/video_coding_utility.gyp @@ -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 +} diff --git a/webrtc/video_engine/test/android/jni/Android.mk b/webrtc/video_engine/test/android/jni/Android.mk index 9daef6aae9..55eae39f70 100644 --- a/webrtc/video_engine/test/android/jni/Android.mk +++ b/webrtc/video_engine/test/android/jni/Android.mk @@ -248,6 +248,12 @@ LOCAL_SRC_FILES := \ $(MY_LIBS_PATH)/libwebrtc_vp8.a 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) LOCAL_MODULE := libjpeg_turbo LOCAL_SRC_FILES := \ @@ -348,6 +354,7 @@ LOCAL_STATIC_LIBRARIES := \ libyuv \ libwebrtc_i420 \ libwebrtc_vp8 \ + libvideo_coding_utility \ libsystem_wrappers \ libjpeg_turbo \ libaudioproc_debug_proto \