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:
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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;}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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_;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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));
|
||||
|
||||
|
||||
@@ -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_
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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_;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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_;
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
/**
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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_;
|
||||
};
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user