Files
BPI-CM9-Linux/amlbian/scripts/chromium/patches/minimal-hwdecode-final.patch
T

661 lines
28 KiB
Diff

diff --git a/content/renderer/media/gpu/gpu_video_accelerator_factories_impl.cc b/content/renderer/media/gpu/gpu_video_accelerator_factories_impl.cc
index 3acfcf5749..45b18d4203 100644
--- a/content/renderer/media/gpu/gpu_video_accelerator_factories_impl.cc
+++ b/content/renderer/media/gpu/gpu_video_accelerator_factories_impl.cc
@@ -183,6 +183,9 @@ void GpuVideoAcceleratorFactoriesImpl::DestroyContext() {
}
bool GpuVideoAcceleratorFactoriesImpl::IsGpuVideoDecodeAcceleratorEnabled() {
+#if BUILDFLAG(IS_AMLOGIC_MEDIA)
+ return true;
+#endif
return video_decode_accelerator_enabled_;
}
bool GpuVideoAcceleratorFactoriesImpl::IsGpuVideoEncodeAcceleratorEnabled() {
diff --git a/content/renderer/render_thread_impl.cc b/content/renderer/render_thread_impl.cc
index c848b7f8f7..e2b5215d17 100644
--- a/content/renderer/render_thread_impl.cc
+++ b/content/renderer/render_thread_impl.cc
@@ -1,3 +1,4 @@
+#include "media/mojo/buildflags.h"
// Copyright 2012 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -1026,8 +1027,10 @@ media::GpuVideoAcceleratorFactories* RenderThreadImpl::GetGpuFactories() {
// Currently, VideoResourceUpdater can't convert hardware resources to
// software resources in software compositing mode. So, fall back to software
// video decoding if gpu compositing is off.
+#if !BUILDFLAG(IS_AMLOGIC_MEDIA)
if (is_gpu_compositing_disabled_)
return nullptr;
+#endif
// This context is only used to create textures and mailbox them, so
// use lower limits than the default.
gpu::SharedMemoryLimits limits = gpu::SharedMemoryLimits::ForMailboxContext();
@@ -1045,6 +1048,9 @@ media::GpuVideoAcceleratorFactories* RenderThreadImpl::GetGpuFactories() {
viz::command_buffer_metrics::ContextType::MEDIA,
kGpuStreamIdMedia, kGpuStreamPriorityMedia);
+#if BUILDFLAG(IS_AMLOGIC_MEDIA)
+ const bool enable_video_decode_accelerator = true;
+#else
const bool enable_video_decode_accelerator =
#if BUILDFLAG(IS_LINUX)
base::FeatureList::IsEnabled(media::kAcceleratedVideoDecodeLinux) &&
@@ -1053,6 +1059,7 @@ media::GpuVideoAcceleratorFactories* RenderThreadImpl::GetGpuFactories() {
(gpu_channel_host->gpu_feature_info()
.status_values[gpu::GPU_FEATURE_TYPE_ACCELERATED_VIDEO_DECODE] ==
gpu::kGpuFeatureStatusEnabled);
+#endif
const bool enable_video_encode_accelerator =
#if BUILDFLAG(IS_LINUX)
diff --git a/media/base/format_utils.cc b/media/base/format_utils.cc
index 0e1080e0a6..98a221b2f4 100644
--- a/media/base/format_utils.cc
+++ b/media/base/format_utils.cc
@@ -65,6 +65,9 @@ std::optional<gfx::BufferFormat> VideoPixelFormatToGfxBufferFormat(
case PIXEL_FORMAT_NV12:
return gfx::BufferFormat::YUV_420_BIPLANAR;
+ case PIXEL_FORMAT_NV21:
+ return gfx::BufferFormat::YUV_420_BIPLANAR;
+
case PIXEL_FORMAT_NV12A:
return gfx::BufferFormat::YUVA_420_TRIPLANAR;
diff --git a/media/base/supported_types.cc b/media/base/supported_types.cc
index 34e1ecb868..bc0cd98fee 100644
--- a/media/base/supported_types.cc
+++ b/media/base/supported_types.cc
@@ -315,7 +315,7 @@ bool IsDecoderAACSupported(const AudioType& type) {
return true;
}
#if BUILDFLAG(ENABLE_MOJO_AUDIO_DECODER) && \
- (BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_WIN))
+ (BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_WIN) || BUILDFLAG(IS_AMLOGIC_MEDIA))
return GetSupplementalDecoderAudioTypeCache()->IsProfileSupported(type);
#else
return false;
@@ -350,12 +350,13 @@ bool IsDecoderDolbyAc3Eac3Supported(const AudioType& type) {
bool IsDecoderDolbyAc4Supported(const AudioType& type) {
#if BUILDFLAG(ENABLE_PLATFORM_AC4_AUDIO) && \
- BUILDFLAG(ENABLE_MOJO_AUDIO_DECODER) && BUILDFLAG(IS_WIN)
+ BUILDFLAG(ENABLE_MOJO_AUDIO_DECODER) && (BUILDFLAG(IS_WIN) || BUILDFLAG(IS_AMLOGIC_MEDIA))
return GetSupplementalDecoderAudioTypeCache()->IsProfileSupported(type);
#else
return false;
#endif // BUILDFLAG(ENABLE_PLATFORM_AC4_AUDIO) &&
- // BUILDFLAG(ENABLE_MOJO_AUDIO_DECODER) && BUILDFLAG(IS_WIN)
+ // BUILDFLAG(ENABLE_MOJO_AUDIO_DECODER) && (BUILDFLAG(IS_WIN) ||
+ // BUILDFLAG(IS_AMLOGIC_MEDIA))
}
bool IsEncoderH264ProfileSupported(const VideoType& type) {
@@ -579,6 +580,11 @@ bool IsDefaultEncoderSupportedVideoType(const VideoType& type) {
}
bool IsDecoderBuiltInVideoCodec(VideoCodec codec) {
+#if BUILDFLAG(IS_AMLOGIC_MEDIA)
+ // On Amlogic platforms, all codecs are treated as built-in since the
+ // hardware decoders are used.
+ return true;
+#endif // BUILDFLAG(IS_AMLOGIC_MEDIA)
#if BUILDFLAG(ENABLE_FFMPEG_VIDEO_DECODERS) && BUILDFLAG(USE_PROPRIETARY_CODECS)
if (codec == VideoCodec::kH264 &&
base::FeatureList::IsEnabled(kBuiltInH264Decoder)) {
diff --git a/media/gpu/chromeos/mailbox_video_frame_converter.cc b/media/gpu/chromeos/mailbox_video_frame_converter.cc
index 6cbc6d89f5..21994b5f34 100644
--- a/media/gpu/chromeos/mailbox_video_frame_converter.cc
+++ b/media/gpu/chromeos/mailbox_video_frame_converter.cc
@@ -389,10 +389,22 @@ void MailboxVideoFrameConverter::WrapSharedImageAndVideoFrameAndOutput(
frame->metadata().needs_detiling
? frame->coded_size()
: GetRectSizeFromOrigin(frame->visible_rect());
+ // AML: NV21 and NV12 have identical layout for GPU texture import.
+ // WrapSharedImage doesn't support NV21, so use NV12 instead.
+ VideoPixelFormat wrap_format = frame->format();
+ if (wrap_format == PIXEL_FORMAT_NV21)
+ wrap_format = PIXEL_FORMAT_NV12;
scoped_refptr<VideoFrame> mailbox_frame = VideoFrame::WrapSharedImage(
- frame->format(), shared_image, shared_image_sync_token,
+ wrap_format, shared_image, shared_image_sync_token,
std::move(release_mailbox_cb), coded_size, frame->visible_rect(),
frame->natural_size(), frame->timestamp());
+ if (!mailbox_frame) {
+ DVLOG(3) << "[AML-CONV] WrapSharedImage returned null! format="
+ << VideoPixelFormatToString(frame->format())
+ << " coded=" << coded_size.ToString()
+ << " visible=" << frame->visible_rect().ToString();
+ return;
+ }
mailbox_frame->set_color_space(frame->ColorSpace());
mailbox_frame->set_hdr_metadata(frame->hdr_metadata());
mailbox_frame->set_metadata(frame->metadata());
@@ -496,8 +508,13 @@ bool MailboxVideoFrameConverter::GenerateSharedImageOnGPUThread(
}
auto gpu_memory_buffer_handle = origin_frame->CreateGpuMemoryBufferHandle();
- DCHECK(!gpu_memory_buffer_handle.is_null());
- DCHECK_EQ(gpu_memory_buffer_handle.type, gfx::NATIVE_PIXMAP);
+ DVLOG(3) << "[AML-CONV] CreateGpuMemoryBufferHandle: null="
+ << gpu_memory_buffer_handle.is_null()
+ << " type=" << gpu_memory_buffer_handle.type
+ << " planes=" << gpu_memory_buffer_handle.native_pixmap_handle.planes.size()
+ << " fmt=" << VideoPixelFormatToString(origin_frame->format())
+ << " size=" << origin_frame->coded_size().ToString();
+ if (gpu_memory_buffer_handle.is_null()) return false;
// The SharedImage size ultimately must correspond to the size used to import
// the decoded frame into a graphics API (e.g., the EGL image size when using
@@ -531,18 +548,18 @@ bool MailboxVideoFrameConverter::GenerateSharedImageOnGPUThread(
shared_image_usage |= gpu::SHARED_IMAGE_USAGE_WEBGPU_READ;
}
+ DVLOG(3) << "[AML-CONV] About to CreateSharedImage size=" << shared_image_size.ToString();
scoped_refptr<gpu::ClientSharedImage> client_shared_image =
gpu_delegate_->CreateSharedImage(std::move(gpu_memory_buffer_handle),
GetSharedImageFormat(*buffer_format),
shared_image_size, src_color_space,
kTopLeft_GrSurfaceOrigin,
kPremul_SkAlphaType, shared_image_usage);
+ DVLOG(3) << "[AML-CONV] CreateSharedImage result: " << (client_shared_image ? "OK" : "FAIL");
if (!client_shared_image) {
OnError(FROM_HERE, "Failed to create shared image.");
return false;
}
- // There's no need to UpdateSharedImage() after CreateSharedImage().
-
shared_image->Reset(std::move(client_shared_image));
return true;
}
diff --git a/media/gpu/chromeos/native_pixmap_frame_resource.cc b/media/gpu/chromeos/native_pixmap_frame_resource.cc
index 09c763a7e8..5ac815656b 100644
--- a/media/gpu/chromeos/native_pixmap_frame_resource.cc
+++ b/media/gpu/chromeos/native_pixmap_frame_resource.cc
@@ -3,6 +3,7 @@
// found in the LICENSE file.
#include "media/gpu/chromeos/native_pixmap_frame_resource.h"
+#include <drm_fourcc.h>
#include "atomic"
@@ -130,10 +131,8 @@ scoped_refptr<NativePixmapFrameResource> NativePixmapFrameResource::Create(
std::move(dmabuf_fds[i]));
}
- // This is only ever called with V4L2-allocated buffers, so |layout.modifier|
- // is expected to be kNoModifier.
- CHECK_EQ(layout.modifier(), gfx::NativePixmapHandle::kNoModifier);
- handle.modifier = layout.modifier();
+ // Keep kNoModifier for V4L2 MMAP buffers.
+ handle.modifier = gfx::NativePixmapHandle::kNoModifier; // AML: force no modifier for V4L2 MMAP
// Note: |buffer_usage| is not set. As a result, the constructed
// NativePixmapFrameResource cannot be converted to a VideoFrame with the
diff --git a/media/gpu/chromeos/video_decoder_pipeline.cc b/media/gpu/chromeos/video_decoder_pipeline.cc
--- a/media/gpu/chromeos/video_decoder_pipeline.cc
+++ b/media/gpu/chromeos/video_decoder_pipeline.cc
@@ -3,6 +3,7 @@
// found in the LICENSE file.
#include "media/gpu/chromeos/video_decoder_pipeline.h"
+#include "media/mojo/buildflags.h"
#include <memory>
#include <optional>
@@ -571,6 +572,7 @@
// Make sure that the configuration requested is supported by the driver,
// which must provide such information.
+#if !BUILDFLAG(IS_AMLOGIC_MEDIA)
const auto supported_configs =
supported_configs_for_testing_.empty()
? VideoDecoderPipeline::GetSupportedConfigs(GetDecoderType(),
@@ -588,6 +590,7 @@
std::move(init_cb).Run(DecoderStatus::Codes::kUnsupportedConfig);
return;
}
+#endif // !BUILDFLAG(IS_AMLOGIC_MEDIA)
constexpr auto kVideoCodecProfileCount = media::VIDEO_CODEC_PROFILE_MAX + 1;
base::UmaHistogramEnumeration(
"Media.PlatformVideoDecoding.VideoCodecProfile", config.profile(),
@@ -647,8 +650,10 @@
get_original_frame_cb = base::BindRepeating(
&OOPVideoDecoder::GetOriginalFrame,
base::Unretained(static_cast<OOPVideoDecoder*>(decoder_.get())));
+ } else if (!main_frame_pool_) {
+ // AML: PickDecoderOutputFormat() drops the pool in V4L2 MMAP mode.
+ get_original_frame_cb = base::NullCallback();
} else {
- CHECK(main_frame_pool_);
PlatformVideoFramePool* platform_video_frame_pool =
main_frame_pool_->AsPlatformVideoFramePool();
// The only |frame_converter_| that needs the GetOriginalFrameCB callback
@@ -1058,6 +1063,15 @@
// vector (CAPCM*1_Sand_E.h264).
CHECK_LE(num_codec_reference_frames, 32u);
+ DVLOG(3) << "[AML-PIPE] PickDecoderOutputFormat: candidates=" << candidates.size()
+ << " renderable=" << renderable_fourccs_.size();
+ for (const auto& c : candidates) {
+ DVLOG(3) << "[AML-PIPE] candidate: " << c.fourcc.ToString()
+ << " size=" << c.size.ToString();
+ }
+ for (const auto& f : renderable_fourccs_) {
+ DVLOG(3) << "[AML-PIPE] renderable: " << f.ToString();
+ }
if (candidates.empty())
return CroStatus::Codes::kNoDecoderOutputFormatCandidates;
@@ -1069,6 +1083,8 @@
// provided by the frame pool matches the one supported by the |decoder_|, we
// don't need an image processor.
std::optional<PixelLayoutCandidate> viable_candidate;
+ DVLOG(3) << "[AML-PIPE] output_size=" << (output_size ? output_size->ToString() : "none")
+ << " decoder_visible=" << decoder_visible_rect.ToString();
if (!output_size || *output_size == decoder_visible_rect.size()) {
for (const auto& fourcc : renderable_fourccs_) {
for (const auto& candidate : candidates) {
@@ -1108,14 +1124,9 @@
*allocator, VideoFrame::STORAGE_DMABUFS);
#elif BUILDFLAG(IS_LINUX) && BUILDFLAG(USE_V4L2_CODEC)
// Linux w/ V4L2 should not use a custom allocator
- // Only tested with video_decode_accelerator_tests
- // TODO(wenst@) Test with full Chromium Browser
CHECK(!allocator.has_value());
if (viable_candidate) {
- // Instead, let V4L2 allocate the buffers if it can decode directly
- // to the preferred formats. There's no need to allocate frames.
- // This is not compatible with VdVideoDecodeAccelerator, which
- // expects GPU buffers in VdVideoDecodeAccelerator::GetPicture()
+ // Let V4L2 allocate the buffers (MMAP mode)
frame_converter_->set_get_original_frame_cb(base::NullCallback());
main_frame_pool_.reset();
return *viable_candidate;
diff --git a/media/gpu/v4l2/legacy/v4l2_video_decoder_backend_stateful.cc b/media/gpu/v4l2/legacy/v4l2_video_decoder_backend_stateful.cc
--- a/media/gpu/v4l2/legacy/v4l2_video_decoder_backend_stateful.cc
+++ b/media/gpu/v4l2/legacy/v4l2_video_decoder_backend_stateful.cc
@@ -464,7 +464,17 @@
// Wrap the frame into another one so we can be signaled when the
// consumer is done with it and reuse the V4L2 buffer.
scoped_refptr<FrameResource> origin_frame = buffer->GetFrameResource();
+ DVLOG(3) << "[AML-V4L2] OnOutputBufferDequeued: origin_frame="
+ << (origin_frame ? "valid" : "NULL")
+ << " memory=" << output_queue_->GetMemoryType();
+ if (!origin_frame) {
+ // Queue was reset (resolution change). Skip this buffer.
+ return;
+ }
frame = origin_frame->CreateWrappingFrame();
+ if (!frame) {
+ return;
+ }
frame->AddDestructionObserver(base::BindOnce(
&V4L2StatefulVideoDecoderBackend::ReuseOutputBufferThunk,
task_runner_, weak_this_, buffer));
@@ -761,6 +771,8 @@
#endif // BUILDFLAG(ENABLE_HEVC_PARSER_AND_HW_DECODER)
V4L2_PIX_FMT_VP8,
V4L2_PIX_FMT_VP9,
+ // AML: without AV01 here every AV1 stream is rejected in Initialize().
+ V4L2_PIX_FMT_AV1,
};
auto device = base::MakeRefCounted<V4L2Device>();
VideoDecodeAccelerator::SupportedProfiles profiles =
diff --git a/media/gpu/v4l2/v4l2_queue.cc b/media/gpu/v4l2/v4l2_queue.cc
index bd6b3f5278..4242e06e38 100644
--- a/media/gpu/v4l2/v4l2_queue.cc
+++ b/media/gpu/v4l2/v4l2_queue.cc
@@ -133,13 +133,12 @@ std::vector<base::ScopedFD> GetDmabufsForV4L2Buffer(
expbuf.type = buf_type;
expbuf.index = index;
expbuf.plane = i;
- expbuf.flags = O_CLOEXEC;
+ expbuf.flags = O_CLOEXEC | O_RDWR; // AML: Mali needs RW access
if (ioctl_cb.Run(VIDIOC_EXPBUF, &expbuf) != 0) {
RecordVidiocIoctlErrorUMA(VidiocIoctlRequests::kVidiocExpbuf);
dmabuf_fds.clear();
break;
}
-
dmabuf_fds.push_back(base::ScopedFD(expbuf.fd));
}
@@ -268,6 +267,15 @@ bool V4L2Buffer::Query() {
return false;
}
+ // Log actual plane info from QUERYBUF
+ for (size_t pi = 0; pi < v4l2_buffer_.length; pi++) {
+ LOG(ERROR) << "[AML-QB] buf=" << v4l2_buffer_.index
+ << " plane" << pi
+ << " length=" << v4l2_planes_[pi].length
+ << " offset=" << v4l2_planes_[pi].m.mem_offset
+ << " bytesused=" << v4l2_planes_[pi].bytesused;
+ }
+
DCHECK(plane_mappings_.size() == v4l2_buffer_.length);
return true;
@@ -314,7 +322,10 @@ size_t V4L2Buffer::GetMemoryUsage() const {
scoped_refptr<FrameResource> V4L2Buffer::CreateFrame() {
auto layout = V4L2FormatToVideoFrameLayout(format_);
if (!layout) {
- VLOGF(1) << "Cannot create frame layout for V4L2 buffers";
+ DVLOG(3) << "[AML-V4L2] CreateFrame: layout failed, pixfmt=0x"
+ << std::hex << format_.fmt.pix_mp.pixelformat << std::dec
+ << " " << format_.fmt.pix_mp.width << "x" << format_.fmt.pix_mp.height
+ << " num_planes=" << format_.fmt.pix_mp.num_planes;
return nullptr;
}
@@ -322,7 +333,8 @@ scoped_refptr<FrameResource> V4L2Buffer::CreateFrame() {
ioctl_cb_, v4l2_buffer_.index, v4l2_buffer_.length,
static_cast<enum v4l2_buf_type>(v4l2_buffer_.type));
if (dmabuf_fds.empty()) {
- VLOGF(1) << "Failed to get DMABUFs of V4L2 buffer";
+ DVLOG(3) << "[AML-V4L2] CreateFrame: GetDmabufs failed, index="
+ << v4l2_buffer_.index << " length=" << v4l2_buffer_.length;
return nullptr;
}
@@ -355,15 +367,19 @@ scoped_refptr<FrameResource> V4L2Buffer::CreateFrame() {
const scoped_refptr<FrameResource>& V4L2Buffer::GetFrameResource() {
// We can create the FrameResource only when using MMAP buffers.
if (v4l2_buffer_.memory != V4L2_MEMORY_MMAP) {
- VLOGF(1) << "Cannot create video frame from non-MMAP buffer";
- // Allow NOTREACHED() on invalid argument because this is an internal
- // method.
- NOTREACHED();
+ DVLOG(3) << "[AML-V4L2] GetFrameResource: memory type is "
+ << v4l2_buffer_.memory << " (not MMAP=" << V4L2_MEMORY_MMAP << ")"
+ << " index=" << v4l2_buffer_.index;
+ static const scoped_refptr<FrameResource> null_res;
+ return null_res;
}
// Create the video frame instance if requiring it for the first time.
if (!frame_) {
frame_ = CreateFrame();
+ if (!frame_) {
+ DVLOG(3) << "[AML-V4L2] CreateFrame returned null for buffer " << v4l2_buffer_.index;
+ }
}
return frame_;
@@ -1178,6 +1194,12 @@ size_t V4L2Queue::AllocateBuffers(size_t count,
return 0;
}
planes_count_ = format->fmt.pix_mp.num_planes;
+ // AML 6.12: queue_setup returns 2 vb2 planes for NV21, but G_FMT
+ // reports num_planes=1. Force 2 so QUERYBUF gets correct length.
+ if (type_ == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE && planes_count_ < 2) {
+ planes_count_ = 2;
+ format->fmt.pix_mp.num_planes = 2;
+ }
DCHECK_LE(planes_count_, static_cast<size_t>(VIDEO_MAX_PLANES));
__u8 flags = incoherent ? V4L2_MEMORY_FLAG_NON_COHERENT : 0;
diff --git a/media/gpu/v4l2/v4l2_utils.cc b/media/gpu/v4l2/v4l2_utils.cc
--- a/media/gpu/v4l2/v4l2_utils.cc
+++ b/media/gpu/v4l2/v4l2_utils.cc
@@ -17,6 +17,10 @@
#if BUILDFLAG(IS_CHROMEOS)
#include <linux/media/av1-ctrls.h>
#endif
+// AML: the Debian uAPI headers predate the AV1 controls.
+#ifndef V4L2_CID_MPEG_VIDEO_AV1_PROFILE
+#define V4L2_CID_MPEG_VIDEO_AV1_PROFILE (V4L2_CID_CODEC_BASE + 656)
+#endif
#include "base/containers/contains.h"
#include "base/metrics/histogram_functions.h"
@@ -264,8 +268,17 @@
planes.reserve(num_color_planes);
for (size_t i = 0; i < num_buffers; ++i) {
const v4l2_plane_pix_format& plane_format = pix_mp.plane_fmt[i];
- planes.emplace_back(static_cast<int32_t>(plane_format.bytesperline), 0u,
- plane_format.sizeimage);
+ int32_t stride = static_cast<int32_t>(plane_format.bytesperline);
+ size_t sizeimage = plane_format.sizeimage;
+ // AML: When num_planes was forced to 2 for NV21, plane_fmt[1] may
+ // have zero values. Fill stride/size from plane0.
+ // Each vb2 plane is a separate DMA-BUF allocation, so offset=0 for all.
+ if (i > 0 && stride == 0 && num_buffers == 2) {
+ stride = static_cast<int32_t>(pix_mp.plane_fmt[0].bytesperline);
+ sizeimage = stride * pix_mp.height / 2;
+ }
+ // AML: each EXPBUF plane is independent DMA-BUF, offset=0 for each
+ planes.emplace_back(stride, 0u, sizeimage);
}
// For the case that #color planes > #buffers, it fills stride of color
// plane which does not map to buffer.
@@ -338,10 +351,9 @@
{V4L2_PIX_FMT_VP8_FRAME, V4L2_CID_MPEG_VIDEO_VP8_PROFILE},
{V4L2_PIX_FMT_VP9, V4L2_CID_MPEG_VIDEO_VP9_PROFILE},
{V4L2_PIX_FMT_VP9_FRAME, V4L2_CID_MPEG_VIDEO_VP9_PROFILE},
-#if BUILDFLAG(IS_CHROMEOS)
+ // AML: needed on Linux too, or no AV1 profile is ever enumerated.
{V4L2_PIX_FMT_AV1, V4L2_CID_MPEG_VIDEO_AV1_PROFILE},
{V4L2_PIX_FMT_AV1_FRAME, V4L2_CID_MPEG_VIDEO_AV1_PROFILE},
-#endif
};
// Default VideoCodecProfiles associated to a V4L2 Codec Control ID.
@@ -359,9 +371,8 @@
#endif // BUILDFLAG(ENABLE_HEVC_PARSER_AND_HW_DECODER)
{V4L2_CID_MPEG_VIDEO_VP8_PROFILE, {VP8PROFILE_ANY}},
{V4L2_CID_MPEG_VIDEO_VP9_PROFILE, {VP9PROFILE_PROFILE0}},
-#if BUILDFLAG(IS_CHROMEOS)
+ // AML: fallback used when the driver has no AV1 profile control.
{V4L2_CID_MPEG_VIDEO_AV1_PROFILE, {AV1PROFILE_PROFILE_MAIN}},
-#endif
};
// Correspondence from a VideoCodecProfiles to V4L2 codec described
@@ -379,10 +390,9 @@
{VP8PROFILE_ANY, MAKE_V4L2_CODEC_PAIR(V4L2_PIX_FMT_VP8, FRAME)},
{VP9PROFILE_PROFILE0, MAKE_V4L2_CODEC_PAIR(V4L2_PIX_FMT_VP9, FRAME)},
{VP9PROFILE_PROFILE2, MAKE_V4L2_CODEC_PAIR(V4L2_PIX_FMT_VP9, FRAME)},
-#if BUILDFLAG(IS_CHROMEOS)
+ // AML: the fourcc -> profile direction is not IS_CHROMEOS gated.
{AV1PROFILE_PROFILE_MAIN,
MAKE_V4L2_CODEC_PAIR(V4L2_PIX_FMT_AV1, FRAME)},
-#endif
};
} // namespace
@@ -545,8 +555,11 @@
uint32_t VideoCodecProfileToV4L2PixFmt(VideoCodecProfile profile,
bool slice_based) {
- CHECK(base::Contains(kVideoCodecProfileToV4L2CodecPixFmt, profile))
- << "Unsupported profile: " << GetProfileName(profile);
+ // AML: the header contract is INVALID for unmapped profiles, not a crash.
+ if (!base::Contains(kVideoCodecProfileToV4L2CodecPixFmt, profile)) {
+ VLOGF(1) << "Unsupported profile: " << GetProfileName(profile);
+ return V4L2_PIX_FMT_INVALID;
+ }
const auto& v4l2_pix_fmt = kVideoCodecProfileToV4L2CodecPixFmt.at(profile);
return slice_based ? v4l2_pix_fmt.first : v4l2_pix_fmt.second;
diff --git a/media/gpu/v4l2/v4l2_vda_helpers.cc b/media/gpu/v4l2/v4l2_vda_helpers.cc
--- a/media/gpu/v4l2/v4l2_vda_helpers.cc
+++ b/media/gpu/v4l2/v4l2_vda_helpers.cc
@@ -160,7 +160,8 @@
#endif // BUILDFLAG(ENABLE_HEVC_PARSER_AND_HW_DECODER)
case VideoCodec::kVP8:
case VideoCodec::kVP9:
- // VP8/VP9 don't need any frame splitting, use the default implementation.
+ case VideoCodec::kAV1:
+ // AML: AV1 needs no frame splitting either, one buffer is one temporal unit.
return std::make_unique<v4l2_vda_helpers::InputBufferFragmentSplitter>();
default:
LOG(ERROR) << "Unhandled profile: " << profile;
diff --git a/media/media_options.gni b/media/media_options.gni
index e235287ebb..36e13c3e91 100644
--- a/media/media_options.gni
+++ b/media/media_options.gni
@@ -347,6 +347,14 @@ declare_args() {
chrome_wide_echo_cancellation_supported = is_win || is_mac || is_linux
}
+declare_args() {
+ is_amlogic_media=false
+}
+
+declare_args() {
+ widevine_version=0
+}
+
# Do not expand this list without double-checking with OWNERS, this is a list of
# all targets which roll up into the //media component. It controls visibility
# of subcomponent targets and public_deps for //media.
diff --git a/media/mojo/BUILD.gn b/media/mojo/BUILD.gn
index 9573d77ba8..92ecf99112 100644
--- a/media/mojo/BUILD.gn
+++ b/media/mojo/BUILD.gn
@@ -55,6 +55,7 @@ buildflag_header("buildflags") {
"ENABLE_MOJO_VIDEO_DECODER=$enable_mojo_video_decoder",
"ENABLE_MOJO_MEDIA_IN_BROWSER_PROCESS=$enable_mojo_media_in_browser_process",
"ENABLE_MOJO_MEDIA_IN_GPU_PROCESS=$enable_mojo_media_in_gpu_process",
+ "IS_AMLOGIC_MEDIA=$is_amlogic_media",
]
}
diff --git a/media/mojo/services/BUILD.gn b/media/mojo/services/BUILD.gn
index 3e2dac7991..b3911dcf35 100644
--- a/media/mojo/services/BUILD.gn
+++ b/media/mojo/services/BUILD.gn
@@ -119,6 +119,11 @@ component("services") {
sources += [ "gpu_mojo_media_client_mac.cc" ]
} else if (is_win) {
sources += [ "gpu_mojo_media_client_win.cc" ]
+ } else if (is_amlogic_media) {
+ sources += [ "gpu_mojo_media_client_amlogic.cc" ]
+ deps += [
+ "//media/gpu/chromeos",
+ ]
} else if (use_vaapi || use_v4l2_codec) {
if (is_linux) {
sources += [ "gpu_mojo_media_client_linux.cc" ]
diff --git a/media/mojo/services/gpu_mojo_media_client.cc b/media/mojo/services/gpu_mojo_media_client.cc
index 7a739e1d73..0475c34757 100644
--- a/media/mojo/services/gpu_mojo_media_client.cc
+++ b/media/mojo/services/gpu_mojo_media_client.cc
@@ -3,6 +3,7 @@
// found in the LICENSE file.
#include "media/mojo/services/gpu_mojo_media_client.h"
+#include "media/mojo/buildflags.h"
#include <optional>
#include <utility>
@@ -156,12 +157,16 @@ GpuMojoMediaClient::GetSupportedVideoDecoderConfigs() {
if (!supported_config_cache_) {
// Only bother to query if accelerated video decoding is enabled.
// (RenderMediaClient does not know about GPU features before it asks.)
+#if BUILDFLAG(IS_AMLOGIC_MEDIA)
+ {
+#else
if (gpu_preferences_.disable_accelerated_video_decode ||
(gpu_feature_info_
.status_values[gpu::GPU_FEATURE_TYPE_ACCELERATED_VIDEO_DECODE] !=
gpu::kGpuFeatureStatusEnabled)) {
supported_config_cache_ = SupportedVideoDecoderConfigs();
} else {
+#endif
supported_config_cache_ = GetPlatformSupportedVideoDecoderConfigs();
}
@@ -230,12 +235,14 @@ std::unique_ptr<VideoDecoder> GpuMojoMediaClient::CreateVideoDecoder(
const gfx::ColorSpace& target_color_space,
mojo::PendingRemote<stable::mojom::StableVideoDecoder> oop_video_decoder) {
// Always respect GPU features.
+#if !BUILDFLAG(IS_AMLOGIC_MEDIA)
if (gpu_preferences_.disable_accelerated_video_decode ||
(gpu_feature_info_
.status_values[gpu::GPU_FEATURE_TYPE_ACCELERATED_VIDEO_DECODE] !=
gpu::kGpuFeatureStatusEnabled)) {
return nullptr;
}
+#endif
// All implementations require a command buffer.
if (!command_buffer_id)
return nullptr;
diff --git a/ui/ozone/common/BUILD.gn b/ui/ozone/common/BUILD.gn
index 7ce40f68de..1036e37a91 100644
--- a/ui/ozone/common/BUILD.gn
+++ b/ui/ozone/common/BUILD.gn
@@ -42,6 +42,7 @@ source_set("common") {
"//ui/gfx/ipc/color",
"//ui/gl",
"//ui/gl:buildflags",
+ "//media/mojo:buildflags",
]
data_deps = [ "//third_party/angle:includes" ]
diff --git a/ui/ozone/common/native_pixmap_egl_binding.cc b/ui/ozone/common/native_pixmap_egl_binding.cc
index b945e14226..b1b0dda89b 100644
--- a/ui/ozone/common/native_pixmap_egl_binding.cc
+++ b/ui/ozone/common/native_pixmap_egl_binding.cc
@@ -8,6 +8,7 @@
#endif
#include "ui/ozone/common/native_pixmap_egl_binding.h"
+#include "media/mojo/buildflags.h"
#include "base/logging.h"
#include "base/memory/scoped_refptr.h"
@@ -70,7 +71,11 @@ EGLint FourCC(gfx::BufferFormat format) {
case gfx::BufferFormat::YVU_420:
return DRM_FORMAT_YVU420;
case gfx::BufferFormat::YUV_420_BIPLANAR:
+#if BUILDFLAG(IS_AMLOGIC_MEDIA)
+ return 0x3132564e; // DRM_FORMAT_NV21 - AML V4L2 outputs VU order
+#else
return DRM_FORMAT_NV12;
+#endif
case gfx::BufferFormat::P010:
return DRM_FORMAT_P010;
case gfx::BufferFormat::RGBA_F16:
@@ -229,11 +234,19 @@ bool NativePixmapEGLBinding::InitializeFromNativePixmap(
attrs.push_back(kPlaneOffsetAttrs[attrs_plane]);
attrs.push_back(pixmap->GetDmaBufOffset(attrs_plane));
attrs.push_back(kPlanePitchAttrs[attrs_plane]);
- attrs.push_back(pixmap->GetDmaBufPitch(attrs_plane));
+ {
+ int p = pixmap->GetDmaBufPitch(attrs_plane);
+ if (attrs_plane > 0 && p == 0 && pixmap->GetNumberOfPlanes() == 2)
+ p = pixmap->GetDmaBufPitch(0);
+ attrs.push_back(p);
+ }
uint64_t modifier = pixmap->GetBufferFormatModifier();
+ // AML: skip modifier only for kNoModifier (V4L2 MMAP video buffers)
+ // GBM-allocated UI buffers have real modifiers and must pass them.
if (has_dma_buf_import_modifier &&
- modifier != gfx::NativePixmapHandle::kNoModifier) {
+ modifier != gfx::NativePixmapHandle::kNoModifier &&
+ modifier != 0) {
DCHECK(attrs_plane < std::size(kPlaneLoModifierAttrs));
DCHECK(attrs_plane < std::size(kPlaneHiModifierAttrs));
attrs.push_back(kPlaneLoModifierAttrs[attrs_plane]);
@@ -252,7 +265,12 @@ bool NativePixmapEGLBinding::InitializeFromNativePixmap(
attrs.push_back(EGL_DMA_BUF_PLANE0_OFFSET_EXT);
attrs.push_back(pixmap->GetDmaBufOffset(pixmap_plane));
attrs.push_back(EGL_DMA_BUF_PLANE0_PITCH_EXT);
- attrs.push_back(pixmap->GetDmaBufPitch(pixmap_plane));
+ {
+ int p = pixmap->GetDmaBufPitch(pixmap_plane);
+ if (pixmap_plane > 0 && p == 0)
+ p = pixmap->GetDmaBufPitch(0);
+ attrs.push_back(p);
+ }
attrs.push_back(EGL_NONE);
}