// 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. // Note: ported from Chromium commit head: 27c98933749f #include "fourcc.h" #include #include "base/logging.h" #include "base/strings/stringprintf.h" #include "macros.h" namespace media { Fourcc::Fourcc(Fourcc::Value fourcc) : value_(fourcc) {} Fourcc::~Fourcc() = default; Fourcc& Fourcc::operator=(const Fourcc& other) = default; // static base::Optional Fourcc::FromUint32(uint32_t fourcc) { switch (fourcc) { case AR24: case AB24: case XR24: case XB24: case RGB4: case YU12: case YV12: case YM12: case YM21: case YUYV: case NV12: case NV21: case NM12: case NM21: case YM16: case MT21: case MM21: return Fourcc(static_cast(fourcc)); } DVLOGF(3) << "Unmapped fourcc: " << FourccToString(fourcc); return base::nullopt; } // static base::Optional Fourcc::FromVideoPixelFormat( VideoPixelFormat pixel_format, bool single_planar) { if (single_planar) { switch (pixel_format) { case PIXEL_FORMAT_ARGB: return Fourcc(AR24); case PIXEL_FORMAT_ABGR: return Fourcc(AB24); case PIXEL_FORMAT_XRGB: return Fourcc(XR24); case PIXEL_FORMAT_XBGR: return Fourcc(XB24); case PIXEL_FORMAT_BGRA: return Fourcc(RGB4); case PIXEL_FORMAT_I420: return Fourcc(YU12); case PIXEL_FORMAT_YV12: return Fourcc(YV12); case PIXEL_FORMAT_YUY2: return Fourcc(YUYV); case PIXEL_FORMAT_NV12: return Fourcc(NV12); case PIXEL_FORMAT_NV21: return Fourcc(NV21); case PIXEL_FORMAT_I422: case PIXEL_FORMAT_I420A: case PIXEL_FORMAT_I444: case PIXEL_FORMAT_RGB24: case PIXEL_FORMAT_MJPEG: case PIXEL_FORMAT_YUV420P9: case PIXEL_FORMAT_YUV420P10: case PIXEL_FORMAT_YUV422P9: case PIXEL_FORMAT_YUV422P10: case PIXEL_FORMAT_YUV444P9: case PIXEL_FORMAT_YUV444P10: case PIXEL_FORMAT_YUV420P12: case PIXEL_FORMAT_YUV422P12: case PIXEL_FORMAT_YUV444P12: case PIXEL_FORMAT_Y16: case PIXEL_FORMAT_P016LE: case PIXEL_FORMAT_XR30: case PIXEL_FORMAT_XB30: case PIXEL_FORMAT_UNKNOWN: break; } } else { switch (pixel_format) { case PIXEL_FORMAT_I420: return Fourcc(YM12); case PIXEL_FORMAT_YV12: return Fourcc(YM21); case PIXEL_FORMAT_NV12: return Fourcc(NM12); case PIXEL_FORMAT_I422: return Fourcc(YM16); case PIXEL_FORMAT_NV21: return Fourcc(NM21); case PIXEL_FORMAT_I420A: case PIXEL_FORMAT_I444: case PIXEL_FORMAT_YUY2: case PIXEL_FORMAT_ARGB: case PIXEL_FORMAT_XRGB: case PIXEL_FORMAT_RGB24: case PIXEL_FORMAT_MJPEG: case PIXEL_FORMAT_YUV420P9: case PIXEL_FORMAT_YUV420P10: case PIXEL_FORMAT_YUV422P9: case PIXEL_FORMAT_YUV422P10: case PIXEL_FORMAT_YUV444P9: case PIXEL_FORMAT_YUV444P10: case PIXEL_FORMAT_YUV420P12: case PIXEL_FORMAT_YUV422P12: case PIXEL_FORMAT_YUV444P12: case PIXEL_FORMAT_Y16: case PIXEL_FORMAT_ABGR: case PIXEL_FORMAT_XBGR: case PIXEL_FORMAT_P016LE: case PIXEL_FORMAT_XR30: case PIXEL_FORMAT_XB30: case PIXEL_FORMAT_BGRA: case PIXEL_FORMAT_UNKNOWN: break; } } DVLOGF(3) << "Unmapped " << VideoPixelFormatToString(pixel_format) << " for " << (single_planar ? "single-planar" : "multi-planar"); return base::nullopt; } VideoPixelFormat Fourcc::ToVideoPixelFormat() const { switch (value_) { case AR24: return PIXEL_FORMAT_ARGB; case AB24: return PIXEL_FORMAT_ABGR; case XR24: return PIXEL_FORMAT_XRGB; case XB24: return PIXEL_FORMAT_XBGR; case RGB4: return PIXEL_FORMAT_BGRA; case YU12: case YM12: return PIXEL_FORMAT_I420; case YV12: case YM21: return PIXEL_FORMAT_YV12; case YUYV: return PIXEL_FORMAT_YUY2; case NV12: case NM12: return PIXEL_FORMAT_NV12; case NV21: case NM21: return PIXEL_FORMAT_NV21; case YM16: return PIXEL_FORMAT_I422; // V4L2_PIX_FMT_MT21C is only used for MT8173 hardware video decoder output // and should be converted by MT8173 image processor for compositor to // render. Since it is an intermediate format for video decoder, // VideoPixelFormat shall not have its mapping. However, we need to create a // VideoFrameLayout for the format to process the intermediate frame. Hence // we map V4L2_PIX_FMT_MT21C to PIXEL_FORMAT_NV12 as their layout are the // same. case MT21: // V4L2_PIX_FMT_MM21 is used for MT8183 hardware video decoder. It is // similar to V4L2_PIX_FMT_MT21C but is not compressed ; thus it can also // be mapped to PIXEL_FORMAT_NV12. case MM21: return PIXEL_FORMAT_NV12; } NOTREACHED() << "Unmapped Fourcc: " << ToString(); return PIXEL_FORMAT_UNKNOWN; } // static base::Optional Fourcc::FromV4L2PixFmt(uint32_t v4l2_pix_fmt) { // We can do that because we adopt the same internal definition of Fourcc as // V4L2. return FromUint32(v4l2_pix_fmt); } uint32_t Fourcc::ToV4L2PixFmt() const { // Note that we can do that because we adopt the same internal definition of // Fourcc as V4L2. return static_cast(value_); } base::Optional Fourcc::ToSinglePlanar() const { switch (value_) { case AR24: case AB24: case XR24: case XB24: case RGB4: case YU12: case YV12: case YUYV: case NV12: case NV21: return Fourcc(value_); case YM12: return Fourcc(YU12); case YM21: return Fourcc(YV12); case NM12: return Fourcc(NV12); case NM21: return Fourcc(NV21); case YM16: case MT21: case MM21: return base::nullopt; } } bool operator!=(const Fourcc& lhs, const Fourcc& rhs) { return !(lhs == rhs); } bool Fourcc::IsMultiPlanar() const { switch (value_) { case AR24: case AB24: case XR24: case XB24: case RGB4: case YU12: case YV12: case YUYV: case NV12: case NV21: return false; case YM12: case YM21: case NM12: case NM21: case YM16: case MT21: case MM21: return true; } } std::string Fourcc::ToString() const { return FourccToString(static_cast(value_)); } static_assert(Fourcc::AR24 == V4L2_PIX_FMT_ABGR32, "Mismatch Fourcc"); #ifdef V4L2_PIX_FMT_RGBA32 // V4L2_PIX_FMT_RGBA32 is defined since v5.2 static_assert(Fourcc::AB24 == V4L2_PIX_FMT_RGBA32, "Mismatch Fourcc"); #endif // V4L2_PIX_FMT_RGBA32 static_assert(Fourcc::XR24 == V4L2_PIX_FMT_XBGR32, "Mismatch Fourcc"); #ifdef V4L2_PIX_FMT_RGBX32 // V4L2_PIX_FMT_RGBX32 is defined since v5.2 static_assert(Fourcc::XB24 == V4L2_PIX_FMT_RGBX32, "Mismatch Fourcc"); #endif // V4L2_PIX_FMT_RGBX32 static_assert(Fourcc::RGB4 == V4L2_PIX_FMT_RGB32, "Mismatch Fourcc"); static_assert(Fourcc::YU12 == V4L2_PIX_FMT_YUV420, "Mismatch Fourcc"); static_assert(Fourcc::YV12 == V4L2_PIX_FMT_YVU420, "Mismatch Fourcc"); static_assert(Fourcc::YM12 == V4L2_PIX_FMT_YUV420M, "Mismatch Fourcc"); static_assert(Fourcc::YM21 == V4L2_PIX_FMT_YVU420M, "Mismatch Fourcc"); static_assert(Fourcc::YUYV == V4L2_PIX_FMT_YUYV, "Mismatch Fourcc"); static_assert(Fourcc::NV12 == V4L2_PIX_FMT_NV12, "Mismatch Fourcc"); static_assert(Fourcc::NV21 == V4L2_PIX_FMT_NV21, "Mismatch Fourcc"); static_assert(Fourcc::NM12 == V4L2_PIX_FMT_NV12M, "Mismatch Fourcc"); static_assert(Fourcc::NM21 == V4L2_PIX_FMT_NV21M, "Mismatch Fourcc"); static_assert(Fourcc::YM16 == V4L2_PIX_FMT_YUV422M, "Mismatch Fourcc"); static_assert(Fourcc::MT21 == V4L2_PIX_FMT_MT21C, "Mismatch Fourcc"); #ifdef V4L2_PIX_FMT_MM21 // V4L2_PIX_FMT_MM21 is not yet upstreamed. static_assert(Fourcc::MM21 == V4L2_PIX_FMT_MM21, "Mismatch Fourcc"); #endif // V4L2_PIX_FMT_MM21 } // namespace media