summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.gitignore2
-rw-r--r--media/base/media.h8
-rw-r--r--media/base/media_posix.cc21
-rw-r--r--media/base/media_win.cc18
-rw-r--r--remoting/base/codec_test.cc5
-rw-r--r--remoting/base/encoder_vp8.cc205
-rw-r--r--remoting/base/encoder_vp8.h43
-rw-r--r--remoting/base/encoder_vp8_unittest.cc62
-rw-r--r--remoting/base/protocol/chromotocol.proto1
-rw-r--r--remoting/remoting.gyp13
-rw-r--r--remoting/run_all_unittests.cc13
-rw-r--r--third_party/libvpx/libvpx.gyp90
12 files changed, 311 insertions, 170 deletions
diff --git a/.gitignore b/.gitignore
index 23e5ad8..5790c0b 100644
--- a/.gitignore
+++ b/.gitignore
@@ -74,6 +74,8 @@
/third_party/hunspell_dictionaries
/third_party/icu
/third_party/libjingle/source
+/third_party/libvpx/lib
+/third_party/libvpx/include
/third_party/libsrtp/src
/third_party/libvpx
/third_party/lighttpd
diff --git a/media/base/media.h b/media/base/media.h
index 3d1a83a..fd3269e 100644
--- a/media/base/media.h
+++ b/media/base/media.h
@@ -25,6 +25,14 @@ bool InitializeMediaLibrary(const FilePath& module_dir);
// Returns true if OpenMAX was successfully initialized and loaded.
bool InitializeOpenMaxLibrary(const FilePath& module_dir);
+// This is temporary to get the address of vpx_codec_vp8_cx_algo in FFmpeg.
+// This method should only be called after media library is loaded.
+
+// TODO(hclam): Remove this after we have a getter function for the same
+// purpose in libvpx.
+// See bug: http://code.google.com/p/webm/issues/detail?id=169
+void* GetVp8CxAlgoAddress();
+
} // namespace media
#endif // MEDIA_BASE_MEDIA_H_
diff --git a/media/base/media_posix.cc b/media/base/media_posix.cc
index eebae5e..d5137eb 100644
--- a/media/base/media_posix.cc
+++ b/media/base/media_posix.cc
@@ -10,6 +10,7 @@
#include "base/file_path.h"
#include "base/logging.h"
+#include "base/native_library.h"
#include "base/path_service.h"
#include "media/ffmpeg/ffmpeg_common.h"
#include "third_party/ffmpeg/ffmpeg_stubs.h"
@@ -69,6 +70,9 @@ std::string GetDSOName(tp_ffmpeg::StubModules stub_key) {
} // namespace
+// Address of vpx_codec_vp8_cx_algo.
+static void* vp8_cx_algo_address = NULL;
+
// Attempts to initialize the media library (loading DSOs, etc.).
// Returns true if everything was successfully initialized, false otherwise.
bool InitializeMediaLibrary(const FilePath& module_dir) {
@@ -85,7 +89,18 @@ bool InitializeMediaLibrary(const FilePath& module_dir) {
paths[module].push_back(path.value());
}
- return tp_ffmpeg::InitializeStubs(paths);
+ bool ret = tp_ffmpeg::InitializeStubs(paths);
+
+ // TODO(hclam): This is temporary to obtain address of
+ // vpx_codec_vp8_cx_algo. This should be removed once libvpx has a
+ // getter method for it.
+ base::NativeLibrary sumo_lib =
+ base::LoadNativeLibrary(module_dir.Append(sumo_name));
+ if (sumo_lib) {
+ vp8_cx_algo_address = base::GetFunctionPointerFromNativeLibrary(
+ sumo_lib, "vpx_codec_vp8_cx_algo");
+ }
+ return ret;
}
#if defined(OS_LINUX)
@@ -114,4 +129,8 @@ bool InitializeOpenMaxLibrary(const FilePath& module_dir) {
}
#endif
+void* GetVp8CxAlgoAddress() {
+ return vp8_cx_algo_address;
+}
+
} // namespace media
diff --git a/media/base/media_win.cc b/media/base/media_win.cc
index 6f9e0f8..f31ab5b 100644
--- a/media/base/media_win.cc
+++ b/media/base/media_win.cc
@@ -8,6 +8,7 @@
#include "base/file_path.h"
#include "base/logging.h"
+#include "base/native_library.h"
#include "base/path_service.h"
#include "base/scoped_ptr.h"
@@ -47,6 +48,9 @@ FilePath::CharType* GetDLLName(FFmpegDLLKeys dll_key) {
} // namespace
+// Address of vpx_codec_vp8_cx_algo.
+static void* vp8_cx_algo_address = NULL;
+
// Attempts to initialize the media library (loading DLLs, DSOs, etc.).
// Returns true if everything was successfully initialized, false otherwise.
bool InitializeMediaLibrary(const FilePath& base_path) {
@@ -78,6 +82,16 @@ bool InitializeMediaLibrary(const FilePath& base_path) {
#endif
}
+ // TODO(hclam): This is temporary to obtain address of
+ // vpx_codec_vp8_cx_algo. This should be removed once libvpx has a
+ // getter method for it.
+ base::NativeLibrary avcodec_lib =
+ base::LoadNativeLibrary(FilePath(GetDLLName(media::FILE_LIBAVCODEC)));
+ if (avcodec_lib) {
+ vp8_cx_algo_address = base::GetFunctionPointerFromNativeLibrary(
+ avcodec_lib, "vpx_codec_vp8_cx_algo");
+ }
+
// Check that we loaded all libraries successfully. We only need to check the
// last array element because the loop above will break without initializing
// it on any prior error.
@@ -97,4 +111,8 @@ bool InitializeOpenMaxLibrary(const FilePath& module_dir) {
return false;
}
+void* GetVp8CxAlgoAddress() {
+ return vp8_cx_algo_address;
+}
+
} // namespace media
diff --git a/remoting/base/codec_test.cc b/remoting/base/codec_test.cc
index 40c42ed..e8f17ca 100644
--- a/remoting/base/codec_test.cc
+++ b/remoting/base/codec_test.cc
@@ -78,9 +78,10 @@ class EncoderMessageTester {
~EncoderMessageTester() {
EXPECT_EQ(begin_rect_, end_rect_);
+ EXPECT_GT(begin_rect_, 0);
EXPECT_EQ(kWaitingForBeginRect, state_);
- if (strict_){
- EXPECT_EQ(begin_rect_, added_rects_);
+ if (strict_) {
+ EXPECT_EQ(added_rects_, begin_rect_);
}
}
diff --git a/remoting/base/encoder_vp8.cc b/remoting/base/encoder_vp8.cc
index 231acd5..eec6ed5 100644
--- a/remoting/base/encoder_vp8.cc
+++ b/remoting/base/encoder_vp8.cc
@@ -5,129 +5,190 @@
#include "base/logging.h"
#include "media/base/callback.h"
#include "media/base/data_buffer.h"
-#include "remoting/host/encoder_vp8.h"
+#include "media/base/media.h"
+#include "remoting/base/capture_data.h"
+#include "remoting/base/encoder_vp8.h"
extern "C" {
-// TODO(garykac): Rix with correct path to vp8 header.
-#include "remoting/third_party/on2/include/vp8cx.h"
+#define VPX_CODEC_DISABLE_COMPAT 1
+#include "third_party/libvpx/include/vpx/vpx_codec.h"
+#include "third_party/libvpx/include/vpx/vpx_encoder.h"
+#include "third_party/libvpx/include/vpx/vp8cx.h"
}
namespace remoting {
EncoderVp8::EncoderVp8()
: initialized_(false),
+ codec_(NULL),
+ image_(NULL),
last_timestamp_(0) {
}
EncoderVp8::~EncoderVp8() {
+ if (initialized_) {
+ vpx_codec_err_t ret = vpx_codec_destroy(codec_.get());
+ DCHECK(ret == VPX_CODEC_OK) << "Failed to destroy codec";
+ }
}
-bool EncoderVp8::Init() {
- // TODO(hclam): Now always assume we receive YV12. May need to extend this
- // so we can do color space conversion manually.
- image_.fmt = IMG_FMT_YV12;
- image_.w = width_;
- image_.h = height_;
-
- on2_codec_enc_cfg_t config;
- on2_codec_err_t result = on2_codec_enc_config_default(&on2_codec_vp8_cx_algo,
- &config, 0);
-
- // TODO(hclam): Adjust the parameters.
- config.g_w = width_;
- config.g_h = height_;
- config.g_pass = ON2_RC_ONE_PASS;
+bool EncoderVp8::Init(int width, int height) {
+ codec_.reset(new vpx_codec_ctx_t());
+ image_.reset(new vpx_image_t());
+ memset(image_.get(), 0, sizeof(vpx_image_t));
+
+ image_->fmt = VPX_IMG_FMT_YV12;
+
+ // libvpx seems to require both to be assigned.
+ image_->d_w = width;
+ image_->w = width;
+ image_->d_h = height;
+ image_->h = height;
+
+ vpx_codec_enc_cfg_t config;
+ const vpx_codec_iface_t* algo =
+ (const vpx_codec_iface_t*)media::GetVp8CxAlgoAddress();
+ vpx_codec_err_t ret = vpx_codec_enc_config_default(algo, &config, 0);
+ if (ret != VPX_CODEC_OK)
+ return false;
+
+ // TODO(hclam): Tune the parameters to better suit the application.
+ config.rc_target_bitrate = width * height * config.rc_target_bitrate
+ / config.g_w / config.g_h;
+ config.g_w = width;
+ config.g_h = height;
+ config.g_pass = VPX_RC_ONE_PASS;
config.g_profile = 1;
config.g_threads = 2;
- config.rc_target_bitrate = 1000000;
config.rc_min_quantizer = 0;
config.rc_max_quantizer = 15;
config.g_timebase.num = 1;
config.g_timebase.den = 30;
- if (on2_codec_enc_init(&codec_, &on2_codec_vp8_cx_algo, &config, 0))
+ if (vpx_codec_enc_init(codec_.get(), algo, &config, 0))
return false;
+ return true;
+}
+
+bool EncoderVp8::PrepareImage(scoped_refptr<CaptureData> capture_data) {
+ if (!yuv_image_.get()) {
+ const int plane_size = capture_data->width() * capture_data->height();
+
+ // YUV image size is 1.5 times of a plane. Multiplication is performed first
+ // to avoid rounding error.
+ const int size = plane_size * 3 / 2;
+
+ yuv_image_.reset(new uint8[size]);
+
+ // Reset image value to 128 so we just need to fill in the y plane.
+ memset(yuv_image_.get(), 128, size);
+
+ // Fill in the information for |image_|.
+ unsigned char* image = reinterpret_cast<unsigned char*>(yuv_image_.get());
+ image_->planes[0] = image;
+ image_->planes[1] = image + plane_size;
+
+ // The V plane starts from 1.25 of the plane size.
+ image_->planes[2] = image + plane_size + plane_size / 4;
- on2_codec_control_(&codec_, VP8E_SET_CPUUSED, -15);
+ // In YV12 Y plane has full width, UV plane has half width because of
+ // subsampling.
+ image_->stride[0] = image_->w;
+ image_->stride[1] = image_->w / 2;
+ image_->stride[2] = image_->w / 2;
+ }
+
+ // And then do RGB->YUV conversion.
+ // Currently we just produce the Y channel as the average of RGB. This will
+ // give a gray scale image after conversion.
+ // TODO(hclam): Implement the actual color space conversion.
+ DCHECK(capture_data->pixel_format() == PixelFormatRgb32)
+ << "Only RGB32 is supported";
+ uint8* in = capture_data->data_planes().data[0];
+ const int in_stride = capture_data->data_planes().strides[0];
+ uint8* out = yuv_image_.get();
+ const int out_stride = image_->stride[0];
+ for (int i = 0; i < capture_data->height(); ++i) {
+ for (int j = 0; j < capture_data->width(); ++j) {
+ // Since the input pixel format is RGB32, there are 4 bytes per pixel.
+ uint8* pixel = in + 4 * j;
+ out[j] = (pixel[0] + pixel[1] + pixel[2]) / 3;
+ }
+ in += in_stride;
+ out += out_stride;
+ }
return true;
}
-void EncoderVp8::Encode(const DirtyRects& dirty_rects,
- const uint8** input_data,
- const int* strides,
+void EncoderVp8::Encode(scoped_refptr<CaptureData> capture_data,
bool key_frame,
- UpdateStreamPacketHeader* header,
- scoped_refptr<media::DataBuffer>* output_data,
- bool* encode_done,
- Task* data_available_task) {
- // This will allow the task be called when this method exits.
- media::AutoTaskRunner task(data_available_task);
- *encode_done = false;
-
- // TODO(hclam): We only initialize the encoder once. We may have to
- // allow encoder be initialized with difference sizes.
+ DataAvailableCallback* data_available_callback) {
if (!initialized_) {
- if (!Init()) {
- LOG(ERROR) << "Can't initialize VP8 encoder";
- return;
- }
- initialized_ = true;
+ bool ret = Init(capture_data->width(), capture_data->height());
+ // TODO(hclam): Handle error better.
+ DCHECK(ret) << "Initialization of encoder failed";
+ initialized_ = ret;
}
- // Assume the capturer has done the color space conversion.
- if (!input_data || !strides)
- return;
-
- image_.planes[0] = (unsigned char*)input_data[0];
- image_.planes[1] = (unsigned char*)input_data[1];
- image_.planes[2] = (unsigned char*)input_data[2];
- image_.stride[0] = strides[0];
- image_.stride[1] = strides[1];
- image_.stride[2] = strides[2];
+ if (!PrepareImage(capture_data)) {
+ NOTREACHED() << "Can't image data for encoding";
+ }
// Do the actual encoding.
- if (on2_codec_encode(&codec_, &image_,
- last_timestamp_, 1, 0, ON2_DL_REALTIME)) {
- return;
- }
+ vpx_codec_err_t ret = vpx_codec_encode(codec_.get(), image_.get(),
+ last_timestamp_,
+ 1, 0, VPX_DL_REALTIME);
+ DCHECK(ret == VPX_CODEC_OK) << "Encoding error: "
+ << vpx_codec_err_to_string(ret)
+ << "\n"
+ << "Details: "
+ << vpx_codec_error(codec_.get())
+ << "\n"
+ << vpx_codec_error_detail(codec_.get());
// TODO(hclam): fix this.
last_timestamp_ += 100;
// Read the encoded data.
- on2_codec_iter_t iter = NULL;
+ vpx_codec_iter_t iter = NULL;
bool got_data = false;
- // TODO(hclam: We assume one frame of input will get exactly one frame of
- // output. This assumption may not be valid.
+ // TODO(hclam): Make sure we get exactly one frame from the packet.
+ // TODO(hclam): We should provide the output buffer to avoid one copy.
+ ChromotingHostMessage* message = new ChromotingHostMessage();
+ UpdateStreamPacketMessage* packet = message->mutable_update_stream_packet();
+
+ // Prepare the begin rect.
+ packet->mutable_begin_rect()->set_x(0);
+ packet->mutable_begin_rect()->set_y(0);
+ packet->mutable_begin_rect()->set_width(capture_data->width());
+ packet->mutable_begin_rect()->set_height(capture_data->height());
+ packet->mutable_begin_rect()->set_encoding(EncodingVp8);
+ packet->mutable_begin_rect()->set_pixel_format(PixelFormatYv12);
+
while (!got_data) {
- on2_codec_cx_pkt_t* packet = on2_codec_get_cx_data(&codec_, &iter);
+ const vpx_codec_cx_pkt_t* packet = vpx_codec_get_cx_data(codec_.get(),
+ &iter);
if (!packet)
continue;
switch (packet->kind) {
- case ON2_CODEC_CX_FRAME_PKT:
+ case VPX_CODEC_CX_FRAME_PKT:
got_data = true;
- *encode_done = true;
- *output_data = new media::DataBuffer(packet->data.frame.sz);
- memcpy((*output_data)->GetWritableData(),
- packet->data.frame.buf,
- packet->data.frame.sz);
+ message->mutable_update_stream_packet()->mutable_rect_data()->set_data(
+ packet->data.frame.buf, packet->data.frame.sz);
break;
default:
break;
}
}
- return;
-}
-
-void EncoderVp8::SetSize(int width, int height) {
- width_ = width;
- height_ = height;
-}
-void EncoderVp8::SetPixelFormat(PixelFormat pixel_format) {
- pixel_format_ = pixel_format;
+ // Enter the end rect.
+ message->mutable_update_stream_packet()->mutable_end_rect();
+ data_available_callback->Run(
+ message,
+ EncodingStarting | EncodingInProgress | EncodingEnded);
+ delete data_available_callback;
}
} // namespace remoting
diff --git a/remoting/base/encoder_vp8.h b/remoting/base/encoder_vp8.h
index 4b8b539..ae29c63 100644
--- a/remoting/base/encoder_vp8.h
+++ b/remoting/base/encoder_vp8.h
@@ -5,20 +5,11 @@
#ifndef REMOTING_BASE_ENCODER_VP8_H_
#define REMOTING_BASE_ENCODER_VP8_H_
-#include "remoting/host/encoder.h"
-
+#include "remoting/base/encoder.h"
#include "remoting/base/protocol/chromotocol.pb.h"
-extern "C" {
-// TODO(garykac): fix this link with the correct path to on2
-#include "remoting/third_party/on2/include/on2_encoder.h"
-} // extern "C"
-
-namespace media {
-
-class DataBuffer;
-
-} // namespace media
+typedef struct vpx_codec_ctx vpx_codec_ctx_t;
+typedef struct vpx_image vpx_image_t;
namespace remoting {
@@ -28,31 +19,27 @@ class EncoderVp8 : public Encoder {
EncoderVp8();
virtual ~EncoderVp8();
- virtual void Encode(const DirtyRects& dirty_rects,
- const uint8** input_data,
- const int* strides,
+ virtual void Encode(scoped_refptr<CaptureData> capture_data,
bool key_frame,
- UpdateStreamPacketHeader* header,
- scoped_refptr<media::DataBuffer>* output_data,
- bool* encode_done,
- Task* data_available_task);
- virtual void SetSize(int width, int height);
- virtual void SetPixelFormat(PixelFormat pixel_format);
+ DataAvailableCallback* data_available_callback);
private:
- // Setup the VP8 encoder.
- bool Init();
+ // Initialize the encoder. Returns true if successful.
+ bool Init(int width, int height);
+
+ // Prepare |image_| for encoding. Returns true if successful.
+ bool PrepareImage(scoped_refptr<CaptureData> capture_data);
// True if the encoder is initialized.
bool initialized_;
- int width_;
- int height_;
- PixelFormat pixel_format_;
- on2_codec_ctx_t codec_;
- on2_image_t image_;
+ scoped_ptr<vpx_codec_ctx_t> codec_;
+ scoped_ptr<vpx_image_t> image_;
int last_timestamp_;
+ // Buffer for storing the yuv image.
+ scoped_array<uint8> yuv_image_;
+
DISALLOW_COPY_AND_ASSIGN(EncoderVp8);
};
diff --git a/remoting/base/encoder_vp8_unittest.cc b/remoting/base/encoder_vp8_unittest.cc
index 0b29830..353b82b 100644
--- a/remoting/base/encoder_vp8_unittest.cc
+++ b/remoting/base/encoder_vp8_unittest.cc
@@ -2,67 +2,15 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "media/base/data_buffer.h"
-#include "remoting/base/pixel_format.h"
-#include "remoting/host/encoder_vp8.h"
-#include "testing/gmock/include/gmock/gmock.h"
+#include "remoting/base/codec_test.h"
+#include "remoting/base/encoder_vp8.h"
+#include "testing/gtest/include/gtest/gtest.h"
namespace remoting {
-static const int kWidth = 1024;
-static const int kHeight = 768;
-static const PixelFormat kPixelFormat = kPixelFormat_YV12;
-
-static void GenerateData(uint8* data, int size) {
- for (int i = 0; i < size; ++i) {
- data[i] = i;
- }
-}
-
-class EncodeDoneHandler
- : public base::RefCountedThreadSafe<EncodeDoneHandler> {
- public:
- MOCK_METHOD0(EncodeDone, void());
-};
-
-TEST(EncoderVp8Test, SimpleEncode) {
+TEST(EncoderVp8Test, TestEncoder) {
EncoderVp8 encoder;
- encoder.SetSize(kWidth, kHeight);
- encoder.SetPixelFormat(kPixelFormat);
-
- DirtyRects rects;
- rects.push_back(gfx::Rect(kWidth, kHeight));
-
- // Prepare memory for encoding.
- int strides[3];
- strides[0] = kWidth;
- strides[1] = strides[2] = kWidth / 2;
-
- uint8* planes[3];
- planes[0] = new uint8[kWidth * kHeight];
- planes[1] = new uint8[kWidth * kHeight / 4];
- planes[2] = new uint8[kWidth * kHeight / 4];
- GenerateData(planes[0], kWidth * kHeight);
- GenerateData(planes[1], kWidth * kHeight / 4);
- GenerateData(planes[2], kWidth * kHeight / 4);
-
- scoped_refptr<EncodeDoneHandler> handler = new EncodeDoneHandler();
- UpdateStreamPacketHeader* header = new UpdateStreamPacketHeader();
- scoped_refptr<media::DataBuffer> encoded_data;
- bool encode_done = false;
- EXPECT_CALL(*handler, EncodeDone());
- encoder.Encode(rects, const_cast<const uint8**>(planes),
- strides, true, header, &encoded_data, &encode_done,
- NewRunnableMethod(handler.get(),
- &EncodeDoneHandler::EncodeDone));
-
- EXPECT_TRUE(encode_done);
- ASSERT_TRUE(encoded_data.get());
- EXPECT_NE(0u, encoded_data->GetBufferSize());
-
- delete [] planes[0];
- delete [] planes[1];
- delete [] planes[2];
+ TestEncoder(&encoder, false);
}
} // namespace remoting
diff --git a/remoting/base/protocol/chromotocol.proto b/remoting/base/protocol/chromotocol.proto
index 865fd3f..00986ac 100644
--- a/remoting/base/protocol/chromotocol.proto
+++ b/remoting/base/protocol/chromotocol.proto
@@ -34,6 +34,7 @@ enum UpdateStreamEncoding {
EncodingInvalid = -1;
EncodingNone = 0;
EncodingZlib = 1;
+ EncodingVp8 = 2;
}
// Identifies the pixel format.
diff --git a/remoting/remoting.gyp b/remoting/remoting.gyp
index 203ec43..33339cb 100644
--- a/remoting/remoting.gyp
+++ b/remoting/remoting.gyp
@@ -114,18 +114,15 @@
'../gfx/gfx.gyp:gfx',
'../media/media.gyp:media',
'../third_party/protobuf2/protobuf.gyp:protobuf_lite',
+ '../third_party/libvpx/libvpx.gyp:libvpx_include',
'../third_party/zlib/zlib.gyp:zlib',
'base/protocol/chromotocol.gyp:chromotocol_proto_lib',
'base/protocol/chromotocol.gyp:trace_proto_lib',
'chromoting_jingle_glue',
- # TODO(hclam): Enable VP8 in the build.
- #'third_party/on2/on2.gyp:vp8',
],
'export_dependent_settings': [
'../third_party/protobuf2/protobuf.gyp:protobuf_lite',
'base/protocol/chromotocol.gyp:chromotocol_proto_lib',
- # TODO(hclam): Enable VP8 in the build.
- #'third_party/on2/on2.gyp:vp8',
],
# This target needs a hard dependency because dependent targets
# depend on chromotocol_proto_lib for headers.
@@ -148,11 +145,10 @@
'base/encoder.h',
'base/encoder_verbatim.cc',
'base/encoder_verbatim.h',
+ 'base/encoder_vp8.cc',
+ 'base/encoder_vp8.h',
'base/encoder_zlib.cc',
'base/encoder_zlib.h',
- # TODO(hclam): Enable VP8 in the build.
- #'base/encoder_vp8.cc',
- #'base/encoder_vp8.h',
'base/multiple_array_input_stream.cc',
'base/multiple_array_input_stream.h',
'base/protocol_decoder.cc',
@@ -407,8 +403,7 @@
'base/decoder_zlib_unittest.cc',
'base/decompressor_zlib_unittest.cc',
'base/encoder_verbatim_unittest.cc',
- # TODO(hclam): Enable VP8 in the build.
- #'base/encoder_vp8_unittest.cc',
+ 'base/encoder_vp8_unittest.cc',
'base/encoder_zlib_unittest.cc',
'base/mock_objects.h',
'base/multiple_array_input_stream_unittest.cc',
diff --git a/remoting/run_all_unittests.cc b/remoting/run_all_unittests.cc
index 2571950..16e4f74 100644
--- a/remoting/run_all_unittests.cc
+++ b/remoting/run_all_unittests.cc
@@ -2,8 +2,19 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include "base/file_path.h"
+#include "base/logging.h"
+#include "base/path_service.h"
#include "base/test/test_suite.h"
+#include "media/base/media.h"
int main(int argc, char** argv) {
- return base::TestSuite(argc, argv).Run();
+ base::TestSuite test_suite(argc, argv);
+
+ // Load the media library so we can use libvpx.
+ FilePath path;
+ PathService::Get(base::DIR_MODULE, &path);
+ CHECK(media::InitializeMediaLibrary(path))
+ << "Cannot load media library";
+ return test_suite.Run();
}
diff --git a/third_party/libvpx/libvpx.gyp b/third_party/libvpx/libvpx.gyp
new file mode 100644
index 0000000..f0e5f34
--- /dev/null
+++ b/third_party/libvpx/libvpx.gyp
@@ -0,0 +1,90 @@
+# Copyright (c) 2010 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+{
+ 'targets': [
+ # libvpx_lib is currently not being used since we use libvpx inside
+ # libavcodec. Keeping this just in case we need this later.
+ {
+ 'target_name': 'libvpx_lib',
+ 'type': 'none',
+ 'variables': {
+ 'libvpx_lib': 'libvpx.a',
+ },
+ 'conditions': [
+ # This section specifies the folder for looking for libvpx.a.
+ #
+ ['OS=="linux" and target_arch=="ia32"', {
+ 'variables': {
+ 'libvpx_path': 'lib/linux/ia32',
+ },
+ }],
+ ['OS=="linux" and target_arch=="x64"', {
+ 'variables': {
+ 'libvpx_path': 'lib/linux/x64',
+ },
+ }],
+ ['OS=="linux" and target_arch=="arm" and arm_neon==1', {
+ 'variables': {
+ 'libvpx_path': 'lib/linux/arm-neon',
+ },
+ }],
+ ['OS=="linux" and target_arch=="arm" and arm_neon==0', {
+ 'variables': {
+ 'libvpx_path': 'lib/linux/arm',
+ },
+ }],
+ ['OS=="win"', {
+ 'variables': {
+ 'libvpx_path': 'lib/win/ia32',
+ },
+ }],
+ ['OS=="mac"', {
+ 'variables': {
+ 'libvpx_path': 'lib/mac/ia32',
+ },
+ }],
+ ],
+ 'actions': [
+ {
+ 'action_name': 'copy_lib',
+ 'inputs': [
+ '<(libvpx_path)/<(libvpx_lib)',
+ ],
+ 'outputs': [
+ '<(SHARED_INTERMEDIATE_DIR)/<(libvpx_lib)',
+ ],
+ 'action': [
+ 'cp',
+ '<(libvpx_path)/<(libvpx_lib)',
+ '<(SHARED_INTERMEDIATE_DIR)/<(libvpx_lib)',
+ ],
+ 'message': 'Copying libvpx.a into <(SHARED_INTERMEDIATE_DIR)',
+ },
+ ],
+ 'all_dependent_settings': {
+ 'link_settings': {
+ 'libraries': [
+ '<(SHARED_INTERMEDIATE_DIR)/<(libvpx_lib)',
+ ],
+ },
+ },
+ },
+ {
+ 'target_name': 'libvpx_include',
+ 'type': 'none',
+ 'direct_dependent_settings': {
+ 'include_dirs': [
+ 'include',
+ ],
+ },
+ }
+ ],
+}
+
+# Local Variables:
+# tab-width:2
+# indent-tabs-mode:nil
+# End:
+# vim: set expandtab tabstop=2 shiftwidth=2: