diff options
author | Chih-Yu Huang <akahuang@google.com> | 2021-05-12 05:54:58 +0000 |
---|---|---|
committer | Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com> | 2021-05-12 05:54:58 +0000 |
commit | f37e5b4b16135f90a8dfc0a1db415448ffa9e5a2 (patch) | |
tree | 7951145509068d268b8fff7fc02070154ebf0501 | |
parent | 1627d9a85e24ee569d137693b8687b1a6b99d8f0 (diff) | |
parent | a214d9a91854b1d144348f601c8103e961adbc99 (diff) | |
download | v4l2_codec2-android12-mainline-art-release.tar.gz |
V4L2Decoder: setup the output pixel format when resolution change am: a214d9a918android-mainline-12.0.0_r99android-mainline-12.0.0_r98android-mainline-12.0.0_r77android-mainline-12.0.0_r70android-mainline-12.0.0_r69android-mainline-12.0.0_r63android-mainline-12.0.0_r59android-mainline-12.0.0_r56android-mainline-12.0.0_r5android-mainline-12.0.0_r49android-mainline-12.0.0_r42android-mainline-12.0.0_r39android-mainline-12.0.0_r22android-mainline-12.0.0_r19android-mainline-12.0.0_r122android-mainline-12.0.0_r115android-mainline-12.0.0_r113android-mainline-12.0.0_r100aml_tz3_311312010android12-mainline-networkstack-releaseandroid12-mainline-art-release
Original change: https://googleplex-android-review.googlesource.com/c/platform/external/v4l2_codec2/+/14511941
Change-Id: I3d8d5af15548a9220da725bc3354eb7e8eaebc1d
-rw-r--r-- | components/V4L2Decoder.cpp | 41 | ||||
-rw-r--r-- | components/include/v4l2_codec2/components/V4L2Decoder.h | 1 |
2 files changed, 39 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()); diff --git a/components/include/v4l2_codec2/components/V4L2Decoder.h b/components/include/v4l2_codec2/components/V4L2Decoder.h index de985a3..b65bd49 100644 --- a/components/include/v4l2_codec2/components/V4L2Decoder.h +++ b/components/include/v4l2_codec2/components/V4L2Decoder.h @@ -63,6 +63,7 @@ private: void serviceDeviceTask(bool event); bool dequeueResolutionChangeEvent(); bool changeResolution(); + bool setupOutputFormat(const ui::Size& size); void tryFetchVideoFrame(); void onVideoFrameReady(std::optional<VideoFramePool::FrameWithBlockId> frameWithBlockId); |