diff --git a/src/video_engine/main/test/AutoTest/automated/vie_standard_integration_test.cc b/src/video_engine/main/test/AutoTest/automated/vie_standard_integration_test.cc index 5ce3e5954..1b556d484 100644 --- a/src/video_engine/main/test/AutoTest/automated/vie_standard_integration_test.cc +++ b/src/video_engine/main/test/AutoTest/automated/vie_standard_integration_test.cc @@ -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()); diff --git a/src/video_engine/main/test/AutoTest/helpers/vie_fake_camera.cc b/src/video_engine/main/test/AutoTest/helpers/vie_fake_camera.cc new file mode 100644 index 000000000..ce701b47c --- /dev/null +++ b/src/video_engine/main/test/AutoTest/helpers/vie_fake_camera.cc @@ -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 + +#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(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; +} diff --git a/src/video_engine/main/test/AutoTest/helpers/vie_fake_camera.h b/src/video_engine/main/test/AutoTest/helpers/vie_fake_camera.h new file mode 100644 index 000000000..0b9c2e732 --- /dev/null +++ b/src/video_engine/main/test/AutoTest/helpers/vie_fake_camera.h @@ -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 + +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_ diff --git a/src/video_engine/main/test/AutoTest/helpers/vie_file_capture_device.cc b/src/video_engine/main/test/AutoTest/helpers/vie_file_capture_device.cc index 7e70d74cd..657c7fb2b 100644 --- a/src/video_engine/main/test/AutoTest/helpers/vie_file_capture_device.cc +++ b/src/video_engine/main/test/AutoTest/helpers/vie_file_capture_device.cc @@ -9,6 +9,8 @@ */ #include "vie_file_capture_device.h" +#include + #include "common_types.h" #include "critical_section_wrapper.h" #include "event_wrapper.h" diff --git a/src/video_engine/main/test/AutoTest/helpers/vie_file_capture_device.h b/src/video_engine/main/test/AutoTest/helpers/vie_file_capture_device.h index b00076759..5e62c48d3 100644 --- a/src/video_engine/main/test/AutoTest/helpers/vie_file_capture_device.h +++ b/src/video_engine/main/test/AutoTest/helpers/vie_file_capture_device.h @@ -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. diff --git a/src/video_engine/main/test/AutoTest/interface/vie_autotest.h b/src/video_engine/main/test/AutoTest/interface/vie_autotest.h index 62723551c..d87d7b607 100644 --- a/src/video_engine/main/test/AutoTest/interface/vie_autotest.h +++ b/src/video_engine/main/test/AutoTest/interface/vie_autotest.h @@ -39,6 +39,8 @@ #include #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; diff --git a/src/video_engine/main/test/AutoTest/source/vie_autotest_base.cc b/src/video_engine/main/test/AutoTest/source/vie_autotest_base.cc index 2486f1d52..27ab17d97 100644 --- a/src/video_engine/main/test/AutoTest/source/vie_autotest_base.cc +++ b/src/video_engine/main/test/AutoTest/source/vie_autotest_base.cc @@ -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(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); diff --git a/src/video_engine/main/test/AutoTest/source/vie_autotest_codec.cc b/src/video_engine/main/test/AutoTest/source/vie_autotest_codec.cc index f1ead3955..ca6007301 100644 --- a/src/video_engine/main/test/AutoTest/source/vie_autotest_codec.cc +++ b/src/video_engine/main/test/AutoTest/source/vie_autotest_codec.cc @@ -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__); +} diff --git a/src/video_engine/main/test/AutoTest/vie_auto_test.gypi b/src/video_engine/main/test/AutoTest/vie_auto_test.gypi index fb6a5962b..fd192d6e3 100644 --- a/src/video_engine/main/test/AutoTest/vie_auto_test.gypi +++ b/src/video_engine/main/test/AutoTest/vie_auto_test.gypi @@ -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',