Skip to content

Commit 78c767f

Browse files
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
1 parent d855c1a commit 78c767f

File tree

9 files changed

+488
-369
lines changed

9 files changed

+488
-369
lines changed

src/video_engine/main/test/AutoTest/automated/vie_standard_integration_test.cc

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -62,14 +62,17 @@ TEST_F(ViEStandardIntegrationTest, RunsBaseTestWithoutErrors) {
6262
FLAGS_i420_test_video_height);
6363
}
6464

65+
TEST_F(ViEStandardIntegrationTest, RunsCodecTestWithoutErrors) {
66+
tests_->ViEAutomatedCodecStandardTest(FLAGS_i420_test_video_path,
67+
FLAGS_i420_test_video_width,
68+
FLAGS_i420_test_video_height);
69+
}
70+
6571
// These tests still require a physical camera:
6672
TEST_F(ViEStandardIntegrationTest, RunsCaptureTestWithoutErrors) {
6773
ASSERT_EQ(0, tests_->ViECaptureStandardTest());
6874
}
6975

70-
TEST_F(ViEStandardIntegrationTest, RunsCodecTestWithoutErrors) {
71-
ASSERT_EQ(0, tests_->ViECodecStandardTest());
72-
}
7376

7477
TEST_F(ViEStandardIntegrationTest, RunsEncryptionTestWithoutErrors) {
7578
ASSERT_EQ(0, tests_->ViEEncryptionStandardTest());
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
/*
2+
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
3+
*
4+
* Use of this source code is governed by a BSD-style license
5+
* that can be found in the LICENSE file in the root of the source
6+
* tree. An additional intellectual property rights grant can be found
7+
* in the file PATENTS. All contributing project authors may
8+
* be found in the AUTHORS file in the root of the source tree.
9+
*/
10+
#include "vie_fake_camera.h"
11+
12+
#include <assert.h>
13+
14+
#include "vie_capture.h"
15+
#include "vie_file_capture_device.h"
16+
#include "thread_wrapper.h"
17+
18+
// This callback runs the camera thread:
19+
bool StreamVideoFileRepeatedlyIntoCaptureDevice(void* data) {
20+
ViEFileCaptureDevice* file_capture_device =
21+
reinterpret_cast<ViEFileCaptureDevice*>(data);
22+
23+
uint64_t time_slice_ms = 1500;
24+
uint32_t max_fps = 30;
25+
file_capture_device->ReadFileFor(time_slice_ms, max_fps);
26+
27+
return true;
28+
}
29+
30+
ViEFakeCamera::ViEFakeCamera(webrtc::ViECapture* capture_interface)
31+
: capture_interface_(capture_interface),
32+
camera_thread_(NULL),
33+
file_capture_device_(NULL) {
34+
}
35+
36+
ViEFakeCamera::~ViEFakeCamera() {
37+
}
38+
39+
bool ViEFakeCamera::StartCameraInNewThread(
40+
const std::string& i420_test_video_path, int width, int height) {
41+
42+
assert(file_capture_device_ == NULL && camera_thread_ == NULL);
43+
44+
webrtc::ViEExternalCapture* externalCapture;
45+
int result = capture_interface_->
46+
AllocateExternalCaptureDevice(capture_id_, externalCapture);
47+
if (result != 0) {
48+
return false;
49+
}
50+
51+
file_capture_device_ = new ViEFileCaptureDevice(externalCapture);
52+
if (!file_capture_device_->OpenI420File(i420_test_video_path,
53+
width,
54+
height)) {
55+
return false;
56+
}
57+
58+
// Set up a thread which runs the fake camera. The capturer object is
59+
// thread-safe.
60+
camera_thread_ = webrtc::ThreadWrapper::CreateThread(
61+
StreamVideoFileRepeatedlyIntoCaptureDevice, file_capture_device_);
62+
unsigned int id;
63+
camera_thread_->Start(id);
64+
65+
return true;
66+
}
67+
68+
bool ViEFakeCamera::StopCamera() {
69+
assert(file_capture_device_ != NULL && camera_thread_ != NULL);
70+
71+
camera_thread_->Stop();
72+
file_capture_device_->CloseFile();
73+
74+
int result = capture_interface_->ReleaseCaptureDevice(capture_id_);
75+
76+
delete camera_thread_;
77+
delete file_capture_device_;
78+
camera_thread_ = NULL;
79+
file_capture_device_ = NULL;
80+
81+
return result == 0;
82+
}
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
/*
2+
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
3+
*
4+
* Use of this source code is governed by a BSD-style license
5+
* that can be found in the LICENSE file in the root of the source
6+
* tree. An additional intellectual property rights grant can be found
7+
* in the file PATENTS. All contributing project authors may
8+
* be found in the AUTHORS file in the root of the source tree.
9+
*/
10+
#ifndef SRC_VIDEO_ENGINE_MAIN_TEST_AUTOTEST_HELPERS_VIE_FAKE_CAMERA_H_
11+
#define SRC_VIDEO_ENGINE_MAIN_TEST_AUTOTEST_HELPERS_VIE_FAKE_CAMERA_H_
12+
13+
#include <string>
14+
15+
namespace webrtc {
16+
class ViECapture;
17+
class ThreadWrapper;
18+
}
19+
20+
class ViEFileCaptureDevice;
21+
22+
// Registers an external capture device with the provided capture interface
23+
// and starts running a fake camera by reading frames from a file. The frame-
24+
// reading code runs in a separate thread which makes it possible to run tests
25+
// while the fake camera feeds data into the system. This class is not thread-
26+
// safe in itself (but handles its own thread in a safe manner).
27+
class ViEFakeCamera {
28+
public:
29+
// The argument is the capture interface to register with.
30+
explicit ViEFakeCamera(webrtc::ViECapture* capture_interface);
31+
virtual ~ViEFakeCamera();
32+
33+
// Runs the scenario in the class comments.
34+
bool StartCameraInNewThread(const std::string& i420_test_video_path,
35+
int width,
36+
int height);
37+
// Stops the camera and cleans up everything allocated by the start method.
38+
bool StopCamera();
39+
40+
int capture_id() const { return capture_id_; }
41+
42+
private:
43+
webrtc::ViECapture* capture_interface_;
44+
45+
int capture_id_;
46+
webrtc::ThreadWrapper* camera_thread_;
47+
ViEFileCaptureDevice* file_capture_device_;
48+
};
49+
50+
#endif // SRC_VIDEO_ENGINE_MAIN_TEST_AUTOTEST_HELPERS_VIE_FAKE_CAMERA_H_

src/video_engine/main/test/AutoTest/helpers/vie_file_capture_device.cc

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99
*/
1010
#include "vie_file_capture_device.h"
1111

12+
#include <assert.h>
13+
1214
#include "common_types.h"
1315
#include "critical_section_wrapper.h"
1416
#include "event_wrapper.h"

src/video_engine/main/test/AutoTest/helpers/vie_file_capture_device.h

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,8 @@ class EventWrapper;
2323
class ViEExternalCapture;
2424
}
2525

