blob: 2d434404c61235418d81c3e8145aee26021298c7 [file] [log] [blame]
/*
* 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 "codec_primitives.h"
#include "general_primitives.h"
#include "vie_autotest.h"
#include "vie_autotest_defines.h"
#include "vie_to_file_renderer.h"
#include "video_capture_factory.h"
#include "tb_interfaces.h"
// Helper functions.
void TestCodecImageProcess(webrtc::VideoCodec video_codec,
webrtc::ViECodec* codec_interface,
int video_channel,
webrtc::ViEImageProcess* image_process) {
EXPECT_EQ(0, codec_interface->SetSendCodec(video_channel, video_codec));
FrameCounterEffectFilter frame_counter;
EXPECT_EQ(0, image_process->RegisterRenderEffectFilter(video_channel,
frame_counter));
AutoTestSleep (KAutoTestSleepTimeMs);
int max_number_of_rendered_frames = video_codec.maxFramerate *
KAutoTestSleepTimeMs / 1000;
if (video_codec.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.
EXPECT_GT(frame_counter.numFrames, 0);
} else {
#ifdef WEBRTC_ANDROID
// Special case to get the autotest to pass on some slow devices
EXPECT_GT(frame_counter.numFrames, max_number_of_rendered_frames / 6);
#else
EXPECT_GT(frame_counter.numFrames, max_number_of_rendered_frames / 4);
#endif
}
EXPECT_EQ(0, image_process->DeregisterRenderEffectFilter(video_channel));
}
// Test switching from i420 to VP8 as send codec and make sure that
// the codec observer gets called after the switch.
void TestCodecCallbacks(webrtc::ViEBase *& base_interface,
webrtc::ViECodec *codec_interface,
int video_channel,
int forced_codec_width,
int forced_codec_height) {
// Set I420 as send codec so we don't make any assumptions about what
// we currently have as send codec:
SetSendCodec(webrtc::kVideoCodecI420, codec_interface, video_channel,
forced_codec_width, forced_codec_height);
// Register the observer:
ViEAutotestCodecObserver codec_observer;
EXPECT_EQ(0, codec_interface->RegisterEncoderObserver(video_channel,
codec_observer));
EXPECT_EQ(0, codec_interface->RegisterDecoderObserver(video_channel,
codec_observer));
// Make the switch.
ViETest::Log("Testing codec callbacks...");
SetSendCodec(webrtc::kVideoCodecVP8, codec_interface, video_channel,
forced_codec_width, forced_codec_height);
AutoTestSleep (KAutoTestSleepTimeMs);
// Verify that we got the right codec.
EXPECT_EQ(webrtc::kVideoCodecVP8, codec_observer.incomingCodec.codecType);
// Clean up.
EXPECT_EQ(0, codec_interface->DeregisterEncoderObserver(video_channel));
EXPECT_EQ(0, codec_interface->DeregisterDecoderObserver(video_channel));
// Verify results.
EXPECT_GT(codec_observer.incomingCodecCalled, 0);
EXPECT_GT(codec_observer.incomingRatecalled, 0);
EXPECT_GT(codec_observer.outgoingRatecalled, 0);
}
void TestCodecs(const TbInterfaces& interfaces,
int capture_id,
int video_channel,
int forced_codec_width,
int forced_codec_height) {
webrtc::VideoEngine *video_engine_interface = interfaces.video_engine;
webrtc::ViEBase *base_interface = interfaces.base;
webrtc::ViECapture *capture_interface = interfaces.capture;
webrtc::ViERender *render_interface = interfaces.render;
webrtc::ViECodec *codec_interface = interfaces.codec;
webrtc::ViENetwork *network_interface = interfaces.network;
// ***************************************************************
// Engine ready. Begin testing class
// ***************************************************************
webrtc::VideoCodec video_codec;
memset(&video_codec, 0, sizeof (webrtc::VideoCodec));
// Set up all receive codecs. This basically trains the codec interface
// to be able to recognize all receive codecs based on payload type.
for (int idx = 0; idx < codec_interface->NumberOfCodecs(); idx++) {
EXPECT_EQ(0, codec_interface->GetCodec(idx, video_codec));
SetSuitableResolution(&video_codec,
forced_codec_width,
forced_codec_height);
EXPECT_EQ(0, codec_interface->SetReceiveCodec(video_channel, video_codec));
}
const char *ip_address = "127.0.0.1";
const unsigned short rtp_port = 6000;
EXPECT_EQ(0, network_interface->SetLocalReceiver(video_channel, rtp_port));
EXPECT_EQ(0, base_interface->StartReceive(video_channel));
EXPECT_EQ(0, network_interface->SetSendDestination(video_channel, ip_address,
rtp_port));
EXPECT_EQ(0, base_interface->StartSend(video_channel));
// Run all found codecs
webrtc::ViEImageProcess *image_process =
webrtc::ViEImageProcess::GetInterface(video_engine_interface);
EXPECT_TRUE(image_process != NULL);
ViETest::Log("Loop through all codecs for %d seconds",
KAutoTestSleepTimeMs / 1000);
for (int i = 0; i < codec_interface->NumberOfCodecs(); i++) {
EXPECT_EQ(0, codec_interface->GetCodec(i, video_codec));
if (video_codec.codecType == webrtc::kVideoCodecRED ||
video_codec.codecType == webrtc::kVideoCodecULPFEC) {
ViETest::Log("\t %d. %s not tested", i, video_codec.plName);
} else {
ViETest::Log("\t %d. %s", i, video_codec.plName);
SetSuitableResolution(&video_codec, forced_codec_width,
forced_codec_height);
TestCodecImageProcess(video_codec, codec_interface, video_channel,
image_process);
}
}
image_process->Release();
TestCodecCallbacks(base_interface, codec_interface, video_channel,
forced_codec_width, forced_codec_height);
ViETest::Log("Done!");
// ***************************************************************
// Testing finished. Tear down Video Engine
// ***************************************************************
EXPECT_EQ(0, base_interface->StopSend(video_channel));
EXPECT_EQ(0, base_interface->StopReceive(video_channel));
EXPECT_EQ(0, render_interface->StopRender(capture_id));
EXPECT_EQ(0, render_interface->StopRender(video_channel));
EXPECT_EQ(0, render_interface->RemoveRenderer(capture_id));
EXPECT_EQ(0, render_interface->RemoveRenderer(video_channel));
EXPECT_EQ(0, capture_interface->DisconnectCaptureDevice(video_channel));
EXPECT_EQ(0, base_interface->DeleteChannel(video_channel));
}
void SetSendCodec(webrtc::VideoCodecType of_type,
webrtc::ViECodec* codec_interface,
int video_channel,
int forced_codec_width,
int forced_codec_height) {
webrtc::VideoCodec codec;
bool ok;
EXPECT_TRUE(ok = FindSpecificCodec(of_type, codec_interface, &codec));
if (!ok) {
return;
}
SetSuitableResolution(&codec, forced_codec_width, forced_codec_height);
EXPECT_EQ(0, codec_interface->SetSendCodec(video_channel, codec));
}