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