Rewrote codec test to use fake camera.

Tests now fail more cleanly if the input video file is incorrect. Fixed some of the style issues in vie_autotest_codec.

Rewrote the automated standard codec test to use the new fake camera.

Started sketching on a new test case. Wrote a new abstraction called ViEFakeCamera which hides the details of how to thread a file capture device in the typical test case.

BUG=
TEST=

Review URL: http://webrtc-codereview.appspot.com/242008

git-svn-id: http://webrtc.googlecode.com/svn/trunk@815 4adac7df-926f-26a2-2b94-8c16560cd09d
This commit is contained in:
phoglund@webrtc.org 2011-10-25 12:54:38 +00:00
parent d855c1a4e8
commit 78c767f9ba
9 changed files with 488 additions and 369 deletions

View File

@ -62,14 +62,17 @@ TEST_F(ViEStandardIntegrationTest, RunsBaseTestWithoutErrors) {
FLAGS_i420_test_video_height);
}
TEST_F(ViEStandardIntegrationTest, RunsCodecTestWithoutErrors) {
tests_->ViEAutomatedCodecStandardTest(FLAGS_i420_test_video_path,
FLAGS_i420_test_video_width,
FLAGS_i420_test_video_height);
}
// These tests still require a physical camera:
TEST_F(ViEStandardIntegrationTest, RunsCaptureTestWithoutErrors) {
ASSERT_EQ(0, tests_->ViECaptureStandardTest());
}
TEST_F(ViEStandardIntegrationTest, RunsCodecTestWithoutErrors) {
ASSERT_EQ(0, tests_->ViECodecStandardTest());
}
TEST_F(ViEStandardIntegrationTest, RunsEncryptionTestWithoutErrors) {
ASSERT_EQ(0, tests_->ViEEncryptionStandardTest());

View File

@ -0,0 +1,82 @@
/*
* Copyright (c) 2011 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.
*/
#include "vie_fake_camera.h"
#include <assert.h>
#include "vie_capture.h"
#include "vie_file_capture_device.h"
#include "thread_wrapper.h"
// This callback runs the camera thread:
bool StreamVideoFileRepeatedlyIntoCaptureDevice(void* data) {
ViEFileCaptureDevice* file_capture_device =
reinterpret_cast<ViEFileCaptureDevice*>(data);
uint64_t time_slice_ms = 1500;
uint32_t max_fps = 30;
file_capture_device->ReadFileFor(time_slice_ms, max_fps);
return true;
}
ViEFakeCamera::ViEFakeCamera(webrtc::ViECapture* capture_interface)
: capture_interface_(capture_interface),
camera_thread_(NULL),
file_capture_device_(NULL) {
}
ViEFakeCamera::~ViEFakeCamera() {
}
bool ViEFakeCamera::StartCameraInNewThread(
const std::string& i420_test_video_path, int width, int height) {
assert(file_capture_device_ == NULL && camera_thread_ == NULL);
webrtc::ViEExternalCapture* externalCapture;
int result = capture_interface_->
AllocateExternalCaptureDevice(capture_id_, externalCapture);
if (result != 0) {
return false;
}
file_capture_device_ = new ViEFileCaptureDevice(externalCapture);
if (!file_capture_device_->OpenI420File(i420_test_video_path,
width,
height)) {
return false;
}
// Set up a thread which runs the fake camera. The capturer object is
// thread-safe.
camera_thread_ = webrtc::ThreadWrapper::CreateThread(
StreamVideoFileRepeatedlyIntoCaptureDevice, file_capture_device_);
unsigned int id;
camera_thread_->Start(id);
return true;
}
bool ViEFakeCamera::StopCamera() {
assert(file_capture_device_ != NULL && camera_thread_ != NULL);
camera_thread_->Stop();
file_capture_device_->CloseFile();
int result = capture_interface_->ReleaseCaptureDevice(capture_id_);
delete camera_thread_;
delete file_capture_device_;
camera_thread_ = NULL;
file_capture_device_ = NULL;
return result == 0;
}

View File

@ -0,0 +1,50 @@
/*
* Copyright (c) 2011 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 SRC_VIDEO_ENGINE_MAIN_TEST_AUTOTEST_HELPERS_VIE_FAKE_CAMERA_H_
#define SRC_VIDEO_ENGINE_MAIN_TEST_AUTOTEST_HELPERS_VIE_FAKE_CAMERA_H_
#include <string>
namespace webrtc {
class ViECapture;
class ThreadWrapper;
}
class ViEFileCaptureDevice;
// Registers an external capture device with the provided capture interface
// and starts running a fake camera by reading frames from a file. The frame-
// reading code runs in a separate thread which makes it possible to run tests
// while the fake camera feeds data into the system. This class is not thread-
// safe in itself (but handles its own thread in a safe manner).
class ViEFakeCamera {
public:
// The argument is the capture interface to register with.
explicit ViEFakeCamera(webrtc::ViECapture* capture_interface);
virtual ~ViEFakeCamera();
// Runs the scenario in the class comments.
bool StartCameraInNewThread(const std::string& i420_test_video_path,
int width,
int height);
// Stops the camera and cleans up everything allocated by the start method.
bool StopCamera();
int capture_id() const { return capture_id_; }
private:
webrtc::ViECapture* capture_interface_;
int capture_id_;
webrtc::ThreadWrapper* camera_thread_;
ViEFileCaptureDevice* file_capture_device_;
};
#endif // SRC_VIDEO_ENGINE_MAIN_TEST_AUTOTEST_HELPERS_VIE_FAKE_CAMERA_H_

View File

@ -9,6 +9,8 @@
*/
#include "vie_file_capture_device.h"
#include <assert.h>
#include "common_types.h"
#include "critical_section_wrapper.h"
#include "event_wrapper.h"

View File

@ -23,10 +23,8 @@ class EventWrapper;
class ViEExternalCapture;
}
/**
* This class opens a i420 file and feeds it into a ExternalCapture instance,
* thereby acting as a faked capture device with deterministic input.
*/
// This class opens a i420 file and feeds it into a ExternalCapture instance,
// thereby acting as a faked capture device with deterministic input.
class ViEFileCaptureDevice {
public:
// The input sink is where to send the I420 video frames.

View File

@ -39,6 +39,8 @@
#include <string>
#endif
class tbInterfaces;
class ViEAutoTest
{
public:
@ -77,6 +79,10 @@ public:
int ViECodecExternalCodecTest();
int ViECodecAPITest();
void ViEAutomatedCodecStandardTest(const std::string& pathToTestI420Video,
int width,
int height);
// vie_autotest_encryption.cc
int ViEEncryptionStandardTest();
int ViEEncryptionExtendedTest();
@ -126,6 +132,10 @@ private:
void PrintAudioCodec(const webrtc::CodecInst audioCodec);
void PrintVideoCodec(const webrtc::VideoCodec videoCodec);
void RunCodecTestInternal(const tbInterfaces& interfaces,
int & numberOfErrors,
int captureId);
void* _window1;
void* _window2;

View File

@ -13,12 +13,12 @@
//
#include "gtest/gtest.h"
#include "thread_wrapper.h"
#include "vie_autotest.h"
#include "vie_autotest_defines.h"
#include "video_capture_factory.h"
#include "vie_autotest_defines.h"
#include "vie_autotest.h"
#include "vie_fake_camera.h"
#include "vie_file_capture_device.h"
#include "thread_wrapper.h"
class BaseObserver : public webrtc::ViEBaseObserver {
public:
@ -238,9 +238,6 @@ void StopEverything(webrtc::ViEBase * ptrViEBase,
error = ptrViECapture->DisconnectCaptureDevice(videoChannel);
numberOfErrors += ViETest::TestError(error == 0, "ERROR: %s at line %d",
__FUNCTION__, __LINE__);
error = ptrViECapture->ReleaseCaptureDevice(captureId);
numberOfErrors += ViETest::TestError(error == 0, "ERROR: %s at line %d",
__FUNCTION__, __LINE__);
}
void ReleaseEverything(webrtc::ViECapture *ptrViECapture,
@ -355,6 +352,10 @@ int ViEAutoTest::ViEBaseStandardTest() {
StopEverything(ptrViEBase, videoChannel, numberOfErrors, ptrViERender,
captureId, ptrViECapture, _vrm1, _vrm2);
error = ptrViECapture->ReleaseCaptureDevice(captureId);
numberOfErrors += ViETest::TestError(error == 0, "ERROR: %s at line %d",
__FUNCTION__, __LINE__);
vcpm->Release();
vcpm = NULL;
@ -590,18 +591,6 @@ int ViEAutoTest::ViEBaseAPITest() {
return 0;
}
// This callback gets used in the automated test case below:
bool StreamVideoFileRepeatedlyIntoCaptureDevice(void* data) {
ViEFileCaptureDevice* file_capture_device =
reinterpret_cast<ViEFileCaptureDevice*>(data);
WebRtc_UWord64 time_slice_ms = 1500;
WebRtc_UWord64 max_fps = 30;
file_capture_device->ReadFileFor(time_slice_ms, max_fps);
return true;
}
void ViEAutoTest::ViEAutomatedBaseStandardTest(
const std::string& pathToTestI420Video, int width, int height) {
int ignoredNumberOfErrors;
@ -617,29 +606,15 @@ void ViEAutoTest::ViEAutomatedBaseStandardTest(
InitializeChannel(ptrViEBase, videoChannel,
ignoredNumberOfErrors, ptrViE);
int captureId;
webrtc::ViEExternalCapture* externalCapture;
int error = ptrViECapture->AllocateExternalCaptureDevice(captureId,
externalCapture);
ViETest::TestError(error == 0, "ERROR: %s at line %d",
__FUNCTION__, __LINE__);
ViEFileCaptureDevice capturer(externalCapture);
if (!capturer.OpenI420File(pathToTestI420Video, width, height)) {
ViEFakeCamera fakeCamera(ptrViECapture);
if (!fakeCamera.StartCameraInNewThread(pathToTestI420Video, width, height)) {
// No point in continuing if we have no proper video source
ViETest::TestError(false, "ERROR: %s at line %d: "
"Could not open input video %s: aborting test...",
__FUNCTION__, __LINE__, pathToTestI420Video.c_str());
return;
}
// Set up a thread which runs the fake camera. Note that the capturer is
// handed off to the other thread - it should not be touched in this
// method until the other thread is stopped!
webrtc::ThreadWrapper* thread = webrtc::ThreadWrapper::CreateThread(
StreamVideoFileRepeatedlyIntoCaptureDevice, &capturer);
unsigned int id;
thread->Start(id);
int captureId = fakeCamera.capture_id();
// Apparently, we need to connect external capture devices, but we should
// not start them since the external device is not a proper device.
@ -667,13 +642,15 @@ void ViEAutoTest::ViEAutomatedBaseStandardTest(
AutoTestSleep(KAutoTestSleepTimeMs);
// Done, clean up
thread->Stop();
capturer.CloseFile();
StopEverything(ptrViEBase, videoChannel, ignoredNumberOfErrors, ptrViERender,
captureId, ptrViECapture, _vrm1, _vrm2);
// Stop sending data, clean up the camera thread and release the capture
// device. Note that this all happens after StopEverything, so this is
// tests that the system doesn't mind that the external capture device sends
// data after rendering has been stopped.
fakeCamera.StopCamera();
ReleaseEverything(ptrViECapture, ignoredNumberOfErrors, ptrViEBase,
videoChannel, ptrViECodec, ptrViERtpRtcp, ptrViERender,
ptrViENetwork, ptrViE);

View File

@ -12,12 +12,13 @@
// vie_autotest_codec.cc
//
#include "vie_autotest_defines.h"
#include "vie_autotest.h"
#include "engine_configurations.h"
#include "common_types.h"
#include "engine_configurations.h"
#include "vie_autotest_defines.h"
#include "tb_capture_device.h"
#include "vie_fake_camera.h"
#include "tb_I420_codec.h"
#include "tb_interfaces.h"
#include "tb_video_channel.h"
@ -117,330 +118,56 @@ public:
}
};
void ViEAutoTest::ViEAutomatedCodecStandardTest(
const std::string& i420_video_file,
int width,
int height) {
int ignored = 0;
tbInterfaces interfaces = tbInterfaces("ViECodecAutomatedStandardTest",
ignored);
ViEFakeCamera fake_camera(interfaces.ptrViECapture);
if (!fake_camera.StartCameraInNewThread(i420_video_file, width, height)) {
// No point in continuing if we have no proper video source
ViETest::TestError(false, "ERROR: %s at line %d: "
"Could not open input video %s: aborting test...",
__FUNCTION__, __LINE__, i420_video_file.c_str());
return;
}
RunCodecTestInternal(interfaces, ignored, fake_camera.capture_id());
fake_camera.StopCamera();
}
int ViEAutoTest::ViECodecStandardTest()
{
ViETest::Log(" ");
ViETest::Log("========================================");
ViETest::Log(" ViECodec Standard Test\n");
//***************************************************************
// Begin create/initialize WebRTC Video Engine for testing
//***************************************************************
int error = 0;
int numberOfErrors = 0;
int number_of_errors = 0;
tbInterfaces interfaces = tbInterfaces("ViECodecStandardTest",
numberOfErrors);
number_of_errors);
tbCaptureDevice captureDevice = tbCaptureDevice(interfaces, numberOfErrors);
int captureId = captureDevice.captureId;
tbCaptureDevice capture_device =
tbCaptureDevice(interfaces, number_of_errors);
RunCodecTestInternal(interfaces,
number_of_errors,
capture_device.captureId);
webrtc::VideoEngine* ptrViE = interfaces.ptrViE;
webrtc::ViEBase* ptrViEBase = interfaces.ptrViEBase;
webrtc::ViECapture* ptrViECapture = interfaces.ptrViECapture;
webrtc::ViERender* ptrViERender = interfaces.ptrViERender;
webrtc::ViECodec* ptrViECodec = interfaces.ptrViECodec;
webrtc::ViERTP_RTCP* ptrViERtpRtcp = interfaces.ptrViERtpRtcp;
webrtc::ViENetwork* ptrViENetwork = interfaces.ptrViENetwork;
int videoChannel = -1;
error = ptrViEBase->CreateChannel(videoChannel);
numberOfErrors += ViETest::TestError(error == 0, "ERROR: %s at line %d",
__FUNCTION__, __LINE__);
error = ptrViECapture->ConnectCaptureDevice(captureId, videoChannel);
numberOfErrors += ViETest::TestError(error == 0, "ERROR: %s at line %d",
__FUNCTION__, __LINE__);
error = ptrViERtpRtcp->SetRTCPStatus(videoChannel,
webrtc::kRtcpCompound_RFC4585);
numberOfErrors += ViETest::TestError(error == 0, "ERROR: %s at line %d",
__FUNCTION__, __LINE__);
error = ptrViERtpRtcp->SetKeyFrameRequestMethod(
videoChannel, webrtc::kViEKeyFrameRequestPliRtcp);
numberOfErrors += ViETest::TestError(error == 0, "ERROR: %s at line %d",
__FUNCTION__, __LINE__);
error = ptrViERtpRtcp->SetTMMBRStatus(videoChannel, true);
numberOfErrors += ViETest::TestError(error == 0, "ERROR: %s at line %d",
__FUNCTION__, __LINE__);
error = ptrViERender->AddRenderer(captureId, _window1, 0, 0.0, 0.0, 1.0,
1.0);
numberOfErrors += ViETest::TestError(error == 0, "ERROR: %s at line %d",
__FUNCTION__, __LINE__);
error = ptrViERender->AddRenderer(videoChannel, _window2, 1, 0.0, 0.0, 1.0,
1.0);
numberOfErrors += ViETest::TestError(error == 0, "ERROR: %s at line %d",
__FUNCTION__, __LINE__);
error = ptrViERender->StartRender(captureId);
numberOfErrors += ViETest::TestError(error == 0, "ERROR: %s at line %d",
__FUNCTION__, __LINE__);
error = ptrViERender->StartRender(videoChannel);
numberOfErrors += ViETest::TestError(error == 0, "ERROR: %s at line %d",
__FUNCTION__, __LINE__);
//***************************************************************
// Engine ready. Begin testing class
//***************************************************************
webrtc::VideoCodec videoCodec;
memset(&videoCodec, 0, sizeof(webrtc::VideoCodec));
for (int idx = 0; idx < ptrViECodec->NumberOfCodecs(); idx++)
{
error = ptrViECodec->GetCodec(idx, videoCodec);
numberOfErrors += ViETest::TestError(error == 0, "ERROR: %s at line %d",
__FUNCTION__, __LINE__);
if (videoCodec.codecType != webrtc::kVideoCodecH263
&& videoCodec.codecType != webrtc::kVideoCodecI420)
{
videoCodec.width = 640;
videoCodec.height = 480;
}
if(videoCodec.codecType == webrtc::kVideoCodecI420)
{
videoCodec.width=176;
videoCodec.height=144;
}
error = ptrViECodec->SetReceiveCodec(videoChannel, videoCodec);
numberOfErrors += ViETest::TestError(error == 0, "ERROR: %s at line %d",
__FUNCTION__, __LINE__);
}
for (int idx = 0; idx < ptrViECodec->NumberOfCodecs(); idx++)
{
error = ptrViECodec->GetCodec(idx, videoCodec);
numberOfErrors += ViETest::TestError(error == 0, "ERROR: %s at line %d",
__FUNCTION__, __LINE__);
if (videoCodec.codecType == webrtc::kVideoCodecVP8)
{
error = ptrViECodec->SetSendCodec(videoChannel, videoCodec);
numberOfErrors += ViETest::TestError(error == 0,
"ERROR: %s at line %d",
__FUNCTION__, __LINE__);
break;
}
}
const char* ipAddress = "127.0.0.1";
const unsigned short rtpPort = 6000;
error = ptrViENetwork->SetLocalReceiver(videoChannel, rtpPort);
numberOfErrors += ViETest::TestError(error == 0, "ERROR: %s at line %d",
__FUNCTION__, __LINE__);
error = ptrViEBase->StartReceive(videoChannel);
numberOfErrors += ViETest::TestError(error == 0, "ERROR: %s at line %d",
__FUNCTION__, __LINE__);
error = ptrViENetwork->SetSendDestination(videoChannel, ipAddress, rtpPort);
numberOfErrors += ViETest::TestError(error == 0, "ERROR: %s at line %d",
__FUNCTION__, __LINE__);
error = ptrViEBase->StartSend(videoChannel);
numberOfErrors += ViETest::TestError(error == 0, "ERROR: %s at line %d",
__FUNCTION__, __LINE__);
//
// Make sure all codecs runs
//
{
webrtc::ViEImageProcess* ptrViEImageProcess =
webrtc::ViEImageProcess::GetInterface(ptrViE);
ViEAutotestCodecObserever codecObserver;
error = ptrViECodec->RegisterDecoderObserver(videoChannel,
codecObserver);
numberOfErrors += ViETest::TestError(error == 0,
"ERROR: %s at line %d",
__FUNCTION__, __LINE__);
ViETest::Log("Loop through all codecs for %d seconds",
KAutoTestSleepTimeMs / 1000);
for (int idx = 0; idx < ptrViECodec->NumberOfCodecs() - 2; idx++)
{
error = ptrViECodec->GetCodec(idx, videoCodec);
numberOfErrors += ViETest::TestError(error == 0,
"ERROR: %s at line %d",
__FUNCTION__, __LINE__);
if (videoCodec.codecType != webrtc::kVideoCodecMPEG4)
{
if(videoCodec.codecType == webrtc::kVideoCodecI420)
{
// Lower resolution to sockkets keep up.
videoCodec.width=176;
videoCodec.height=144;
videoCodec.maxFramerate=15;
}
error = ptrViECodec->SetSendCodec(videoChannel, videoCodec);
numberOfErrors += ViETest::TestError(error == 0,
"ERROR: %s at line %d",
__FUNCTION__, __LINE__);
ViETest::Log("\t %d. %s", idx, videoCodec.plName);
ViEAutoTestEffectFilter frameCounter;
error = ptrViEImageProcess->RegisterRenderEffectFilter(
videoChannel,
frameCounter);
numberOfErrors += ViETest::TestError(error == 0,
"ERROR: %s at line %d",
__FUNCTION__, __LINE__);
AutoTestSleep( KAutoTestSleepTimeMs);
// Verify we've received and decoded correct payload
numberOfErrors += ViETest::TestError(
codecObserver.incomingCodec.codecType
== videoCodec.codecType, "ERROR: %s at line %d",
__FUNCTION__, __LINE__);
int maxNumberOfRenderedFrames = videoCodec.maxFramerate
* KAutoTestSleepTimeMs / 1000;
if(videoCodec.codecType == webrtc::kVideoCodecI420)
{
// Due to that I420 needs a huge bandwidht- rate control can set frame rate very low.
// This happen since we use the same channel as we just tested with vp8.
numberOfErrors += ViETest::TestError(frameCounter.numFrames>0,
"ERROR: %s at line %d", __FUNCTION__,
__LINE__);
}
else
{
#ifdef WEBRTC_ANDROID
// To get the autotest to pass on some slow devices
numberOfErrors += ViETest::TestError(frameCounter.numFrames
> maxNumberOfRenderedFrames/6, // Safety margin due to bitrate
"ERROR: %s at line %d", __FUNCTION__, __LINE__);
#else
numberOfErrors += ViETest::TestError(frameCounter.numFrames
> maxNumberOfRenderedFrames / 4, // Safety margin due to bitrate
"ERROR: %s at line %d", __FUNCTION__,
__LINE__);
#endif
}
error = ptrViEImageProcess->DeregisterRenderEffectFilter(
videoChannel);
numberOfErrors += ViETest::TestError(error == 0,
"ERROR: %s at line %d",
__FUNCTION__, __LINE__);
}
else
{
ViETest::Log("\t %d. %s not tested", idx, videoCodec.plName);
}
}
ptrViEImageProcess->Release();
error = ptrViECodec->DeregisterDecoderObserver(videoChannel);
numberOfErrors += ViETest::TestError(error == 0,
"ERROR: %s at line %d",
__FUNCTION__, __LINE__);
ViETest::Log("Done!");
}
//
// Callbacks
//
ViEAutotestCodecObserever codecObserver;
error = ptrViECodec->RegisterEncoderObserver(videoChannel, codecObserver);
numberOfErrors += ViETest::TestError(error == 0, "ERROR: %s at line %d",
__FUNCTION__, __LINE__);
error = ptrViECodec->RegisterDecoderObserver(videoChannel, codecObserver);
numberOfErrors += ViETest::TestError(error == 0, "ERROR: %s at line %d",
__FUNCTION__, __LINE__);
ViETest::Log("\nTesting codec callbacks...");
for (int idx = 0; idx < ptrViECodec->NumberOfCodecs(); idx++)
{
error = ptrViECodec->GetCodec(idx, videoCodec);
numberOfErrors += ViETest::TestError(error == 0, "ERROR: %s at line %d",
__FUNCTION__, __LINE__);
if (videoCodec.codecType == webrtc::kVideoCodecVP8)
{
error = ptrViECodec->SetSendCodec(videoChannel, videoCodec);
numberOfErrors += ViETest::TestError(error == 0,
"ERROR: %s at line %d",
__FUNCTION__, __LINE__);
break;
}
}
AutoTestSleep(KAutoTestSleepTimeMs);
error = ptrViEBase->StopSend(videoChannel);
numberOfErrors += ViETest::TestError(error == 0, "ERROR: %s at line %d",
__FUNCTION__, __LINE__);
error = ptrViECodec->DeregisterEncoderObserver(videoChannel);
numberOfErrors += ViETest::TestError(error == 0, "ERROR: %s at line %d",
__FUNCTION__, __LINE__);
error = ptrViECodec->DeregisterDecoderObserver(videoChannel);
numberOfErrors += ViETest::TestError(error == 0, "ERROR: %s at line %d",
__FUNCTION__, __LINE__);
numberOfErrors += ViETest::TestError(codecObserver.incomingCodecCalled > 0,
"ERROR: %s at line %d", __FUNCTION__,
__LINE__);
numberOfErrors += ViETest::TestError(codecObserver.incomingRatecalled > 0,
"ERROR: %s at line %d", __FUNCTION__,
__LINE__);
numberOfErrors += ViETest::TestError(codecObserver.outgoingRatecalled > 0,
"ERROR: %s at line %d", __FUNCTION__,
__LINE__);
//***************************************************************
// Testing finished. Tear down Video Engine
//***************************************************************
error = ptrViEBase->StopReceive(videoChannel);
numberOfErrors += ViETest::TestError(error == 0, "ERROR: %s at line %d",
__FUNCTION__, __LINE__);
error = ptrViEBase->StopSend(videoChannel); // Already stopped
numberOfErrors += ViETest::TestError(error == -1, "ERROR: %s at line %d",
__FUNCTION__, __LINE__);
error = ptrViERender->StopRender(videoChannel);
numberOfErrors += ViETest::TestError(error == 0, "ERROR: %s at line %d",
__FUNCTION__, __LINE__);
error = ptrViERender->RemoveRenderer(captureId);
numberOfErrors += ViETest::TestError(error == 0, "ERROR: %s at line %d",
__FUNCTION__, __LINE__);
error = ptrViERender->RemoveRenderer(videoChannel);
numberOfErrors += ViETest::TestError(error == 0, "ERROR: %s at line %d",
__FUNCTION__, __LINE__);
error = ptrViECapture->DisconnectCaptureDevice(videoChannel);
numberOfErrors += ViETest::TestError(error == 0, "ERROR: %s at line %d",
__FUNCTION__, __LINE__);
error = ptrViEBase->DeleteChannel(videoChannel);
numberOfErrors += ViETest::TestError(error == 0, "ERROR: %s at line %d",
__FUNCTION__, __LINE__);
if (numberOfErrors > 0)
if (number_of_errors > 0)
{
// Test failed
ViETest::Log(" ");
ViETest::Log(" ERROR ViECodec Standard Test FAILED!");
ViETest::Log(" Number of errors: %d", numberOfErrors);
ViETest::Log(" Number of errors: %d", number_of_errors);
ViETest::Log("========================================");
ViETest::Log(" ");
return numberOfErrors;
return number_of_errors;
}
ViETest::Log(" ");
@ -462,7 +189,7 @@ int ViEAutoTest::ViECodecExtendedTest()
numberOfErrors = ViECodecAPITest();
numberOfErrors += ViECodecStandardTest();
numberOfErrors += ViECodecExternalCodecTest();
numberOfErrors += ViECodecExternalCodecTest();
tbInterfaces interfaces = tbInterfaces("ViECodecExtendedTest",
numberOfErrors);
@ -891,9 +618,9 @@ int ViEAutoTest::ViECodecAPITest()
ViETest::Log("========================================");
ViETest::Log(" ViECodec API Test\n");
//***************************************************************
// Begin create/initialize WebRTC Video Engine for testing
//***************************************************************
// ***************************************************************
// Begin create/initialize WebRTC Video Engine for testing
// ***************************************************************
int error = 0;
int numberOfErrors = 0;
@ -1025,14 +752,14 @@ int ViEAutoTest::ViECodecExternalCodecTest()
ViETest::Log("========================================");
ViETest::Log(" ViEExternalCodec Test\n");
//***************************************************************
// Begin create/initialize WebRTC Video Engine for testing
//***************************************************************
// ***************************************************************
// Begin create/initialize WebRTC Video Engine for testing
// ***************************************************************
//***************************************************************
// Engine ready. Begin testing class
//***************************************************************
// ***************************************************************
// Engine ready. Begin testing class
// ***************************************************************
#ifdef WEBRTC_VIDEO_ENGINE_EXTERNAL_CODEC_API
int numberOfErrors=0;
@ -1093,7 +820,8 @@ int ViEAutoTest::ViECodecExternalCodecTest()
__FUNCTION__, __LINE__);
// Use new external encoder
error = ViE.ptrViECodec->SetSendCodec(channel.videoChannel,codecStruct);
error = ViE.ptrViECodec->SetSendCodec(channel.videoChannel,
codecStruct);
numberOfErrors += ViETest::TestError(error == 0,
"ERROR: %s at line %d",
__FUNCTION__, __LINE__);
@ -1135,7 +863,8 @@ int ViEAutoTest::ViECodecExternalCodecTest()
error = ptrViEExtCodec->DeRegisterExternalSendCodec(
channel.videoChannel,codecStruct.plType);
numberOfErrors += ViETest::TestError(error == 0,
"ERROR: %s at line %d", __FUNCTION__, __LINE__);
"ERROR: %s at line %d",
__FUNCTION__, __LINE__);
error = ptrViEExtCodec->DeRegisterExternalReceiveCodec(
channel.videoChannel,codecStruct.plType);
@ -1293,3 +1022,270 @@ int ViEAutoTest::ViECodecExternalCodecTest()
return 0;
#endif
}
void ViEAutoTest::RunCodecTestInternal(const tbInterfaces& interfaces,
int & numberOfErrors,
int captureId)
{
webrtc::VideoEngine *ptrViE = interfaces.ptrViE;
webrtc::ViEBase *ptrViEBase = interfaces.ptrViEBase;
webrtc::ViECapture *ptrViECapture = interfaces.ptrViECapture;
webrtc::ViERender *ptrViERender = interfaces.ptrViERender;
webrtc::ViECodec *ptrViECodec = interfaces.ptrViECodec;
webrtc::ViERTP_RTCP *ptrViERtpRtcp = interfaces.ptrViERtpRtcp;
webrtc::ViENetwork *ptrViENetwork = interfaces.ptrViENetwork;
int videoChannel = -1;
int error = ptrViEBase->CreateChannel(videoChannel);
numberOfErrors += ViETest::TestError(error == 0, "ERROR: %s at line %d",
__FUNCTION__, __LINE__);
error = ptrViECapture->ConnectCaptureDevice(captureId, videoChannel);
numberOfErrors += ViETest::TestError(error == 0, "ERROR: %s at line %d",
__FUNCTION__, __LINE__);
error = ptrViERtpRtcp->SetRTCPStatus(videoChannel,
webrtc::kRtcpCompound_RFC4585);
numberOfErrors += ViETest::TestError(error == 0, "ERROR: %s at line %d",
__FUNCTION__, __LINE__);
error = ptrViERtpRtcp->
SetKeyFrameRequestMethod(videoChannel,
webrtc::kViEKeyFrameRequestPliRtcp);
numberOfErrors += ViETest::TestError(error == 0, "ERROR: %s at line %d",
__FUNCTION__, __LINE__);
error = ptrViERtpRtcp->SetTMMBRStatus(videoChannel, true);
numberOfErrors += ViETest::TestError(error == 0, "ERROR: %s at line %d",
__FUNCTION__, __LINE__);
error = ptrViERender->AddRenderer(captureId, _window1, 0, 0.0, 0.0, 1.0, 1.0);
numberOfErrors += ViETest::TestError(error == 0, "ERROR: %s at line %d",
__FUNCTION__, __LINE__);
error = ptrViERender->AddRenderer(videoChannel, _window2, 1, 0.0, 0.0,
1.0, 1.0);
numberOfErrors += ViETest::TestError(error == 0, "ERROR: %s at line %d",
__FUNCTION__, __LINE__);
error = ptrViERender->StartRender(captureId);
numberOfErrors += ViETest::TestError(error == 0, "ERROR: %s at line %d",
__FUNCTION__, __LINE__);
error = ptrViERender->StartRender(videoChannel);
numberOfErrors += ViETest::TestError(error == 0, "ERROR: %s at line %d",
__FUNCTION__, __LINE__);
//***************************************************************
// Engine ready. Begin testing class
//***************************************************************
webrtc::VideoCodec videoCodec;
memset(&videoCodec, 0, sizeof (webrtc::VideoCodec));
for (int idx = 0; idx < ptrViECodec->NumberOfCodecs(); idx++)
{
error = ptrViECodec->GetCodec(idx, videoCodec);
numberOfErrors += ViETest::TestError(error == 0, "ERROR: %s at line %d",
__FUNCTION__, __LINE__);
if (videoCodec.codecType != webrtc::kVideoCodecH263
&& videoCodec.codecType != webrtc::kVideoCodecI420)
{
videoCodec.width = 640;
videoCodec.height = 480;
}
if(videoCodec.codecType == webrtc::kVideoCodecI420)
{
videoCodec.width=176;
videoCodec.height=144;
}
error = ptrViECodec->SetReceiveCodec(videoChannel, videoCodec);
numberOfErrors += ViETest::TestError(error == 0, "ERROR: %s at line %d",
__FUNCTION__, __LINE__);
}
for (int idx = 0; idx < ptrViECodec->NumberOfCodecs(); idx++)
{
error = ptrViECodec->GetCodec(idx, videoCodec);
numberOfErrors += ViETest::TestError(error == 0, "ERROR: %s at line %d",
__FUNCTION__, __LINE__);
if (videoCodec.codecType == webrtc::kVideoCodecVP8)
{
error = ptrViECodec->SetSendCodec(videoChannel, videoCodec);
numberOfErrors += ViETest::TestError(error == 0,
"ERROR: %s at line %d",
__FUNCTION__, __LINE__);
break;
}
}
const char *ipAddress = "127.0.0.1";
const unsigned short rtpPort = 6000;
error = ptrViENetwork->SetLocalReceiver(videoChannel, rtpPort);
numberOfErrors += ViETest::TestError(error == 0, "ERROR: %s at line %d",
__FUNCTION__, __LINE__);
error = ptrViEBase->StartReceive(videoChannel);
numberOfErrors += ViETest::TestError(error == 0, "ERROR: %s at line %d",
__FUNCTION__, __LINE__);
error = ptrViENetwork->SetSendDestination(videoChannel, ipAddress, rtpPort);
numberOfErrors += ViETest::TestError(error == 0, "ERROR: %s at line %d",
__FUNCTION__, __LINE__);
error = ptrViEBase->StartSend(videoChannel);
numberOfErrors += ViETest::TestError(error == 0, "ERROR: %s at line %d",
__FUNCTION__, __LINE__);
//
// Make sure all codecs runs
//
{
webrtc::ViEImageProcess *ptrViEImageProcess =
webrtc::ViEImageProcess::GetInterface(ptrViE);
ViEAutotestCodecObserever codecObserver;
error = ptrViECodec->RegisterDecoderObserver(videoChannel, codecObserver);
numberOfErrors += ViETest::TestError(error == 0,
"ERROR: %s at line %d",
__FUNCTION__, __LINE__);
ViETest::Log("Loop through all codecs for %d seconds",
KAutoTestSleepTimeMs / 1000);
for (int idx = 0; idx < ptrViECodec->NumberOfCodecs() - 2; idx++)
{
error = ptrViECodec->GetCodec(idx, videoCodec);
numberOfErrors += ViETest::TestError(error == 0,
"ERROR: %s at line %d",
__FUNCTION__, __LINE__);
if (videoCodec.codecType != webrtc::kVideoCodecMPEG4)
{
if(videoCodec.codecType == webrtc::kVideoCodecI420)
{
// Lower resolution to sockkets keep up.
videoCodec.width=176;
videoCodec.height=144;
videoCodec.maxFramerate=15;
}
error = ptrViECodec->SetSendCodec(videoChannel, videoCodec);
numberOfErrors += ViETest::TestError(error == 0,
"ERROR: %s at line %d",
__FUNCTION__, __LINE__);
ViETest::Log("\t %d. %s", idx, videoCodec.plName);
ViEAutoTestEffectFilter frameCounter;
error = ptrViEImageProcess->RegisterRenderEffectFilter(
videoChannel,
frameCounter);
numberOfErrors += ViETest::TestError(error == 0,
"ERROR: %s at line %d",
__FUNCTION__, __LINE__);
AutoTestSleep( KAutoTestSleepTimeMs);
// Verify we've received and decoded correct payload
numberOfErrors += ViETest::TestError(
codecObserver.incomingCodec.codecType
== videoCodec.codecType, "ERROR: %s at line %d",
__FUNCTION__, __LINE__);
int maxNumberOfRenderedFrames = videoCodec.maxFramerate
* KAutoTestSleepTimeMs / 1000;
if(videoCodec.codecType == webrtc::kVideoCodecI420)
{
// Due to that I420 needs a huge bandwidth, rate control can set
// frame rate very low. This happen since we use the same channel
// as we just tested with vp8.
numberOfErrors += ViETest::TestError(frameCounter.numFrames>0,
"ERROR: %s at line %d",
__FUNCTION__, __LINE__);
}
else
{
#ifdef WEBRTC_ANDROID
// Special case to get the autotest to pass on some slow devices
numberOfErrors +=
ViETest::TestError(frameCounter.numFrames
> maxNumberOfRenderedFrames / 6,
"ERROR: %s at line %d",
__FUNCTION__, __LINE__);
#else
numberOfErrors += ViETest::TestError(frameCounter.numFrames
> maxNumberOfRenderedFrames / 4,
"ERROR: %s at line %d",
__FUNCTION__, __LINE__);
#endif
}
error = ptrViEImageProcess->DeregisterRenderEffectFilter(
videoChannel);
numberOfErrors += ViETest::TestError(error == 0,
"ERROR: %s at line %d",
__FUNCTION__, __LINE__);
}
else
{
ViETest::Log("\t %d. %s not tested", idx, videoCodec.plName);
}
}
ptrViEImageProcess->Release();
error = ptrViECodec->DeregisterDecoderObserver(videoChannel);
numberOfErrors += ViETest::TestError(error == 0,
"ERROR: %s at line %d",
__FUNCTION__, __LINE__);
ViETest::Log("Done!");
}
//
// Callbacks
//
ViEAutotestCodecObserever codecObserver;
error = ptrViECodec->RegisterEncoderObserver(videoChannel, codecObserver);
numberOfErrors += ViETest::TestError(error == 0, "ERROR: %s at line %d",
__FUNCTION__, __LINE__);
error = ptrViECodec->RegisterDecoderObserver(videoChannel, codecObserver);
numberOfErrors += ViETest::TestError(error == 0, "ERROR: %s at line %d",
__FUNCTION__, __LINE__);
ViETest::Log("\nTesting codec callbacks...");
for (int idx = 0; idx < ptrViECodec->NumberOfCodecs(); idx++)
{
error = ptrViECodec->GetCodec(idx, videoCodec);
numberOfErrors += ViETest::TestError(error == 0, "ERROR: %s at line %d",
__FUNCTION__, __LINE__);
if (videoCodec.codecType == webrtc::kVideoCodecVP8)
{
error = ptrViECodec->SetSendCodec(videoChannel, videoCodec);
numberOfErrors += ViETest::TestError(error == 0,
"ERROR: %s at line %d",
__FUNCTION__, __LINE__);
break;
}
}
AutoTestSleep (KAutoTestSleepTimeMs);
error = ptrViEBase->StopSend(videoChannel);
numberOfErrors += ViETest::TestError(error == 0, "ERROR: %s at line %d",
__FUNCTION__, __LINE__);
error = ptrViECodec->DeregisterEncoderObserver(videoChannel);
numberOfErrors += ViETest::TestError(error == 0, "ERROR: %s at line %d",
__FUNCTION__, __LINE__);
error = ptrViECodec->DeregisterDecoderObserver(videoChannel);
numberOfErrors += ViETest::TestError(error == 0, "ERROR: %s at line %d",
__FUNCTION__, __LINE__);
numberOfErrors += ViETest::TestError(codecObserver.incomingCodecCalled > 0,
"ERROR: %s at line %d", __FUNCTION__,
__LINE__);
numberOfErrors += ViETest::TestError(codecObserver.incomingRatecalled > 0,
"ERROR: %s at line %d", __FUNCTION__,
__LINE__);
numberOfErrors += ViETest::TestError(codecObserver.outgoingRatecalled > 0,
"ERROR: %s at line %d", __FUNCTION__,
__LINE__);
//***************************************************************
// Testing finished. Tear down Video Engine
//***************************************************************
error = ptrViEBase->StopReceive(videoChannel);
numberOfErrors += ViETest::TestError(error == 0, "ERROR: %s at line %d",
__FUNCTION__, __LINE__);
error = ptrViEBase->StopSend(videoChannel); // Already stopped
numberOfErrors += ViETest::TestError(error == -1, "ERROR: %s at line %d",
__FUNCTION__, __LINE__);
error = ptrViERender->StopRender(videoChannel);
numberOfErrors += ViETest::TestError(error == 0, "ERROR: %s at line %d",
__FUNCTION__, __LINE__);
error = ptrViERender->RemoveRenderer(captureId);
numberOfErrors += ViETest::TestError(error == 0, "ERROR: %s at line %d",
__FUNCTION__, __LINE__);
error = ptrViERender->RemoveRenderer(videoChannel);
numberOfErrors += ViETest::TestError(error == 0, "ERROR: %s at line %d",
__FUNCTION__, __LINE__);
error = ptrViECapture->DisconnectCaptureDevice(videoChannel);
numberOfErrors += ViETest::TestError(error == 0, "ERROR: %s at line %d",
__FUNCTION__, __LINE__);
error = ptrViEBase->DeleteChannel(videoChannel);
numberOfErrors += ViETest::TestError(error == 0, "ERROR: %s at line %d",
__FUNCTION__, __LINE__);
}

View File

@ -46,6 +46,7 @@
# Helper classes
'helpers/vie_window_creator.cc',
'helpers/vie_file_capture_device.cc',
'helpers/vie_fake_camera.cc',
# New, fully automated tests
'automated/vie_api_integration_test.cc',