Commit 38b8cff0 authored by Hirokazu Honda's avatar Hirokazu Honda Committed by Commit Bot

media/gpu/test/Video: Fix a bug with compressed data input

video_encode_accelerator_tests can accept compressed data as
input and decode it by using SW decoder before encoding. The code
copies the entire decoded frames to encoder input data. However,
the decoded frames might have different stride from the expected
resolution. For instance, compressed data has 320x192 video
frames and the SW decoder produces 384x192 video frames. The test
must copy the resolution area that is specified by json file.

Bug: 1045825
Test: video_encode_accelerator_tests on eve
Change-Id: I3f6b5a78a30ef0e9e96211bee2c981af437607cb
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2217831
Commit-Queue: Hirokazu Honda <hiroh@chromium.org>
Reviewed-by: default avatarDavid Staessens <dstaessens@chromium.org>
Cr-Commit-Position: refs/heads/master@{#774001}
parent f34c1af4
......@@ -98,8 +98,9 @@ bool Video::Decode() {
bool success = false;
base::WaitableEvent done;
decode_thread.task_runner()->PostTask(
FROM_HERE, base::BindOnce(&Video::DecodeTask, std::move(data_),
&decompressed_data, &success, &done));
FROM_HERE,
base::BindOnce(&Video::DecodeTask, std::move(data_), resolution_,
&decompressed_data, &success, &done));
done.Wait();
decode_thread.Stop();
......@@ -350,6 +351,7 @@ base::Optional<base::FilePath> Video::ResolveFilePath(
// static
void Video::DecodeTask(const std::vector<uint8_t> data,
const gfx::Size& resolution,
std::vector<uint8_t>* decompressed_data,
bool* success,
base::WaitableEvent* done) {
......@@ -389,10 +391,10 @@ void Video::DecodeTask(const std::vector<uint8_t> data,
base::BindOnce([](media::Status* save_to,
media::Status save_from) { *save_to = save_from; },
&init_result);
decoder.Initialize(
config, false, nullptr, std::move(init_cb),
base::BindRepeating(&Video::OnFrameDecoded, decompressed_data),
base::NullCallback());
decoder.Initialize(config, false, nullptr, std::move(init_cb),
base::BindRepeating(&Video::OnFrameDecoded, resolution,
decompressed_data),
base::NullCallback());
if (!init_result.is_ok()) {
done->Signal();
return;
......@@ -419,18 +421,30 @@ void Video::DecodeTask(const std::vector<uint8_t> data,
}
// static
void Video::OnFrameDecoded(std::vector<uint8_t>* data,
void Video::OnFrameDecoded(const gfx::Size& resolution,
std::vector<uint8_t>* data,
scoped_refptr<VideoFrame> frame) {
ASSERT_EQ(frame->format(), VideoPixelFormat::PIXEL_FORMAT_I420);
size_t num_planes = VideoFrame::NumPlanes(frame->format());
// Copy the resolution area.
for (size_t plane = 0; plane < num_planes; ++plane) {
size_t current_pos = data->size();
size_t plane_size =
VideoFrame::PlaneSize(frame->format(), plane, frame->coded_size())
.GetArea();
const int stride = frame->stride(plane);
const int rows =
VideoFrame::Rows(plane, frame->format(), resolution.height());
const int row_bytes =
VideoFrame::RowBytes(plane, frame->format(), resolution.width());
const size_t plane_size =
VideoFrame::PlaneSize(frame->format(), plane, resolution).GetArea();
const size_t current_pos = data->size();
// TODO(dstaessens): Avoid resizing.
data->resize(data->size() + plane_size);
std::memcpy(&data->at(current_pos), frame->data(plane), plane_size);
uint8_t* dst = &data->at(current_pos);
const uint8_t* src = frame->data(plane);
for (int row = 0; row < rows; ++row) {
std::memcpy(dst, src, row_bytes);
dst += row_bytes;
src += stride;
}
}
}
......
......@@ -98,14 +98,19 @@ class Video {
base::Optional<base::FilePath> ResolveFilePath(
const base::FilePath& file_path);
// Decode the video on a separate thread.
// Decode the video on a separate thread. The |resolution| needs to be
// specified here as the resolution of the decoded frames might differ due to
// the software decoder alignment.
static void DecodeTask(const std::vector<uint8_t> data,
const gfx::Size& resolution,
std::vector<uint8_t>* decompressed_data,
bool* success,
base::WaitableEvent* done);
// Called each time a |frame| is decoded while decoding a video. The decoded
// frame will be appended to the specified |data|.
static void OnFrameDecoded(std::vector<uint8_t>* data,
// Called each time a |frame| is decoded while decoding a video. The area
// specified by |resolution| of the decoded frame will be appended to the
// |data|.
static void OnFrameDecoded(const gfx::Size& resolution,
std::vector<uint8_t>* data,
scoped_refptr<VideoFrame> frame);
// The path where all test video files are stored.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment