Switching to I420VideoFrame

Review URL: https://webrtc-codereview.appspot.com/922004

git-svn-id: http://webrtc.googlecode.com/svn/trunk@2983 4adac7df-926f-26a2-2b94-8c16560cd09d
This commit is contained in:
mikhal@webrtc.org
2012-10-24 18:33:04 +00:00
parent 6392657643
commit 9fedff7c17
152 changed files with 2076 additions and 1862 deletions

View File

@@ -47,7 +47,7 @@ public:
//
// Return value : WEBRTC_VIDEO_CODEC_OK if OK.
// <0 - Error
virtual int Encode(const VideoFrame& inputImage,
virtual int Encode(const I420VideoFrame& inputImage,
const CodecSpecificInfo* /*codecSpecificInfo*/,
const std::vector<VideoFrameType>* /*frame_types*/);
@@ -138,7 +138,7 @@ public:
private:
VideoFrame _decodedImage;
I420VideoFrame _decodedImage;
int _width;
int _height;
bool _inited;

View File

@@ -14,7 +14,6 @@
#include "common_video/libyuv/include/webrtc_libyuv.h"
namespace webrtc
{
@@ -76,9 +75,9 @@ int I420Encoder::InitEncode(const VideoCodec* codecSettings,
int I420Encoder::Encode(const VideoFrame& inputImage,
const CodecSpecificInfo* /*codecSpecificInfo*/,
const std::vector<VideoFrameType>* /*frame_types*/) {
int I420Encoder::Encode(const I420VideoFrame& inputImage,
const CodecSpecificInfo* /*codecSpecificInfo*/,
const std::vector<VideoFrameType>* /*frame_types*/) {
if (!_inited) {
return WEBRTC_VIDEO_CODEC_UNINITIALIZED;
}
@@ -87,29 +86,32 @@ int I420Encoder::Encode(const VideoFrame& inputImage,
}
_encodedImage._frameType = kKeyFrame; // No coding.
_encodedImage._timeStamp = inputImage.TimeStamp();
_encodedImage._encodedHeight = inputImage.Height();
_encodedImage._encodedWidth = inputImage.Width();
if (inputImage.Length() > _encodedImage._size) {
_encodedImage._timeStamp = inputImage.timestamp();
_encodedImage._encodedHeight = inputImage.height();
_encodedImage._encodedWidth = inputImage.width();
int req_length = CalcBufferSize(kI420, inputImage.width(),
inputImage.height());
if (_encodedImage._size > static_cast<unsigned int>(req_length)) {
// Allocating encoded memory.
if (_encodedImage._buffer != NULL) {
delete [] _encodedImage._buffer;
_encodedImage._buffer = NULL;
_encodedImage._size = 0;
}
const uint32_t newSize = CalcBufferSize(kI420,
_encodedImage._encodedWidth,
_encodedImage._encodedHeight);
uint8_t* newBuffer = new uint8_t[newSize];
uint8_t* newBuffer = new uint8_t[req_length];
if (newBuffer == NULL) {
return WEBRTC_VIDEO_CODEC_MEMORY;
}
_encodedImage._size = newSize;
_encodedImage._size = req_length;
_encodedImage._buffer = newBuffer;
}
memcpy(_encodedImage._buffer, inputImage.Buffer(), inputImage.Length());
_encodedImage._length = inputImage.Length();
int ret_length = ExtractBuffer(inputImage, req_length, _encodedImage._buffer);
if (ret_length < 0)
return WEBRTC_VIDEO_CODEC_MEMORY;
_encodedImage._length = ret_length;
_encodedCompleteCallback->Encoded(_encodedImage);
return WEBRTC_VIDEO_CODEC_OK;
}
@@ -174,12 +176,24 @@ I420Decoder::Decode(const EncodedImage& inputImage,
}
// Set decoded image parameters.
if (_decodedImage.CopyFrame(inputImage._length, inputImage._buffer) < 0) {
int half_width = (_width + 1) / 2;
int half_height = (_height + 1) / 2;
int size_y = _width * _height;
int size_uv = half_width * half_height;
const uint8_t* buffer_y = inputImage._buffer;
const uint8_t* buffer_u = buffer_y + size_y;
const uint8_t* buffer_v = buffer_u + size_uv;
// TODO(mikhal): Do we need an align stride?
int ret = _decodedImage.CreateFrame(size_y, buffer_y,
size_uv, buffer_u,
size_uv, buffer_v,
_width, _height,
_width, half_width, half_width);
if (ret < 0) {
return WEBRTC_VIDEO_CODEC_MEMORY;
}
_decodedImage.SetHeight(_height);
_decodedImage.SetWidth(_width);
_decodedImage.SetTimeStamp(inputImage._timeStamp);
_decodedImage.set_timestamp(inputImage._timeStamp);
_decodeCompleteCallback->Decoded(_decodedImage);
return WEBRTC_VIDEO_CODEC_OK;
@@ -193,7 +207,6 @@ I420Decoder::RegisterDecodeCompleteCallback(DecodedImageCallback* callback) {
int
I420Decoder::Release() {
_decodedImage.Free();
_inited = false;
return WEBRTC_VIDEO_CODEC_OK;
}

View File

@@ -37,7 +37,7 @@ class MockVideoEncoder : public VideoEncoder {
WebRtc_Word32 numberOfCores,
WebRtc_UWord32 maxPayloadSize));
MOCK_METHOD3(Encode,
WebRtc_Word32(const VideoFrame& inputImage,
WebRtc_Word32(const I420VideoFrame& inputImage,
const CodecSpecificInfo* codecSpecificInfo,
const std::vector<VideoFrameType>* frame_types));
MOCK_METHOD1(RegisterEncodeCompleteCallback,
@@ -57,7 +57,7 @@ class MockVideoEncoder : public VideoEncoder {
class MockDecodedImageCallback : public DecodedImageCallback {
public:
MOCK_METHOD1(Decoded,
WebRtc_Word32(VideoFrame& decodedImage));
WebRtc_Word32(I420VideoFrame& decodedImage));
MOCK_METHOD1(ReceivedDecodedReferenceFrame,
WebRtc_Word32(const WebRtc_UWord64 pictureId));
MOCK_METHOD1(ReceivedDecodedFrame,

View File

@@ -14,9 +14,11 @@
#include <vector>
#include "common_types.h"
#include "common_video/interface/i420_video_frame.h"
#include "modules/interface/module_common_types.h"
#include "modules/video_coding/codecs/interface/video_error_codes.h"
#include "common_video/interface/video_image.h"
#include "typedefs.h"
namespace webrtc
@@ -102,7 +104,7 @@ public:
// Return value : WEBRTC_VIDEO_CODEC_OK if OK, < 0
// otherwise.
virtual WebRtc_Word32 Encode(
const VideoFrame& inputImage,
const I420VideoFrame& inputImage,
const CodecSpecificInfo* codecSpecificInfo,
const std::vector<VideoFrameType>* frame_types) = 0;
@@ -167,7 +169,7 @@ public:
// - decodedImage : The decoded image.
//
// Return value : 0 if OK, < 0 otherwise.
virtual WebRtc_Word32 Decoded(VideoFrame& decodedImage) = 0;
virtual WebRtc_Word32 Decoded(I420VideoFrame& decodedImage) = 0;
virtual WebRtc_Word32 ReceivedDecodedReferenceFrame(const WebRtc_UWord64 pictureId) {return -1;}

View File

@@ -58,18 +58,11 @@ bool VideoProcessorImpl::Init() {
// Calculate a factor used for bit rate calculations:
bit_rate_factor_ = config_.codec_settings->maxFramerate * 0.001 * 8; // bits
int frame_length_in_bytes = frame_reader_->FrameLength();
// Initialize data structures used by the encoder/decoder APIs
int frame_length_in_bytes = frame_reader_->FrameLength();
source_buffer_ = new WebRtc_UWord8[frame_length_in_bytes];
last_successful_frame_buffer_ = new WebRtc_UWord8[frame_length_in_bytes];
// Set fixed properties common for all frames:
source_frame_.SetWidth(config_.codec_settings->width);
source_frame_.SetHeight(config_.codec_settings->height);
source_frame_.VerifyAndAllocate(frame_length_in_bytes);
source_frame_.SetLength(frame_length_in_bytes);
// Set fixed properties common for all frames.
// To keep track of spatial resize actions by encoder.
last_encoder_frame_width_ = config_.codec_settings->width;
last_encoder_frame_height_ = config_.codec_settings->height;
@@ -169,15 +162,24 @@ bool VideoProcessorImpl::ProcessFrame(int frame_number) {
}
if (frame_reader_->ReadFrame(source_buffer_)) {
// Copy the source frame to the newly read frame data.
// Length is common for all frames.
source_frame_.CopyFrame(source_frame_.Length(), source_buffer_);
int size_y = config_.codec_settings->width * config_.codec_settings->height;
int half_width = (config_.codec_settings->width + 1) / 2;
int half_height = (config_.codec_settings->height + 1) / 2;
int size_uv = half_width * half_height;
source_frame_.CreateFrame(size_y, source_buffer_,
size_uv, source_buffer_ + size_y,
size_uv, source_buffer_ + size_y + size_uv,
config_.codec_settings->width,
config_.codec_settings->height,
config_.codec_settings->width,
half_width, half_width);
// Ensure we have a new statistics data object we can fill:
FrameStatistic& stat = stats_->NewFrame(frame_number);
encode_start_ = TickTime::Now();
// Use the frame number as "timestamp" to identify frames
source_frame_.SetTimeStamp(frame_number);
source_frame_.set_timestamp(frame_number);
// Decide if we're going to force a keyframe:
std::vector<VideoFrameType> frame_types(1, kDeltaFrame);
@@ -273,9 +275,9 @@ void VideoProcessorImpl::FrameEncoded(EncodedImage* encoded_image) {
last_frame_missing_ = encoded_image->_length == 0;
}
void VideoProcessorImpl::FrameDecoded(const VideoFrame& image) {
void VideoProcessorImpl::FrameDecoded(const I420VideoFrame& image) {
TickTime decode_stop = TickTime::Now();
int frame_number = image.TimeStamp();
int frame_number = image.timestamp();
// Report stats
FrameStatistic& stat = stats_->stats_[frame_number];
stat.decode_time_in_us = GetElapsedTimeMicroseconds(decode_start_,
@@ -283,18 +285,18 @@ void VideoProcessorImpl::FrameDecoded(const VideoFrame& image) {
stat.decoding_successful = true;
// Check for resize action (either down or up):
if (static_cast<int>(image.Width()) != last_encoder_frame_width_ ||
static_cast<int>(image.Height()) != last_encoder_frame_height_ ) {
if (static_cast<int>(image.width()) != last_encoder_frame_width_ ||
static_cast<int>(image.height()) != last_encoder_frame_height_ ) {
++num_spatial_resizes_;
last_encoder_frame_width_ = image.Width();
last_encoder_frame_height_ = image.Height();
last_encoder_frame_width_ = image.width();
last_encoder_frame_height_ = image.height();
}
// Check if codec size is different from native/original size, and if so,
// upsample back to original size: needed for PSNR and SSIM computations.
if (image.Width() != config_.codec_settings->width ||
image.Height() != config_.codec_settings->height) {
VideoFrame up_image;
int ret_val = scaler_.Set(image.Width(), image.Height(),
if (image.width() != config_.codec_settings->width ||
image.height() != config_.codec_settings->height) {
I420VideoFrame up_image;
int ret_val = scaler_.Set(image.width(), image.height(),
config_.codec_settings->width,
config_.codec_settings->height,
kI420, kI420, kScaleBilinear);
@@ -309,20 +311,27 @@ void VideoProcessorImpl::FrameDecoded(const VideoFrame& image) {
fprintf(stderr, "Failed to scale frame: %d, return code: %d\n",
frame_number, ret_val);
}
// TODO(mikhal): Extracting the buffer for now - need to update test.
int length = CalcBufferSize(kI420, up_image.width(), up_image.height());
scoped_array<uint8_t> image_buffer(new uint8_t[length]);
length = ExtractBuffer(up_image, length, image_buffer.get());
// Update our copy of the last successful frame:
memcpy(last_successful_frame_buffer_, up_image.Buffer(), up_image.Length());
bool write_success = frame_writer_->WriteFrame(up_image.Buffer());
memcpy(last_successful_frame_buffer_, image_buffer.get(), length);
bool write_success = frame_writer_->WriteFrame(image_buffer.get());
assert(write_success);
if (!write_success) {
fprintf(stderr, "Failed to write frame %d to disk!", frame_number);
}
up_image.Free();
} else { // No resize.
// Update our copy of the last successful frame:
memcpy(last_successful_frame_buffer_, image.Buffer(), image.Length());
// TODO(mikhal): Add as a member function, so won't be allocated per frame.
int length = CalcBufferSize(kI420,image.width(), image.height());
scoped_array<uint8_t> image_buffer(new uint8_t[length]);
length = ExtractBuffer(image, length, image_buffer.get());
assert(length > 0);
memcpy(last_successful_frame_buffer_, image_buffer.get(), length);
bool write_success = frame_writer_->WriteFrame(image.Buffer());
bool write_success = frame_writer_->WriteFrame(image_buffer.get());
assert(write_success);
if (!write_success) {
fprintf(stderr, "Failed to write frame %d to disk!", frame_number);
@@ -379,7 +388,7 @@ VideoProcessorImpl::VideoProcessorEncodeCompleteCallback::Encoded(
}
WebRtc_Word32
VideoProcessorImpl::VideoProcessorDecodeCompleteCallback::Decoded(
VideoFrame& image) {
I420VideoFrame& image) {
video_processor_->FrameDecoded(image); // forward to parent class
return 0;
}

View File

@@ -15,7 +15,7 @@
#include "common_video/libyuv/include/webrtc_libyuv.h"
#include "common_video/libyuv/include/scaler.h"
#include "modules/interface/module_common_types.h"
#include "common_video/interface/i420_video_frame.h"
#include "modules/video_coding/codecs/interface/video_codec_interface.h"
#include "modules/video_coding/codecs/test/packet_manipulator.h"
#include "modules/video_coding/codecs/test/stats.h"
@@ -175,7 +175,7 @@ class VideoProcessorImpl : public VideoProcessor {
// Invoked by the callback when a frame has completed encoding.
void FrameEncoded(webrtc::EncodedImage* encodedImage);
// Invoked by the callback when a frame has completed decoding.
void FrameDecoded(const webrtc::VideoFrame& image);
void FrameDecoded(const webrtc::I420VideoFrame& image);
// Used for getting a 32-bit integer representing time
// (checks the size is within signed 32-bit bounds before casting it)
int GetElapsedTimeMicroseconds(const webrtc::TickTime& start,
@@ -204,7 +204,7 @@ class VideoProcessorImpl : public VideoProcessor {
// Keep track of the last successful frame, since we need to write that
// when decoding fails:
WebRtc_UWord8* last_successful_frame_buffer_;
webrtc::VideoFrame source_frame_;
webrtc::I420VideoFrame source_frame_;
// To keep track of if we have excluded the first key frame from packet loss:
bool first_key_frame_has_been_excluded_;
// To tell the decoder previous frame have been dropped due to packet loss:
@@ -247,7 +247,7 @@ class VideoProcessorImpl : public VideoProcessor {
explicit VideoProcessorDecodeCompleteCallback(VideoProcessorImpl* vp)
: video_processor_(vp) {
}
WebRtc_Word32 Decoded(webrtc::VideoFrame& image);
WebRtc_Word32 Decoded(webrtc::I420VideoFrame& image);
private:
VideoProcessorImpl* video_processor_;

View File

@@ -156,7 +156,8 @@ class VideoProcessorIntegrationTest: public testing::Test {
webrtc::test::ResourcePath("foreman_cif", "yuv");
config_.output_filename = webrtc::test::OutputPath() +
"foreman_cif_short_video_codecs_test_framework_integrationtests.yuv";
config_.frame_length_in_bytes = 3 * kCIFWidth * kCIFHeight / 2;
config_.frame_length_in_bytes = CalcBufferSize(kI420,
kCIFWidth, kCIFHeight);
config_.verbose = false;
// Only allow encoder/decoder to use single core, for predictability.
config_.use_single_core = true;

View File

@@ -64,7 +64,7 @@ class VideoProcessorTest: public testing::Test {
EXPECT_CALL(frame_reader_mock_, NumberOfFrames())
.WillOnce(Return(1));
EXPECT_CALL(frame_reader_mock_, FrameLength())
.WillOnce(Return(150000));
.WillOnce(Return(152064));
}
};

View File

@@ -230,9 +230,6 @@ Benchmark::PerformNormalTest()
CodecSettings(_target->GetWidth(), _target->GetHeight(), _target->GetFrameRate(), _bitRate);
Setup();
EventWrapper* waitEvent = EventWrapper::Create();
_inputVideoBuffer.VerifyAndAllocate(_lengthSourceFrame);
_decodedVideoBuffer.VerifyAndAllocate(_lengthSourceFrame);
_encoder->InitEncode(&_inst, 4, 1440);
CodecSpecific_InitBitrate();
_decoder->InitDecode(&_inst,1);
@@ -282,9 +279,7 @@ Benchmark::PerformNormalTest()
waitEvent->Wait(5);
}
_inputVideoBuffer.Free();
_encodedVideoBuffer.Free();
_decodedVideoBuffer.Free();
_encoder->Release();
_decoder->Release();

View File

@@ -16,6 +16,7 @@
#include <sstream>
#include <vector>
#include "common_video/libyuv/include/webrtc_libyuv.h"
#include "gtest/gtest.h"
#include "tick_util.h"
#include "testsupport/fileutils.h"
@@ -262,16 +263,13 @@ WebRtc_UWord32 VideoDecodeCompleteCallback::DecodedBytes()
}
WebRtc_Word32
VideoDecodeCompleteCallback::Decoded(VideoFrame& image)
VideoDecodeCompleteCallback::Decoded(I420VideoFrame& image)
{
_test.Decoded(image);
_decodedBytes += image.Length();
_decodedBytes += CalcBufferSize(kI420, image.width(), image.height());
if (_decodedFile != NULL)
{
if (fwrite(image.Buffer(), 1, image.Length(),
_decodedFile) != image.Length()) {
return -1;
}
return PrintI420VideoFrame(image, _decodedFile);
}
return 0;
}
@@ -300,14 +298,14 @@ NormalAsyncTest::Encoded(const EncodedImage& encodedImage)
}
void
NormalAsyncTest::Decoded(const VideoFrame& decodedImage)
NormalAsyncTest::Decoded(const I420VideoFrame& decodedImage)
{
_decodeCompleteTime = tGetTime();
_decFrameCnt++;
_totalDecodePipeTime += _decodeCompleteTime -
_decodeTimes[decodedImage.TimeStamp()];
_decodedWidth = decodedImage.Width();
_decodedHeight = decodedImage.Height();
_decodeTimes[decodedImage.timestamp()];
_decodedWidth = decodedImage.width();
_decodedHeight = decodedImage.height();
}
void
@@ -316,8 +314,6 @@ NormalAsyncTest::Perform()
_inname = webrtc::test::ProjectRootPath() + "resources/foreman_cif.yuv";
CodecSettings(352, 288, 30, _bitRate);
Setup();
_inputVideoBuffer.VerifyAndAllocate(_lengthSourceFrame);
_decodedVideoBuffer.VerifyAndAllocate(_lengthSourceFrame);
if(_encoder->InitEncode(&_inst, 1, 1440) < 0)
{
exit(EXIT_FAILURE);
@@ -410,17 +406,19 @@ NormalAsyncTest::Encode()
{
_lengthEncFrame = 0;
EXPECT_GT(fread(_sourceBuffer, 1, _lengthSourceFrame, _sourceFile), 0u);
_inputVideoBuffer.CopyFrame(_lengthSourceFrame, _sourceBuffer);
_inputVideoBuffer.SetTimeStamp((unsigned int)
_inputVideoBuffer.CreateFrame(_sizeY, _sourceBuffer,
_sizeUv, _sourceBuffer + _sizeY,
_sizeUv, _sourceBuffer + _sizeY + _sizeUv,
_width, _height,
_width, _halfWidth, _halfWidth);
_inputVideoBuffer.set_timestamp((unsigned int)
(_encFrameCnt * 9e4 / _inst.maxFramerate));
_inputVideoBuffer.SetWidth(_inst.width);
_inputVideoBuffer.SetHeight(_inst.height);
if (feof(_sourceFile) != 0)
{
return true;
}
_encodeCompleteTime = 0;
_encodeTimes[_inputVideoBuffer.TimeStamp()] = tGetTime();
_encodeTimes[_inputVideoBuffer.timestamp()] = tGetTime();
std::vector<VideoFrameType> frame_types(1, kDeltaFrame);
// check SLI queue
@@ -474,12 +472,12 @@ NormalAsyncTest::Encode()
if (_encodeCompleteTime > 0)
{
_totalEncodeTime += _encodeCompleteTime -
_encodeTimes[_inputVideoBuffer.TimeStamp()];
_encodeTimes[_inputVideoBuffer.timestamp()];
}
else
{
_totalEncodeTime += tGetTime() -
_encodeTimes[_inputVideoBuffer.TimeStamp()];
_encodeTimes[_inputVideoBuffer.timestamp()];
}
assert(ret >= 0);
return false;

View File

@@ -80,7 +80,7 @@ public:
virtual ~NormalAsyncTest() {};
virtual void Perform();
virtual void Encoded(const webrtc::EncodedImage& encodedImage);
virtual void Decoded(const webrtc::VideoFrame& decodedImage);
virtual void Decoded(const webrtc::I420VideoFrame& decodedImage);
virtual webrtc::CodecSpecificInfo*
CopyCodecSpecificInfo(
const webrtc::CodecSpecificInfo* codecSpecificInfo) const;
@@ -172,7 +172,7 @@ public:
_decodedBytes(0)
{}
virtual WebRtc_Word32 Decoded(webrtc::VideoFrame& decodedImage);
virtual WebRtc_Word32 Decoded(webrtc::I420VideoFrame& decodedImage);
virtual WebRtc_Word32
ReceivedDecodedReferenceFrame(const WebRtc_UWord64 pictureId);
virtual WebRtc_Word32 ReceivedDecodedFrame(const WebRtc_UWord64 pictureId);

View File

@@ -14,6 +14,7 @@
#include <sstream>
#include <string.h>
#include "common_video/libyuv/include/webrtc_libyuv.h"
#include "gtest/gtest.h"
#include "testsupport/fileutils.h"
@@ -22,7 +23,13 @@ NormalTest::NormalTest()
CodecTest("Normal Test 1", "A test of normal execution of the codec"),
_testNo(1),
_lengthEncFrame(0),
_appendNext(false)
_appendNext(false),
_width(0),
_halfWidth(0),
_height(0),
_halfHeight(0),
_sizeY(0),
_sizeUv(0)
{
}
@@ -33,7 +40,13 @@ CodecTest(name, description),
_requestKeyFrame(false),
_testNo(testNo),
_lengthEncFrame(0),
_appendNext(false)
_appendNext(false),
_width(0),
_halfWidth(0),
_height(0),
_halfHeight(0),
_sizeY(0),
_sizeUv(0)
{
}
@@ -108,12 +121,22 @@ NormalTest::Teardown()
void
NormalTest::Perform()
{
_width = 352;
_halfWidth = (_width + 1) / 2;
_height = 288;
_halfHeight = (_height + 1) / 2;
_sizeY = _width * _height;
_sizeUv = _halfWidth * _halfHeight;
_inname = webrtc::test::ProjectRootPath() + "resources/foreman_cif.yuv";
CodecSettings(352, 288, 30, _bitRate);
CodecSettings(_width, _height, 30, _bitRate);
Setup();
_inputVideoBuffer.VerifyAndAllocate(_lengthSourceFrame);
_decodedVideoBuffer.VerifyAndAllocate(_lengthSourceFrame);
_inputVideoBuffer.CreateEmptyFrame(_width, _height,
_width, _halfWidth, _halfWidth);
_inputVideoBuffer.CreateEmptyFrame(_width, _height,
_width, _halfWidth, _halfWidth);
_decodedVideoBuffer.CreateEmptyFrame(_width, _height,
_width, _halfWidth, _halfWidth);
_encodedVideoBuffer.VerifyAndAllocate(_lengthSourceFrame);
_encoder->InitEncode(&_inst, 1, 1460);
@@ -140,8 +163,7 @@ NormalTest::Perform()
fprintf(stderr,"\n\nError in decoder: %d\n\n", decodeLength);
exit(EXIT_FAILURE);
}
if (fwrite(_decodedVideoBuffer.Buffer(), 1, decodeLength,
_decodedFile) != static_cast<unsigned int>(decodeLength)) {
if (PrintI420VideoFrame(_decodedVideoBuffer, _decodedFile) < 0) {
return;
}
CodecSpecific_InitBitrate();
@@ -157,8 +179,7 @@ NormalTest::Perform()
fprintf(stderr,"\n\nError in decoder: %d\n\n", decodeLength);
exit(EXIT_FAILURE);
}
if (fwrite(_decodedVideoBuffer.Buffer(), 1, decodeLength,
_decodedFile) != static_cast<unsigned int>(decodeLength)) {
if (PrintI420VideoFrame(_decodedVideoBuffer, _decodedFile) < 0) {
return;
}
}
@@ -173,8 +194,6 @@ NormalTest::Perform()
(*_log) << "Average encode time: " << avgEncTime << " s" << std::endl;
(*_log) << "Average decode time: " << avgDecTime << " s" << std::endl;
_inputVideoBuffer.Free();
_encoder->Release();
_decoder->Release();
@@ -190,8 +209,13 @@ NormalTest::Encode()
{
return true;
}
_inputVideoBuffer.CopyFrame(_lengthSourceFrame, _sourceBuffer);
_inputVideoBuffer.SetTimeStamp(_framecnt);
_inputVideoBuffer.CreateFrame(_sizeY, _sourceBuffer,
_sizeUv, _sourceBuffer + _sizeY,
_sizeUv, _sourceBuffer + _sizeY +
_sizeUv,
_width, _height,
_width, _halfWidth, _halfWidth);
_inputVideoBuffer.set_timestamp(_framecnt);
// This multiple attempt ridiculousness is to accomodate VP7:
// 1. The wrapper can unilaterally reduce the framerate for low bitrates.
@@ -204,8 +228,8 @@ NormalTest::Encode()
{
starttime = clock()/(double)CLOCKS_PER_SEC;
_inputVideoBuffer.SetWidth(_inst.width);
_inputVideoBuffer.SetHeight(_inst.height);
_inputVideoBuffer.set_width(_inst.width);
_inputVideoBuffer.set_height(_inst.height);
//_lengthEncFrame = _encoder->Encode(_inputVideoBuffer, _encodedVideoBuffer, _frameInfo,
// _inst.frameRate, _requestKeyFrame && !(_framecnt%50));

View File

@@ -40,6 +40,12 @@ protected:
unsigned int _testNo;
int _lengthEncFrame;
bool _appendNext;
int _width;
int _halfWidth;
int _height;
int _halfHeight;
int _sizeY;
int _sizeUv;
};
#endif // WEBRTC_MODULES_VIDEO_CODING_CODECS_TEST_FRAMEWORK_NORMAL_TEST_H_

View File

@@ -64,11 +64,11 @@ PacketLossTest::Encoded(const EncodedImage& encodedImage)
}
void
PacketLossTest::Decoded(const VideoFrame& decodedImage)
PacketLossTest::Decoded(const I420VideoFrame& decodedImage)
{
// check the frame queue if any frames have gone missing
assert(!_frameQueue.empty()); // decoded frame is not in the queue
while(_frameQueue.front() < decodedImage.TimeStamp())
while(_frameQueue.front() < decodedImage.timestamp())
{
// this frame is missing
// write previous decoded frame again (frame freeze)
@@ -84,20 +84,23 @@ PacketLossTest::Decoded(const VideoFrame& decodedImage)
_frameQueue.pop_front();
}
// Decoded frame is not in the queue.
assert(_frameQueue.front() == decodedImage.TimeStamp());
assert(_frameQueue.front() == decodedImage.timestamp());
// pop the current frame
_frameQueue.pop_front();
// save image for future freeze-frame
if (_lastFrameLength < decodedImage.Length())
unsigned int length = CalcBufferSize(kI420, decodedImage.width(),
decodedImage.height());
if (_lastFrameLength < length)
{
if (_lastFrame) delete [] _lastFrame;
_lastFrame = new WebRtc_UWord8[decodedImage.Length()];
_lastFrame = new WebRtc_UWord8[length];
}
memcpy(_lastFrame, decodedImage.Buffer(), decodedImage.Length());
_lastFrameLength = decodedImage.Length();
// TODO(mikhal): Can't the last frame be a I420VideoFrame?
ExtractBuffer(decodedImage, length, _lastFrame);
_lastFrameLength = length;
NormalAsyncTest::Decoded(decodedImage);
}

View File

@@ -21,7 +21,7 @@ public:
PacketLossTest();
virtual ~PacketLossTest() {if(_lastFrame) {delete [] _lastFrame; _lastFrame = NULL;}}
virtual void Encoded(const webrtc::EncodedImage& encodedImage);
virtual void Decoded(const webrtc::VideoFrame& decodedImage);
virtual void Decoded(const webrtc::I420VideoFrame& decodedImage);
protected:
PacketLossTest(std::string name, std::string description);
PacketLossTest(std::string name,

View File

@@ -49,11 +49,11 @@ protected:
WebRtc_UWord32 _bitRate;
unsigned int _lengthSourceFrame;
unsigned char* _sourceBuffer;
webrtc::VideoFrame _inputVideoBuffer;
webrtc::I420VideoFrame _inputVideoBuffer;
// TODO(mikhal): For now using VideoFrame for encodedBuffer, should use a
// designated class.
webrtc::VideoFrame _encodedVideoBuffer;
webrtc::VideoFrame _decodedVideoBuffer;
webrtc::I420VideoFrame _decodedVideoBuffer;
webrtc::VideoCodec _inst;
std::fstream* _log;
std::string _inname;

View File

@@ -98,7 +98,8 @@ UnitTestEncodeCompleteCallback::Encoded(EncodedImage& encodedImage,
_encodedVideoBuffer->VerifyAndAllocate(encodedImage._size);
_encodedVideoBuffer->CopyFrame(encodedImage._size, encodedImage._buffer);
_encodedVideoBuffer->SetLength(encodedImage._length);
// _encodedVideoBuffer->SetFrameType(encodedImage._frameType);
// TODO(mikhal): Update frame type API.
// _encodedVideoBuffer->SetFrameType(encodedImage._frameType);
_encodedVideoBuffer->SetWidth(
(WebRtc_UWord16)encodedImage._encodedWidth);
_encodedVideoBuffer->SetHeight(
@@ -109,12 +110,9 @@ UnitTestEncodeCompleteCallback::Encoded(EncodedImage& encodedImage,
return 0;
}
WebRtc_Word32 UnitTestDecodeCompleteCallback::Decoded(VideoFrame& image)
WebRtc_Word32 UnitTestDecodeCompleteCallback::Decoded(I420VideoFrame& image)
{
_decodedVideoBuffer->CopyFrame(image.Length(), image.Buffer());
_decodedVideoBuffer->SetWidth(image.Width());
_decodedVideoBuffer->SetHeight(image.Height());
_decodedVideoBuffer->SetTimeStamp(image.TimeStamp());
_decodedVideoBuffer->CopyFrame(image);
_decodeComplete = true;
return 0;
}
@@ -155,7 +153,7 @@ UnitTest::WaitForEncodedFrame() const
{
if (_encodeCompleteCallback->EncodeComplete())
{
return _encodedVideoBuffer.Length();
return _encodedVideoBuffer.Length();
}
}
return 0;
@@ -169,7 +167,8 @@ UnitTest::WaitForDecodedFrame() const
{
if (_decodeCompleteCallback->DecodeComplete())
{
return _decodedVideoBuffer.Length();
return webrtc::CalcBufferSize(kI420, _decodedVideoBuffer.width(),
_decodedVideoBuffer.height());
}
}
return 0;
@@ -224,12 +223,16 @@ UnitTest::Setup()
_inst.codecSpecific.VP8.denoisingOn = true;
// Get input frame.
_inputVideoBuffer.VerifyAndAllocate(_lengthSourceFrame);
ASSERT_TRUE(fread(_refFrame, 1, _lengthSourceFrame, _sourceFile)
== _lengthSourceFrame);
_inputVideoBuffer.CopyFrame(_lengthSourceFrame, _refFrame);
_inputVideoBuffer.SetWidth(_source->GetWidth());
_inputVideoBuffer.SetHeight(_source->GetHeight());
int size_y = _inst.width * _inst.height;
int size_uv = ((_inst.width + 1) / 2) * ((_inst.height + 1) / 2);
_inputVideoBuffer.CreateFrame(size_y, _refFrame,
size_uv, _refFrame + size_y,
size_uv, _refFrame + size_y + size_uv,
_inst.width, _inst.height,
_inst.width,
(_inst.width + 1) / 2, (_inst.width + 1) / 2);
rewind(_sourceFile);
// Get a reference encoded frame.
@@ -244,7 +247,9 @@ UnitTest::Setup()
memcpy(_refEncFrame, _encodedVideoBuffer.Buffer(), _refEncFrameLength);
// Get a reference decoded frame.
_decodedVideoBuffer.VerifyAndAllocate(_lengthSourceFrame);
_decodedVideoBuffer.CreateEmptyFrame(_inst.width, _inst.height, _inst.width,
(_inst.width + 1) / 2,
(_inst.width + 1) / 2);
EXPECT_TRUE(_decoder->InitDecode(&_inst, 1) == WEBRTC_VIDEO_CODEC_OK);
ASSERT_FALSE(SetCodecSpecificParameters() != WEBRTC_VIDEO_CODEC_OK);
@@ -255,12 +260,15 @@ UnitTest::Setup()
if (i > 0)
{
// Insert yet another frame
_inputVideoBuffer.VerifyAndAllocate(_lengthSourceFrame);
ASSERT_TRUE(fread(_refFrame, 1, _lengthSourceFrame,
_sourceFile) == _lengthSourceFrame);
_inputVideoBuffer.CopyFrame(_lengthSourceFrame, _refFrame);
_inputVideoBuffer.SetWidth(_source->GetWidth());
_inputVideoBuffer.SetHeight(_source->GetHeight());
_inputVideoBuffer.CreateFrame(size_y, _refFrame,
size_uv, _refFrame + size_y,
size_uv, _refFrame + size_y + size_uv,
_inst.width, _inst.height,
_inst.width,
(_inst.width + 1) / 2,
(_inst.width + 1) / 2);
_encoder->Encode(_inputVideoBuffer, NULL, NULL);
ASSERT_TRUE(WaitForEncodedFrame() > 0);
}
@@ -274,7 +282,7 @@ UnitTest::Setup()
}
rewind(_sourceFile);
EXPECT_TRUE(frameLength == _lengthSourceFrame);
memcpy(_refDecFrame, _decodedVideoBuffer.Buffer(), _lengthSourceFrame);
ExtractBuffer(_decodedVideoBuffer, _lengthSourceFrame, _refDecFrame);
}
void
@@ -342,7 +350,7 @@ UnitTest::Perform()
{
UnitTest::Setup();
int frameLength;
VideoFrame inputImage;
I420VideoFrame inputImage;
EncodedImage encodedImage;
//----- Encoder parameter tests -----
@@ -409,17 +417,20 @@ UnitTest::Perform()
EXPECT_TRUE(_encoder->InitEncode(&_inst, 1, 1440) == WEBRTC_VIDEO_CODEC_OK);
//-- Encode() errors --
// inputVideoBuffer unallocated.
_inputVideoBuffer.Free();
inputImage.Free();
inputImage.ResetSize();
EXPECT_TRUE(_encoder->Encode(inputImage, NULL, NULL) ==
WEBRTC_VIDEO_CODEC_ERR_PARAMETER);
_inputVideoBuffer.VerifyAndAllocate(_lengthSourceFrame);
_inputVideoBuffer.CopyFrame(_lengthSourceFrame, _refFrame);
_inputVideoBuffer.SetWidth(_source->GetWidth());
_inputVideoBuffer.SetHeight(_source->GetHeight());
int width = _source->GetWidth();
int half_width = (width + 1) / 2;
int height = _source->GetHeight();
int half_height = (height + 1) / 2;
int size_y = width * height;
int size_uv = half_width * half_height;
_inputVideoBuffer.CreateFrame(size_y, _refFrame,
size_uv, _refFrame + size_y,
size_uv, _refFrame + size_y + size_uv,
width, height,
width, half_width, half_width);
//----- Encoder stress tests -----
// Vary frame rate and I-frame request.
@@ -539,8 +550,12 @@ UnitTest::Perform()
_decoder->Decode(encodedImage, false, NULL);
frameLength = WaitForDecodedFrame();
}
EXPECT_TRUE(CheckIfBitExact(_decodedVideoBuffer.Buffer(), frameLength,
_refDecFrame, _lengthSourceFrame) == true);
unsigned int length = CalcBufferSize(kI420, width, height);
scoped_array<uint8_t> decoded_buffer(new uint8_t[length]);
ExtractBuffer(_decodedVideoBuffer, _lengthSourceFrame,
decoded_buffer.get());
EXPECT_TRUE(CheckIfBitExact(decoded_buffer.get(), frameLength, _refDecFrame,
_lengthSourceFrame) == true);
// Reset then decode.
EXPECT_TRUE(_decoder->Reset() == WEBRTC_VIDEO_CODEC_OK);
@@ -551,8 +566,10 @@ UnitTest::Perform()
_decoder->Decode(encodedImage, false, NULL);
frameLength = WaitForDecodedFrame();
}
EXPECT_TRUE(CheckIfBitExact(_decodedVideoBuffer.Buffer(), frameLength,
_refDecFrame, _lengthSourceFrame) == true);
ExtractBuffer(_decodedVideoBuffer, _lengthSourceFrame,
decoded_buffer.get());
EXPECT_TRUE(CheckIfBitExact(decoded_buffer.get(), frameLength,
_refDecFrame, _lengthSourceFrame) == true);
// Decode with other size, reset, then decode with original size again
// to verify that decoder is reset to a "fresh" state upon Reset().
@@ -565,20 +582,25 @@ UnitTest::Perform()
memcpy(&tempInst, &_inst, sizeof(VideoCodec));
tempInst.width /= 2;
tempInst.height /= 2;
int tmpHalfWidth = (tempInst.width + 1) / 2;
int tmpHalfHeight = (tempInst.height + 1) / 2;
int tmpSizeY = tempInst.width * tempInst.height;
int tmpSizeUv = tmpHalfWidth * tmpHalfHeight;
// Encode reduced (quarter) frame size.
EXPECT_TRUE(_encoder->Release() == WEBRTC_VIDEO_CODEC_OK);
EXPECT_TRUE(_encoder->InitEncode(&tempInst, 1, 1440) ==
WEBRTC_VIDEO_CODEC_OK);
VideoFrame tempInput;
unsigned int tmpLength = _inputVideoBuffer.Length() / 4;
tempInput.CopyFrame(tmpLength, _inputVideoBuffer.Buffer());
tempInput.SetWidth(tempInst.width);
tempInput.SetHeight(tempInst.height);
webrtc::I420VideoFrame tempInput;
tempInput.CreateFrame(tmpSizeY, _inputVideoBuffer.buffer(kYPlane),
tmpSizeUv, _inputVideoBuffer.buffer(kUPlane),
tmpSizeUv, _inputVideoBuffer.buffer(kVPlane),
tempInst.width, tempInst.height,
tempInst.width, tmpHalfWidth, tmpHalfWidth);
_encoder->Encode(tempInput, NULL, NULL);
frameLength = WaitForEncodedFrame();
EXPECT_TRUE(frameLength > 0);
tempInput.Free();
// Reset then decode.
EXPECT_TRUE(_decoder->Reset() == WEBRTC_VIDEO_CODEC_OK);
frameLength = 0;
@@ -608,9 +630,11 @@ UnitTest::Perform()
}
// check that decoded frame matches with reference
EXPECT_TRUE(CheckIfBitExact(_decodedVideoBuffer.Buffer(), frameLength,
_refDecFrame, _lengthSourceFrame) == true);
unsigned int length = CalcBufferSize(kI420, width, height);
scoped_array<uint8_t> decoded_buffer(new uint8_t[length]);
ExtractBuffer(_decodedVideoBuffer, length, decoded_buffer.get());
EXPECT_TRUE(CheckIfBitExact(decoded_buffer.get(), length,
_refDecFrame, _lengthSourceFrame) == true);
}
// Release then decode.
@@ -624,8 +648,9 @@ UnitTest::Perform()
_decoder->Decode(encodedImage, false, NULL);
frameLength = WaitForDecodedFrame();
}
EXPECT_TRUE(CheckIfBitExact(_decodedVideoBuffer.Buffer(), frameLength,
_refDecFrame, _lengthSourceFrame) == true);
ExtractBuffer(_decodedVideoBuffer, length, decoded_buffer.get());
EXPECT_TRUE(CheckIfBitExact(decoded_buffer.get(), frameLength,
_refDecFrame, _lengthSourceFrame) == true);
_encodedVideoBuffer.SetLength(0);
delete [] tmpBuf;
@@ -644,19 +669,24 @@ UnitTest::Perform()
frames = 0;
int frameDelay = 0;
int encTimeStamp;
_decodedVideoBuffer.SetTimeStamp(0);
_decodedVideoBuffer.set_timestamp(0);
while (fread(_sourceBuffer, 1, _lengthSourceFrame, _sourceFile) ==
_lengthSourceFrame)
{
_inputVideoBuffer.CopyFrame(_lengthSourceFrame, _sourceBuffer);
_inputVideoBuffer.SetTimeStamp(frames);
_inputVideoBuffer.CreateFrame(size_y, _sourceBuffer,
size_uv, _sourceBuffer + size_y,
size_uv, _sourceBuffer + size_y + size_uv,
width, height,
width, half_width, half_width);
_inputVideoBuffer.set_timestamp(frames);
ASSERT_TRUE(_encoder->Encode(_inputVideoBuffer, NULL, NULL) ==
WEBRTC_VIDEO_CODEC_OK);
frameLength = WaitForEncodedFrame();
//ASSERT_TRUE(frameLength);
EXPECT_TRUE(frameLength > 0);
encTimeStamp = _encodedVideoBuffer.TimeStamp();
EXPECT_TRUE(_inputVideoBuffer.TimeStamp() ==
EXPECT_TRUE(_inputVideoBuffer.timestamp() ==
static_cast<unsigned>(encTimeStamp));
frameLength = Decode();
@@ -670,7 +700,7 @@ UnitTest::Perform()
{
encTimeStamp = 0;
}
EXPECT_TRUE(_decodedVideoBuffer.TimeStamp() ==
EXPECT_TRUE(_decodedVideoBuffer.timestamp() ==
static_cast<unsigned>(encTimeStamp));
frames++;
}
@@ -678,7 +708,6 @@ UnitTest::Perform()
rewind(_sourceFile);
RateControlTests();
inputImage.Free();
Teardown();
}
@@ -719,13 +748,22 @@ UnitTest::RateControlTests()
{
CodecSpecific_SetBitrate(_bitRate, _inst.maxFramerate);
}
int width = _source->GetWidth();
int half_width = (width + 1) / 2;
int height = _source->GetHeight();
int half_height = (height + 1) / 2;
int size_y = width * height;
int size_uv = half_width * half_height;
while (fread(_sourceBuffer, 1, _lengthSourceFrame, _sourceFile) ==
_lengthSourceFrame)
{
_inputVideoBuffer.CopyFrame(_lengthSourceFrame, _sourceBuffer);
_inputVideoBuffer.SetTimeStamp(_inputVideoBuffer.TimeStamp() +
static_cast<WebRtc_UWord32>(9e4 /
_inputVideoBuffer.CreateFrame(size_y, _sourceBuffer,
size_uv, _sourceBuffer + size_y,
size_uv, _sourceBuffer + size_y +
size_uv,
width, height,
width, half_width, half_width);
_inputVideoBuffer.set_timestamp(static_cast<WebRtc_UWord32>(9e4 /
static_cast<float>(_inst.maxFramerate)));
ASSERT_EQ(_encoder->Encode(_inputVideoBuffer, NULL, NULL),
WEBRTC_VIDEO_CODEC_OK);

View File

@@ -94,12 +94,12 @@ private:
class UnitTestDecodeCompleteCallback : public webrtc::DecodedImageCallback
{
public:
UnitTestDecodeCompleteCallback(webrtc::VideoFrame* buffer) :
UnitTestDecodeCompleteCallback(webrtc::I420VideoFrame* buffer) :
_decodedVideoBuffer(buffer), _decodeComplete(false) {}
WebRtc_Word32 Decoded(webrtc::VideoFrame& image);
WebRtc_Word32 Decoded(webrtc::I420VideoFrame& image);
bool DecodeComplete();
private:
webrtc::VideoFrame* _decodedVideoBuffer;
webrtc::I420VideoFrame* _decodedVideoBuffer;
bool _decodeComplete;
};

View File

@@ -36,8 +36,6 @@ VP8DualDecoderTest::~VP8DualDecoderTest()
_decoder2->Release();
delete _decoder2;
}
_decodedVideoBuffer2.Free();
}
void
@@ -46,9 +44,6 @@ VP8DualDecoderTest::Perform()
_inname = webrtc::test::ProjectRootPath() + "resources/foreman_cif.yuv";
CodecSettings(352, 288, 30, _bitRate);
Setup();
_inputVideoBuffer.VerifyAndAllocate(_lengthSourceFrame);
_decodedVideoBuffer.VerifyAndAllocate(_lengthSourceFrame);
_decodedVideoBuffer2.VerifyAndAllocate(_lengthSourceFrame);
if(_encoder->InitEncode(&_inst, 4, 1460) < 0)
{
exit(EXIT_FAILURE);
@@ -171,9 +166,7 @@ VP8DualDecoderTest::Decode(int lossValue)
}
// compare decoded images
if (!CheckIfBitExact(_decodedVideoBuffer.Buffer(),
_decodedVideoBuffer.Length(),
_decodedVideoBuffer2.Buffer(), _decodedVideoBuffer.Length()))
if (!CheckIfBitExactFrames(_decodedVideoBuffer, _decodedVideoBuffer2))
{
fprintf(stderr,"\n\nClone output different from master.\n\n");
exit(EXIT_FAILURE);
@@ -185,26 +178,10 @@ VP8DualDecoderTest::Decode(int lossValue)
return ret;
}
bool
VP8DualDecoderTest::CheckIfBitExact(const void* ptrA, unsigned int aLengthBytes,
const void* ptrB, unsigned int bLengthBytes)
WebRtc_Word32 DualDecoderCompleteCallback::Decoded(webrtc::I420VideoFrame&
image)
{
if (aLengthBytes != bLengthBytes)
{
return false;
}
return memcmp(ptrA, ptrB, aLengthBytes) == 0;
}
WebRtc_Word32 DualDecoderCompleteCallback::Decoded(webrtc::VideoFrame& image)
{
_decodedVideoBuffer->VerifyAndAllocate(image.Length());
_decodedVideoBuffer->CopyFrame(image.Length(), image.Buffer());
_decodedVideoBuffer->SetWidth(image.Width());
_decodedVideoBuffer->SetHeight(image.Height());
_decodedVideoBuffer->SetTimeStamp(image.TimeStamp());
_decodedVideoBuffer->CopyFrame(image);
_decodeComplete = true;
return 0;
}
@@ -219,3 +196,20 @@ bool DualDecoderCompleteCallback::DecodeComplete()
return false;
}
bool
VP8DualDecoderTest::CheckIfBitExactFrames(const webrtc::I420VideoFrame& frame1,
const webrtc::I420VideoFrame& frame2) {
for (int plane = 0; plane < webrtc::kNumOfPlanes; plane ++) {
webrtc::PlaneType plane_type = static_cast<webrtc::PlaneType>(plane);
int allocated_size1 = frame1.allocated_size(plane_type);
int allocated_size2 = frame2.allocated_size(plane_type);
if (allocated_size1 != allocated_size2)
return false;
const uint8_t* plane_buffer1 = frame1.buffer(plane_type);
const uint8_t* plane_buffer2 = frame2.buffer(plane_type);
if (memcmp(plane_buffer1, plane_buffer2, allocated_size1) != 0)
return false;
}
return true;
}

View File

@@ -30,21 +30,21 @@ protected:
virtual int Decode(int lossValue = 0);
webrtc::VP8Decoder* _decoder2;
webrtc::VideoFrame _decodedVideoBuffer2;
static bool CheckIfBitExact(const void *ptrA, unsigned int aLengthBytes,
const void *ptrB, unsigned int bLengthBytes);
webrtc::I420VideoFrame _decodedVideoBuffer2;
static bool CheckIfBitExactFrames(const webrtc::I420VideoFrame& frame1,
const webrtc::I420VideoFrame& frame2);
private:
};
class DualDecoderCompleteCallback : public webrtc::DecodedImageCallback
{
public:
DualDecoderCompleteCallback(webrtc::VideoFrame* buffer)
DualDecoderCompleteCallback(webrtc::I420VideoFrame* buffer)
: _decodedVideoBuffer(buffer), _decodeComplete(false) {}
WebRtc_Word32 Decoded(webrtc::VideoFrame& decodedImage);
WebRtc_Word32 Decoded(webrtc::I420VideoFrame& decodedImage);
bool DecodeComplete();
private:
webrtc::VideoFrame* _decodedVideoBuffer;
webrtc::I420VideoFrame* _decodedVideoBuffer;
bool _decodeComplete;
};

View File

@@ -34,16 +34,12 @@ VP8RpsTest::~VP8RpsTest() {
decoder2_->Release();
delete decoder2_;
}
decoded_frame2_.Free();
}
void VP8RpsTest::Perform() {
_inname = "test/testFiles/foreman_cif.yuv";
CodecSettings(352, 288, 30, _bitRate);
Setup();
_inputVideoBuffer.VerifyAndAllocate(_lengthSourceFrame);
_decodedVideoBuffer.VerifyAndAllocate(_lengthSourceFrame);
decoded_frame2_.VerifyAndAllocate(_lengthSourceFrame);
// Enable RPS functionality
_inst.codecSpecific.VP8.pictureLossIndicationOn = true;
@@ -137,16 +133,22 @@ bool VP8RpsTest::EncodeRps(RpsDecodeCompleteCallback* decodeCallback) {
size_t bytes_read = fread(_sourceBuffer, 1, _lengthSourceFrame, _sourceFile);
if (bytes_read < _lengthSourceFrame)
return true;
_inputVideoBuffer.CopyFrame(_lengthSourceFrame, _sourceBuffer);
_inputVideoBuffer.SetTimeStamp((unsigned int)
(_encFrameCnt * 9e4 / _inst.maxFramerate));
_inputVideoBuffer.SetWidth(_inst.width);
_inputVideoBuffer.SetHeight(_inst.height);
int half_width = (_inst.width + 1) / 2;
int half_height = (_inst.height + 1) / 2;
int size_y = _inst.width * _inst.height;
int size_uv = half_width * half_height;
_inputVideoBuffer.CreateFrame(size_y, _sourceBuffer,
size_uv, _sourceBuffer + size_y,
size_uv, _sourceBuffer + size_y + size_uv,
_inst.width, _inst.height,
_inst.width, half_width, half_width);
_inputVideoBuffer.set_timestamp((unsigned int)
(_encFrameCnt * 9e4 / _inst.maxFramerate));
if (feof(_sourceFile) != 0) {
return true;
}
_encodeCompleteTime = 0;
_encodeTimes[_inputVideoBuffer.TimeStamp()] = tGetTime();
_encodeTimes[_inputVideoBuffer.timestamp()] = tGetTime();
webrtc::CodecSpecificInfo* codecSpecificInfo = CreateEncoderSpecificInfo();
codecSpecificInfo->codecSpecific.VP8.pictureIdRPSI =
@@ -169,11 +171,11 @@ bool VP8RpsTest::EncodeRps(RpsDecodeCompleteCallback* decodeCallback) {
}
if (_encodeCompleteTime > 0) {
_totalEncodeTime += _encodeCompleteTime -
_encodeTimes[_inputVideoBuffer.TimeStamp()];
_encodeTimes[_inputVideoBuffer.timestamp()];
}
else {
_totalEncodeTime += tGetTime() -
_encodeTimes[_inputVideoBuffer.TimeStamp()];
_encodeTimes[_inputVideoBuffer.timestamp()];
}
return false;
}
@@ -219,9 +221,8 @@ int VP8RpsTest::Decode(int lossValue) {
// compare decoded images
#if FRAME_LOSS
if (!_missingFrames) {
if (!CheckIfBitExact(_decodedVideoBuffer.GetBuffer(),
_decodedVideoBuffer.GetLength(),
decoded_frame2_.GetBuffer(), _decodedVideoBuffer.GetLength())) {
if (!CheckIfBitExactFrames(_decodedVideoBuffer,
decoded_frame2_)) {
fprintf(stderr,"\n\nRPS decoder different from master: %u\n\n",
_framecnt);
return -1;
@@ -229,9 +230,7 @@ int VP8RpsTest::Decode(int lossValue) {
}
#else
if (_framecnt > 0 && _framecnt % 10 != 0) {
if (!CheckIfBitExact(_decodedVideoBuffer.Buffer(),
_decodedVideoBuffer.Length(),
decoded_frame2_.Buffer(), _decodedVideoBuffer.Length())) {
if (!CheckIfBitExactFrames(_decodedVideoBuffer, decoded_frame2_)) {
fprintf(stderr,"\n\nRPS decoder different from master: %u\n\n",
_framecnt);
return -1;
@@ -247,24 +246,30 @@ int VP8RpsTest::Decode(int lossValue) {
return 0;
}
bool
VP8RpsTest::CheckIfBitExact(const void* ptrA, unsigned int aLengthBytes,
const void* ptrB, unsigned int bLengthBytes) {
if (aLengthBytes != bLengthBytes)
return false;
return memcmp(ptrA, ptrB, aLengthBytes) == 0;
VP8RpsTest::CheckIfBitExactFrames(const webrtc::I420VideoFrame& frame1,
const webrtc::I420VideoFrame& frame2) {
for (int plane = 0; plane < webrtc::kNumOfPlanes; plane ++) {
webrtc::PlaneType plane_type = static_cast<webrtc::PlaneType>(plane);
int allocated_size1 = frame1.allocated_size(plane_type);
int allocated_size2 = frame2.allocated_size(plane_type);
if (allocated_size1 != allocated_size2)
return false;
const uint8_t* plane_buffer1 = frame1.buffer(plane_type);
const uint8_t* plane_buffer2 = frame2.buffer(plane_type);
if (memcmp(plane_buffer1, plane_buffer2, allocated_size1) != 0)
return false;
}
return true;
}
RpsDecodeCompleteCallback::RpsDecodeCompleteCallback(webrtc::VideoFrame* buffer)
RpsDecodeCompleteCallback::RpsDecodeCompleteCallback(webrtc::I420VideoFrame*
buffer)
: decoded_frame_(buffer),
decode_complete_(false),
last_decoded_picture_id_(0),
last_decoded_ref_picture_id_(0),
updated_ref_picture_id_(false) {
}
decode_complete_(false) {}
WebRtc_Word32 RpsDecodeCompleteCallback::Decoded(webrtc::VideoFrame& image) {
WebRtc_Word32 RpsDecodeCompleteCallback::Decoded(webrtc::I420VideoFrame&
image) {
return decoded_frame_->CopyFrame(image);
decode_complete_ = true;
}

View File

@@ -11,6 +11,7 @@
#ifndef WEBRTC_MODULES_VIDEO_CODING_CODECS_VP8_RPS_TEST_H_
#define WEBRTC_MODULES_VIDEO_CODING_CODECS_VP8_RPS_TEST_H_
#include "common_video/interface/i420_video_frame.h"
#include "vp8.h"
#include "normal_async_test.h"
@@ -28,18 +29,18 @@ class VP8RpsTest : public VP8NormalAsyncTest {
virtual bool EncodeRps(RpsDecodeCompleteCallback* decodeCallback);
virtual int Decode(int lossValue = 0);
static bool CheckIfBitExact(const void *ptrA, unsigned int aLengthBytes,
const void *ptrB, unsigned int bLengthBytes);
static bool CheckIfBitExactFrames(const webrtc::I420VideoFrame& frame1,
const webrtc::I420VideoFrame& frame2);
webrtc::VP8Decoder* decoder2_;
webrtc::VideoFrame decoded_frame2_;
webrtc::I420VideoFrame decoded_frame2_;
bool sli_;
};
class RpsDecodeCompleteCallback : public webrtc::DecodedImageCallback {
public:
RpsDecodeCompleteCallback(webrtc::VideoFrame* buffer);
WebRtc_Word32 Decoded(webrtc::VideoFrame& decodedImage);
RpsDecodeCompleteCallback(webrtc::I420VideoFrame* buffer);
WebRtc_Word32 Decoded(webrtc::I420VideoFrame& decodedImage);
bool DecodeComplete();
WebRtc_Word32 ReceivedDecodedReferenceFrame(const WebRtc_UWord64 picture_id);
WebRtc_Word32 ReceivedDecodedFrame(const WebRtc_UWord64 picture_id);
@@ -47,7 +48,7 @@ class RpsDecodeCompleteCallback : public webrtc::DecodedImageCallback {
WebRtc_UWord64 LastDecodedRefPictureId(bool *updated);
private:
webrtc::VideoFrame* decoded_frame_;
webrtc::I420VideoFrame* decoded_frame_;
bool decode_complete_;
WebRtc_UWord64 last_decoded_picture_id_;
WebRtc_UWord64 last_decoded_ref_picture_id_;

View File

@@ -324,13 +324,13 @@ uint32_t VP8EncoderImpl::MaxIntraTarget(uint32_t optimalBuffersize) {
return (targetPct < minIntraTh) ? minIntraTh: targetPct;
}
int VP8EncoderImpl::Encode(const VideoFrame& input_image,
int VP8EncoderImpl::Encode(const I420VideoFrame& input_image,
const CodecSpecificInfo* codec_specific_info,
const std::vector<VideoFrameType>* frame_types) {
if (!inited_) {
return WEBRTC_VIDEO_CODEC_UNINITIALIZED;
}
if (input_image.Buffer() == NULL) {
if (input_image.IsZeroSize()) {
return WEBRTC_VIDEO_CODEC_ERR_PARAMETER;
}
if (encoded_complete_callback_ == NULL) {
@@ -344,20 +344,18 @@ int VP8EncoderImpl::Encode(const VideoFrame& input_image,
}
// Check for change in frame size.
if (input_image.Width() != codec_.width ||
input_image.Height() != codec_.height) {
int ret = UpdateCodecFrameSize(input_image.Width(), input_image.Height());
if (input_image.width() != codec_.width ||
input_image.height() != codec_.height) {
int ret = UpdateCodecFrameSize(input_image.width(), input_image.height());
if (ret < 0) {
return ret;
}
}
// Image in vpx_image_t format.
uint8_t* buffer = input_image.Buffer();
uint32_t v_plane_loc = codec_.height * codec_.width +
((codec_.width + 1) >> 1) * ((codec_.height + 1) >> 1);
raw_->planes[PLANE_Y] = buffer;
raw_->planes[PLANE_U] = &buffer[codec_.width * codec_.height];
raw_->planes[PLANE_V] = &buffer[v_plane_loc];
// Input image is const. VP8's raw image is not defined as const.
raw_->planes[PLANE_Y] = const_cast<uint8_t*>(input_image.buffer(kYPlane));
raw_->planes[PLANE_U] = const_cast<uint8_t*>(input_image.buffer(kUPlane));
raw_->planes[PLANE_V] = const_cast<uint8_t*>(input_image.buffer(kVPlane));
int flags = 0;
#if WEBRTC_LIBVPX_VERSION >= 971
@@ -379,11 +377,11 @@ int VP8EncoderImpl::Encode(const VideoFrame& input_image,
codec_specific_info->codecSpecific.VP8.pictureIdRPSI);
}
if (codec_specific_info->codecSpecific.VP8.hasReceivedSLI) {
sendRefresh = rps_->ReceivedSLI(input_image.TimeStamp());
sendRefresh = rps_->ReceivedSLI(input_image.timestamp());
}
}
flags = rps_->EncodeFlags(picture_id_, sendRefresh,
input_image.TimeStamp());
input_image.timestamp());
}
// TODO(holmer): Ideally the duration should be the timestamp diff of this
@@ -456,7 +454,7 @@ void VP8EncoderImpl::PopulateCodecSpecific(CodecSpecificInfo* codec_specific,
picture_id_ = (picture_id_ + 1) & 0x7FFF; // prepare next
}
int VP8EncoderImpl::GetEncodedFrame(const VideoFrame& input_image) {
int VP8EncoderImpl::GetEncodedFrame(const I420VideoFrame& input_image) {
vpx_codec_iter_t iter = NULL;
encoded_image_._frameType = kDeltaFrame;
const vpx_codec_cx_pkt_t *pkt= vpx_codec_get_cx_data(encoder_, &iter);
@@ -469,7 +467,7 @@ int VP8EncoderImpl::GetEncodedFrame(const VideoFrame& input_image) {
}
} else if (pkt->kind == VPX_CODEC_CX_FRAME_PKT) {
CodecSpecificInfo codecSpecific;
PopulateCodecSpecific(&codecSpecific, *pkt, input_image.TimeStamp());
PopulateCodecSpecific(&codecSpecific, *pkt, input_image.timestamp());
assert(pkt->data.frame.sz <= encoded_image_._size);
memcpy(encoded_image_._buffer, pkt->data.frame.buf, pkt->data.frame.sz);
@@ -484,9 +482,9 @@ int VP8EncoderImpl::GetEncodedFrame(const VideoFrame& input_image) {
}
if (encoded_image_._length > 0) {
encoded_image_._timeStamp = input_image.TimeStamp();
encoded_image_._timeStamp = input_image.timestamp();
// TODO(mikhal): Resolve confusion in terms.
encoded_image_.capture_time_ms_ = input_image.RenderTimeMs();
encoded_image_.capture_time_ms_ = input_image.render_time_ms();
// Figure out where partition boundaries are located.
RTPFragmentationHeader fragInfo;
@@ -518,7 +516,7 @@ int VP8EncoderImpl::GetEncodedFrame(const VideoFrame& input_image) {
}
#if WEBRTC_LIBVPX_VERSION >= 971
int VP8EncoderImpl::GetEncodedPartitions(const VideoFrame& input_image) {
int VP8EncoderImpl::GetEncodedPartitions(const I420VideoFrame& input_image) {
vpx_codec_iter_t iter = NULL;
int part_idx = 0;
encoded_image_._length = 0;
@@ -554,13 +552,13 @@ int VP8EncoderImpl::GetEncodedPartitions(const VideoFrame& input_image) {
encoded_image_._frameType = kKeyFrame;
rps_->EncodedKeyFrame(picture_id_);
}
PopulateCodecSpecific(&codec_specific, *pkt, input_image.TimeStamp());
PopulateCodecSpecific(&codec_specific, *pkt, input_image.timestamp());
break;
}
}
if (encoded_image_._length > 0) {
encoded_image_._timeStamp = input_image.TimeStamp();
encoded_image_.capture_time_ms_ = input_image.RenderTimeMs();
encoded_image_._timeStamp = input_image.timestamp();
encoded_image_.capture_time_ms_ = input_image.render_time_ms();
encoded_image_._encodedHeight = raw_->h;
encoded_image_._encodedWidth = raw_->w;
encoded_complete_callback_->Encoded(encoded_image_, &codec_specific,
@@ -873,30 +871,18 @@ int VP8DecoderImpl::ReturnFrame(const vpx_image_t* img, uint32_t timestamp) {
// Decoder OK and NULL image => No show frame
return WEBRTC_VIDEO_CODEC_NO_OUTPUT;
}
uint32_t required_size = CalcBufferSize(kI420, img->d_w, img->d_h);
decoded_image_.VerifyAndAllocate(required_size);
uint8_t* buf;
uint32_t pos = 0;
uint32_t plane, y;
uint8_t* buffer = decoded_image_.Buffer();
for (plane = 0; plane < 3; plane++) {
unsigned int width = (plane ? (img->d_w + 1) >> 1 : img->d_w);
unsigned int height = (plane ? (img->d_h + 1) >> 1 : img->d_h);
buf = img->planes[plane];
for (y = 0; y < height; y++) {
memcpy(&buffer[pos], buf, width);
pos += width;
buf += img->stride[plane];
}
}
// Set decoded image parameters.
decoded_image_.SetHeight(img->d_h);
decoded_image_.SetWidth(img->d_w);
decoded_image_.SetLength(CalcBufferSize(kI420, img->d_w, img->d_h));
decoded_image_.SetTimeStamp(timestamp);
int size_y = img->stride[VPX_PLANE_Y] * img->d_h;
int size_u = img->stride[VPX_PLANE_U] * ((img->d_h + 1) / 2);
int size_v = img->stride[VPX_PLANE_V] * ((img->d_h + 1) / 2);
// TODO(mikhal): This does a copy - need to SwapBuffers.
decoded_image_.CreateFrame(size_y, img->planes[VPX_PLANE_Y],
size_u, img->planes[VPX_PLANE_U],
size_v, img->planes[VPX_PLANE_V],
img->d_w, img->d_h,
img->stride[VPX_PLANE_Y],
img->stride[VPX_PLANE_U],
img->stride[VPX_PLANE_V]);
decoded_image_.set_timestamp(timestamp);
int ret = decode_complete_callback_->Decoded(decoded_image_);
if (ret != 0)
return ret;
@@ -913,7 +899,6 @@ int VP8DecoderImpl::RegisterDecodeCompleteCallback(
}
int VP8DecoderImpl::Release() {
decoded_image_.Free();
if (last_keyframe_._buffer != NULL) {
delete [] last_keyframe_._buffer;
last_keyframe_._buffer = NULL;
@@ -941,7 +926,7 @@ VideoDecoder* VP8DecoderImpl::Copy() {
assert(false);
return NULL;
}
if (decoded_image_.Buffer() == NULL) {
if (decoded_image_.IsZeroSize()) {
// Nothing has been decoded before; cannot clone.
return NULL;
}
@@ -964,13 +949,13 @@ VideoDecoder* VP8DecoderImpl::Copy() {
return NULL;
}
// Allocate memory for reference image copy
assert(decoded_image_.Width() > 0);
assert(decoded_image_.Height() > 0);
assert(decoded_image_.width() > 0);
assert(decoded_image_.height() > 0);
assert(image_format_ > VPX_IMG_FMT_NONE);
// Check if frame format has changed.
if (ref_frame_ &&
(decoded_image_.Width() != ref_frame_->img.d_w ||
decoded_image_.Height() != ref_frame_->img.d_h ||
(decoded_image_.width() != static_cast<int>(ref_frame_->img.d_w) ||
decoded_image_.height() != static_cast<int>(ref_frame_->img.d_h) ||
image_format_ != ref_frame_->img.fmt)) {
vpx_img_free(&ref_frame_->img);
delete ref_frame_;
@@ -982,12 +967,12 @@ VideoDecoder* VP8DecoderImpl::Copy() {
ref_frame_ = new vpx_ref_frame_t;
unsigned int align = 1;
if (decoded_image_.Width() % 32 == 0) {
if (decoded_image_.width() % 32 == 0) {
align = 32;
}
if (!vpx_img_alloc(&ref_frame_->img,
static_cast<vpx_img_fmt_t>(image_format_),
decoded_image_.Width(), decoded_image_.Height(),
decoded_image_.width(), decoded_image_.height(),
align)) {
assert(false);
delete copy;

View File

@@ -72,7 +72,7 @@ class VP8EncoderImpl : public VP8Encoder {
// WEBRTC_VIDEO_CODEC_ERROR
// WEBRTC_VIDEO_CODEC_TIMEOUT
virtual int Encode(const VideoFrame& input_image,
virtual int Encode(const I420VideoFrame& input_image,
const CodecSpecificInfo* codec_specific_info,
const std::vector<VideoFrameType>* frame_types);
@@ -115,9 +115,9 @@ class VP8EncoderImpl : public VP8Encoder {
const vpx_codec_cx_pkt& pkt,
uint32_t timestamp);
int GetEncodedFrame(const VideoFrame& input_image);
int GetEncodedFrame(const I420VideoFrame& input_image);
int GetEncodedPartitions(const VideoFrame& input_image);
int GetEncodedPartitions(const I420VideoFrame& input_image);
// Determine maximum target for Intra frames
//
@@ -219,7 +219,7 @@ class VP8DecoderImpl : public VP8Decoder {
int ReturnFrame(const vpx_image_t* img, uint32_t timeStamp);
VideoFrame decoded_image_;
I420VideoFrame decoded_image_;
DecodedImageCallback* decode_complete_callback_;
bool inited_;
bool feedback_mode_;

View File

@@ -11,6 +11,7 @@
#ifndef WEBRTC_MODULES_INTERFACE_VIDEO_CODING_H_
#define WEBRTC_MODULES_INTERFACE_VIDEO_CODING_H_
#include "common_video/interface/i420_video_frame.h"
#include "modules/interface/module.h"
#include "modules/interface/module_common_types.h"
#include "modules/video_coding/main/interface/video_coding_defines.h"
@@ -252,7 +253,7 @@ public:
// Return value : VCM_OK, on success.
// < 0, on error.
virtual WebRtc_Word32 AddVideoFrame(
const VideoFrame& videoFrame,
const I420VideoFrame& videoFrame,
const VideoContentMetrics* contentMetrics = NULL,
const CodecSpecificInfo* codecSpecificInfo = NULL) = 0;

View File

@@ -12,6 +12,7 @@
#define WEBRTC_MODULES_INTERFACE_VIDEO_CODING_DEFINES_H_
#include "typedefs.h"
#include "common_video/interface/i420_video_frame.h"
#include "modules/interface/module_common_types.h"
namespace webrtc {
@@ -96,7 +97,7 @@ class VCMFrameStorageCallback {
// Callback class used for passing decoded frames which are ready to be rendered.
class VCMReceiveCallback {
public:
virtual WebRtc_Word32 FrameToRender(VideoFrame& videoFrame) = 0;
virtual WebRtc_Word32 FrameToRender(I420VideoFrame& videoFrame) = 0;
virtual WebRtc_Word32 ReceivedDecodedReferenceFrame(
const WebRtc_UWord64 pictureId) {
return -1;

View File

@@ -40,13 +40,13 @@ void VCMDecodedFrameCallback::SetUserReceiveCallback(
_receiveCallback = receiveCallback;
}
WebRtc_Word32 VCMDecodedFrameCallback::Decoded(VideoFrame& decodedImage)
WebRtc_Word32 VCMDecodedFrameCallback::Decoded(I420VideoFrame& decodedImage)
{
// TODO(holmer): We should improve this so that we can handle multiple
// callbacks from one call to Decode().
CriticalSectionScoped cs(_critSect);
VCMFrameInformation* frameInfo = static_cast<VCMFrameInformation*>(
_timestampMap.Pop(decodedImage.TimeStamp()));
_timestampMap.Pop(decodedImage.timestamp()));
if (frameInfo == NULL)
{
// The map should never be empty or full if this callback is called.
@@ -54,14 +54,14 @@ WebRtc_Word32 VCMDecodedFrameCallback::Decoded(VideoFrame& decodedImage)
}
_timing.StopDecodeTimer(
decodedImage.TimeStamp(),
decodedImage.timestamp(),
frameInfo->decodeStartTimeMs,
_clock->MillisecondTimestamp());
if (_receiveCallback != NULL)
{
_frame.SwapFrame(decodedImage);
_frame.SetRenderTime(frameInfo->renderTimeMs);
_frame.SwapFrame(&decodedImage);
_frame.set_render_time_ms(frameInfo->renderTimeMs);
WebRtc_Word32 callbackReturn = _receiveCallback->FrameToRender(_frame);
if (callbackReturn < 0)
{

View File

@@ -38,7 +38,7 @@ public:
virtual ~VCMDecodedFrameCallback();
void SetUserReceiveCallback(VCMReceiveCallback* receiveCallback);
virtual WebRtc_Word32 Decoded(VideoFrame& decodedImage);
virtual WebRtc_Word32 Decoded(I420VideoFrame& decodedImage);
virtual WebRtc_Word32 ReceivedDecodedReferenceFrame(const WebRtc_UWord64 pictureId);
virtual WebRtc_Word32 ReceivedDecodedFrame(const WebRtc_UWord64 pictureId);
@@ -50,7 +50,7 @@ public:
private:
CriticalSectionWrapper* _critSect;
TickTimeBase* _clock;
VideoFrame _frame;
I420VideoFrame _frame;
VCMReceiveCallback* _receiveCallback;
VCMTiming& _timing;
VCMTimestampMap _timestampMap;

View File

@@ -57,7 +57,7 @@ VCMGenericEncoder::InitEncode(const VideoCodec* settings,
}
WebRtc_Word32
VCMGenericEncoder::Encode(const VideoFrame& inputFrame,
VCMGenericEncoder::Encode(const I420VideoFrame& inputFrame,
const CodecSpecificInfo* codecSpecificInfo,
const std::vector<FrameType>* frameTypes) {
std::vector<VideoFrameType> video_frame_types(frameTypes->size(),
@@ -119,7 +119,7 @@ WebRtc_Word32 VCMGenericEncoder::RequestFrame(
if (!frame_types) {
return 0;
}
VideoFrame image;
I420VideoFrame image;
std::vector<VideoFrameType> video_frame_types(kVideoFrameDelta);
if (frame_types) {
VCMEncodedFrame::ConvertFrameTypes(*frame_types, &video_frame_types);

View File

@@ -99,7 +99,7 @@ public:
* cameraFrameRate : request or information from the remote side
* frameType : The requested frame type to encode
*/
WebRtc_Word32 Encode(const VideoFrame& inputFrame,
WebRtc_Word32 Encode(const I420VideoFrame& inputFrame,
const CodecSpecificInfo* codecSpecificInfo,
const std::vector<FrameType>* frameTypes);
/**

View File

@@ -9,6 +9,7 @@
*/
#include "video_coding_impl.h"
#include "common_video/libyuv/include/webrtc_libyuv.h"
#include "common_types.h"
#include "encoded_frame.h"
#include "jitter_buffer.h"
@@ -652,7 +653,7 @@ VideoCodingModuleImpl::SetVideoProtection(VCMVideoProtection videoProtection,
// Add one raw video frame to the encoder, blocking.
WebRtc_Word32
VideoCodingModuleImpl::AddVideoFrame(const VideoFrame& videoFrame,
VideoCodingModuleImpl::AddVideoFrame(const I420VideoFrame& videoFrame,
const VideoContentMetrics* contentMetrics,
const CodecSpecificInfo* codecSpecificInfo)
{
@@ -685,10 +686,10 @@ VideoCodingModuleImpl::AddVideoFrame(const VideoFrame& videoFrame,
&_nextFrameTypes);
if (_encoderInputFile != NULL)
{
if (fwrite(videoFrame.Buffer(), 1, videoFrame.Length(),
_encoderInputFile) != videoFrame.Length()) {
return -1;
}
if (PrintI420VideoFrame(videoFrame, _encoderInputFile) < 0)
{
return -1;
}
}
if (ret < 0)
{

View File

@@ -144,7 +144,7 @@ public:
// Add one raw video frame to the encoder, blocking.
virtual WebRtc_Word32 AddVideoFrame(
const VideoFrame& videoFrame,
const I420VideoFrame& videoFrame,
const VideoContentMetrics* _contentMetrics = NULL,
const CodecSpecificInfo* codecSpecificInfo = NULL);

View File

@@ -54,7 +54,6 @@ class TestVideoCodingModule : public ::testing::Test {
virtual void TearDown() {
VideoCodingModule::Destroy(vcm_);
input_frame_.Free();
}
void ExpectIntraRequest(int stream) {
@@ -88,7 +87,7 @@ class TestVideoCodingModule : public ::testing::Test {
VideoCodingModule* vcm_;
NiceMock<MockVideoEncoder> encoder_;
VideoFrame input_frame_;
I420VideoFrame input_frame_;
VideoCodec settings_;
};

View File

@@ -114,15 +114,20 @@ CodecDataBaseTest::Perform(CmdArgs& args)
// registering the callback - encode and decode with the same vcm (could be later changed)
_encodeCompleteCallback->RegisterReceiverVCM(_vcm);
// preparing a frame to be encoded
VideoFrame sourceFrame;
sourceFrame.VerifyAndAllocate(_lengthSourceFrame);
WebRtc_UWord8* tmpBuffer = new WebRtc_UWord8[_lengthSourceFrame];
TEST(fread(tmpBuffer, 1, _lengthSourceFrame, _sourceFile) > 0);
sourceFrame.CopyFrame(_lengthSourceFrame, tmpBuffer);
sourceFrame.SetHeight(_height);
sourceFrame.SetWidth(_width);
I420VideoFrame sourceFrame;
int half_width = (_width + 1) / 2;
int half_height = (_height + 1) / 2;
int size_y = _width * _height;
int size_uv = half_width * half_height;
sourceFrame.CreateFrame(size_y, tmpBuffer,
size_uv, tmpBuffer + size_y,
size_uv, tmpBuffer + size_y + size_uv,
_width, _height,
_width, half_width, half_width);
_timeStamp += (WebRtc_UWord32)(9e4 / _frameRate);
sourceFrame.SetTimeStamp(_timeStamp);
sourceFrame.set_timestamp(_timeStamp);
// Encoder registration
TEST (VideoCodingModule::NumberOfCodecs() > 0);
TEST(VideoCodingModule::Codec(-1, &sendCodec) < 0);
@@ -199,7 +204,7 @@ CodecDataBaseTest::Perform(CmdArgs& args)
TEST(_vcm->Decode() == VCM_OK);
waitEvent->Wait(33);
_timeStamp += (WebRtc_UWord32)(9e4 / _frameRate);
sourceFrame.SetTimeStamp(_timeStamp);
sourceFrame.set_timestamp(_timeStamp);
TEST(_vcm->AddVideoFrame(sourceFrame) == VCM_OK);
TEST(_vcm->Decode() == VCM_OK);
@@ -234,14 +239,14 @@ CodecDataBaseTest::Perform(CmdArgs& args)
TEST(_vcm->ResetDecoder() == VCM_OK);
waitEvent->Wait(33);
_timeStamp += (WebRtc_UWord32)(9e4 / _frameRate);
sourceFrame.SetTimeStamp(_timeStamp);
sourceFrame.set_timestamp(_timeStamp);
TEST(_vcm->AddVideoFrame(sourceFrame) == VCM_OK);
// Try to decode a delta frame. Should get a warning since we have enabled the "require key frame" setting
// and because no frame type request callback has been registered.
TEST(_vcm->Decode() == VCM_MISSING_CALLBACK);
TEST(_vcm->IntraFrameRequest(0) == VCM_OK);
_timeStamp += (WebRtc_UWord32)(9e4 / _frameRate);
sourceFrame.SetTimeStamp(_timeStamp);
sourceFrame.set_timestamp(_timeStamp);
TEST(_vcm->AddVideoFrame(sourceFrame) == VCM_OK);
TEST(_vcm->Decode() == VCM_OK);
@@ -254,13 +259,13 @@ CodecDataBaseTest::Perform(CmdArgs& args)
TEST(_vcm->IntraFrameRequest(0) == VCM_OK);
waitEvent->Wait(33);
_timeStamp += (WebRtc_UWord32)(9e4 / _frameRate);
sourceFrame.SetTimeStamp(_timeStamp);
sourceFrame.set_timestamp(_timeStamp);
TEST(_vcm->AddVideoFrame(sourceFrame) == VCM_OK);
TEST(_vcm->Decode() == VCM_OK);
TEST(_vcm->RegisterReceiveCodec(&sendCodec, 1) == VCM_OK);
waitEvent->Wait(33);
_timeStamp += (WebRtc_UWord32)(9e4 / _frameRate);
sourceFrame.SetTimeStamp(_timeStamp);
sourceFrame.set_timestamp(_timeStamp);
TEST(_vcm->IntraFrameRequest(0) == VCM_OK);
TEST(_vcm->AddVideoFrame(sourceFrame) == VCM_OK);
TEST(_vcm->Decode() == VCM_OK);
@@ -280,7 +285,6 @@ CodecDataBaseTest::Perform(CmdArgs& args)
rewind(_sourceFile);
_vcm->InitializeReceiver();
_vcm->InitializeSender();
sourceFrame.Free();
VCMDecodeCompleteCallback* decodeCallCDT = new VCMDecodeCompleteCallback(_decodedFile);
VCMEncodeCompleteCallback* encodeCallCDT = new VCMEncodeCompleteCallback(_encodedFile);
_vcm->RegisterReceiveCallback(decodeCallCDT);
@@ -290,8 +294,8 @@ CodecDataBaseTest::Perform(CmdArgs& args)
{
// Register all available decoders.
int i, j;
//double psnr;
sourceFrame.VerifyAndAllocate(_lengthSourceFrame);
sourceFrame.CreateEmptyFrame(_width, _height, _width,
(_width + 1) / 2, (_width + 1) / 2);
_vcm->RegisterReceiveCallback(decodeCallCDT);
for (i=0; i < VideoCodingModule::NumberOfCodecs(); i++)
{
@@ -326,17 +330,18 @@ CodecDataBaseTest::Perform(CmdArgs& args)
_vcm->EnableFrameDropper(false);
printf("Encoding with %s \n\n", sendCodec.plName);
for (j=0; j < int(300/VideoCodingModule::NumberOfCodecs()); j++)// assuming 300 frames, NumberOfCodecs <= 10
// Assuming 300 frames, NumberOfCodecs <= 10.
for (j=0; j < int(300/VideoCodingModule::NumberOfCodecs()); j++)
{
frameCnt++;
TEST(fread(tmpBuffer, 1, _lengthSourceFrame, _sourceFile) > 0);
// building source frame
sourceFrame.CopyFrame(_lengthSourceFrame, tmpBuffer);
sourceFrame.SetHeight(_height);
sourceFrame.SetWidth(_width);
sourceFrame.SetLength(_lengthSourceFrame);
sourceFrame.CreateFrame(size_y, tmpBuffer,
size_uv, tmpBuffer + size_y,
size_uv, tmpBuffer + size_y + size_uv,
_width, _height,
_width, half_width, half_width);
_timeStamp += (WebRtc_UWord32)(9e4 / _frameRate);
sourceFrame.SetTimeStamp(_timeStamp);
sourceFrame.set_timestamp(_timeStamp);
// send frame to the encoder
TEST (_vcm->AddVideoFrame(sourceFrame) == VCM_OK);
waitEvent->Wait(33); // was 100
@@ -373,7 +378,6 @@ CodecDataBaseTest::Perform(CmdArgs& args)
}
} // end: iterate codecs
rewind(_sourceFile);
sourceFrame.Free();
delete [] tmpBuffer;
delete decodeCallCDT;
delete encodeCallCDT;

View File

@@ -13,7 +13,7 @@
#include <stdio.h>
#include "../source/event.h"
#include "rtp_rtcp.h"
#include "module_common_types.h"
#include "common_video/interface/i420_video_frame.h"
#include "test_macros.h"
#include "modules/video_coding/main/source/mock/fake_tick_time.h"
@@ -122,8 +122,7 @@ GenericCodecTest::Perform(CmdArgs& args)
_vcm->Codec(0, &_sendCodec);
TEST(_vcm->RegisterSendCodec(&_sendCodec, 4, 1440) == VCM_OK);
// sanity on encoder registration
VideoFrame sourceFrame;
sourceFrame.VerifyAndAllocate(_lengthSourceFrame);
I420VideoFrame sourceFrame;
_vcm->InitializeSender();
TEST(_vcm->Codec(kVideoCodecVP8, &sendCodec) == 0);
TEST(_vcm->RegisterSendCodec(&sendCodec, -1, 1440) < 0); // bad number of cores
@@ -147,12 +146,16 @@ GenericCodecTest::Perform(CmdArgs& args)
}
WebRtc_UWord8* tmpBuffer = new WebRtc_UWord8[_lengthSourceFrame];
TEST(fread(tmpBuffer, 1, _lengthSourceFrame, _sourceFile) > 0);
// building source frame
sourceFrame.CopyFrame(_lengthSourceFrame, tmpBuffer);
sourceFrame.SetHeight(_height);
sourceFrame.SetWidth(_width);
sourceFrame.SetTimeStamp(_timeStamp++);
// encode/decode
int half_width = (_width + 1) / 2;
int half_height = (_height + 1) / 2;
int size_y = _width * _height;
int size_uv = half_width * half_height;
sourceFrame.CreateFrame(size_y, tmpBuffer,
size_uv, tmpBuffer + size_y,
size_uv, tmpBuffer + size_y + size_uv,
_width, _height,
_width, half_width, half_width);
sourceFrame.set_timestamp(_timeStamp++);
TEST(_vcm->AddVideoFrame(sourceFrame) < 0 ); // encoder uninitialized
_vcm->InitializeReceiver();
TEST(_vcm->SetChannelParameters(100, 0, 0) < 0);// setting rtt when receiver uninitialized
@@ -162,7 +165,6 @@ GenericCodecTest::Perform(CmdArgs& args)
/**************************************/
//Register both encoder and decoder, reset decoder - encode, set up decoder, reset encoder - decode.
rewind(_sourceFile);
sourceFrame.Free();
_vcm->InitializeReceiver();
_vcm->InitializeSender();
NumberOfCodecs = _vcm->NumberOfCodecs();
@@ -195,11 +197,13 @@ GenericCodecTest::Perform(CmdArgs& args)
for (i = 0; i < _frameRate; i++)
{
TEST(fread(tmpBuffer, 1, _lengthSourceFrame, _sourceFile) > 0);
sourceFrame.CopyFrame(_lengthSourceFrame, tmpBuffer);
sourceFrame.SetHeight(_height);
sourceFrame.SetWidth(_width);
sourceFrame.CreateFrame(size_y, tmpBuffer,
size_uv, tmpBuffer + size_y,
size_uv, tmpBuffer + size_y + size_uv,
_width, _height,
_width, half_width, half_width);
_timeStamp += (WebRtc_UWord32)(9e4 / static_cast<float>(_frameRate));
sourceFrame.SetTimeStamp(_timeStamp);
sourceFrame.set_timestamp(_timeStamp);
TEST(_vcm->AddVideoFrame(sourceFrame) == VCM_OK);
IncrementDebugClock(_frameRate);
_vcm->Process();
@@ -245,7 +249,7 @@ GenericCodecTest::Perform(CmdArgs& args)
TEST(_vcm->RegisterReceiveCodec(&sendCodec, 1) == VCM_OK);
TEST(_vcm->AddVideoFrame(sourceFrame) == VCM_OK);
_timeStamp += (WebRtc_UWord32)(9e4 / static_cast<float>(_frameRate));
sourceFrame.SetTimeStamp(_timeStamp);
sourceFrame.set_timestamp(_timeStamp);
// First packet of a subsequent frame required before the jitter buffer
// will allow decoding an incomplete frame.
TEST(_vcm->AddVideoFrame(sourceFrame) == VCM_OK);
@@ -269,8 +273,8 @@ GenericCodecTest::Perform(CmdArgs& args)
_vcm->InitializeSender();
_vcm->InitializeReceiver();
rewind(_sourceFile);
sourceFrame.Free();
sourceFrame.VerifyAndAllocate(_lengthSourceFrame);
sourceFrame.CreateEmptyFrame(_width, _height, _width,
(_width + 1) / 2, (_width + 1) / 2);
const float bitRate[] = {100, 400, 600, 1000, 2000};
const float nBitrates = sizeof(bitRate)/sizeof(*bitRate);
float _bitRate = 0;
@@ -315,11 +319,14 @@ GenericCodecTest::Perform(CmdArgs& args)
_lengthSourceFrame)
{
_frameCnt++;
sourceFrame.CopyFrame(_lengthSourceFrame, tmpBuffer);
sourceFrame.SetHeight(_height);
sourceFrame.SetWidth(_width);
sourceFrame.CreateFrame(size_y, tmpBuffer,
size_uv, tmpBuffer + size_y,
size_uv, tmpBuffer + size_y + size_uv,
_width, _height,
_width, (_width + 1) / 2,
(_width + 1) / 2);
_timeStamp += (WebRtc_UWord32)(9e4 / static_cast<float>(_frameRate));
sourceFrame.SetTimeStamp(_timeStamp);
sourceFrame.set_timestamp(_timeStamp);
ret = _vcm->AddVideoFrame(sourceFrame);
IncrementDebugClock(_frameRate);
@@ -364,8 +371,6 @@ GenericCodecTest::Perform(CmdArgs& args)
/* Encoder Pipeline Delay Test */
/******************************/
_vcm->InitializeSender();
sourceFrame.Free();
sourceFrame.VerifyAndAllocate(_lengthSourceFrame);
NumberOfCodecs = _vcm->NumberOfCodecs();
bool encodeComplete = false;
// going over all available codecs
@@ -383,11 +388,13 @@ GenericCodecTest::Perform(CmdArgs& args)
{
TEST(fread(tmpBuffer, 1, _lengthSourceFrame, _sourceFile) > 0);
_frameCnt++;
sourceFrame.CopyFrame(_lengthSourceFrame, tmpBuffer);
sourceFrame.SetHeight(_height);
sourceFrame.SetWidth(_width);
sourceFrame.CreateFrame(size_y, tmpBuffer,
size_uv, tmpBuffer + size_y,
size_uv, tmpBuffer + size_y + size_uv,
_width, _height,
_width, half_width, half_width);
_timeStamp += (WebRtc_UWord32)(9e4 / static_cast<float>(_frameRate));
sourceFrame.SetTimeStamp(_timeStamp);
sourceFrame.set_timestamp(_timeStamp);
_vcm->AddVideoFrame(sourceFrame);
encodeComplete = _encodeCompleteCallback->EncodeComplete();
} // first frame encoded
@@ -410,47 +417,6 @@ GenericCodecTest::Perform(CmdArgs& args)
VCMRTPEncodeCompleteCallback encCompleteCallback(&rtpModule);
_vcm->InitializeSender();
// TEST DISABLED FOR NOW SINCE VP8 DOESN'T HAVE THIS FEATURE
// sourceFrame.Free();
// sourceFrame.VerifyAndAllocate(_lengthSourceFrame);
// NumberOfCodecs = _vcm->NumberOfCodecs();
// WebRtc_UWord32 targetPayloadSize = 500;
// rtpModule.SetMaxTransferUnit(targetPayloadSize);
// // going over all available codecs
// for (int k = 0; k < NumberOfCodecs; k++)
// {
// _vcm->Codec(k, &_sendCodec);
// if (strncmp(_sendCodec.plName, "VP8", 3) == 0)
// {
// // Only test with VP8
// continue;
// }
// rtpModule.RegisterSendPayload(_sendCodec.plName, _sendCodec.plType);
// // Make sure we only get one NAL unit per packet
// _vcm->InitializeSender();
// _vcm->RegisterSendCodec(&_sendCodec, 4, targetPayloadSize);
// sendCallback.SetMaxPayloadSize(targetPayloadSize);
// _vcm->RegisterTransportCallback(&encCompleteCallback);
// sendCallback.Reset();
// _frameCnt = 0;
// rewind(_sourceFile);
// while (!feof(_sourceFile))
// {
// fread(tmpBuffer, 1, _lengthSourceFrame, _sourceFile);
// _frameCnt++;
// sourceFrame.CopyFrame(_lengthSourceFrame, tmpBuffer);
// sourceFrame.SetHeight(_height);
// sourceFrame.SetWidth(_width);
// _timeStamp += (WebRtc_UWord32)(9e4 / static_cast<float>(_frameRate));
// sourceFrame.SetTimeStamp(_timeStamp);
// ret = _vcm->AddVideoFrame(sourceFrame);
// } // first frame encoded
// printf ("\n Codec type = %s \n",_sendCodec.plName);
// printf(" Average payload size = %f bytes, target = %u bytes\n", sendCallback.AveragePayloadSize(), targetPayloadSize);
// } // end for all codecs
// Test temporal decimation settings
for (int k = 0; k < NumberOfCodecs; k++)
{
@@ -474,13 +440,14 @@ GenericCodecTest::Perform(CmdArgs& args)
_vcm->RegisterSendStatisticsCallback(&sendStats);
rewind(_sourceFile);
while (fread(tmpBuffer, 1, _lengthSourceFrame, _sourceFile) ==
_lengthSourceFrame)
{
sourceFrame.CopyFrame(_lengthSourceFrame, tmpBuffer);
sourceFrame.SetHeight(_height);
sourceFrame.SetWidth(_width);
_lengthSourceFrame) {
sourceFrame.CreateFrame(size_y, tmpBuffer,
size_uv, tmpBuffer + size_y,
size_uv, tmpBuffer + size_y + size_uv,
_width, _height,
_width, half_width, half_width);
_timeStamp += (WebRtc_UWord32)(9e4 / static_cast<float>(_frameRate));
sourceFrame.SetTimeStamp(_timeStamp);
sourceFrame.set_timestamp(_timeStamp);
ret = _vcm->AddVideoFrame(sourceFrame);
if (_vcm->TimeUntilNextProcess() <= 0)
{

View File

@@ -290,8 +290,7 @@ MediaOptTest::Perform()
}
// START TEST
VideoFrame sourceFrame;
sourceFrame.VerifyAndAllocate(_lengthSourceFrame);
I420VideoFrame sourceFrame;
WebRtc_UWord8* tmpBuffer = new WebRtc_UWord8[_lengthSourceFrame];
_vcm->SetChannelParameters((WebRtc_UWord32)_bitRate, (WebRtc_UWord8)_lossRate, _rttMS);
_vcm->RegisterReceiveCallback(&receiveCallback);
@@ -299,17 +298,22 @@ MediaOptTest::Perform()
_frameCnt = 0;
_sumEncBytes = 0.0;
_numFramesDropped = 0;
int half_width = (_width + 1) / 2;
int half_height = (_height + 1) / 2;
int size_y = _width * _height;
int size_uv = half_width * half_height;
while (feof(_sourceFile)== 0)
{
TEST(fread(tmpBuffer, 1, _lengthSourceFrame, _sourceFile) > 0);
_frameCnt++;
sourceFrame.CopyFrame(_lengthSourceFrame, tmpBuffer);
sourceFrame.SetHeight(_height);
sourceFrame.SetWidth(_width);
sourceFrame.CreateFrame(size_y, tmpBuffer,
size_uv, tmpBuffer + size_y,
size_uv, tmpBuffer + size_y + size_uv,
_width, _height,
_width, half_width, half_width);
_timeStamp += (WebRtc_UWord32)(9e4 / static_cast<float>(_frameRate));
sourceFrame.SetTimeStamp(_timeStamp);
sourceFrame.set_timestamp(_timeStamp);
TEST(_vcm->AddVideoFrame(sourceFrame) == VCM_OK);
// inform RTP Module of error resilience features
//_rtp->SetFECCodeRate(protectionCallback.FECKeyRate(),protectionCallback.FECDeltaRate());
@@ -331,8 +335,7 @@ MediaOptTest::Perform()
else
{
// write frame to file
if (fwrite(sourceFrame.Buffer(), 1, sourceFrame.Length(),
_actualSourceFile) != sourceFrame.Length()) {
if (PrintI420VideoFrame(sourceFrame, _actualSourceFile) < 0) {
return -1;
}
}

View File

@@ -34,12 +34,11 @@ MainSenderThread(void* obj)
SendSharedState* state = static_cast<SendSharedState*>(obj);
EventWrapper& waitEvent = *EventWrapper::Create();
// preparing a frame for encoding
VideoFrame sourceFrame;
I420VideoFrame sourceFrame;
WebRtc_Word32 width = state->_args.width;
WebRtc_Word32 height = state->_args.height;
float frameRate = state->_args.frameRate;
WebRtc_Word32 lengthSourceFrame = 3*width*height/2;
sourceFrame.VerifyAndAllocate(lengthSourceFrame);
WebRtc_UWord8* tmpBuffer = new WebRtc_UWord8[lengthSourceFrame];
if (state->_sourceFile == NULL)
@@ -58,11 +57,17 @@ MainSenderThread(void* obj)
TEST(fread(tmpBuffer, 1, lengthSourceFrame,state->_sourceFile) > 0 ||
feof(state->_sourceFile));
state->_frameCnt++;
sourceFrame.CopyFrame(lengthSourceFrame, tmpBuffer);
sourceFrame.SetHeight(height);
sourceFrame.SetWidth(width);
int size_y = width * height;
int half_width = (width + 1) / 2;
int half_height = (height + 1) / 2;
int size_uv = half_width * half_height;
sourceFrame.CreateFrame(size_y, tmpBuffer,
size_uv, tmpBuffer + size_y,
size_uv, tmpBuffer + size_y + size_uv,
width, height,
width, half_width, half_width);
state->_timestamp += (WebRtc_UWord32)(9e4 / frameRate);
sourceFrame.SetTimeStamp(state->_timestamp);
sourceFrame.set_timestamp(state->_timestamp);
WebRtc_Word32 ret = state->_vcm.AddVideoFrame(sourceFrame);
if (ret < 0)

View File

@@ -16,6 +16,7 @@
#include <time.h>
#include "../source/event.h"
#include "common_video/libyuv/include/webrtc_libyuv.h"
#include "common_types.h"
#include "modules/video_coding/main/source/mock/fake_tick_time.h"
#include "test_callbacks.h"
@@ -152,13 +153,13 @@ VCMNTDecodeCompleCallback::~VCMNTDecodeCompleCallback()
fclose(_decodedFile);
}
WebRtc_Word32
VCMNTDecodeCompleCallback::FrameToRender(webrtc::VideoFrame& videoFrame)
VCMNTDecodeCompleCallback::FrameToRender(webrtc::I420VideoFrame& videoFrame)
{
if (videoFrame.Width() != _currentWidth ||
videoFrame.Height() != _currentHeight)
if (videoFrame.width() != _currentWidth ||
videoFrame.height() != _currentHeight)
{
_currentWidth = videoFrame.Width();
_currentHeight = videoFrame.Height();
_currentWidth = videoFrame.width();
_currentHeight = videoFrame.height();
if (_decodedFile != NULL)
{
fclose(_decodedFile);
@@ -166,11 +167,11 @@ VCMNTDecodeCompleCallback::FrameToRender(webrtc::VideoFrame& videoFrame)
}
_decodedFile = fopen(_outname.c_str(), "wb");
}
if (fwrite(videoFrame.Buffer(), 1, videoFrame.Length(),
_decodedFile) != videoFrame.Length()) {
if (PrintI420VideoFrame(videoFrame, _decodedFile) < 0) {
return -1;
}
_decodedBytes+= videoFrame.Length();
_decodedBytes+= webrtc::CalcBufferSize(webrtc::kI420,
videoFrame.width(), videoFrame.height());
return VCM_OK;
}
@@ -270,8 +271,13 @@ NormalTest::Perform(CmdArgs& args)
///////////////////////
/// Start Test
///////////////////////
VideoFrame sourceFrame;
sourceFrame.VerifyAndAllocate(_lengthSourceFrame);
I420VideoFrame sourceFrame;
int size_y = _width * _height;
int half_width = (_width + 1) / 2;
int half_height = (_height + 1) / 2;
int size_uv = half_width * half_height;
sourceFrame.CreateEmptyFrame(_width, _height,
_width, half_width, half_width);
WebRtc_UWord8* tmpBuffer = new WebRtc_UWord8[_lengthSourceFrame];
double startTime = clock()/(double)CLOCKS_PER_SEC;
_vcm->SetChannelParameters((WebRtc_UWord32)_bitRate, 0, 0);
@@ -288,23 +294,29 @@ NormalTest::Perform(CmdArgs& args)
TEST(fread(tmpBuffer, 1, _lengthSourceFrame, _sourceFile) > 0 ||
feof(_sourceFile));
_frameCnt++;
sourceFrame.CopyFrame(_lengthSourceFrame, tmpBuffer);
sourceFrame.SetHeight(_height);
sourceFrame.SetWidth(_width);
sourceFrame.CreateFrame(size_y, tmpBuffer,
size_uv, tmpBuffer + size_y,
size_uv, tmpBuffer + size_y + size_uv,
_width, _height,
_width, half_width, half_width);
_timeStamp += (WebRtc_UWord32)(9e4 / static_cast<float>(_sendCodec.maxFramerate));
sourceFrame.SetTimeStamp(_timeStamp);
_encodeTimes[int(sourceFrame.TimeStamp())] = clock()/(double)CLOCKS_PER_SEC;
sourceFrame.set_timestamp(_timeStamp);
_encodeTimes[int(sourceFrame.timestamp())] =
clock()/(double)CLOCKS_PER_SEC;
WebRtc_Word32 ret = _vcm->AddVideoFrame(sourceFrame);
double encodeTime = clock()/(double)CLOCKS_PER_SEC - _encodeTimes[int(sourceFrame.TimeStamp())];
double encodeTime = clock()/(double)CLOCKS_PER_SEC -
_encodeTimes[int(sourceFrame.timestamp())];
_totalEncodeTime += encodeTime;
if (ret < 0)
{
printf("Error in AddFrame: %d\n", ret);
//exit(1);
}
_decodeTimes[int(sourceFrame.TimeStamp())] = clock()/(double)CLOCKS_PER_SEC; // same timestamp value for encode and decode
_decodeTimes[int(sourceFrame.timestamp())] =
clock()/(double)CLOCKS_PER_SEC;
ret = _vcm->Decode();
_totalDecodeTime += clock()/(double)CLOCKS_PER_SEC - _decodeTimes[int(sourceFrame.TimeStamp())];
_totalDecodeTime += clock()/(double)CLOCKS_PER_SEC -
_decodeTimes[int(sourceFrame.timestamp())];
if (ret < 0)
{
printf("Error in Decode: %d\n", ret);

View File

@@ -68,14 +68,14 @@ public:
virtual ~VCMNTDecodeCompleCallback();
void SetUserReceiveCallback(webrtc::VCMReceiveCallback* receiveCallback);
// will write decoded frame into file
WebRtc_Word32 FrameToRender(webrtc::VideoFrame& videoFrame);
WebRtc_Word32 FrameToRender(webrtc::I420VideoFrame& videoFrame);
WebRtc_Word32 DecodedBytes();
private:
FILE* _decodedFile;
std::string _outname;
WebRtc_UWord32 _decodedBytes;
WebRtc_UWord32 _currentWidth;
WebRtc_UWord32 _currentHeight;
int _decodedBytes;
int _currentWidth;
int _currentHeight;
}; // end of VCMDecodeCompleCallback class
@@ -89,8 +89,8 @@ public:
static int RunTest(CmdArgs& args);
WebRtc_Word32 Perform(CmdArgs& args);
// option:: turn into private and call from perform
WebRtc_UWord32 Width() const { return _width; };
WebRtc_UWord32 Height() const { return _height; };
int Width() const { return _width; };
int Height() const { return _height; };
webrtc::VideoCodecType VideoType() const { return _videoType; };
@@ -118,8 +118,8 @@ protected:
FILE* _decodedFile;
FILE* _encodedFile;
std::fstream _log;
WebRtc_UWord32 _width;
WebRtc_UWord32 _height;
int _width;
int _height;
float _frameRate;
float _bitRate;
WebRtc_UWord32 _lengthSourceFrame;

View File

@@ -15,11 +15,11 @@
#include <time.h>
#include "../source/event.h"
#include "common_video/libyuv/include/webrtc_libyuv.h"
#include "modules/video_coding/main/source/tick_time_base.h"
#include "test_callbacks.h"
#include "test_macros.h"
#include "testsupport/metrics/video_metrics.h"
#include "common_video/libyuv/include/webrtc_libyuv.h"
using namespace webrtc;
@@ -215,9 +215,8 @@ QualityModesTest::Perform()
// disabling internal VCM frame dropper
_vcm->EnableFrameDropper(false);
VideoFrame sourceFrame;
VideoFrame *decimatedFrame = NULL;
sourceFrame.VerifyAndAllocate(_lengthSourceFrame);
I420VideoFrame sourceFrame;
I420VideoFrame *decimatedFrame = NULL;
WebRtc_UWord8* tmpBuffer = new WebRtc_UWord8[_lengthSourceFrame];
double startTime = clock()/(double)CLOCKS_PER_SEC;
_vcm->SetChannelParameters((WebRtc_UWord32)_bitRate, 0, 0);
@@ -238,18 +237,22 @@ QualityModesTest::Perform()
WebRtc_Word32 ret = 0;
_numFramesDroppedVPM = 0;
_numFramesDroppedVPM = 0;
while (feof(_sourceFile)== 0)
{
TEST(fread(tmpBuffer, 1, _lengthSourceFrame, _sourceFile) > 0);
_frameCnt++;
sourceFrame.CopyFrame(_lengthSourceFrame, tmpBuffer);
sourceFrame.SetHeight(_nativeHeight);
sourceFrame.SetWidth(_nativeWidth);
int size_y = _nativeWidth * _nativeHeight;
int size_uv = ((_nativeWidth + 1) / 2) * ((_nativeHeight + 1) / 2);
sourceFrame.CreateFrame(size_y, tmpBuffer,
size_uv, tmpBuffer + size_y,
size_uv, tmpBuffer + size_y + size_uv,
_nativeWidth, _nativeHeight,
_nativeWidth, (_nativeWidth + 1) / 2,
(_nativeWidth + 1) / 2);
_timeStamp += (WebRtc_UWord32)(9e4 / static_cast<float>(codec.maxFramerate));
sourceFrame.SetTimeStamp(_timeStamp);
sourceFrame.set_timestamp(_timeStamp);
ret = _vpm->PreprocessFrame(sourceFrame, &decimatedFrame);
if (ret == 1)
@@ -270,20 +273,24 @@ QualityModesTest::Perform()
}
// counting only encoding time
_encodeTimes[int(sourceFrame.TimeStamp())] = clock()/(double)CLOCKS_PER_SEC;
_encodeTimes[int(sourceFrame.timestamp())] =
clock()/(double)CLOCKS_PER_SEC;
WebRtc_Word32 ret = _vcm->AddVideoFrame(*decimatedFrame, contentMetrics);
_totalEncodeTime += clock()/(double)CLOCKS_PER_SEC - _encodeTimes[int(sourceFrame.TimeStamp())];
_totalEncodeTime += clock()/(double)CLOCKS_PER_SEC -
_encodeTimes[int(sourceFrame.timestamp())];
if (ret < 0)
{
printf("Error in AddFrame: %d\n", ret);
//exit(1);
}
_decodeTimes[int(sourceFrame.TimeStamp())] = clock()/(double)CLOCKS_PER_SEC; // same timestamp value for encode and decode
_decodeTimes[int(sourceFrame.timestamp())] = clock() /
(double)CLOCKS_PER_SEC - _decodeTimes[int(sourceFrame.timestamp())];
ret = _vcm->Decode();
_totalDecodeTime += clock()/(double)CLOCKS_PER_SEC - _decodeTimes[int(sourceFrame.TimeStamp())];
_totalDecodeTime += clock()/(double)CLOCKS_PER_SEC -
_decodeTimes[int(sourceFrame.timestamp())];
if (ret < 0)
{
printf("Error in Decode: %d\n", ret);
@@ -308,7 +315,7 @@ QualityModesTest::Perform()
_frameRate = frameRateUpdate[change];
codec.startBitrate = (int)_bitRate;
codec.maxFramerate = (WebRtc_UWord8) _frameRate;
TEST(_vcm->RegisterSendCodec(&codec, 2, 1440) == VCM_OK);// will also set and init the desired codec
TEST(_vcm->RegisterSendCodec(&codec, 2, 1440) == VCM_OK);
change++;
}
}
@@ -326,8 +333,6 @@ QualityModesTest::Perform()
return 0;
}
// implementing callback to be called from VCM to update VPM of frame rate and size
QMTestVideoSettingsCallback::QMTestVideoSettingsCallback():
_vpm(NULL),
_vcm(NULL)
@@ -415,48 +420,32 @@ VCMQMDecodeCompleCallback::~VCMQMDecodeCompleCallback()
}
}
WebRtc_Word32
VCMQMDecodeCompleCallback::FrameToRender(VideoFrame& videoFrame)
VCMQMDecodeCompleCallback::FrameToRender(I420VideoFrame& videoFrame)
{
if ((_origWidth == videoFrame.Width()) && (_origHeight == videoFrame.Height()))
if ((_origWidth == videoFrame.width()) &&
(_origHeight == videoFrame.height()))
{
if (fwrite(videoFrame.Buffer(), 1, videoFrame.Length(),
_decodedFile) != videoFrame.Length()) {
if (PrintI420VideoFrame(videoFrame, _decodedFile) < 0) {
return -1;
}
_frameCnt++;
//printf("frame dec # %d", _frameCnt);
// no need for interpolator and decBuffer
if (_decBuffer != NULL)
{
delete [] _decBuffer;
_decBuffer = NULL;
}
// if (_interpolator != NULL)
// {
// deleteInterpolator(_interpolator);
// _interpolator = NULL;
// }
_decWidth = 0;
_decHeight = 0;
}
else
{
if ((_decWidth != videoFrame.Width()) || (_decHeight != videoFrame.Height()))
{
_decWidth = videoFrame.Width();
_decHeight = videoFrame.Height();
buildInterpolator();
}
// interpolateFrame(_interpolator, videoFrame.Buffer(),_decBuffer);
if (fwrite(_decBuffer, 1, _origWidth*_origHeight * 3/2,
_decodedFile) != _origWidth*_origHeight * 3/2) {
return -1;
}
_frameCnt++;
// TODO(mikhal): Add support for scaling.
return -1;
}
_decodedBytes += videoFrame.Length();
_decodedBytes += CalcBufferSize(kI420, videoFrame.width(),
videoFrame.height());
return VCM_OK;
}
@@ -467,7 +456,8 @@ VCMQMDecodeCompleCallback::DecodedBytes()
}
void
VCMQMDecodeCompleCallback::SetOriginalFrameDimensions(WebRtc_Word32 width, WebRtc_Word32 height)
VCMQMDecodeCompleCallback::SetOriginalFrameDimensions(WebRtc_Word32 width,
WebRtc_Word32 height)
{
_origWidth = width;
_origHeight = height;

View File

@@ -34,11 +34,11 @@ private:
webrtc::VideoProcessingModule* _vpm;
WebRtc_UWord32 _width;
WebRtc_UWord32 _height;
int _width;
int _height;
float _frameRate;
WebRtc_UWord32 _nativeWidth;
WebRtc_UWord32 _nativeHeight;
int _nativeWidth;
int _nativeHeight;
float _nativeFrameRate;
WebRtc_UWord32 _numFramesDroppedVPM;
@@ -54,7 +54,7 @@ public:
virtual ~VCMQMDecodeCompleCallback();
void SetUserReceiveCallback(webrtc::VCMReceiveCallback* receiveCallback);
// will write decoded frame into file
WebRtc_Word32 FrameToRender(webrtc::VideoFrame& videoFrame);
WebRtc_Word32 FrameToRender(webrtc::I420VideoFrame& videoFrame);
WebRtc_Word32 DecodedBytes();
void SetOriginalFrameDimensions(WebRtc_Word32 width, WebRtc_Word32 height);
WebRtc_Word32 buildInterpolator();
@@ -62,10 +62,10 @@ private:
FILE* _decodedFile;
WebRtc_UWord32 _decodedBytes;
// QualityModesTest& _test;
WebRtc_UWord32 _origWidth;
WebRtc_UWord32 _origHeight;
WebRtc_UWord32 _decWidth;
WebRtc_UWord32 _decHeight;
int _origWidth;
int _origHeight;
int _decWidth;
int _decHeight;
// VideoInterpolator* _interpolator;
WebRtc_UWord8* _decBuffer;
WebRtc_UWord32 _frameCnt; // debug

View File

@@ -47,7 +47,7 @@ public:
virtual ~FrameReceiveCallback();
WebRtc_Word32 FrameToRender(webrtc::VideoFrame& videoFrame);
WebRtc_Word32 FrameToRender(webrtc::I420VideoFrame& videoFrame);
private:
static void SplitFilename(std::string filename, std::string* basename,

View File

@@ -12,6 +12,7 @@
#include <cmath>
#include "common_video/libyuv/include/webrtc_libyuv.h"
#include "modules/video_coding/main/source/tick_time_base.h"
#include "rtp_dump.h"
#include "test_macros.h"
@@ -187,13 +188,13 @@ VCMRTPEncodeCompleteCallback::EncodeComplete()
// Decoded Frame Callback Implementation
WebRtc_Word32
VCMDecodeCompleteCallback::FrameToRender(VideoFrame& videoFrame)
VCMDecodeCompleteCallback::FrameToRender(I420VideoFrame& videoFrame)
{
if (fwrite(videoFrame.Buffer(), 1, videoFrame.Length(),
_decodedFile) != videoFrame.Length()) {
if (PrintI420VideoFrame(videoFrame, _decodedFile) < 0) {
return -1;
}
_decodedBytes+= videoFrame.Length();
_decodedBytes+= CalcBufferSize(kI420, videoFrame.width(),
videoFrame.height());
return VCM_OK;
}

View File

@@ -142,7 +142,7 @@ public:
_decodedFile(decodedFile), _decodedBytes(0) {}
virtual ~VCMDecodeCompleteCallback() {}
// Write decoded frame into file
WebRtc_Word32 FrameToRender(webrtc::VideoFrame& videoFrame);
WebRtc_Word32 FrameToRender(webrtc::I420VideoFrame& videoFrame);
WebRtc_Word32 DecodedBytes();
private:
FILE* _decodedFile;

View File

@@ -8,6 +8,7 @@
* be found in the AUTHORS file in the root of the source tree.
*/
#include "common_video/libyuv/include/webrtc_libyuv.h"
#include "receiver_tests.h"
#include "video_coding.h"
#include "rtp_rtcp.h"
@@ -45,7 +46,7 @@ FrameReceiveCallback::~FrameReceiveCallback()
}
WebRtc_Word32
FrameReceiveCallback::FrameToRender(VideoFrame& videoFrame)
FrameReceiveCallback::FrameToRender(I420VideoFrame& videoFrame)
{
if (_timingFile == NULL)
{
@@ -56,15 +57,16 @@ FrameReceiveCallback::FrameToRender(VideoFrame& videoFrame)
return -1;
}
}
if (_outFile == NULL || videoFrame.Width() != width_ ||
videoFrame.Height() != height_)
if (_outFile == NULL ||
videoFrame.width() != static_cast<int>(width_) ||
videoFrame.height() != static_cast<int>(height_))
{
if (_outFile) {
fclose(_outFile);
}
printf("New size: %ux%u\n", videoFrame.Width(), videoFrame.Height());
width_ = videoFrame.Width();
height_ = videoFrame.Height();
printf("New size: %ux%u\n", videoFrame.width(), videoFrame.height());
width_ = videoFrame.width();
height_ = videoFrame.height();
std::string filename_with_width_height = AppendWidthAndHeight(
_outFilename, width_, height_);
_outFile = fopen(filename_with_width_height.c_str(), "wb");
@@ -74,10 +76,9 @@ FrameReceiveCallback::FrameToRender(VideoFrame& videoFrame)
}
}
fprintf(_timingFile, "%u, %u\n",
videoFrame.TimeStamp(),
MaskWord64ToUWord32(videoFrame.RenderTimeMs()));
if (fwrite(videoFrame.Buffer(), 1, videoFrame.Length(),
_outFile) != videoFrame.Length()) {
videoFrame.timestamp(),
MaskWord64ToUWord32(videoFrame.render_time_ms()));
if (PrintI420VideoFrame(videoFrame, _outFile) < 0) {
return -1;
}
return 0;