New helper function test::ReadI420Buffer, refactor FrameReader to use it.

This change reduces the number of places where we first fread a I420
frame into a uint8_t buffer, followed by a copy into a frame buffer
object.

BUG=None

Review-Url: https://codereview.webrtc.org/2362683002
Cr-Commit-Position: refs/heads/master@{#14456}
This commit is contained in:
nisse
2016-09-30 04:14:07 -07:00
committed by Commit bot
parent 6f112cc136
commit 115bd153c7
19 changed files with 182 additions and 229 deletions

View File

@ -56,7 +56,6 @@ VideoProcessorImpl::VideoProcessorImpl(webrtc::VideoEncoder* encoder,
stats_(stats),
encode_callback_(NULL),
decode_callback_(NULL),
source_buffer_(NULL),
first_key_frame_has_been_excluded_(false),
last_frame_missing_(false),
initialized_(false),
@ -81,7 +80,6 @@ bool VideoProcessorImpl::Init() {
// Initialize data structures used by the encoder/decoder APIs
size_t frame_length_in_bytes = frame_reader_->FrameLength();
source_buffer_ = new uint8_t[frame_length_in_bytes];
last_successful_frame_buffer_ = new uint8_t[frame_length_in_bytes];
// Set fixed properties common for all frames.
// To keep track of spatial resize actions by encoder.
@ -143,7 +141,6 @@ bool VideoProcessorImpl::Init() {
}
VideoProcessorImpl::~VideoProcessorImpl() {
delete[] source_buffer_;
delete[] last_successful_frame_buffer_;
encoder_->RegisterEncodeCompleteCallback(NULL);
delete encode_callback_;
@ -190,17 +187,15 @@ bool VideoProcessorImpl::ProcessFrame(int frame_number) {
if (frame_number == 0) {
prev_time_stamp_ = -1;
}
if (frame_reader_->ReadFrame(source_buffer_)) {
// Copy the source frame to the newly read frame data.
source_frame_.CreateFrame(source_buffer_, config_.codec_settings->width,
config_.codec_settings->height, kVideoRotation_0);
rtc::scoped_refptr<VideoFrameBuffer> buffer(frame_reader_->ReadFrame());
if (buffer) {
// Use the frame number as "timestamp" to identify frames
VideoFrame source_frame(buffer, frame_number, 0, webrtc::kVideoRotation_0);
// Ensure we have a new statistics data object we can fill:
FrameStatistic& stat = stats_->NewFrame(frame_number);
encode_start_ns_ = rtc::TimeNanos();
// Use the frame number as "timestamp" to identify frames
source_frame_.set_timestamp(frame_number);
// Decide if we're going to force a keyframe:
std::vector<FrameType> frame_types(1, kVideoFrameDelta);
@ -213,7 +208,7 @@ bool VideoProcessorImpl::ProcessFrame(int frame_number) {
encoded_frame_size_ = 0;
encoded_frame_type_ = kVideoFrameDelta;
int32_t encode_result = encoder_->Encode(source_frame_, NULL, &frame_types);
int32_t encode_result = encoder_->Encode(source_frame, NULL, &frame_types);
if (encode_result != WEBRTC_VIDEO_CODEC_OK) {
fprintf(stderr, "Failed to encode frame %d, return code: %d\n",

View File

@ -199,8 +199,6 @@ class VideoProcessorImpl : public VideoProcessor {
EncodedImageCallback* encode_callback_;
DecodedImageCallback* decode_callback_;
// Buffer used for reading the source video file:
uint8_t* source_buffer_;
// Keep track of the last successful frame, since we need to write that
// when decoding fails:
uint8_t* last_successful_frame_buffer_;

View File

@ -226,7 +226,8 @@ class VideoProcessorIntegrationTest : public testing::Test {
break;
}
frame_reader_ = new webrtc::test::FrameReaderImpl(
config_.input_filename, config_.frame_length_in_bytes);
config_.input_filename, config_.codec_settings->width,
config_.codec_settings->height);
frame_writer_ = new webrtc::test::FrameWriterImpl(
config_.output_filename, config_.frame_length_in_bytes);
ASSERT_TRUE(frame_reader_->Init());

View File

@ -75,7 +75,8 @@ TEST_F(VideoProcessorTest, Init) {
TEST_F(VideoProcessorTest, ProcessFrame) {
ExpectInit();
EXPECT_CALL(encoder_mock_, Encode(_, _, _)).Times(1);
EXPECT_CALL(frame_reader_mock_, ReadFrame(_)).WillOnce(Return(true));
EXPECT_CALL(frame_reader_mock_, ReadFrame())
.WillOnce(Return(I420Buffer::Create(50, 50)));
// Since we don't return any callback from the mock, the decoder will not
// be more than initialized...
VideoProcessorImpl video_processor(

View File

@ -17,6 +17,7 @@
#include "webrtc/base/timeutils.h"
#include "webrtc/common_video/libyuv/include/webrtc_libyuv.h"
#include "webrtc/modules/video_coding/codecs/vp8/include/vp8.h"
#include "webrtc/test/frame_utils.h"
#include "webrtc/test/testsupport/fileutils.h"
namespace webrtc {
@ -128,14 +129,11 @@ class TestVp8Impl : public ::testing::Test {
decoder_->RegisterDecodeCompleteCallback(decode_complete_callback_.get());
// Using a QCIF image (aligned stride (u,v planes) > width).
// Processing only one frame.
length_source_frame_ = CalcBufferSize(kI420, kWidth, kHeight);
source_buffer_.reset(new uint8_t[length_source_frame_]);
source_file_ = fopen(test::ResourcePath("paris_qcif", "yuv").c_str(), "rb");
ASSERT_TRUE(source_file_ != NULL);
// Set input frame.
ASSERT_EQ(
fread(source_buffer_.get(), 1, length_source_frame_, source_file_),
length_source_frame_);
rtc::scoped_refptr<VideoFrameBuffer> compact_buffer(
test::ReadI420Buffer(kWidth, kHeight, source_file_));
ASSERT_TRUE(compact_buffer);
codec_inst_.width = kWidth;
codec_inst_.height = kHeight;
const int kFramerate = 30;
@ -147,15 +145,15 @@ class TestVp8Impl : public ::testing::Test {
EXPECT_EQ(stride_y, 176);
EXPECT_EQ(stride_uv, 96);
rtc::scoped_refptr<I420Buffer> buffer = I420Buffer::Create(
codec_inst_.width, codec_inst_.height, stride_y, stride_uv, stride_uv);
// Using ConvertToI420 to add stride to the image.
EXPECT_EQ(
0, ConvertToI420(kI420, source_buffer_.get(), 0, 0, codec_inst_.width,
codec_inst_.height, 0, kVideoRotation_0,
buffer.get()));
rtc::scoped_refptr<I420Buffer> stride_buffer(
I420Buffer::Create(kWidth, kHeight, stride_y, stride_uv, stride_uv));
// No scaling in our case, just a copy, to add stride to the image.
stride_buffer->ScaleFrom(compact_buffer);
input_frame_.reset(
new VideoFrame(buffer, kTestTimestamp, 0, webrtc::kVideoRotation_0));
new VideoFrame(stride_buffer, kVideoRotation_0, 0));
input_frame_->set_timestamp(kTestTimestamp);
}
void SetUpEncodeDecode() {
@ -202,7 +200,6 @@ class TestVp8Impl : public ::testing::Test {
std::unique_ptr<VideoDecoder> decoder_;
EncodedImage encoded_frame_;
VideoFrame decoded_frame_;
size_t length_source_frame_;
VideoCodec codec_inst_;
};

View File

@ -163,19 +163,16 @@ int SequenceCoder(webrtc::test::CommandLineParser* parser) {
int64_t starttime = rtc::TimeMillis();
int frame_cnt = 1;
int frames_processed = 0;
rtc::scoped_refptr<webrtc::I420Buffer> i420_buffer =
webrtc::I420Buffer::Create(width, height, width, half_width, half_width);
while (!feof(input_file) &&
(num_frames == -1 || frames_processed < num_frames)) {
if (fread(frame_buffer.get(), 1, length, input_file) != length)
continue;
while (num_frames == -1 || frames_processed < num_frames) {
rtc::scoped_refptr<VideoFrameBuffer> buffer(
test::ReadI420Buffer(width, height, input_file));
if (!buffer) {
// EOF or read error.
break;
}
if (frame_cnt >= start_frame) {
webrtc::ConvertToI420(webrtc::kI420, frame_buffer.get(), 0, 0, width,
height, 0, webrtc::kVideoRotation_0, &i420_buffer);
webrtc::VideoFrame input_frame(i420_buffer, 0, 0,
webrtc::kVideoRotation_0);
encoder->Encode(input_frame, NULL, NULL);
encoder->Encode(VideoFrame(buffer, webrtc::kVideoRotation_0, 0),
NULL, NULL);
decoder->Decode(encoder_callback.encoded_image(), false, NULL);
++frames_processed;
}