diff options
author | Chih-Yu Huang <akahuang@google.com> | 2021-05-11 16:10:12 +0900 |
---|---|---|
committer | Chih-Yu Huang <akahuang@google.com> | 2021-05-12 11:53:19 +0900 |
commit | a214d9a91854b1d144348f601c8103e961adbc99 (patch) | |
tree | 7951145509068d268b8fff7fc02070154ebf0501 /components/V4L2Decoder.cpp | |
parent | e2fc88c05cb1c2cf08feac473a9747aa9270caa8 (diff) | |
download | v4l2_codec2-android12-dev.tar.gz |
V4L2Decoder: setup the output pixel format when resolution changeandroid-12.0.0_r32android-12.0.0_r29android-12.0.0_r28android-12.0.0_r27android-12.0.0_r26android-12.0.0_r21android-12.0.0_r20android-12.0.0_r19android-12.0.0_r18android-12.0.0_r16android12-qpr1-releaseandroid12-qpr1-d-s3-releaseandroid12-qpr1-d-s2-releaseandroid12-qpr1-d-s1-releaseandroid12-qpr1-d-releaseandroid12-dev
This CL setups the supported pixel format when resolution change.
Currently the supported pixel format is flexible 420 format.
Bug: 170199771
Test: android.media.cts.AdaptivePlaybackTest
Change-Id: Ic1b8f5c23fa5ff14c5dba026e0d927df092a6351
Diffstat (limited to 'components/V4L2Decoder.cpp')
-rw-r--r-- | components/V4L2Decoder.cpp | 41 |
1 files changed, 38 insertions, 3 deletions
diff --git a/components/V4L2Decoder.cpp b/components/V4L2Decoder.cpp index 9c6d42b..d694837 100644 --- a/components/V4L2Decoder.cpp +++ b/components/V4L2Decoder.cpp @@ -17,6 +17,7 @@ #include <log/log.h> #include <v4l2_codec2/common/Common.h> +#include <v4l2_codec2/common/Fourcc.h> namespace android { namespace { @@ -25,6 +26,13 @@ constexpr size_t kNumInputBuffers = 16; // Extra buffers for transmitting in the whole video pipeline. constexpr size_t kNumExtraOutputBuffers = 4; +// Currently we only support flexible pixel 420 format YCBCR_420_888 in Android. +// Here is the list of flexible 420 format. +constexpr std::initializer_list<uint32_t> kSupportedOutputFourccs = { + Fourcc::YU12, Fourcc::YV12, Fourcc::YM12, Fourcc::YM21, + Fourcc::NV12, Fourcc::NV21, Fourcc::NM12, Fourcc::NM21, +}; + uint32_t VideoCodecToV4L2PixFmt(VideoCodec codec) { switch (codec) { case VideoCodec::H264: @@ -483,13 +491,22 @@ bool V4L2Decoder::changeResolution() { ALOGV("%s()", __func__); ALOG_ASSERT(mTaskRunner->RunsTasksInCurrentSequence()); - std::optional<struct v4l2_format> format = getFormatInfo(); + const std::optional<struct v4l2_format> format = getFormatInfo(); std::optional<size_t> numOutputBuffers = getNumOutputBuffers(); if (!format || !numOutputBuffers) { return false; } - mCodedSize.set(format->fmt.pix_mp.width, format->fmt.pix_mp.height); + const ui::Size codedSize(format->fmt.pix_mp.width, format->fmt.pix_mp.height); + if (!setupOutputFormat(codedSize)) { + return false; + } + + const std::optional<struct v4l2_format> adjustedFormat = getFormatInfo(); + if (!adjustedFormat) { + return false; + } + mCodedSize.set(adjustedFormat->fmt.pix_mp.width, adjustedFormat->fmt.pix_mp.height); mVisibleRect = getVisibleRect(mCodedSize); ALOGI("Need %zu output buffers. coded size: %s, visible rect: %s", *numOutputBuffers, @@ -516,7 +533,7 @@ bool V4L2Decoder::changeResolution() { // Release the previous VideoFramePool before getting a new one to guarantee only one pool // exists at the same time. mVideoFramePool.reset(); - // Always use fexible pixel 420 format YCBCR_420_888 in Android. + // Always use flexible pixel 420 format YCBCR_420_888 in Android. mVideoFramePool = mGetPoolCb.Run(mCodedSize, HalPixelFormat::YCBCR_420_888, *numOutputBuffers); if (!mVideoFramePool) { ALOGE("Failed to get block pool with size: %s", toString(mCodedSize).c_str()); @@ -527,6 +544,24 @@ bool V4L2Decoder::changeResolution() { return true; } +bool V4L2Decoder::setupOutputFormat(const ui::Size& size) { + for (const uint32_t& pixfmt : + mDevice->enumerateSupportedPixelformats(V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)) { + if (std::find(kSupportedOutputFourccs.begin(), kSupportedOutputFourccs.end(), pixfmt) == + kSupportedOutputFourccs.end()) { + ALOGD("Pixel format %s is not supported, skipping...", fourccToString(pixfmt).c_str()); + continue; + } + + if (mOutputQueue->setFormat(pixfmt, size, 0) != std::nullopt) { + return true; + } + } + + ALOGE("Failed to find supported pixel format"); + return false; +} + void V4L2Decoder::tryFetchVideoFrame() { ALOGV("%s()", __func__); ALOG_ASSERT(mTaskRunner->RunsTasksInCurrentSequence()); |