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:
parent
ddb85ab85b
commit
a3344cfda4
@ -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.
|
||||
|
100
talk/media/base/executablehelpers.h
Normal file
100
talk/media/base/executablehelpers.h
Normal file
@ -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)
|
||||
|
Loading…
x
Reference in New Issue
Block a user