Commit a1921808 authored by Chih-Yu Huang's avatar Chih-Yu Huang Committed by Commit Bot

components/arc: Create mojo struct for media::DecoderBuffer.

We need media::DecoderBuffer for passing input bitstream buffer.
This CL adds a mojo struct for it.

BUG=b:136716638
TEST=components_unittest --gtest_filter=VideoAcceleratorStructTraitsTest.*

Change-Id: I96d23020630bb98b69e3ef1c3707e9dc31cb12ab
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1699349Reviewed-by: default avatarDominick Ng <dominickn@chromium.org>
Reviewed-by: default avatarHirokazu Honda <hiroh@chromium.org>
Commit-Queue: Chih-Yu Huang <akahuang@chromium.org>
Cr-Commit-Position: refs/heads/master@{#697114}
parent e37aeb7d
...@@ -4,6 +4,9 @@ ...@@ -4,6 +4,9 @@
#include "components/arc/mojom/video_accelerator_mojom_traits.h" #include "components/arc/mojom/video_accelerator_mojom_traits.h"
#include "base/files/platform_file.h"
#include "mojo/public/cpp/system/platform_handle.h"
namespace mojo { namespace mojo {
// Make sure values in arc::mojom::VideoCodecProfile match to the values in // Make sure values in arc::mojom::VideoCodecProfile match to the values in
...@@ -296,4 +299,22 @@ bool StructTraits<arc::mojom::VideoFrameDataView, ...@@ -296,4 +299,22 @@ bool StructTraits<arc::mojom::VideoFrameDataView,
return true; return true;
} }
// static
bool StructTraits<arc::mojom::DecoderBufferDataView, arc::DecoderBuffer>::Read(
arc::mojom::DecoderBufferDataView data,
arc::DecoderBuffer* out) {
base::PlatformFile platform_file = base::kInvalidPlatformFile;
if (mojo::UnwrapPlatformFile(data.TakeHandleFd(), &platform_file) !=
MOJO_RESULT_OK) {
return false;
}
out->handle_fd = base::ScopedFD(platform_file);
out->offset = data.offset();
out->payload_size = data.payload_size();
out->end_of_stream = data.end_of_stream();
out->timestamp = base::TimeDelta::FromMilliseconds(data.timestamp());
return true;
}
} // namespace mojo } // namespace mojo
...@@ -11,12 +11,15 @@ ...@@ -11,12 +11,15 @@
#include "components/arc/mojom/arc_gfx_mojom_traits.h" #include "components/arc/mojom/arc_gfx_mojom_traits.h"
#include "components/arc/mojom/video_common.mojom.h" #include "components/arc/mojom/video_common.mojom.h"
#include "components/arc/video_accelerator/decoder_buffer.h"
#include "components/arc/video_accelerator/video_frame_plane.h" #include "components/arc/video_accelerator/video_frame_plane.h"
#include "media/base/decode_status.h" #include "media/base/decode_status.h"
#include "media/base/video_codecs.h" #include "media/base/video_codecs.h"
#include "media/base/video_frame.h" #include "media/base/video_frame.h"
#include "media/base/video_frame_layout.h" #include "media/base/video_frame_layout.h"
#include "media/base/video_types.h" #include "media/base/video_types.h"
#include "mojo/public/cpp/platform/platform_handle.h"
#include "mojo/public/cpp/system/platform_handle.h"
#include "ui/gfx/geometry/size.h" #include "ui/gfx/geometry/size.h"
namespace mojo { namespace mojo {
...@@ -189,6 +192,33 @@ struct StructTraits<arc::mojom::VideoFrameDataView, ...@@ -189,6 +192,33 @@ struct StructTraits<arc::mojom::VideoFrameDataView,
scoped_refptr<media::VideoFrame>* out); scoped_refptr<media::VideoFrame>* out);
}; };
template <>
struct StructTraits<arc::mojom::DecoderBufferDataView, arc::DecoderBuffer> {
static mojo::ScopedHandle handle_fd(arc::DecoderBuffer& input) {
return mojo::WrapPlatformHandle(
mojo::PlatformHandle(std::move(input.handle_fd)));
}
static uint32_t offset(const arc::DecoderBuffer& input) {
return input.offset;
}
static uint32_t payload_size(const arc::DecoderBuffer& input) {
return input.payload_size;
}
static bool end_of_stream(const arc::DecoderBuffer& input) {
return input.end_of_stream;
}
static int64_t timestamp(const arc::DecoderBuffer& input) {
return input.timestamp.InMilliseconds();
}
static bool Read(arc::mojom::DecoderBufferDataView data,
arc::DecoderBuffer* out);
};
} // namespace mojo } // namespace mojo
#endif // COMPONENTS_ARC_MOJOM_VIDEO_ACCELERATOR_MOJOM_TRAITS_H_ #endif // COMPONENTS_ARC_MOJOM_VIDEO_ACCELERATOR_MOJOM_TRAITS_H_
...@@ -6,7 +6,11 @@ ...@@ -6,7 +6,11 @@
#include <vector> #include <vector>
#include "base/files/file_util.h"
#include "base/stl_util.h"
#include "components/arc/mojom/video_common.mojom.h" #include "components/arc/mojom/video_common.mojom.h"
#include "components/arc/video_accelerator/arc_video_accelerator_util.h"
#include "components/arc/video_accelerator/decoder_buffer.h"
#include "media/base/video_frame_layout.h" #include "media/base/video_frame_layout.h"
#include "media/base/video_types.h" #include "media/base/video_types.h"
#include "mojo/public/cpp/test_support/test_utils.h" #include "mojo/public/cpp/test_support/test_utils.h"
...@@ -96,4 +100,27 @@ TEST(VideoAcceleratorStructTraitsTest, ConvertNullVideoFrame) { ...@@ -96,4 +100,27 @@ TEST(VideoAcceleratorStructTraitsTest, ConvertNullVideoFrame) {
EXPECT_FALSE(output); EXPECT_FALSE(output);
} }
TEST(VideoAcceleratorStructTraitsTest, ConvertDecoderBuffer) {
const std::string kData = "TESTING_STRING";
const uint32_t kOffset = 3;
const uint32_t kDataSize = kData.size() - kOffset;
constexpr bool kEndOfStream = false;
arc::DecoderBuffer input(arc::CreateTempFileForTesting(kData), kOffset,
kDataSize, kEndOfStream,
base::TimeDelta::FromMilliseconds(kTimestamp));
arc::DecoderBuffer output;
mojo::test::SerializeAndDeserialize<arc::mojom::DecoderBuffer>(&input,
&output);
EXPECT_EQ(output.end_of_stream, input.end_of_stream);
EXPECT_EQ(output.timestamp, input.timestamp);
EXPECT_EQ(output.offset, input.offset);
EXPECT_EQ(output.payload_size, input.payload_size);
scoped_refptr<media::DecoderBuffer> buf =
std::move(output).ToMediaDecoderBuffer();
EXPECT_EQ(memcmp(kData.c_str() + kOffset, buf->data(), kDataSize), 0);
}
} // namespace mojo } // namespace mojo
...@@ -130,3 +130,21 @@ struct VideoFrame { ...@@ -130,3 +130,21 @@ struct VideoFrame {
// timestamp in milliseconds. // timestamp in milliseconds.
int64 timestamp; int64 timestamp;
}; };
// Struct for storing bitstream buffer.
struct DecoderBuffer {
// Field for a physical buffer. This buffer is passed over an interface from
// ARC++ to Chrome, with a callback method that will be run when the buffer is
// used and the file descriptor is closed.
handle handle_fd;
// Distance in bytes between the beginning of the buffer pointed by
// |handle_fd| and the beginning of bitstream buffer.
uint32 offset;
// Bitstream buffer size in bytes. The buffer length referred by |handle_fd|
// can be more than |offset| + |payload_size|.
uint32 payload_size;
// Whether the buffer is an end-of-stream (EOS) buffer.
bool end_of_stream;
// Timestamp in microseconds.
int64 timestamp;
};
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
mojom = "//components/arc/mojom/video_common.mojom" mojom = "//components/arc/mojom/video_common.mojom"
public_headers = [ public_headers = [
"//components/arc/video_accelerator/decoder_buffer.h",
"//components/arc/video_accelerator/video_frame_plane.h", "//components/arc/video_accelerator/video_frame_plane.h",
"//media/base/decode_status.h", "//media/base/decode_status.h",
"//media/base/video_codecs.h", "//media/base/video_codecs.h",
...@@ -14,6 +15,7 @@ public_headers = [ ...@@ -14,6 +15,7 @@ public_headers = [
] ]
public_deps = [ public_deps = [
"//components/arc/video_accelerator:common",
"//media", "//media",
] ]
...@@ -29,6 +31,7 @@ deps = [ ...@@ -29,6 +31,7 @@ deps = [
] ]
type_mappings = [ type_mappings = [
"arc.mojom.DecoderBuffer=arc::DecoderBuffer[move_only]",
"arc.mojom.DecodeStatus=media::DecodeStatus", "arc.mojom.DecodeStatus=media::DecodeStatus",
"arc.mojom.MediaVideoFramePlane=media::VideoFrameLayout::Plane", "arc.mojom.MediaVideoFramePlane=media::VideoFrameLayout::Plane",
"arc.mojom.Size=gfx::Size", "arc.mojom.Size=gfx::Size",
......
...@@ -4,8 +4,6 @@ ...@@ -4,8 +4,6 @@
static_library("video_accelerator") { static_library("video_accelerator") {
sources = [ sources = [
"arc_video_accelerator_util.cc",
"arc_video_accelerator_util.h",
"gpu_arc_video_decode_accelerator.cc", "gpu_arc_video_decode_accelerator.cc",
"gpu_arc_video_decode_accelerator.h", "gpu_arc_video_decode_accelerator.h",
"gpu_arc_video_encode_accelerator.cc", "gpu_arc_video_encode_accelerator.cc",
...@@ -19,8 +17,26 @@ static_library("video_accelerator") { ...@@ -19,8 +17,26 @@ static_library("video_accelerator") {
] ]
deps = [ deps = [
":common",
"//components/arc/mojom:media", "//components/arc/mojom:media",
"//media", "//media",
"//ui/ozone", "//ui/ozone",
] ]
} }
source_set("common") {
sources = [
"arc_video_accelerator_util.cc",
"arc_video_accelerator_util.h",
"decoder_buffer.cc",
"decoder_buffer.h",
"video_frame_plane.h",
]
deps = [
"//media",
"//media/gpu:common",
"//mojo/public/cpp/system:system",
"//ui/gfx:memory_buffer",
]
}
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
#include <sys/types.h> #include <sys/types.h>
#include <unistd.h> #include <unistd.h>
#include "base/files/file_util.h"
#include "base/files/platform_file.h" #include "base/files/platform_file.h"
#include "base/numerics/checked_math.h" #include "base/numerics/checked_math.h"
#include "base/numerics/safe_conversions.h" #include "base/numerics/safe_conversions.h"
...@@ -195,4 +196,22 @@ base::Optional<gfx::GpuMemoryBufferHandle> CreateGpuMemoryBufferHandle( ...@@ -195,4 +196,22 @@ base::Optional<gfx::GpuMemoryBufferHandle> CreateGpuMemoryBufferHandle(
return gmb_handle; return gmb_handle;
} }
base::ScopedFD CreateTempFileForTesting(const std::string& data) {
base::FilePath path;
base::CreateTemporaryFile(&path);
if (base::WriteFile(path, data.c_str(), data.size()) !=
base::MakeStrictNum(data.size())) {
VLOGF(1) << "Cannot write the whole data into file.";
return base::ScopedFD();
}
base::File file(path, base::File::FLAG_OPEN | base::File::FLAG_READ);
if (!file.IsValid()) {
VLOGF(1) << "Failed to create file.";
return base::ScopedFD();
}
return base::ScopedFD(file.TakePlatformFile());
}
} // namespace arc } // namespace arc
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
#ifndef COMPONENTS_ARC_VIDEO_ACCELERATOR_ARC_VIDEO_ACCELERATOR_UTIL_H_ #ifndef COMPONENTS_ARC_VIDEO_ACCELERATOR_ARC_VIDEO_ACCELERATOR_UTIL_H_
#define COMPONENTS_ARC_VIDEO_ACCELERATOR_ARC_VIDEO_ACCELERATOR_UTIL_H_ #define COMPONENTS_ARC_VIDEO_ACCELERATOR_ARC_VIDEO_ACCELERATOR_UTIL_H_
#include <string>
#include <vector> #include <vector>
#include "base/files/scoped_file.h" #include "base/files/scoped_file.h"
...@@ -32,5 +33,9 @@ base::Optional<gfx::GpuMemoryBufferHandle> CreateGpuMemoryBufferHandle( ...@@ -32,5 +33,9 @@ base::Optional<gfx::GpuMemoryBufferHandle> CreateGpuMemoryBufferHandle(
const gfx::Size& coded_size, const gfx::Size& coded_size,
base::ScopedFD fd, base::ScopedFD fd,
const std::vector<VideoFramePlane>& planes); const std::vector<VideoFramePlane>& planes);
// Create a temp file and write |data| into the file.
base::ScopedFD CreateTempFileForTesting(const std::string& data);
} // namespace arc } // namespace arc
#endif // COMPONENTS_ARC_VIDEO_ACCELERATOR_ARC_VIDEO_ACCELERATOR_UTIL_H_ #endif // COMPONENTS_ARC_VIDEO_ACCELERATOR_ARC_VIDEO_ACCELERATOR_UTIL_H_
// 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/arc/video_accelerator/decoder_buffer.h"
#include "base/logging.h"
#include "base/memory/platform_shared_memory_region.h"
#include "base/memory/read_only_shared_memory_region.h"
#include "base/numerics/checked_math.h"
#include "base/unguessable_token.h"
#include "components/arc/video_accelerator/arc_video_accelerator_util.h"
#include "media/base/decoder_buffer.h"
namespace arc {
DecoderBuffer::DecoderBuffer() = default;
DecoderBuffer::DecoderBuffer(base::ScopedFD handle_fd,
uint32_t offset,
uint32_t payload_size,
bool end_of_stream,
base::TimeDelta timestamp)
: handle_fd(std::move(handle_fd)),
offset(offset),
payload_size(payload_size),
end_of_stream(end_of_stream),
timestamp(timestamp) {}
DecoderBuffer::DecoderBuffer(DecoderBuffer&& buf) = default;
DecoderBuffer& DecoderBuffer::operator=(DecoderBuffer&& buf) = default;
DecoderBuffer::~DecoderBuffer() = default;
scoped_refptr<media::DecoderBuffer> DecoderBuffer::ToMediaDecoderBuffer() && {
if (end_of_stream)
return media::DecoderBuffer::CreateEOSBuffer();
base::CheckedNumeric<off_t> checked_offset(offset);
base::CheckedNumeric<size_t> checked_payload_size(payload_size);
if (!checked_offset.IsValid() || !checked_payload_size.IsValid()) {
VLOG(1) << "Overflow when convert offset and payload size to size_t.";
return nullptr;
}
size_t required_size;
if (!base::CheckAdd<size_t>(offset, payload_size)
.AssignIfValid(&required_size)) {
VLOG(1) << "Overflow when adding offset and payload size.";
return nullptr;
}
size_t file_size = 0;
if (!GetFileSize(handle_fd.get(), &file_size) || file_size < required_size) {
VLOG(1) << "File size(" << file_size << ") is smaller than required size("
<< required_size << ").";
return nullptr;
}
DCHECK(handle_fd.is_valid());
auto readonly_region = base::ReadOnlySharedMemoryRegion::Deserialize(
base::subtle::PlatformSharedMemoryRegion::Take(
std::move(handle_fd),
base::subtle::PlatformSharedMemoryRegion::Mode::kReadOnly, file_size,
base::UnguessableToken::Create()));
scoped_refptr<media::DecoderBuffer> output =
media::DecoderBuffer::FromSharedMemoryRegion(
std::move(readonly_region), checked_offset.ValueOrDie(),
checked_payload_size.ValueOrDie());
output->set_timestamp(timestamp);
return output;
}
} // namespace arc
// 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.
#ifndef COMPONENTS_ARC_VIDEO_ACCELERATOR_DECODER_BUFFER_H_
#define COMPONENTS_ARC_VIDEO_ACCELERATOR_DECODER_BUFFER_H_
#include "base/files/scoped_file.h"
#include "base/memory/scoped_refptr.h"
#include "base/time/time.h"
namespace media {
class DecoderBuffer;
} // namespace media
namespace arc {
// Intermediate class in converting from a mojom::DecoderBuffer to
// media::DecoderBuffer. Because media::DecoderBuffer doesn't have a public
// constructor, we cannot convert to media::DecoderBuffer directly by
// StructTraits::Read().
struct DecoderBuffer {
DecoderBuffer();
DecoderBuffer(base::ScopedFD handle_fd,
uint32_t offset,
uint32_t payload_size,
bool end_of_stream,
base::TimeDelta timestamp);
~DecoderBuffer();
DecoderBuffer(DecoderBuffer&& buf);
DecoderBuffer& operator=(DecoderBuffer&& buf);
// Convert to media::DecoderBuffer.
scoped_refptr<media::DecoderBuffer> ToMediaDecoderBuffer() &&;
// See components/arc/mojom/video_common.mojom for descriptions of each field.
base::ScopedFD handle_fd;
uint32_t offset;
uint32_t payload_size;
bool end_of_stream;
base::TimeDelta timestamp;
};
} // namespace arc
#endif // COMPONENTS_ARC_VIDEO_ACCELERATOR_DECODER_BUFFER_H_
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