Fix webrtcvideoframe tests.

R=fbarchard@google.com, harryjin@google.com, henrike@webrtc.org

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

git-svn-id: http://webrtc.googlecode.com/svn/trunk@7088 4adac7df-926f-26a2-2b94-8c16560cd09d
This commit is contained in:
thorcarpenter@google.com 2014-09-05 16:34:13 +00:00
parent ddb85ab85b
commit a3344cfda4
5 changed files with 138 additions and 92 deletions

@ -157,9 +157,8 @@
'media/sctp/sctpdataengine_unittest.cc',
'media/webrtc/webrtcpassthroughrender_unittest.cc',
'media/webrtc/webrtcvideocapturer_unittest.cc',
# Omitted because depends on non-open-source testdata files.
# 'media/base/videoframe_unittest.h',
# 'media/webrtc/webrtcvideoframe_unittest.cc',
'media/base/videoframe_unittest.h',
'media/webrtc/webrtcvideoframe_unittest.cc',
# Disabled because some tests fail.
# TODO(ronghuawu): Reenable these tests.

@ -0,0 +1,100 @@
/*
* libjingle
* Copyright 2014 Google Inc.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
* EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef TALK_MEDIA_BASE_EXECUTABLEHELPERS_H_
#define TALK_MEDIA_BASE_EXECUTABLEHELPERS_H_
#ifdef OSX
#include <mach-o/dyld.h>
#endif
#include <string>
#include "webrtc/base/logging.h"
#include "webrtc/base/pathutils.h"
namespace rtc {
// Returns the path to the running executable or an empty path.
// TODO(thorcarpenter): Consolidate with FluteClient::get_executable_dir.
inline Pathname GetExecutablePath() {
const int32 kMaxExePathSize = 255;
#ifdef WIN32
TCHAR exe_path_buffer[kMaxExePathSize];
DWORD copied_length = GetModuleFileName(NULL, // NULL = Current process
exe_path_buffer, kMaxExePathSize);
if (0 == copied_length) {
LOG(LS_ERROR) << "Copied length is zero";
return rtc::Pathname();
}
if (kMaxExePathSize == copied_length) {
LOG(LS_ERROR) << "Buffer too small";
return rtc::Pathname();
}
#ifdef UNICODE
std::wstring wdir(exe_path_buffer);
std::string dir_tmp(wdir.begin(), wdir.end());
rtc::Pathname path(dir_tmp);
#else // UNICODE
rtc::Pathname path(exe_path_buffer);
#endif // UNICODE
#elif defined(OSX) || defined(LINUX)
char exe_path_buffer[kMaxExePathSize];
#ifdef OSX
uint32_t copied_length = kMaxExePathSize - 1;
if (_NSGetExecutablePath(exe_path_buffer, &copied_length) == -1) {
LOG(LS_ERROR) << "Buffer too small";
return rtc::Pathname();
}
#elif defined LINUX
int32 copied_length = kMaxExePathSize - 1;
const char* kProcExeFmt = "/proc/%d/exe";
char proc_exe_link[40];
snprintf(proc_exe_link, sizeof(proc_exe_link), kProcExeFmt, getpid());
copied_length = readlink(proc_exe_link, exe_path_buffer, copied_length);
if (copied_length == -1) {
LOG_ERR(LS_ERROR) << "Error reading link " << proc_exe_link;
return rtc::Pathname();
}
if (copied_length == kMaxExePathSize - 1) {
LOG(LS_ERROR) << "Probably truncated result when reading link "
<< proc_exe_link;
return rtc::Pathname();
}
exe_path_buffer[copied_length] = '\0';
#endif // LINUX
rtc::Pathname path(exe_path_buffer);
#else // Android || IOS
rtc::Pathname path;
#endif // OSX || LINUX
return path;
}
} // namespace rtc
#endif // TALK_MEDIA_BASE_EXECUTABLEHELPERS_H_

@ -33,6 +33,7 @@
#include <math.h>
#include "talk/media/base/executablehelpers.h"
#include "talk/media/base/rtpdump.h"
#include "talk/media/base/videocapturer.h"
#include "talk/media/base/videoframe.h"
@ -256,77 +257,18 @@ void VideoCapturerListener::OnFrameCaptured(VideoCapturer* capturer,
}
}
// Returns the path to the running executable or an empty path.
// TODO(thorcarpenter): Consolidate with FluteClient::get_executable_dir.
#ifdef FLUTE_IN_CHROME_BUILD
inline rtc::Pathname GetExecutablePath() {
const int32 kMaxExePathSize = 255;
#ifdef WIN32
TCHAR exe_path_buffer[kMaxExePathSize];
DWORD copied_length = GetModuleFileName(NULL, // NULL = Current process
exe_path_buffer, kMaxExePathSize);
if (0 == copied_length) {
LOG(LS_ERROR) << "Copied length is zero";
return rtc::Pathname();
}
if (kMaxExePathSize == copied_length) {
LOG(LS_ERROR) << "Buffer too small";
return rtc::Pathname();
}
#ifdef UNICODE
std::wstring wdir(exe_path_buffer);
std::string dir_tmp(wdir.begin(), wdir.end());
rtc::Pathname path(dir_tmp);
#else // UNICODE
rtc::Pathname path(exe_path_buffer);
#endif // UNICODE
#elif defined(OSX) || defined(LINUX)
char exe_path_buffer[kMaxExePathSize];
#ifdef OSX
uint32_t copied_length = kMaxExePathSize - 1;
if (_NSGetExecutablePath(exe_path_buffer, &copied_length) == -1) {
LOG(LS_ERROR) << "Buffer too small";
return rtc::Pathname();
}
#elif defined LINUX
int32 copied_length = kMaxExePathSize - 1;
const char* kProcExeFmt = "/proc/%d/exe";
char proc_exe_link[40];
snprintf(proc_exe_link, sizeof(proc_exe_link), kProcExeFmt, getpid());
copied_length = readlink(proc_exe_link, exe_path_buffer, copied_length);
if (copied_length == -1) {
LOG_ERR(LS_ERROR) << "Error reading link " << proc_exe_link;
return rtc::Pathname();
}
if (copied_length == kMaxExePathSize - 1) {
LOG(LS_ERROR) << "Probably truncated result when reading link "
<< proc_exe_link;
return rtc::Pathname();
}
exe_path_buffer[copied_length] = '\0';
#endif // LINUX
rtc::Pathname path(exe_path_buffer);
#else // Android/iOS etc
rtc::Pathname path;
#endif // OSX || LINUX
return path;
}
#endif
// Returns the absolute path to a file in the testdata/ directory.
std::string GetTestFilePath(const std::string& filename) {
// Locate test data directory.
#ifdef FLUTE_IN_CHROME_BUILD
rtc::Pathname path = GetExecutablePath();
#ifdef ENABLE_WEBRTC
rtc::Pathname path = rtc::GetExecutablePath();
EXPECT_FALSE(path.empty());
path.AppendPathname("../../magicflute/");
path.AppendFolder("talk");
path.AppendPathname("../../talk/");
#else
rtc::Pathname path = testing::GetTalkDirectory();
EXPECT_FALSE(path.empty()); // must be run from inside "talk"
#endif
path.AppendFolder("media");
path.AppendFolder("testdata");
path.AppendFolder("media/testdata/");
path.SetFilename(filename);
return path.pathname();
}

@ -135,6 +135,9 @@ class VideoFrameTest : public testing::Test {
rtc::scoped_ptr<rtc::FileStream> fs(
rtc::Filesystem::OpenFile(path, "rb"));
if (!fs.get()) {
LOG(LS_ERROR) << "Could not open test file path: " << path.pathname()
<< " from current dir "
<< rtc::Filesystem::GetCurrentDirectory().pathname();
return NULL;
}
@ -143,6 +146,7 @@ class VideoFrameTest : public testing::Test {
new rtc::MemoryStream());
rtc::StreamResult res = Flow(fs.get(), buf, sizeof(buf), ms.get());
if (res != rtc::SR_SUCCESS) {
LOG(LS_ERROR) << "Could not load test file path: " << path.pathname();
return NULL;
}
@ -419,17 +423,22 @@ class VideoFrameTest : public testing::Test {
const uint8* u, uint32 upitch,
const uint8* v, uint32 vpitch,
int max_error) {
return IsSize(frame, width, height) &&
return IsSize(frame,
static_cast<uint32>(width),
static_cast<uint32>(height)) &&
frame.GetPixelWidth() == pixel_width &&
frame.GetPixelHeight() == pixel_height &&
frame.GetElapsedTime() == elapsed_time &&
frame.GetTimeStamp() == time_stamp &&
IsPlaneEqual("y", frame.GetYPlane(), frame.GetYPitch(), y, ypitch,
width, height, max_error) &&
static_cast<uint32>(width),
static_cast<uint32>(height), max_error) &&
IsPlaneEqual("u", frame.GetUPlane(), frame.GetUPitch(), u, upitch,
(width + 1) / 2, (height + 1) / 2, max_error) &&
static_cast<uint32>((width + 1) / 2),
static_cast<uint32>((height + 1) / 2), max_error) &&
IsPlaneEqual("v", frame.GetVPlane(), frame.GetVPitch(), v, vpitch,
(width + 1) / 2, (height + 1) / 2, max_error);
static_cast<uint32>((width + 1) / 2),
static_cast<uint32>((height + 1) / 2), max_error);
}
static bool IsEqual(const cricket::VideoFrame& frame1,
@ -719,7 +728,7 @@ class VideoFrameTest : public testing::Test {
T frame1, frame2;
size_t out_size = kWidth * kHeight * 2;
rtc::scoped_ptr<uint8[]> outbuf(new uint8[out_size + kAlignment]);
uint8 *out = ALIGNP(outbuf.get(), kAlignment);
uint8* out = ALIGNP(outbuf.get(), kAlignment);
T frame;
ASSERT_TRUE(LoadFrameNoRepeat(&frame1));
EXPECT_EQ(out_size, frame1.ConvertToRgbBuffer(cricket::FOURCC_RGBP,
@ -735,7 +744,7 @@ class VideoFrameTest : public testing::Test {
T frame1, frame2;
size_t out_size = kWidth * kHeight * 2;
rtc::scoped_ptr<uint8[]> outbuf(new uint8[out_size + kAlignment]);
uint8 *out = ALIGNP(outbuf.get(), kAlignment);
uint8* out = ALIGNP(outbuf.get(), kAlignment);
T frame;
ASSERT_TRUE(LoadFrameNoRepeat(&frame1));
EXPECT_EQ(out_size, frame1.ConvertToRgbBuffer(cricket::FOURCC_RGBO,
@ -751,7 +760,7 @@ class VideoFrameTest : public testing::Test {
T frame1, frame2;
size_t out_size = kWidth * kHeight * 2;
rtc::scoped_ptr<uint8[]> outbuf(new uint8[out_size + kAlignment]);
uint8 *out = ALIGNP(outbuf.get(), kAlignment);
uint8* out = ALIGNP(outbuf.get(), kAlignment);
T frame;
ASSERT_TRUE(LoadFrameNoRepeat(&frame1));
EXPECT_EQ(out_size, frame1.ConvertToRgbBuffer(cricket::FOURCC_R444,
@ -771,12 +780,12 @@ class VideoFrameTest : public testing::Test {
size_t bayer_size = kWidth * kHeight; \
rtc::scoped_ptr<uint8[]> bayerbuf(new uint8[ \
bayer_size + kAlignment]); \
uint8 *bayer = ALIGNP(bayerbuf.get(), kAlignment); \
uint8* bayer = ALIGNP(bayerbuf.get(), kAlignment); \
T frame1, frame2; \
rtc::scoped_ptr<rtc::MemoryStream> ms( \
CreateRgbSample(cricket::FOURCC_ARGB, kWidth, kHeight)); \
ASSERT_TRUE(ms.get() != NULL); \
libyuv::ARGBToBayer##BAYER(reinterpret_cast<uint8 *>(ms->GetBuffer()), \
libyuv::ARGBToBayer##BAYER(reinterpret_cast<uint8* >(ms->GetBuffer()), \
kWidth * 4, \
bayer, kWidth, \
kWidth, kHeight); \
@ -812,8 +821,8 @@ void Construct##FOURCC##Mirror() { \
reinterpret_cast<uint8*>(ms->GetBuffer()), \
data_size, \
1, 1, 0, 0, 0)); \
int width_rotate = frame1.GetWidth(); \
int height_rotate = frame1.GetHeight(); \
int width_rotate = static_cast<int>(frame1.GetWidth()); \
int height_rotate = static_cast<int>(frame1.GetHeight()); \
EXPECT_TRUE(frame3.InitToBlack(width_rotate, height_rotate, 1, 1, 0, 0)); \
libyuv::I420Mirror(frame2.GetYPlane(), frame2.GetYPitch(), \
frame2.GetUPlane(), frame2.GetUPitch(), \
@ -845,8 +854,8 @@ void Construct##FOURCC##Rotate##ROTATE() { \
reinterpret_cast<uint8*>(ms->GetBuffer()), \
data_size, \
1, 1, 0, 0, 0)); \
int width_rotate = frame1.GetWidth(); \
int height_rotate = frame1.GetHeight(); \
int width_rotate = static_cast<int>(frame1.GetWidth()); \
int height_rotate = static_cast<int>(frame1.GetHeight()); \
EXPECT_TRUE(frame3.InitToBlack(width_rotate, height_rotate, 1, 1, 0, 0)); \
libyuv::I420Rotate(frame2.GetYPlane(), frame2.GetYPitch(), \
frame2.GetUPlane(), frame2.GetUPitch(), \
@ -995,7 +1004,7 @@ void Construct##FOURCC##Rotate##ROTATE() { \
// Convert back to ARGB.
size_t out_size = 4;
rtc::scoped_ptr<uint8[]> outbuf(new uint8[out_size + kAlignment]);
uint8 *out = ALIGNP(outbuf.get(), kAlignment);
uint8* out = ALIGNP(outbuf.get(), kAlignment);
EXPECT_EQ(out_size, frame.ConvertToRgbBuffer(cricket::FOURCC_ARGB,
out,
@ -1032,7 +1041,7 @@ void Construct##FOURCC##Rotate##ROTATE() { \
// Convert back to ARGB
size_t out_size = 10 * 4;
rtc::scoped_ptr<uint8[]> outbuf(new uint8[out_size + kAlignment]);
uint8 *out = ALIGNP(outbuf.get(), kAlignment);
uint8* out = ALIGNP(outbuf.get(), kAlignment);
EXPECT_EQ(out_size, frame.ConvertToRgbBuffer(cricket::FOURCC_ARGB,
out,
@ -1431,8 +1440,8 @@ void Construct##FOURCC##Rotate##ROTATE() { \
size_t out_size = astride * kHeight;
rtc::scoped_ptr<uint8[]> outbuf(new uint8[out_size + kAlignment + 1]);
memset(outbuf.get(), 0, out_size + kAlignment + 1);
uint8 *outtop = ALIGNP(outbuf.get(), kAlignment);
uint8 *out = outtop;
uint8* outtop = ALIGNP(outbuf.get(), kAlignment);
uint8* out = outtop;
int stride = astride;
if (invert) {
out += (kHeight - 1) * stride; // Point to last row.
@ -1869,7 +1878,7 @@ void Construct##FOURCC##Rotate##ROTATE() { \
size_t bayer_size = kWidth * kHeight; \
rtc::scoped_ptr<uint8[]> bayerbuf(new uint8[ \
bayer_size + kAlignment]); \
uint8 *bayer = ALIGNP(bayerbuf.get(), kAlignment); \
uint8* bayer = ALIGNP(bayerbuf.get(), kAlignment); \
T frame; \
rtc::scoped_ptr<rtc::MemoryStream> ms( \
CreateRgbSample(cricket::FOURCC_ARGB, kWidth, kHeight)); \
@ -1898,7 +1907,7 @@ void Construct##FOURCC##Rotate##ROTATE() { \
size_t bayer_size = kWidth * kHeight; \
rtc::scoped_ptr<uint8[]> bayerbuf(new uint8[ \
bayer_size + 1 + kAlignment]); \
uint8 *bayer = ALIGNP(bayerbuf.get(), kAlignment) + 1; \
uint8* bayer = ALIGNP(bayerbuf.get(), kAlignment) + 1; \
T frame; \
rtc::scoped_ptr<rtc::MemoryStream> ms( \
CreateRgbSample(cricket::FOURCC_ARGB, kWidth, kHeight)); \
@ -1935,7 +1944,7 @@ void Construct##FOURCC##Rotate##ROTATE() { \
size_t bayer_size = kWidth * kHeight; \
rtc::scoped_ptr<uint8[]> bayerbuf(new uint8[ \
bayer_size + kAlignment]); \
uint8 *bayer1 = ALIGNP(bayerbuf.get(), kAlignment); \
uint8* bayer1 = ALIGNP(bayerbuf.get(), kAlignment); \
for (int i = 0; i < kWidth * kHeight; ++i) { \
bayer1[i] = static_cast<uint8>(i * 33u + 183u); \
} \
@ -1951,7 +1960,7 @@ void Construct##FOURCC##Rotate##ROTATE() { \
} \
rtc::scoped_ptr<uint8[]> bayer2buf(new uint8[ \
bayer_size + kAlignment]); \
uint8 *bayer2 = ALIGNP(bayer2buf.get(), kAlignment); \
uint8* bayer2 = ALIGNP(bayer2buf.get(), kAlignment); \
libyuv::ARGBToBayer##BAYER(reinterpret_cast<uint8*>(ms->GetBuffer()), \
kWidth * 4, \
bayer2, kWidth, \

@ -27,14 +27,10 @@
#include "talk/media/base/videoframe_unittest.h"
#include "talk/media/webrtc/webrtcvideoframe.h"
#include "webrtc/base/flags.h"
extern int FLAG_yuvconverter_repeat; // From lmivideoframe_unittest.cc.
class WebRtcVideoFrameTest : public VideoFrameTest<cricket::WebRtcVideoFrame> {
public:
WebRtcVideoFrameTest() {
repeat_ = FLAG_yuvconverter_repeat;
}
void TestInit(int cropped_width, int cropped_height) {
@ -136,7 +132,7 @@ TEST_WEBRTCVIDEOFRAME(ConstructI420CropVertical)
TEST_WEBRTCVIDEOFRAME(ConstructBlack)
// TODO(fbarchard): Implement Jpeg
// TEST_WEBRTCVIDEOFRAME(ConstructMjpgI420)
// TEST_WEBRTCVIDEOFRAME(ConstructMjpgI422)
TEST_WEBRTCVIDEOFRAME(ConstructMjpgI422)
// TEST_WEBRTCVIDEOFRAME(ConstructMjpgI444)
// TEST_WEBRTCVIDEOFRAME(ConstructMjpgI411)
// TEST_WEBRTCVIDEOFRAME(ConstructMjpgI400)