Commit deec397e authored by Hirokazu Honda's avatar Hirokazu Honda Committed by Commit Bot

media/gpu/test: Move CloneVideoFrameLayout to video_frame_helpers

CloneVideoFrameLayout is not specific function for image processor client. There
is a possibility to use in any test code. Move it to video_frame_helpers.h.

Bug: None
Test: video_decode_accelerator_unittest w/wo video frame validator
Test: video_decode_accelerator_tests w/wo video frame validator
Change-Id: I92e96296b378de248f441ca416246002e102c263
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1563594
Commit-Queue: Hirokazu Honda <hiroh@chromium.org>
Reviewed-by: default avatarDavid Staessens <dstaessens@chromium.org>
Cr-Commit-Position: refs/heads/master@{#649819}
parent cf39e6ed
...@@ -8,7 +8,6 @@ ...@@ -8,7 +8,6 @@
#include <utility> #include <utility>
#include "base/bind.h" #include "base/bind.h"
#include "third_party/libyuv/include/libyuv/planar_functions.h"
#include "base/bind_helpers.h" #include "base/bind_helpers.h"
#include "base/logging.h" #include "base/logging.h"
...@@ -27,47 +26,6 @@ ...@@ -27,47 +26,6 @@
namespace media { namespace media {
namespace test { namespace test {
namespace {
// TODO(crbug.com/917951): Move these functions to video_frame_helpers.h
// Copy |src_frame| into a new VideoFrame with |dst_layout|. The created
// VideoFrame's content is the same as |src_frame|. Returns nullptr on failure.
scoped_refptr<VideoFrame> CloneVideoFrameWithLayout(
const VideoFrame* const src_frame,
const VideoFrameLayout& dst_layout) {
if (!src_frame)
return nullptr;
LOG_ASSERT(src_frame->IsMappable());
LOG_ASSERT(src_frame->format() == dst_layout.format());
// Create VideoFrame, which allocates and owns data.
auto dst_frame = VideoFrame::CreateFrameWithLayout(
dst_layout, src_frame->visible_rect(), src_frame->natural_size(),
src_frame->timestamp(), false /* zero_initialize_memory*/);
if (!dst_frame) {
LOG(ERROR) << "Failed to create VideoFrame";
return nullptr;
}
// Copy every plane's content from |src_frame| to |dst_frame|.
const size_t num_planes = VideoFrame::NumPlanes(dst_layout.format());
LOG_ASSERT(dst_layout.planes().size() == num_planes);
LOG_ASSERT(src_frame->layout().planes().size() == num_planes);
for (size_t i = 0; i < num_planes; ++i) {
// |width| in libyuv::CopyPlane() is in bytes, not pixels.
gfx::Size plane_size = VideoFrame::PlaneSize(dst_frame->format(), i,
dst_frame->natural_size());
libyuv::CopyPlane(
src_frame->data(i), src_frame->layout().planes()[i].stride,
dst_frame->data(i), dst_frame->layout().planes()[i].stride,
plane_size.width(), plane_size.height());
}
return dst_frame;
}
} // namespace
// static // static
std::unique_ptr<ImageProcessorClient> ImageProcessorClient::Create( std::unique_ptr<ImageProcessorClient> ImageProcessorClient::Create(
const ImageProcessor::PortConfig& input_config, const ImageProcessor::PortConfig& input_config,
......
...@@ -155,34 +155,38 @@ scoped_refptr<VideoFrame> ConvertVideoFrame(const VideoFrame* src_frame, ...@@ -155,34 +155,38 @@ scoped_refptr<VideoFrame> ConvertVideoFrame(const VideoFrame* src_frame,
return dst_frame; return dst_frame;
} }
base::Optional<VideoFrameLayout> CreateVideoFrameLayout(VideoPixelFormat format, scoped_refptr<VideoFrame> CloneVideoFrameWithLayout(
const gfx::Size& size, const VideoFrame* const src_frame,
bool single_buffer) { const VideoFrameLayout& dst_layout) {
const size_t num_planes = VideoFrame::NumPlanes(format); if (!src_frame)
const size_t num_buffers = single_buffer ? 1u : num_planes; return nullptr;
// If num_buffers = 1, all the planes are stored in the same buffer.
// If num_buffers = num_planes, each of plane is stored in a separate LOG_ASSERT(src_frame->IsMappable());
// buffer and located in the beginning of the buffer. LOG_ASSERT(src_frame->format() == dst_layout.format());
std::vector<size_t> buffer_sizes(num_buffers); // Create VideoFrame, which allocates and owns data.
std::vector<VideoFrameLayout::Plane> planes(num_planes); auto dst_frame = VideoFrame::CreateFrameWithLayout(
const auto strides = VideoFrame::ComputeStrides(format, size); dst_layout, src_frame->visible_rect(), src_frame->natural_size(),
size_t offset = 0; src_frame->timestamp(), false /* zero_initialize_memory*/);
for (size_t i = 0; i < num_planes; ++i) { if (!dst_frame) {
planes[i].stride = strides[i]; LOG(ERROR) << "Failed to create VideoFrame";
if (num_buffers == 1) { return nullptr;
planes[i].offset = offset;
offset += VideoFrame::PlaneSize(format, i, size).GetArea();
} else {
planes[i].offset = 0;
buffer_sizes[i] = VideoFrame::PlaneSize(format, i, size).GetArea();
}
} }
if (num_buffers == 1) // Copy every plane's content from |src_frame| to |dst_frame|.
buffer_sizes[0] = VideoFrame::AllocationSize(format, size); const size_t num_planes = VideoFrame::NumPlanes(dst_layout.format());
LOG_ASSERT(dst_layout.planes().size() == num_planes);
LOG_ASSERT(src_frame->layout().planes().size() == num_planes);
for (size_t i = 0; i < num_planes; ++i) {
// |width| in libyuv::CopyPlane() is in bytes, not pixels.
gfx::Size plane_size = VideoFrame::PlaneSize(dst_frame->format(), i,
dst_frame->natural_size());
libyuv::CopyPlane(
src_frame->data(i), src_frame->layout().planes()[i].stride,
dst_frame->data(i), dst_frame->layout().planes()[i].stride,
plane_size.width(), plane_size.height());
}
return VideoFrameLayout::CreateWithPlanes(format, size, std::move(planes), return dst_frame;
std::move(buffer_sizes));
} }
scoped_refptr<const VideoFrame> CreateVideoFrameFromImage(const Image& image) { scoped_refptr<const VideoFrame> CreateVideoFrameFromImage(const Image& image) {
...@@ -213,5 +217,35 @@ scoped_refptr<const VideoFrame> CreateVideoFrameFromImage(const Image& image) { ...@@ -213,5 +217,35 @@ scoped_refptr<const VideoFrame> CreateVideoFrameFromImage(const Image& image) {
return video_frame; return video_frame;
} }
base::Optional<VideoFrameLayout> CreateVideoFrameLayout(VideoPixelFormat format,
const gfx::Size& size,
bool single_buffer) {
const size_t num_planes = VideoFrame::NumPlanes(format);
const size_t num_buffers = single_buffer ? 1u : num_planes;
// If num_buffers = 1, all the planes are stored in the same buffer.
// If num_buffers = num_planes, each of plane is stored in a separate
// buffer and located in the beginning of the buffer.
std::vector<size_t> buffer_sizes(num_buffers);
std::vector<VideoFrameLayout::Plane> planes(num_planes);
const auto strides = VideoFrame::ComputeStrides(format, size);
size_t offset = 0;
for (size_t i = 0; i < num_planes; ++i) {
planes[i].stride = strides[i];
if (num_buffers == 1) {
planes[i].offset = offset;
offset += VideoFrame::PlaneSize(format, i, size).GetArea();
} else {
planes[i].offset = 0;
buffer_sizes[i] = VideoFrame::PlaneSize(format, i, size).GetArea();
}
}
if (num_buffers == 1)
buffer_sizes[0] = VideoFrame::AllocationSize(format, size);
return VideoFrameLayout::CreateWithPlanes(format, size, std::move(planes),
std::move(buffer_sizes));
}
} // namespace test } // namespace test
} // namespace media } // namespace media
...@@ -50,6 +50,19 @@ bool ConvertVideoFrame(const VideoFrame* src_frame, VideoFrame* dst_frame); ...@@ -50,6 +50,19 @@ bool ConvertVideoFrame(const VideoFrame* src_frame, VideoFrame* dst_frame);
scoped_refptr<VideoFrame> ConvertVideoFrame(const VideoFrame* src_frame, scoped_refptr<VideoFrame> ConvertVideoFrame(const VideoFrame* src_frame,
VideoPixelFormat dst_pixel_format); VideoPixelFormat dst_pixel_format);
// Copy |src_frame| into a new VideoFrame with |dst_layout|. This doesn't
// convert pixel format. That is, |dst_layout|'s format must be the same as
// |src_frame|'s format. This function supports all formats. The created
// VideoFrame's content is the same as |src_frame|. The created VideoFrame owns
// the buffer. Returns nullptr on failure.
scoped_refptr<VideoFrame> CloneVideoFrameWithLayout(
const VideoFrame* const src_frame,
const VideoFrameLayout& dst_layout);
// Get VideoFrame that contains Load()ed data. The returned VideoFrame doesn't
// own the data and thus must not be changed.
scoped_refptr<const VideoFrame> CreateVideoFrameFromImage(const Image& image);
// Create a video frame layout for the specified |pixel_format| and // Create a video frame layout for the specified |pixel_format| and
// |coded_size|. If |single_buffer| is true, the created VideoFrameLayout // |coded_size|. If |single_buffer| is true, the created VideoFrameLayout
// represents all the planes are stored in the same buffer. Otherwise, it // represents all the planes are stored in the same buffer. Otherwise, it
...@@ -59,10 +72,6 @@ base::Optional<VideoFrameLayout> CreateVideoFrameLayout( ...@@ -59,10 +72,6 @@ base::Optional<VideoFrameLayout> CreateVideoFrameLayout(
const gfx::Size& size, const gfx::Size& size,
bool single_buffer); bool single_buffer);
// Get VideoFrame that contains Load()ed data. The returned VideoFrame doesn't
// own the data and thus must not be changed.
scoped_refptr<const VideoFrame> CreateVideoFrameFromImage(const Image& image);
} // namespace test } // namespace test
} // namespace media } // namespace media
......
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