26-
/**
27-
* This class opens a i420 file and feeds it into a ExternalCapture instance,
28-
* thereby acting as a faked capture device with deterministic input.
29-
*/
26+
// This class opens a i420 file and feeds it into a ExternalCapture instance,
27+
// thereby acting as a faked capture device with deterministic input.
3028
class ViEFileCaptureDevice {
3129
public:
3230
// The input sink is where to send the I420 video frames.

src/video_engine/main/test/AutoTest/interface/vie_autotest.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,8 @@
3939
#include <string>
4040
#endif
4141

42+
class tbInterfaces;
43+
4244
class ViEAutoTest
4345
{
4446
public:
@@ -77,6 +79,10 @@ class ViEAutoTest
7779
int ViECodecExternalCodecTest();
7880
int ViECodecAPITest();
7981

82+
void ViEAutomatedCodecStandardTest(const std::string& pathToTestI420Video,
83+
int width,
84+
int height);
85+
8086
// vie_autotest_encryption.cc
8187
int ViEEncryptionStandardTest();
8288
int ViEEncryptionExtendedTest();
@@ -126,6 +132,10 @@ class ViEAutoTest
126132
void PrintAudioCodec(const webrtc::CodecInst audioCodec);
127133
void PrintVideoCodec(const webrtc::VideoCodec videoCodec);
128134

135+
void RunCodecTestInternal(const tbInterfaces& interfaces,
136+
int & numberOfErrors,
137+
int captureId);
138+
129139
void* _window1;
130140
void* _window2;
131141

src/video_engine/main/test/AutoTest/source/vie_autotest_base.cc

Lines changed: 17 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,12 @@
1313
//
1414

1515
#include "gtest/gtest.h"
16-
17-
#include "thread_wrapper.h"
18-
#include "vie_autotest.h"
19-
#include "vie_autotest_defines.h"
2016
#include "video_capture_factory.h"
17+
#include "vie_autotest_defines.h"
18+
#include "vie_autotest.h"
19+
#include "vie_fake_camera.h"
2120
#include "vie_file_capture_device.h"
21+
#include "thread_wrapper.h"
2222

2323
class BaseObserver : public webrtc::ViEBaseObserver {
2424
public:
@@ -238,9 +238,6 @@ void StopEverything(webrtc::ViEBase * ptrViEBase,
238238
error = ptrViECapture->DisconnectCaptureDevice(videoChannel);
239239
numberOfErrors += ViETest::TestError(error == 0, "ERROR: %s at line %d",
240240
__FUNCTION__, __LINE__);
241-
error = ptrViECapture->ReleaseCaptureDevice(captureId);
242-
numberOfErrors += ViETest::TestError(error == 0, "ERROR: %s at line %d",
243-
__FUNCTION__, __LINE__);
244241
}
245242

246243
void ReleaseEverything(webrtc::ViECapture *ptrViECapture,
@@ -355,6 +352,10 @@ int ViEAutoTest::ViEBaseStandardTest() {
355352
StopEverything(ptrViEBase, videoChannel, numberOfErrors, ptrViERender,
356353
captureId, ptrViECapture, _vrm1, _vrm2);
357354

355+
error = ptrViECapture->ReleaseCaptureDevice(captureId);
356+
numberOfErrors += ViETest::TestError(error == 0, "ERROR: %s at line %d",
357+
__FUNCTION__, __LINE__);
358+
358359
vcpm->Release();
359360
vcpm = NULL;
360361

@@ -590,18 +591,6 @@ int ViEAutoTest::ViEBaseAPITest() {
590591
return 0;
591592
}
592593

593-
// This callback gets used in the automated test case below:
594-
bool StreamVideoFileRepeatedlyIntoCaptureDevice(void* data) {
595-
ViEFileCaptureDevice* file_capture_device =
596-
reinterpret_cast<ViEFileCaptureDevice*>(data);
597-
598-
WebRtc_UWord64 time_slice_ms = 1500;
599-
WebRtc_UWord64 max_fps = 30;
600-
file_capture_device->ReadFileFor(time_slice_ms, max_fps);
601-
602-
return true;
603-
}
604-
605594
void ViEAutoTest::ViEAutomatedBaseStandardTest(
606595
const std::string& pathToTestI420Video, int width, int height) {
607596
int ignoredNumberOfErrors;
@@ -617,29 +606,15 @@ void ViEAutoTest::ViEAutomatedBaseStandardTest(
617606
InitializeChannel(ptrViEBase, videoChannel,
618607
ignoredNumberOfErrors, ptrViE);
619608

620-
int captureId;
621-
webrtc::ViEExternalCapture* externalCapture;
622-
int error = ptrViECapture->AllocateExternalCaptureDevice(captureId,
623-
externalCapture);
624-
ViETest::TestError(error == 0, "ERROR: %s at line %d",
625-
__FUNCTION__, __LINE__);
626-
627-
ViEFileCaptureDevice capturer(externalCapture);
628-
if (!capturer.OpenI420File(pathToTestI420Video, width, height)) {
609+
ViEFakeCamera fakeCamera(ptrViECapture);
610+
if (!fakeCamera.StartCameraInNewThread(pathToTestI420Video, width, height)) {
629611
// No point in continuing if we have no proper video source
630612
ViETest::TestError(false, "ERROR: %s at line %d: "
631613
"Could not open input video %s: aborting test...",
632614
__FUNCTION__, __LINE__, pathToTestI420Video.c_str());
633615
return;
634616
}
635-
636-
// Set up a thread which runs the fake camera. Note that the capturer is
637-
// handed off to the other thread - it should not be touched in this
638-
// method until the other thread is stopped!
639-
webrtc::ThreadWrapper* thread = webrtc::ThreadWrapper::CreateThread(
640-
StreamVideoFileRepeatedlyIntoCaptureDevice, &capturer);
641-
unsigned int id;
642-
thread->Start(id);
617+
int captureId = fakeCamera.capture_id();
643618

644619
// Apparently, we need to connect external capture devices, but we should
645620
// not start them since the external device is not a proper device.
@@ -667,13 +642,15 @@ void ViEAutoTest::ViEAutomatedBaseStandardTest(
667642

668643
AutoTestSleep(KAutoTestSleepTimeMs);
669644

670-
// Done, clean up
671-
thread->Stop();
672-
capturer.CloseFile();
673-
674645
StopEverything(ptrViEBase, videoChannel, ignoredNumberOfErrors, ptrViERender,
675646
captureId, ptrViECapture, _vrm1, _vrm2);
676647

648+
// Stop sending data, clean up the camera thread and release the capture
649+
// device. Note that this all happens after StopEverything, so this is
650+
// tests that the system doesn't mind that the external capture device sends
651+
// data after rendering has been stopped.
652+
fakeCamera.StopCamera();
653+
677654
ReleaseEverything(ptrViECapture, ignoredNumberOfErrors, ptrViEBase,
678655
videoChannel, ptrViECodec, ptrViERtpRtcp, ptrViERender,
679656
ptrViENetwork, ptrViE);

0 commit comments

Comments
 (0)