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
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 2096eb5..43020f7 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 <stdlib.h>
 #include <string.h>
 #include <cassert>
 
-#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 @@
   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 @@
   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 @@
   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 0000000..6918e45
--- /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 5c57319..fe8588a 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 @@
 };
 
 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 @@
       { 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 @@
       { 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 @@
       { 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 @@
   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 463f95e..71b1cd4 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 <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;
 
 namespace webrtc {
@@ -23,64 +24,23 @@
 
 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 a53ea29..6ca057e 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 cda9091..c1e7e4a 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 @@
   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 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<uint16_t>(rand()) & 0x7FFF;
@@ -190,7 +190,8 @@
   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 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 2ecf45d..9ebdbed 100644
--- a/webrtc/modules/video_coding/main/source/Android.mk
+++ b/webrtc/modules/video_coding/main/source/Android.mk
@@ -23,9 +23,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 \
@@ -57,6 +55,7 @@
     $(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 7cf97fb..f4a8ba4 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 <cmath>
 #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
 {
diff --git a/webrtc/modules/video_coding/main/source/media_optimization.cc b/webrtc/modules/video_coding/main/source/media_optimization.cc
index dd428b4..8836fd8 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 @@
     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 a642c5d..e0d67b1 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 { kBitrateAverageWinMs    = 1000 };
 
 class Clock;
+class FrameDropper;
 class VCMContentMetricsProcessing;
-class VCMFrameDropper;
 
 struct VCMEncodedFrameSample
 {
@@ -170,7 +170,7 @@
     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 fab85dd..3f5eb35 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 0000000..4af007c
--- /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 1d6f9a7..44f280bc 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 <math.h>
 
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 09d031c..b871022 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 @@
 }
 
 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 @@
 }
 
 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 @@
 }
 
 void
-VCMFrameDropper::Leak(WebRtc_UWord32 inputFrameRate)
+FrameDropper::Leak(WebRtc_UWord32 inputFrameRate)
 {
     if (!_enabled)
     {
@@ -143,7 +142,7 @@
 }
 
 void
-VCMFrameDropper::UpdateNack(WebRtc_UWord32 nackBytes)
+FrameDropper::UpdateNack(WebRtc_UWord32 nackBytes)
 {
     if (!_enabled)
     {
@@ -153,13 +152,13 @@
 }
 
 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 @@
         _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 @@
 }
 
 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 @@
 }
 
 float
-VCMFrameDropper::ActualFrameRate(WebRtc_UWord32 inputFrameRate) const
+FrameDropper::ActualFrameRate(WebRtc_UWord32 inputFrameRate) const
 {
     if (!_enabled)
     {
@@ -340,7 +338,7 @@
 // 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 46d206a..42fbe3f 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 @@
 
 } // 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 fdf024c..fd15dd0 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 @@
     //                                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 @@
     //
     // 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 @@
     void UpdateRatio();
     void CapAccumulator();
 
-    WebRtc_Word32     _vcmId;
     VCMExpFilter       _keyFrameSizeAvgKbits;
     VCMExpFilter       _keyFrameRatio;
     float           _keyFrameSpreadFrames;
@@ -95,4 +93,4 @@
 
 } // 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 0000000..e8a6acc
--- /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 <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_
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 0000000..24f8880
--- /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
+}