Skip to content

Commit

Permalink
media/gpu/v4l2: implement flat stateful VD GetSupportedConfigs()
Browse files Browse the repository at this point in the history
As said, implement the static config-enumeration method. based on
utility functions from v4l2_utils.

Bug: b:279980150
Change-Id: Iceb6d549bd8a3e6a6fbcea11de4922034f8a4259
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4527140
Reviewed-by: Steve Cho <stevecho@chromium.org>
Commit-Queue: Miguel Casas-Sanchez <mcasas@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1146821}
  • Loading branch information
yellowdoge authored and Chromium LUCI CQ committed May 20, 2023
1 parent 686113e commit d6d9c9d
Show file tree
Hide file tree
Showing 2 changed files with 79 additions and 4 deletions.
14 changes: 12 additions & 2 deletions media/gpu/test/video_decode_accelerator_tests.cc
Original file line number Diff line number Diff line change
Expand Up @@ -304,8 +304,18 @@ TEST_F(VideoDecoderTest, GetSupportedConfigs) {
#else
media::VideoDecoderType::kUnknown;
#endif
ASSERT_TRUE(VideoDecoderPipeline::GetSupportedConfigs(
decoder_type, gpu::GpuDriverBugWorkarounds()));
const auto supported_configs = VideoDecoderPipeline::GetSupportedConfigs(
decoder_type, gpu::GpuDriverBugWorkarounds());
ASSERT_FALSE(supported_configs->empty());

const bool contains_h264 =
std::find_if(supported_configs->begin(), supported_configs->end(),
[](SupportedVideoDecoderConfig config) {
return config.profile_min >= H264PROFILE_MIN &&
config.profile_max <= H264PROFILE_MAX;
}) != supported_configs->end();
// Every hardware video decoder in ChromeOS supports some kind of H.264.
EXPECT_TRUE(contains_h264);
}
#endif // BUILDFLAG(USE_CHROMEOS_MEDIA_ACCELERATION)

Expand Down
69 changes: 67 additions & 2 deletions media/gpu/v4l2/v4l2_stateful_video_decoder.cc
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,22 @@

#include "media/gpu/v4l2/v4l2_stateful_video_decoder.h"

#include <fcntl.h>
#include <sys/ioctl.h>

#include "base/files/file_util.h"
#include "base/memory/ptr_util.h"
#include "base/posix/eintr_wrapper.h"
#include "media/base/media_log.h"
#include "media/gpu/macros.h"
#include "media/gpu/v4l2/v4l2_utils.h"
#include "ui/gfx/geometry/size.h"

namespace {
int HandledIoctl(int fd, int request, void* arg) {
return HANDLE_EINTR(ioctl(fd, request, arg));
}
} // namespace

namespace media {

Expand All @@ -25,8 +38,60 @@ std::unique_ptr<VideoDecoderMixin> V4L2StatefulVideoDecoder::Create(
// static
absl::optional<SupportedVideoDecoderConfigs>
V4L2StatefulVideoDecoder::GetSupportedConfigs() {
NOTIMPLEMENTED();
return absl::nullopt;
SupportedVideoDecoderConfigs supported_media_configs;

constexpr char kVideoDeviceDriverPath[] = "/dev/video-dec0";
CHECK(base::PathExists(base::FilePath(kVideoDeviceDriverPath)));

base::ScopedFD device_fd(HANDLE_EINTR(
open(kVideoDeviceDriverPath, O_RDWR | O_NONBLOCK | O_CLOEXEC)));
if (!device_fd.is_valid()) {
return absl::nullopt;
}

std::vector<uint32_t> v4l2_codecs = EnumerateSupportedPixFmts(
base::BindRepeating(&HandledIoctl, device_fd.get()),
V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);

// V4L2 stateful formats (don't end up with _SLICE or _FRAME) supported.
constexpr std::array<uint32_t, 4> kSupportedInputCodecs = {
V4L2_PIX_FMT_H264,
#if BUILDFLAG(ENABLE_HEVC_PARSER_AND_HW_DECODER)
V4L2_PIX_FMT_HEVC,
#endif // BUILDFLAG(ENABLE_HEVC_PARSER_AND_HW_DECODER)
V4L2_PIX_FMT_VP8,
V4L2_PIX_FMT_VP9,
};
std::erase_if(v4l2_codecs, [kSupportedInputCodecs](uint32_t v4l2_codec) {
return !base::Contains(kSupportedInputCodecs, v4l2_codec);
});

for (const uint32_t v4l2_codec : v4l2_codecs) {
const std::vector<VideoCodecProfile> media_codec_profiles =
EnumerateSupportedProfilesForV4L2Codec(
base::BindRepeating(&HandledIoctl, device_fd.get()), v4l2_codec);

gfx::Size min_coded_size;
gfx::Size max_coded_size;
GetSupportedResolution(base::BindRepeating(&HandledIoctl, device_fd.get()),
v4l2_codec, &min_coded_size, &max_coded_size);

for (const auto& profile : media_codec_profiles) {
supported_media_configs.emplace_back(SupportedVideoDecoderConfig(
profile, profile, min_coded_size, max_coded_size,
/*allow_encrypted=*/false, /*require_encrypted=*/false));
}
}

#if DCHECK_IS_ON()
for (const auto& config : supported_media_configs) {
DVLOGF(3) << "Enumerated " << GetProfileName(config.profile_min) << " ("
<< config.coded_size_min.ToString() << "-"
<< config.coded_size_max.ToString() << ")";
}
#endif

return supported_media_configs;
}

void V4L2StatefulVideoDecoder::Initialize(const VideoDecoderConfig& config,
Expand Down

0 comments on commit d6d9c9d

Please sign in to comment.