Adding operator== and != methods for CodecInst and VideoCodec structures.
R=juberti@google.com, mflodman@webrtc.org Review URL: https://webrtc-codereview.appspot.com/10099005 git-svn-id: http://webrtc.googlecode.com/svn/trunk@5746 4adac7df-926f-26a2-2b94-8c16560cd09d
This commit is contained in:
parent
9c2bd2b288
commit
0209e565de
@ -12,7 +12,7 @@
|
||||
#define WEBRTC_COMMON_TYPES_H_
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#include <string.h>
|
||||
#include <vector>
|
||||
|
||||
#include "webrtc/typedefs.h"
|
||||
@ -37,7 +37,7 @@
|
||||
|
||||
#define RTP_PAYLOAD_NAME_SIZE 32
|
||||
|
||||
#if defined(WEBRTC_WIN)
|
||||
#if defined(WEBRTC_WIN) || defined(WIN32)
|
||||
// Compares two strings without regard to case.
|
||||
#define STR_CASE_CMP(s1, s2) ::_stricmp(s1, s2)
|
||||
// Compares characters of two strings without regard to case.
|
||||
@ -272,14 +272,26 @@ class FrameCountObserver {
|
||||
// ==================================================================
|
||||
|
||||
// Each codec supported can be described by this structure.
|
||||
struct CodecInst
|
||||
{
|
||||
int pltype;
|
||||
char plname[RTP_PAYLOAD_NAME_SIZE];
|
||||
int plfreq;
|
||||
int pacsize;
|
||||
int channels;
|
||||
int rate; // bits/sec unlike {start,min,max}Bitrate elsewhere in this file!
|
||||
struct CodecInst {
|
||||
int pltype;
|
||||
char plname[RTP_PAYLOAD_NAME_SIZE];
|
||||
int plfreq;
|
||||
int pacsize;
|
||||
int channels;
|
||||
int rate; // bits/sec unlike {start,min,max}Bitrate elsewhere in this file!
|
||||
|
||||
bool operator==(const CodecInst& other) const {
|
||||
return pltype == other.pltype &&
|
||||
(STR_CASE_CMP(plname, other.plname) == 0) &&
|
||||
plfreq == other.plfreq &&
|
||||
pacsize == other.pacsize &&
|
||||
channels == other.channels &&
|
||||
rate == other.rate;
|
||||
}
|
||||
|
||||
bool operator!=(const CodecInst& other) const {
|
||||
return !(*this == other);
|
||||
}
|
||||
};
|
||||
|
||||
// RTP
|
||||
@ -541,18 +553,34 @@ enum VP8ResilienceMode {
|
||||
};
|
||||
|
||||
// VP8 specific
|
||||
struct VideoCodecVP8
|
||||
{
|
||||
bool pictureLossIndicationOn;
|
||||
bool feedbackModeOn;
|
||||
VideoCodecComplexity complexity;
|
||||
VP8ResilienceMode resilience;
|
||||
unsigned char numberOfTemporalLayers;
|
||||
bool denoisingOn;
|
||||
bool errorConcealmentOn;
|
||||
bool automaticResizeOn;
|
||||
bool frameDroppingOn;
|
||||
int keyFrameInterval;
|
||||
struct VideoCodecVP8 {
|
||||
bool pictureLossIndicationOn;
|
||||
bool feedbackModeOn;
|
||||
VideoCodecComplexity complexity;
|
||||
VP8ResilienceMode resilience;
|
||||
unsigned char numberOfTemporalLayers;
|
||||
bool denoisingOn;
|
||||
bool errorConcealmentOn;
|
||||
bool automaticResizeOn;
|
||||
bool frameDroppingOn;
|
||||
int keyFrameInterval;
|
||||
|
||||
bool operator==(const VideoCodecVP8& other) const {
|
||||
return pictureLossIndicationOn == other.pictureLossIndicationOn &&
|
||||
feedbackModeOn == other.feedbackModeOn &&
|
||||
complexity == other.complexity &&
|
||||
resilience == other.resilience &&
|
||||
numberOfTemporalLayers == other.numberOfTemporalLayers &&
|
||||
denoisingOn == other.denoisingOn &&
|
||||
errorConcealmentOn == other.errorConcealmentOn &&
|
||||
automaticResizeOn == other.automaticResizeOn &&
|
||||
frameDroppingOn == other.frameDroppingOn &&
|
||||
keyFrameInterval == other.keyFrameInterval;
|
||||
}
|
||||
|
||||
bool operator!=(const VideoCodecVP8& other) const {
|
||||
return !(*this == other);
|
||||
}
|
||||
};
|
||||
|
||||
// Video codec types
|
||||
@ -574,15 +602,28 @@ union VideoCodecUnion
|
||||
|
||||
// Simulcast is when the same stream is encoded multiple times with different
|
||||
// settings such as resolution.
|
||||
struct SimulcastStream
|
||||
{
|
||||
unsigned short width;
|
||||
unsigned short height;
|
||||
unsigned char numberOfTemporalLayers;
|
||||
unsigned int maxBitrate; // kilobits/sec.
|
||||
unsigned int targetBitrate; // kilobits/sec.
|
||||
unsigned int minBitrate; // kilobits/sec.
|
||||
unsigned int qpMax; // minimum quality
|
||||
struct SimulcastStream {
|
||||
unsigned short width;
|
||||
unsigned short height;
|
||||
unsigned char numberOfTemporalLayers;
|
||||
unsigned int maxBitrate; // kilobits/sec.
|
||||
unsigned int targetBitrate; // kilobits/sec.
|
||||
unsigned int minBitrate; // kilobits/sec.
|
||||
unsigned int qpMax; // minimum quality
|
||||
|
||||
bool operator==(const SimulcastStream& other) const {
|
||||
return width == other.width &&
|
||||
height == other.height &&
|
||||
numberOfTemporalLayers == other.numberOfTemporalLayers &&
|
||||
maxBitrate == other.maxBitrate &&
|
||||
targetBitrate == other.targetBitrate &&
|
||||
minBitrate == other.minBitrate &&
|
||||
qpMax == other.qpMax;
|
||||
}
|
||||
|
||||
bool operator!=(const SimulcastStream& other) const {
|
||||
return !(*this == other);
|
||||
}
|
||||
};
|
||||
|
||||
enum VideoCodecMode {
|
||||
@ -591,31 +632,63 @@ enum VideoCodecMode {
|
||||
};
|
||||
|
||||
// Common video codec properties
|
||||
struct VideoCodec
|
||||
{
|
||||
VideoCodecType codecType;
|
||||
char plName[kPayloadNameSize];
|
||||
unsigned char plType;
|
||||
struct VideoCodec {
|
||||
VideoCodecType codecType;
|
||||
char plName[kPayloadNameSize];
|
||||
unsigned char plType;
|
||||
|
||||
unsigned short width;
|
||||
unsigned short height;
|
||||
unsigned short width;
|
||||
unsigned short height;
|
||||
|
||||
unsigned int startBitrate; // kilobits/sec.
|
||||
unsigned int maxBitrate; // kilobits/sec.
|
||||
unsigned int minBitrate; // kilobits/sec.
|
||||
unsigned char maxFramerate;
|
||||
unsigned int startBitrate; // kilobits/sec.
|
||||
unsigned int maxBitrate; // kilobits/sec.
|
||||
unsigned int minBitrate; // kilobits/sec.
|
||||
unsigned char maxFramerate;
|
||||
|
||||
VideoCodecUnion codecSpecific;
|
||||
VideoCodecUnion codecSpecific;
|
||||
|
||||
unsigned int qpMax;
|
||||
unsigned char numberOfSimulcastStreams;
|
||||
SimulcastStream simulcastStream[kMaxSimulcastStreams];
|
||||
unsigned int qpMax;
|
||||
unsigned char numberOfSimulcastStreams;
|
||||
SimulcastStream simulcastStream[kMaxSimulcastStreams];
|
||||
|
||||
VideoCodecMode mode;
|
||||
VideoCodecMode mode;
|
||||
|
||||
// When using an external encoder/decoder this allows to pass
|
||||
// extra options without requiring webrtc to be aware of them.
|
||||
Config* extra_options;
|
||||
// When using an external encoder/decoder this allows to pass
|
||||
// extra options without requiring webrtc to be aware of them.
|
||||
Config* extra_options;
|
||||
};
|
||||
|
||||
// TODO(mallinath) - Remove this and push these two methods inside VideoCodec.
|
||||
// This is done to handle operator== defined in fakewebrtcvideoengine.h
|
||||
// This modification allows us to commit this CL directly and not with libjingle
|
||||
// push.
|
||||
struct VideoCodecDerived : public VideoCodec {
|
||||
bool operator==(const VideoCodec& other) const {
|
||||
bool ret = codecType == other.codecType &&
|
||||
(STR_CASE_CMP(plName, other.plName) == 0) &&
|
||||
plType == other.plType &&
|
||||
width == other.width &&
|
||||
height == other.height &&
|
||||
startBitrate == other.startBitrate &&
|
||||
maxBitrate == other.maxBitrate &&
|
||||
minBitrate == other.minBitrate &&
|
||||
maxFramerate == other.maxFramerate &&
|
||||
qpMax == other.qpMax &&
|
||||
numberOfSimulcastStreams == other.numberOfSimulcastStreams &&
|
||||
mode == other.mode;
|
||||
if (ret && codecType == kVideoCodecVP8) {
|
||||
ret &= (codecSpecific.VP8 == other.codecSpecific.VP8);
|
||||
}
|
||||
|
||||
for (unsigned char i = 0; i < other.numberOfSimulcastStreams && ret; ++i) {
|
||||
ret &= (simulcastStream[i] == other.simulcastStream[i]);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool operator!=(const VideoCodec& other) const {
|
||||
return !(*this == other);
|
||||
}
|
||||
};
|
||||
|
||||
// Bandwidth over-use detector options. These are used to drive
|
||||
|
@ -131,6 +131,7 @@
|
||||
'encoder_state_feedback_unittest.cc',
|
||||
'overuse_frame_detector_unittest.cc',
|
||||
'stream_synchronization_unittest.cc',
|
||||
'vie_codec_unittest.cc',
|
||||
'vie_remb_unittest.cc',
|
||||
],
|
||||
'conditions': [
|
||||
|
230
webrtc/video_engine/vie_codec_unittest.cc
Normal file
230
webrtc/video_engine/vie_codec_unittest.cc
Normal file
@ -0,0 +1,230 @@
|
||||
/*
|
||||
* Copyright (c) 2014 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 "testing/gtest/include/gtest/gtest.h"
|
||||
#include "webrtc/common_types.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
// Builds VP8 codec with 0 simulcast streams.
|
||||
void BuildVP8Codec(webrtc::VideoCodec* video_codec) {
|
||||
video_codec->codecType = kVideoCodecVP8;
|
||||
strncpy(video_codec->plName, "VP8", 4);
|
||||
video_codec->plType = 100;
|
||||
video_codec->width = 1280;
|
||||
video_codec->height = 720;
|
||||
|
||||
video_codec->startBitrate = 1000; // kbps
|
||||
video_codec->maxBitrate = 2000; // kbps
|
||||
video_codec->minBitrate = 1000; // kbps
|
||||
video_codec->maxFramerate = 30;
|
||||
|
||||
video_codec->qpMax = 50;
|
||||
video_codec->numberOfSimulcastStreams = 0;
|
||||
video_codec->mode = kRealtimeVideo;
|
||||
|
||||
// Set VP8 codec specific info.
|
||||
video_codec->codecSpecific.VP8.pictureLossIndicationOn = true;
|
||||
video_codec->codecSpecific.VP8.feedbackModeOn = true;
|
||||
video_codec->codecSpecific.VP8.complexity = kComplexityNormal;
|
||||
video_codec->codecSpecific.VP8.resilience = kResilienceOff;
|
||||
video_codec->codecSpecific.VP8.numberOfTemporalLayers = 0;
|
||||
video_codec->codecSpecific.VP8.denoisingOn = true;
|
||||
video_codec->codecSpecific.VP8.errorConcealmentOn = true;
|
||||
video_codec->codecSpecific.VP8.automaticResizeOn = true;
|
||||
video_codec->codecSpecific.VP8.frameDroppingOn = true;
|
||||
video_codec->codecSpecific.VP8.keyFrameInterval = 200;
|
||||
}
|
||||
|
||||
|
||||
void SetSimulcastSettings(webrtc::VideoCodec* video_codec) {
|
||||
// Simulcast settings.
|
||||
video_codec->numberOfSimulcastStreams = 1;
|
||||
video_codec->simulcastStream[0].width = 320;
|
||||
video_codec->simulcastStream[0].height = 180;
|
||||
video_codec->simulcastStream[0].numberOfTemporalLayers = 0;
|
||||
video_codec->simulcastStream[0].maxBitrate = 100;
|
||||
video_codec->simulcastStream[0].targetBitrate = 100;
|
||||
video_codec->simulcastStream[0].minBitrate = 0;
|
||||
video_codec->simulcastStream[0].qpMax = video_codec->qpMax;
|
||||
}
|
||||
|
||||
|
||||
// This test compares two VideoCodecInst objects except codec specific and
|
||||
// simulcast streams.
|
||||
TEST(ViECodecTest, TestCompareCodecs) {
|
||||
VideoCodecDerived codec1, codec2;
|
||||
memset(&codec1, 0, sizeof(VideoCodec));
|
||||
memset(&codec2, 0, sizeof(VideoCodec));
|
||||
|
||||
BuildVP8Codec(&codec1);
|
||||
BuildVP8Codec(&codec2);
|
||||
|
||||
EXPECT_TRUE(codec1 == codec2);
|
||||
EXPECT_FALSE(codec1 != codec2);
|
||||
|
||||
// plname is case insensitive.
|
||||
strncpy(codec2.plName, "vp8", 4);
|
||||
EXPECT_TRUE(codec1 == codec2);
|
||||
|
||||
codec2.codecType = kVideoCodecUnknown;
|
||||
EXPECT_FALSE(codec1 == codec2);
|
||||
|
||||
// Modify pltype.
|
||||
BuildVP8Codec(&codec2);
|
||||
codec2.plType = 101;
|
||||
EXPECT_FALSE(codec1 == codec2);
|
||||
|
||||
// Modifing height and width.
|
||||
BuildVP8Codec(&codec2);
|
||||
codec2.width = 640;
|
||||
codec2.height = 480;
|
||||
EXPECT_FALSE(codec1 == codec2);
|
||||
|
||||
// Modify framerate, default value is 30.
|
||||
BuildVP8Codec(&codec2);
|
||||
codec2.maxFramerate = 15;
|
||||
EXPECT_FALSE(codec1 == codec2);
|
||||
|
||||
// Modifying startBitrate, default value is 1000 kbps.
|
||||
BuildVP8Codec(&codec2);
|
||||
codec2.startBitrate = 2000;
|
||||
EXPECT_FALSE(codec1 == codec2);
|
||||
// maxBitrate
|
||||
BuildVP8Codec(&codec2);
|
||||
codec2.startBitrate = 3000;
|
||||
EXPECT_FALSE(codec1 == codec2);
|
||||
// minBirate
|
||||
BuildVP8Codec(&codec2);
|
||||
codec2.startBitrate = 500;
|
||||
EXPECT_FALSE(codec1 == codec2);
|
||||
|
||||
// Modify qpMax.
|
||||
BuildVP8Codec(&codec2);
|
||||
codec2.qpMax = 100;
|
||||
EXPECT_FALSE(codec1 == codec2);
|
||||
|
||||
// Modify mode
|
||||
BuildVP8Codec(&codec2);
|
||||
codec2.mode = kScreensharing;
|
||||
EXPECT_FALSE(codec1 == codec2);
|
||||
}
|
||||
|
||||
// Test VP8 specific comparision.
|
||||
TEST(ViECodecTest, TestCompareVP8CodecSpecific) {
|
||||
VideoCodecDerived codec1, codec2;
|
||||
memset(&codec1, 0, sizeof(VideoCodec));
|
||||
memset(&codec2, 0, sizeof(VideoCodec));
|
||||
|
||||
BuildVP8Codec(&codec1);
|
||||
BuildVP8Codec(&codec2);
|
||||
EXPECT_TRUE(codec1 == codec2);
|
||||
|
||||
// pictureLossIndicationOn
|
||||
codec2.codecSpecific.VP8.pictureLossIndicationOn = false;
|
||||
EXPECT_FALSE(codec1 == codec2);
|
||||
|
||||
// feedbackModeOn
|
||||
BuildVP8Codec(&codec2);
|
||||
codec2.codecSpecific.VP8.feedbackModeOn = false;
|
||||
EXPECT_FALSE(codec1 == codec2);
|
||||
|
||||
// complexity
|
||||
BuildVP8Codec(&codec2);
|
||||
codec2.codecSpecific.VP8.complexity = kComplexityHigh;
|
||||
EXPECT_FALSE(codec1 == codec2);
|
||||
|
||||
// resilience
|
||||
BuildVP8Codec(&codec2);
|
||||
codec2.codecSpecific.VP8.resilience = kResilientStream;
|
||||
EXPECT_FALSE(codec1 == codec2);
|
||||
|
||||
// numberOfTemporalLayers
|
||||
BuildVP8Codec(&codec2);
|
||||
codec2.codecSpecific.VP8.numberOfTemporalLayers = 2;
|
||||
EXPECT_FALSE(codec1 == codec2);
|
||||
|
||||
// denoisingOn
|
||||
BuildVP8Codec(&codec2);
|
||||
codec2.codecSpecific.VP8.denoisingOn = false;
|
||||
EXPECT_FALSE(codec1 == codec2);
|
||||
|
||||
// errorConcealmentOn
|
||||
BuildVP8Codec(&codec2);
|
||||
codec2.codecSpecific.VP8.errorConcealmentOn = false;
|
||||
EXPECT_FALSE(codec1 == codec2);
|
||||
|
||||
// pictureLossIndicationOn
|
||||
BuildVP8Codec(&codec2);
|
||||
codec2.codecSpecific.VP8.automaticResizeOn = false;
|
||||
EXPECT_FALSE(codec1 == codec2);
|
||||
|
||||
// frameDroppingOn
|
||||
BuildVP8Codec(&codec2);
|
||||
codec2.codecSpecific.VP8.frameDroppingOn = false;
|
||||
EXPECT_FALSE(codec1 == codec2);
|
||||
|
||||
// keyFrameInterval
|
||||
BuildVP8Codec(&codec2);
|
||||
codec2.codecSpecific.VP8.keyFrameInterval = 100;
|
||||
EXPECT_FALSE(codec1 == codec2);
|
||||
}
|
||||
|
||||
// This test compares simulcast stream information in VideoCodec.
|
||||
TEST(ViECodecTest, TestCompareSimulcastStreams) {
|
||||
VideoCodecDerived codec1, codec2;
|
||||
memset(&codec1, 0, sizeof(VideoCodec));
|
||||
memset(&codec2, 0, sizeof(VideoCodec));
|
||||
|
||||
BuildVP8Codec(&codec1);
|
||||
BuildVP8Codec(&codec2);
|
||||
// Set simulacast settings.
|
||||
SetSimulcastSettings(&codec1);
|
||||
SetSimulcastSettings(&codec2);
|
||||
EXPECT_TRUE(codec1 == codec2);
|
||||
|
||||
// Modify number of streams.
|
||||
codec2.numberOfSimulcastStreams = 2;
|
||||
EXPECT_FALSE(codec1 == codec2);
|
||||
|
||||
// Resetting steram count.
|
||||
codec2.numberOfSimulcastStreams = 1;
|
||||
// Modify height and width in codec2.
|
||||
codec2.simulcastStream[0].width = 640;
|
||||
codec2.simulcastStream[0].height = 480;
|
||||
EXPECT_FALSE(codec1 == codec2);
|
||||
|
||||
// numberOfTemporalLayers
|
||||
SetSimulcastSettings(&codec2);
|
||||
codec2.simulcastStream[0].numberOfTemporalLayers = 2;
|
||||
EXPECT_FALSE(codec1 == codec2);
|
||||
|
||||
// maxBitrate
|
||||
SetSimulcastSettings(&codec2);
|
||||
codec2.simulcastStream[0].maxBitrate = 1000;
|
||||
EXPECT_FALSE(codec1 == codec2);
|
||||
|
||||
// targetBitrate
|
||||
SetSimulcastSettings(&codec2);
|
||||
codec2.simulcastStream[0].targetBitrate = 1000;
|
||||
EXPECT_FALSE(codec1 == codec2);
|
||||
|
||||
// minBitrate
|
||||
SetSimulcastSettings(&codec2);
|
||||
codec2.simulcastStream[0].minBitrate = 50;
|
||||
EXPECT_FALSE(codec1 == codec2);
|
||||
|
||||
// qpMax
|
||||
SetSimulcastSettings(&codec2);
|
||||
codec2.simulcastStream[0].qpMax = 100;
|
||||
EXPECT_FALSE(codec1 == codec2);
|
||||
}
|
||||
|
||||
} // namespace webrtc
|
@ -169,6 +169,56 @@ TEST_F(VoECodecTest, DISABLED_ON_ANDROID(DualStreamRemoveSecondaryCodec)) {
|
||||
EXPECT_EQ(-1, voe_codec_->GetSecondarySendCodec(channel_, my_codec));
|
||||
}
|
||||
|
||||
TEST(VoECodecInst, TestCompareCodecInstances) {
|
||||
CodecInst codec1, codec2;
|
||||
memset(&codec1, 0, sizeof(CodecInst));
|
||||
memset(&codec2, 0, sizeof(CodecInst));
|
||||
|
||||
codec1.pltype = 101;
|
||||
strncpy(codec1.plname, "isac", 4);
|
||||
codec1.plfreq = 8000;
|
||||
codec1.pacsize = 110;
|
||||
codec1.channels = 1;
|
||||
codec1.rate = 8000;
|
||||
memcpy(&codec2, &codec1, sizeof(CodecInst));
|
||||
// Compare two codecs now.
|
||||
EXPECT_TRUE(codec1 == codec2);
|
||||
EXPECT_FALSE(codec1 != codec2);
|
||||
|
||||
// Changing pltype.
|
||||
codec2.pltype = 102;
|
||||
EXPECT_FALSE(codec1 == codec2);
|
||||
EXPECT_TRUE(codec1 != codec2);
|
||||
|
||||
// Reset to codec2 to codec1 state.
|
||||
memcpy(&codec2, &codec1, sizeof(CodecInst));
|
||||
// payload name should be case insensitive.
|
||||
strncpy(codec2.plname, "ISAC", 4);
|
||||
EXPECT_TRUE(codec1 == codec2);
|
||||
|
||||
// Test modifying the |plfreq|
|
||||
codec2.plfreq = 16000;
|
||||
EXPECT_FALSE(codec1 == codec2);
|
||||
|
||||
// Reset to codec2 to codec1 state.
|
||||
memcpy(&codec2, &codec1, sizeof(CodecInst));
|
||||
// Test modifying the |pacsize|.
|
||||
codec2.pacsize = 440;
|
||||
EXPECT_FALSE(codec1 == codec2);
|
||||
|
||||
// Reset to codec2 to codec1 state.
|
||||
memcpy(&codec2, &codec1, sizeof(CodecInst));
|
||||
// Test modifying the |channels|.
|
||||
codec2.channels = 2;
|
||||
EXPECT_FALSE(codec1 == codec2);
|
||||
|
||||
// Reset to codec2 to codec1 state.
|
||||
memcpy(&codec2, &codec1, sizeof(CodecInst));
|
||||
// Test modifying the |rate|.
|
||||
codec2.rate = 0;
|
||||
EXPECT_FALSE(codec1 == codec2);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace voe
|
||||
} // namespace webrtc
|
||||
|
Loading…
x
Reference in New Issue
Block a user