The function GetExecutablePath is a hack with poor portability. Delete it and its caller GetTestFilePath. The latter was used in videoframe_unittest.h, where it is replaced by webrtc::test::ResourcePath. Delete unused functions declared in base/testutils.h: ReadFile, GetSiblingDirectory, GetGoogle3Directory, GetTalkDirectory, CmpHelperFileEq, EXPECT_FILEEQ, ASSERT_FILEEQ. Delete unused functions declared in media/base/testutils.h: GetTestFilePath (see above), LoadPlanarYuvTestImage, DumpPlanarYuvTestImage, ComputePSNR, ComputeSumSquareError. The functions LoadPlanarYuvTestImage, DumpPlanarYuvTestImage were used in yuvscaler_unittests.cc and planarfunctions_unittests.cc, under webrtc/pc. However, these tests are never compiled or run, and appear not to have been for the last few years, and are therefore deleted rather than updated. It might make sense to check if libyuv have comparable tests, and if not, resurrect them as part of libyuv unittests. BUG= R=perkj@webrtc.org Review URL: https://codereview.webrtc.org/2058043002 . Cr-Commit-Position: refs/heads/master@{#13163}
273 lines
9.2 KiB
C++
273 lines
9.2 KiB
C++
/*
|
|
* Copyright (c) 2004 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 "webrtc/media/base/testutils.h"
|
|
|
|
#include <math.h>
|
|
#include <algorithm>
|
|
#include <memory>
|
|
|
|
#include "webrtc/base/bytebuffer.h"
|
|
#include "webrtc/base/fileutils.h"
|
|
#include "webrtc/base/gunit.h"
|
|
#include "webrtc/base/pathutils.h"
|
|
#include "webrtc/base/stream.h"
|
|
#include "webrtc/base/stringutils.h"
|
|
#include "webrtc/base/testutils.h"
|
|
#include "webrtc/media/base/rtpdump.h"
|
|
#include "webrtc/media/base/videocapturer.h"
|
|
#include "webrtc/media/base/videoframe.h"
|
|
|
|
namespace cricket {
|
|
|
|
/////////////////////////////////////////////////////////////////////////
|
|
// Implementation of RawRtpPacket
|
|
/////////////////////////////////////////////////////////////////////////
|
|
void RawRtpPacket::WriteToByteBuffer(uint32_t in_ssrc,
|
|
rtc::ByteBufferWriter* buf) const {
|
|
if (!buf) return;
|
|
|
|
buf->WriteUInt8(ver_to_cc);
|
|
buf->WriteUInt8(m_to_pt);
|
|
buf->WriteUInt16(sequence_number);
|
|
buf->WriteUInt32(timestamp);
|
|
buf->WriteUInt32(in_ssrc);
|
|
buf->WriteBytes(payload, sizeof(payload));
|
|
}
|
|
|
|
bool RawRtpPacket::ReadFromByteBuffer(rtc::ByteBufferReader* buf) {
|
|
if (!buf) return false;
|
|
|
|
bool ret = true;
|
|
ret &= buf->ReadUInt8(&ver_to_cc);
|
|
ret &= buf->ReadUInt8(&m_to_pt);
|
|
ret &= buf->ReadUInt16(&sequence_number);
|
|
ret &= buf->ReadUInt32(×tamp);
|
|
ret &= buf->ReadUInt32(&ssrc);
|
|
ret &= buf->ReadBytes(payload, sizeof(payload));
|
|
return ret;
|
|
}
|
|
|
|
bool RawRtpPacket::SameExceptSeqNumTimestampSsrc(const RawRtpPacket& packet,
|
|
uint16_t seq,
|
|
uint32_t ts,
|
|
uint32_t ssc) const {
|
|
return sequence_number == seq &&
|
|
timestamp == ts &&
|
|
ver_to_cc == packet.ver_to_cc &&
|
|
m_to_pt == packet.m_to_pt &&
|
|
ssrc == ssc &&
|
|
0 == memcmp(payload, packet.payload, sizeof(payload));
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////
|
|
// Implementation of RawRtcpPacket
|
|
/////////////////////////////////////////////////////////////////////////
|
|
void RawRtcpPacket::WriteToByteBuffer(rtc::ByteBufferWriter *buf) const {
|
|
if (!buf) return;
|
|
|
|
buf->WriteUInt8(ver_to_count);
|
|
buf->WriteUInt8(type);
|
|
buf->WriteUInt16(length);
|
|
buf->WriteBytes(payload, sizeof(payload));
|
|
}
|
|
|
|
bool RawRtcpPacket::ReadFromByteBuffer(rtc::ByteBufferReader* buf) {
|
|
if (!buf) return false;
|
|
|
|
bool ret = true;
|
|
ret &= buf->ReadUInt8(&ver_to_count);
|
|
ret &= buf->ReadUInt8(&type);
|
|
ret &= buf->ReadUInt16(&length);
|
|
ret &= buf->ReadBytes(payload, sizeof(payload));
|
|
return ret;
|
|
}
|
|
|
|
bool RawRtcpPacket::EqualsTo(const RawRtcpPacket& packet) const {
|
|
return ver_to_count == packet.ver_to_count &&
|
|
type == packet.type &&
|
|
length == packet.length &&
|
|
0 == memcmp(payload, packet.payload, sizeof(payload));
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////
|
|
// Implementation of class RtpTestUtility
|
|
/////////////////////////////////////////////////////////////////////////
|
|
const RawRtpPacket RtpTestUtility::kTestRawRtpPackets[] = {
|
|
{0x80, 0, 0, 0, RtpTestUtility::kDefaultSsrc, "RTP frame 0"},
|
|
{0x80, 0, 1, 30, RtpTestUtility::kDefaultSsrc, "RTP frame 1"},
|
|
{0x80, 0, 2, 30, RtpTestUtility::kDefaultSsrc, "RTP frame 1"},
|
|
{0x80, 0, 3, 60, RtpTestUtility::kDefaultSsrc, "RTP frame 2"}
|
|
};
|
|
const RawRtcpPacket RtpTestUtility::kTestRawRtcpPackets[] = {
|
|
// The Version is 2, the Length is 2, and the payload has 8 bytes.
|
|
{0x80, 0, 2, "RTCP0000"},
|
|
{0x80, 0, 2, "RTCP0001"},
|
|
{0x80, 0, 2, "RTCP0002"},
|
|
{0x80, 0, 2, "RTCP0003"},
|
|
};
|
|
|
|
size_t RtpTestUtility::GetTestPacketCount() {
|
|
return std::min(arraysize(kTestRawRtpPackets),
|
|
arraysize(kTestRawRtcpPackets));
|
|
}
|
|
|
|
bool RtpTestUtility::WriteTestPackets(size_t count,
|
|
bool rtcp,
|
|
uint32_t rtp_ssrc,
|
|
RtpDumpWriter* writer) {
|
|
if (!writer || count > GetTestPacketCount()) return false;
|
|
|
|
bool result = true;
|
|
uint32_t elapsed_time_ms = 0;
|
|
for (size_t i = 0; i < count && result; ++i) {
|
|
rtc::ByteBufferWriter buf;
|
|
if (rtcp) {
|
|
kTestRawRtcpPackets[i].WriteToByteBuffer(&buf);
|
|
} else {
|
|
kTestRawRtpPackets[i].WriteToByteBuffer(rtp_ssrc, &buf);
|
|
}
|
|
|
|
RtpDumpPacket dump_packet(buf.Data(), buf.Length(), elapsed_time_ms, rtcp);
|
|
elapsed_time_ms += kElapsedTimeInterval;
|
|
result &= (rtc::SR_SUCCESS == writer->WritePacket(dump_packet));
|
|
}
|
|
return result;
|
|
}
|
|
|
|
bool RtpTestUtility::VerifyTestPacketsFromStream(size_t count,
|
|
rtc::StreamInterface* stream,
|
|
uint32_t ssrc) {
|
|
if (!stream) return false;
|
|
|
|
uint32_t prev_elapsed_time = 0;
|
|
bool result = true;
|
|
stream->Rewind();
|
|
RtpDumpLoopReader reader(stream);
|
|
for (size_t i = 0; i < count && result; ++i) {
|
|
// Which loop and which index in the loop are we reading now.
|
|
size_t loop = i / GetTestPacketCount();
|
|
size_t index = i % GetTestPacketCount();
|
|
|
|
RtpDumpPacket packet;
|
|
result &= (rtc::SR_SUCCESS == reader.ReadPacket(&packet));
|
|
// Check the elapsed time of the dump packet.
|
|
result &= (packet.elapsed_time >= prev_elapsed_time);
|
|
prev_elapsed_time = packet.elapsed_time;
|
|
|
|
// Check the RTP or RTCP packet.
|
|
rtc::ByteBufferReader buf(reinterpret_cast<const char*>(&packet.data[0]),
|
|
packet.data.size());
|
|
if (packet.is_rtcp()) {
|
|
// RTCP packet.
|
|
RawRtcpPacket rtcp_packet;
|
|
result &= rtcp_packet.ReadFromByteBuffer(&buf);
|
|
result &= rtcp_packet.EqualsTo(kTestRawRtcpPackets[index]);
|
|
} else {
|
|
// RTP packet.
|
|
RawRtpPacket rtp_packet;
|
|
result &= rtp_packet.ReadFromByteBuffer(&buf);
|
|
result &= rtp_packet.SameExceptSeqNumTimestampSsrc(
|
|
kTestRawRtpPackets[index],
|
|
static_cast<uint16_t>(kTestRawRtpPackets[index].sequence_number +
|
|
loop * GetTestPacketCount()),
|
|
static_cast<uint32_t>(kTestRawRtpPackets[index].timestamp +
|
|
loop * kRtpTimestampIncrease),
|
|
ssrc);
|
|
}
|
|
}
|
|
|
|
stream->Rewind();
|
|
return result;
|
|
}
|
|
|
|
bool RtpTestUtility::VerifyPacket(const RtpDumpPacket* dump,
|
|
const RawRtpPacket* raw,
|
|
bool header_only) {
|
|
if (!dump || !raw) return false;
|
|
|
|
rtc::ByteBufferWriter buf;
|
|
raw->WriteToByteBuffer(RtpTestUtility::kDefaultSsrc, &buf);
|
|
|
|
if (header_only) {
|
|
size_t header_len = 0;
|
|
dump->GetRtpHeaderLen(&header_len);
|
|
return header_len == dump->data.size() &&
|
|
buf.Length() > dump->data.size() &&
|
|
0 == memcmp(buf.Data(), &dump->data[0], dump->data.size());
|
|
} else {
|
|
return buf.Length() == dump->data.size() &&
|
|
0 == memcmp(buf.Data(), &dump->data[0], dump->data.size());
|
|
}
|
|
}
|
|
|
|
// Implementation of VideoCaptureListener.
|
|
VideoCapturerListener::VideoCapturerListener(VideoCapturer* capturer)
|
|
: last_capture_state_(CS_STARTING),
|
|
frame_count_(0),
|
|
frame_fourcc_(0),
|
|
frame_width_(0),
|
|
frame_height_(0),
|
|
frame_size_(0),
|
|
resolution_changed_(false) {
|
|
capturer->SignalStateChange.connect(this,
|
|
&VideoCapturerListener::OnStateChange);
|
|
capturer->SignalFrameCaptured.connect(this,
|
|
&VideoCapturerListener::OnFrameCaptured);
|
|
}
|
|
|
|
void VideoCapturerListener::OnStateChange(VideoCapturer* capturer,
|
|
CaptureState result) {
|
|
last_capture_state_ = result;
|
|
}
|
|
|
|
void VideoCapturerListener::OnFrameCaptured(VideoCapturer* capturer,
|
|
const CapturedFrame* frame) {
|
|
++frame_count_;
|
|
if (1 == frame_count_) {
|
|
frame_fourcc_ = frame->fourcc;
|
|
frame_width_ = frame->width;
|
|
frame_height_ = frame->height;
|
|
frame_size_ = frame->data_size;
|
|
} else if (frame_width_ != frame->width || frame_height_ != frame->height) {
|
|
resolution_changed_ = true;
|
|
}
|
|
}
|
|
|
|
cricket::StreamParams CreateSimStreamParams(
|
|
const std::string& cname,
|
|
const std::vector<uint32_t>& ssrcs) {
|
|
cricket::StreamParams sp;
|
|
cricket::SsrcGroup sg(cricket::kSimSsrcGroupSemantics, ssrcs);
|
|
sp.ssrcs = ssrcs;
|
|
sp.ssrc_groups.push_back(sg);
|
|
sp.cname = cname;
|
|
return sp;
|
|
}
|
|
|
|
// There should be an rtx_ssrc per ssrc.
|
|
cricket::StreamParams CreateSimWithRtxStreamParams(
|
|
const std::string& cname,
|
|
const std::vector<uint32_t>& ssrcs,
|
|
const std::vector<uint32_t>& rtx_ssrcs) {
|
|
cricket::StreamParams sp = CreateSimStreamParams(cname, ssrcs);
|
|
for (size_t i = 0; i < ssrcs.size(); ++i) {
|
|
sp.ssrcs.push_back(rtx_ssrcs[i]);
|
|
std::vector<uint32_t> fid_ssrcs;
|
|
fid_ssrcs.push_back(ssrcs[i]);
|
|
fid_ssrcs.push_back(rtx_ssrcs[i]);
|
|
cricket::SsrcGroup fid_group(cricket::kFidSsrcGroupSemantics, fid_ssrcs);
|
|
sp.ssrc_groups.push_back(fid_group);
|
|
}
|
|
return sp;
|
|
}
|
|
|
|
} // namespace cricket
|