Skip to content

Commit

Permalink
VideoFrameLayout: Add offsets and aggregate strides and offsets as Plane
Browse files Browse the repository at this point in the history
VideoFrameLayout should have information about offset per plane, not only
stride. The number of stride should be the same as the number of offsets. To
guarantee this, they are stored in the vector of struct, Plane.

BUG=chromium:876986, chromium:856562
TEST=VDA unittest and media_unittest

Cq-Include-Trybots: luci.chromium.try:android_optional_gpu_tests_rel;luci.chromium.try:linux_optional_gpu_tests_rel;luci.chromium.try:mac_optional_gpu_tests_rel;luci.chromium.try:win_optional_gpu_tests_rel
Change-Id: Ie9d9afa5db7dabaee2f48fbcd355c13d29be8035
Reviewed-on: https://chromium-review.googlesource.com/1188730
Commit-Queue: Hirokazu Honda <hiroh@chromium.org>
Reviewed-by: Dale Curtis <dalecurtis@chromium.org>
Cr-Commit-Position: refs/heads/master@{#590242}
  • Loading branch information
rosetta-jpn authored and Commit Bot committed Sep 11, 2018
1 parent 364d030 commit 76f2212
Show file tree
Hide file tree
Showing 9 changed files with 214 additions and 64 deletions.
9 changes: 5 additions & 4 deletions media/base/video_frame.cc
Original file line number Diff line number Diff line change
Expand Up @@ -382,13 +382,14 @@ scoped_refptr<VideoFrame> VideoFrame::WrapExternalYuvaData(
#if defined(OS_LINUX)
// static
scoped_refptr<VideoFrame> VideoFrame::WrapExternalDmabufs(
VideoPixelFormat format,
const gfx::Size& coded_size,
const VideoFrameLayout& layout,
const gfx::Rect& visible_rect,
const gfx::Size& natural_size,
std::vector<base::ScopedFD> dmabuf_fds,
base::TimeDelta timestamp) {
const StorageType storage = STORAGE_DMABUFS;
const VideoPixelFormat format = layout.format();
const gfx::Size& coded_size = layout.coded_size();
if (!IsValidConfig(format, storage, coded_size, visible_rect, natural_size)) {
DLOG(ERROR) << __func__ << " Invalid config."
<< ConfigToString(format, storage, coded_size, visible_rect,
Expand All @@ -403,8 +404,8 @@ scoped_refptr<VideoFrame> VideoFrame::WrapExternalDmabufs(
}

gpu::MailboxHolder mailbox_holders[kMaxPlanes];
scoped_refptr<VideoFrame> frame = new VideoFrame(
format, storage, coded_size, visible_rect, natural_size, timestamp);
scoped_refptr<VideoFrame> frame =
new VideoFrame(layout, storage, visible_rect, natural_size, timestamp);
if (!frame) {
DLOG(ERROR) << __func__ << " Couldn't create VideoFrame instance.";
return nullptr;
Expand Down
7 changes: 3 additions & 4 deletions media/base/video_frame.h
Original file line number Diff line number Diff line change
Expand Up @@ -250,8 +250,7 @@ class MEDIA_EXPORT VideoFrame : public base::RefCountedThreadSafe<VideoFrame> {
// mapped via mmap() for CPU access.
// Returns NULL on failure.
static scoped_refptr<VideoFrame> WrapExternalDmabufs(
VideoPixelFormat format,
const gfx::Size& coded_size,
const VideoFrameLayout& layout,
const gfx::Rect& visible_rect,
const gfx::Size& natural_size,
std::vector<base::ScopedFD> dmabuf_fds,
Expand Down Expand Up @@ -367,8 +366,8 @@ class MEDIA_EXPORT VideoFrame : public base::RefCountedThreadSafe<VideoFrame> {

int stride(size_t plane) const {
DCHECK(IsValidPlane(plane, format()));
DCHECK_LT(plane, layout_.num_strides());
return layout_.strides()[plane];
DCHECK_LT(plane, layout_.num_planes());
return layout_.planes()[plane].stride;
}

// Returns the number of bytes per row and number of rows for a given plane.
Expand Down
50 changes: 37 additions & 13 deletions media/base/video_frame_layout.cc
Original file line number Diff line number Diff line change
Expand Up @@ -7,40 +7,64 @@
#include <numeric>
#include <sstream>

namespace media {

namespace {

std::ostringstream& operator<<(std::ostringstream& ostrm,
const media::VideoFrameLayout::Plane& plane) {
ostrm << "(" << plane.stride << ", " << plane.offset << ")";
return ostrm;
}

template <class T>
std::string VectorToString(const std::vector<T>& vec) {
std::ostringstream result;
std::string delim;
result << "[";
for (auto v : vec) {
result << delim << v;
result << delim;
result << v;
if (delim.size() == 0)
delim = ", ";
}
result << "]";
return result.str();
}

} // namespace
std::vector<VideoFrameLayout::Plane> PlanesFromStrides(
const std::vector<int32_t> strides) {
std::vector<VideoFrameLayout::Plane> planes(strides.size());
for (size_t i = 0; i < strides.size(); i++) {
planes[i].stride = strides[i];
}
return planes;
}

namespace media {
} // namespace

VideoFrameLayout::VideoFrameLayout(VideoPixelFormat format,
const gfx::Size& coded_size,
std::vector<int32_t> strides,
std::vector<size_t> buffer_sizes)
: format_(format),
coded_size_(coded_size),
strides_(std::move(strides)),
planes_(PlanesFromStrides(strides)),
buffer_sizes_(std::move(buffer_sizes)) {}

VideoFrameLayout::VideoFrameLayout(VideoPixelFormat format,
const gfx::Size& coded_size,
std::vector<Plane> planes,
std::vector<size_t> buffer_sizes)
: format_(format),
coded_size_(coded_size),
planes_(std::move(planes)),
buffer_sizes_(std::move(buffer_sizes)) {}

VideoFrameLayout::VideoFrameLayout()
: format_(PIXEL_FORMAT_UNKNOWN),
coded_size_(),
strides_({0, 0, 0, 0}),
buffer_sizes_({0, 0, 0, 0}) {}
planes_(kDefaultPlaneCount),
buffer_sizes_(kDefaultBufferCount, 0) {}

VideoFrameLayout::~VideoFrameLayout() = default;
VideoFrameLayout::VideoFrameLayout(const VideoFrameLayout&) = default;
Expand All @@ -54,12 +78,12 @@ size_t VideoFrameLayout::GetTotalBufferSize() const {

std::string VideoFrameLayout::ToString() const {
std::ostringstream s;
s << "VideoFrameLayout format:" << VideoPixelFormatToString(format_)
<< " coded_size:" << coded_size_.ToString()
<< " num_buffers:" << num_buffers()
<< " buffer_sizes:" << VectorToString(buffer_sizes_)
<< " num_strides:" << num_strides()
<< " strides:" << VectorToString(strides_);
s << "VideoFrameLayout format: " << VideoPixelFormatToString(format_)
<< ", coded_size: " << coded_size_.ToString()
<< ", num_buffers: " << num_buffers()
<< ", buffer_sizes: " << VectorToString(buffer_sizes_)
<< ", num_planes: " << num_planes()
<< ", planes (stride, offset): " << VectorToString(planes_);
return s.str();
}

Expand Down
54 changes: 40 additions & 14 deletions media/base/video_frame_layout.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,18 +21,46 @@ namespace media {
// A class to describes how physical buffer is allocated for video frame.
// In stores format, coded size of the frame and size of physical buffers
// which can be used to allocate buffer(s) hardware expected.
// Also, it stores stride (bytes per line) per color plane to calculate each
// color plane's size (note that a buffer may contains multiple color planes.)
// It also stores stride (bytes per line) and offset per color plane as Plane.
// stride is to calculate each color plane's size (note that a buffer may
// contains multiple color planes.)
// offset is to describe a start point of each plane from buffer's dmabuf fd.
// Note that it is copyable.
class MEDIA_EXPORT VideoFrameLayout {
public:
struct Plane {
// Strides of a plane, typically greater or equal to the
// width of the surface divided by the horizontal sampling period. Note that
// strides can be negative if the image layout is bottom-up.
int32_t stride = 0;

// Offset of a plane, which stands for the offset of a start point of a
// color plane from a buffer fd.
size_t offset = 0;
};

enum {
kDefaultPlaneCount = 4,
kDefaultBufferCount = 4,
};

// Constructor with strides and buffers' size.
// If strides and buffer_sizes are not assigned, their default value are
// {0, 0, 0, 0} for compatibility with video_frame.cc's original behavior.
// If strides and buffer_sizes are not assigned, strides, offsets and
// buffer_sizes are {0, 0, 0, 0}.
VideoFrameLayout(VideoPixelFormat format,
const gfx::Size& coded_size,
std::vector<int32_t> strides =
std::vector<int32_t>(kDefaultPlaneCount, 0),
std::vector<size_t> buffer_sizes =
std::vector<size_t>(kDefaultBufferCount, 0));

// Constructor with plane's stride/offset, and buffers' size.
// If buffer_sizes are not assigned, it is {0, 0, 0, 0}.
VideoFrameLayout(VideoPixelFormat format,
const gfx::Size& coded_size,
std::vector<int32_t> strides = {0, 0, 0, 0},
std::vector<size_t> buffer_sizes = {0, 0, 0, 0});
std::vector<Plane> planes,
std::vector<size_t> buffer_sizes =
std::vector<size_t>(kDefaultBufferCount));

VideoFrameLayout();
~VideoFrameLayout();
Expand All @@ -43,13 +71,13 @@ class MEDIA_EXPORT VideoFrameLayout {
VideoPixelFormat format() const { return format_; }
const gfx::Size& coded_size() const { return coded_size_; }

// Return number of buffers. Note that num_strides >= num_buffers.
// Return number of buffers. Note that num_planes >= num_buffers.
size_t num_buffers() const { return buffer_sizes_.size(); }

// Returns number of strides. Note that num_strides >= num_buffers.
size_t num_strides() const { return strides_.size(); }
// Returns number of planes. Note that num_planes >= num_buffers.
size_t num_planes() const { return planes_.size(); }

const std::vector<int32_t>& strides() const { return strides_; }
const std::vector<Plane>& planes() const { return planes_; }
const std::vector<size_t>& buffer_sizes() const { return buffer_sizes_; }

// Returns sum of bytes of all buffers.
Expand All @@ -68,10 +96,8 @@ class MEDIA_EXPORT VideoFrameLayout {
// the pixel data provided for the odd pixels.
gfx::Size coded_size_;

// Vector of strides for each buffer, typically greater or equal to the
// width of the surface divided by the horizontal sampling period. Note that
// strides can be negative if the image layout is bottom-up.
std::vector<int32_t> strides_;
// Layout property for each color planes, e.g. stride and buffer offset.
std::vector<Plane> planes_;

// Vector of sizes for each buffer, typically greater or equal to the area of
// |coded_size_|.
Expand Down
Loading

0 comments on commit 76f2212

Please sign in to comment.