blob: dd420e15327f0d85f44eb10a4706b64d8fc97776 [file] [log] [blame]
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "components/chromeos_camera/dmabuf_utils.h"
#include <utility>
#include "base/files/scoped_file.h"
#include "base/logging.h"
#include "base/numerics/safe_conversions.h"
#include "base/time/time.h"
#include "media/base/video_frame.h"
#include "media/base/video_frame_layout.h"
#include "mojo/public/cpp/system/platform_handle.h"
#include "ui/gfx/geometry/rect.h"
namespace chromeos_camera {
scoped_refptr<media::VideoFrame> ConstructVideoFrame(
std::vector<mojom::DmaBufPlanePtr> dma_buf_planes,
media::VideoPixelFormat pixel_format,
const gfx::Size& coded_size) {
const size_t num_planes = media::VideoFrame::NumPlanes(pixel_format);
if (num_planes != dma_buf_planes.size()) {
DLOG(ERROR) << "The number of DMA buf planes does not match the format";
return nullptr;
}
if (coded_size.IsEmpty()) {
DLOG(ERROR) << "Invalid coded size: " << coded_size.width() << ", "
<< coded_size.height();
return nullptr;
}
const gfx::Rect visible_rect(coded_size);
std::vector<base::ScopedFD> dma_buf_fds(num_planes);
std::vector<media::VideoFrameLayout::Plane> planes(num_planes);
for (size_t i = 0; i < num_planes; ++i) {
mojo::PlatformHandle handle =
mojo::UnwrapPlatformHandle(std::move(dma_buf_planes[i]->fd_handle));
if (!handle.is_valid()) {
DLOG(ERROR) << "Invalid DMA buf file descriptor";
return nullptr;
}
dma_buf_fds[i] = handle.TakeFD();
planes[i] = media::VideoFrameLayout::Plane(
dma_buf_planes[i]->stride,
base::strict_cast<size_t>(dma_buf_planes[i]->offset),
base::strict_cast<size_t>(dma_buf_planes[i]->size));
}
const base::Optional<media::VideoFrameLayout> layout =
media::VideoFrameLayout::CreateWithPlanes(pixel_format, coded_size,
std::move(planes));
if (!layout) {
DLOG(ERROR) << "Failed to create video frame layout";
return nullptr;
}
return media::VideoFrame::WrapExternalDmabufs(
*layout, // layout
visible_rect, // visible_rect
coded_size, // natural_size
std::move(dma_buf_fds), // dmabuf_fds
base::TimeDelta()); // timestamp
}
} // namespace chromeos_camera