[FFmpeg-cvslog] libvpx: Support the vp9 extended profiles

Luca Barbato git at videolan.org
Sun Jun 21 23:07:21 CEST 2015


ffmpeg | branch: master | Luca Barbato <lu_zero at gentoo.org> | Thu Jun 11 16:56:31 2015 +0200| [8655c54160767de1a6b96f8bc310d6e4eaceff48] | committer: Luca Barbato

libvpx: Support the vp9 extended profiles

Bump the minimum libvpx version to 1.3.0 and rework the configure logic
to fail only if no decoders and encoders are found.

Based on the original patch from Vittorio.

Signed-off-by: Vittorio Giovara <vittorio.giovara at gmail.com>
Signed-off-by: Luca Barbato <lu_zero at gentoo.org>

> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=8655c54160767de1a6b96f8bc310d6e4eaceff48
---

 Changelog              |    1 +
 configure              |   28 ++++++++++++++++------
 libavcodec/avcodec.h   |    4 ++++
 libavcodec/libvpx.c    |   60 +++++++++++++++++++++++++++++++++++++++++-------
 libavcodec/libvpx.h    |    3 ++-
 libavcodec/libvpxdec.c |    7 ++----
 libavcodec/libvpxenc.c |   36 +++++++++++++++++++++--------
 libavcodec/version.h   |    2 +-
 8 files changed, 110 insertions(+), 31 deletions(-)

diff --git a/Changelog b/Changelog
index 0628666..5d37006 100644
--- a/Changelog
+++ b/Changelog
@@ -33,6 +33,7 @@ version <next>:
 - improved Quickdraw compatibility
 - NVIDIA NVENC-accelerated H.264 and HEVC encoding support
 - Multipart JPEG demuxer
+- Support the extended vp9 profiles in the libvpx wrapper
 
 
 version 11:
diff --git a/configure b/configure
index b10715f..90e5787 100755
--- a/configure
+++ b/configure
@@ -4310,13 +4310,27 @@ enabled libtwolame        && require libtwolame twolame.h twolame_init -ltwolame
 enabled libvo_aacenc      && require libvo_aacenc vo-aacenc/voAAC.h voGetAACEncAPI -lvo-aacenc
 enabled libvo_amrwbenc    && require libvo_amrwbenc vo-amrwbenc/enc_if.h E_IF_init -lvo-amrwbenc
 enabled libvorbis         && require libvorbis vorbis/vorbisenc.h vorbis_info_init -lvorbisenc -lvorbis -logg
-enabled libvpx            && {
-    enabled libvpx_vp8_decoder && { check_lib2 "vpx/vpx_decoder.h vpx/vp8dx.h" vpx_codec_dec_init_ver -lvpx ||
-                                    die "ERROR: libvpx decoder version must be >=0.9.1"; }
-    enabled libvpx_vp8_encoder && { check_lib2 "vpx/vpx_encoder.h vpx/vp8cx.h" "vpx_codec_enc_init_ver VPX_CQ" -lvpx ||
-                                    die "ERROR: libvpx encoder version must be >=0.9.6"; }
-    enabled libvpx_vp9_decoder && { check_lib2 "vpx/vpx_decoder.h vpx/vp8dx.h" "vpx_codec_vp9_dx" -lvpx || disable libvpx_vp9_decoder; }
-    enabled libvpx_vp9_encoder && { check_lib2 "vpx/vpx_encoder.h vpx/vp8cx.h" "vpx_codec_vp9_cx" -lvpx || disable libvpx_vp9_encoder; } }
+enabled libvpx            && require_pkg_config "vpx >= 1.3.0" vpx/vpx_codec.h vpx_codec_version && {
+    enabled libvpx_vp8_decoder && {
+        check_pkg_config vpx "vpx/vpx_decoder.h vpx/vp8dx.h" vpx_codec_vp8_dx ||
+            disable libvpx_vp8_decoder;
+    }
+    enabled libvpx_vp8_encoder && {
+        check_pkg_config vpx "vpx/vpx_encoder.h vpx/vp8cx.h" vpx_codec_vp8_cx ||
+            disable libvpx_vp8_encoder;
+    }
+    enabled libvpx_vp9_decoder && {
+        check_pkg_config vpx "vpx/vpx_decoder.h vpx/vp8dx.h" vpx_codec_vp9_dx ||
+            disable libvpx_vp9_decoder;
+    }
+    enabled libvpx_vp9_encoder && {
+        check_pkg_config vpx "vpx/vpx_encoder.h vpx/vp8cx.h" vpx_codec_vp9_cx ||
+            disable libvpx_vp9_encoder;
+    }
+    if disabled_all libvpx_vp8_decoder libvpx_vp9_decoder libvpx_vp8_encoder libvpx_vp9_encoder; then
+        die "libvpx enabled but no supported decoders found"
+    fi
+}
 enabled libwavpack        && require libwavpack wavpack/wavpack.h WavpackOpenFileOutput  -lwavpack
 enabled libwebp           && require_pkg_config libwebp webp/encode.h WebPGetEncoderVersion
 enabled libx264           && require_pkg_config x264 "stdint.h x264.h" x264_encoder_encode &&
diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h
index 7edea2c..e82867e 100644
--- a/libavcodec/avcodec.h
+++ b/libavcodec/avcodec.h
@@ -2718,6 +2718,10 @@ typedef struct AVCodecContext {
 #define FF_PROFILE_JPEG2000_DCINEMA_2K              3
 #define FF_PROFILE_JPEG2000_DCINEMA_4K              4
 
+#define FF_PROFILE_VP9_0                            0
+#define FF_PROFILE_VP9_1                            1
+#define FF_PROFILE_VP9_2                            2
+#define FF_PROFILE_VP9_3                            3
 
 #define FF_PROFILE_HEVC_MAIN                        1
 #define FF_PROFILE_HEVC_MAIN_10                     2
diff --git a/libavcodec/libvpx.c b/libavcodec/libvpx.c
index 20f4484..4cc050d 100644
--- a/libavcodec/libvpx.c
+++ b/libavcodec/libvpx.c
@@ -22,14 +22,58 @@
 
 #include "libvpx.h"
 
-int ff_vp9_check_experimental(AVCodecContext *avctx)
+enum AVPixelFormat ff_vpx_imgfmt_to_pixfmt(vpx_img_fmt_t img)
 {
-    if (avctx->strict_std_compliance > FF_COMPLIANCE_EXPERIMENTAL &&
-        (vpx_codec_version_major() < 1 ||
-         (vpx_codec_version_major() == 1 && vpx_codec_version_minor() < 3))) {
-        av_log(avctx, AV_LOG_ERROR,
-               "Non-experimental support of VP9 requires libvpx >= 1.3.0\n");
-        return AVERROR_EXPERIMENTAL;
+    switch (img) {
+    case VPX_IMG_FMT_RGB24:     return AV_PIX_FMT_RGB24;
+    case VPX_IMG_FMT_RGB565:    return AV_PIX_FMT_RGB565BE;
+    case VPX_IMG_FMT_RGB555:    return AV_PIX_FMT_RGB555BE;
+    case VPX_IMG_FMT_UYVY:      return AV_PIX_FMT_UYVY422;
+    case VPX_IMG_FMT_YUY2:      return AV_PIX_FMT_YUYV422;
+    case VPX_IMG_FMT_YVYU:      return AV_PIX_FMT_YVYU422;
+    case VPX_IMG_FMT_BGR24:     return AV_PIX_FMT_BGR24;
+    case VPX_IMG_FMT_ARGB:      return AV_PIX_FMT_ARGB;
+    case VPX_IMG_FMT_ARGB_LE:   return AV_PIX_FMT_BGRA;
+    case VPX_IMG_FMT_RGB565_LE: return AV_PIX_FMT_RGB565LE;
+    case VPX_IMG_FMT_RGB555_LE: return AV_PIX_FMT_RGB555LE;
+    case VPX_IMG_FMT_I420:      return AV_PIX_FMT_YUV420P;
+    case VPX_IMG_FMT_I422:      return AV_PIX_FMT_YUV422P;
+    case VPX_IMG_FMT_I444:      return AV_PIX_FMT_YUV444P;
+    case VPX_IMG_FMT_444A:      return AV_PIX_FMT_YUVA444P;
+#ifdef VPX_IMAGE_ABI_VERSION >= 3
+    case VPX_IMG_FMT_I440:      return AV_PIX_FMT_YUV440P;
+    case VPX_IMG_FMT_I42016:    return AV_PIX_FMT_YUV420P16BE;
+    case VPX_IMG_FMT_I42216:    return AV_PIX_FMT_YUV422P16BE;
+    case VPX_IMG_FMT_I44416:    return AV_PIX_FMT_YUV444P16BE;
+#endif
+    default:                    return AV_PIX_FMT_NONE;
+    }
+}
+
+vpx_img_fmt_t ff_vpx_pixfmt_to_imgfmt(enum AVPixelFormat pix)
+{
+    switch (pix) {
+    case AV_PIX_FMT_RGB24:        return VPX_IMG_FMT_RGB24;
+    case AV_PIX_FMT_RGB565BE:     return VPX_IMG_FMT_RGB565;
+    case AV_PIX_FMT_RGB555BE:     return VPX_IMG_FMT_RGB555;
+    case AV_PIX_FMT_UYVY422:      return VPX_IMG_FMT_UYVY;
+    case AV_PIX_FMT_YUYV422:      return VPX_IMG_FMT_YUY2;
+    case AV_PIX_FMT_YVYU422:      return VPX_IMG_FMT_YVYU;
+    case AV_PIX_FMT_BGR24:        return VPX_IMG_FMT_BGR24;
+    case AV_PIX_FMT_ARGB:         return VPX_IMG_FMT_ARGB;
+    case AV_PIX_FMT_BGRA:         return VPX_IMG_FMT_ARGB_LE;
+    case AV_PIX_FMT_RGB565LE:     return VPX_IMG_FMT_RGB565_LE;
+    case AV_PIX_FMT_RGB555LE:     return VPX_IMG_FMT_RGB555_LE;
+    case AV_PIX_FMT_YUV420P:      return VPX_IMG_FMT_I420;
+    case AV_PIX_FMT_YUV422P:      return VPX_IMG_FMT_I422;
+    case AV_PIX_FMT_YUV444P:      return VPX_IMG_FMT_I444;
+    case AV_PIX_FMT_YUVA444P:     return VPX_IMG_FMT_444A;
+#ifdef VPX_IMAGE_ABI_VERSION >= 3
+    case AV_PIX_FMT_YUV440P:      return VPX_IMG_FMT_I440;
+    case AV_PIX_FMT_YUV420P16BE:  return VPX_IMG_FMT_I42016;
+    case AV_PIX_FMT_YUV422P16BE:  return VPX_IMG_FMT_I42216;
+    case AV_PIX_FMT_YUV444P16BE:  return VPX_IMG_FMT_I44416;
+#endif
+    default:                      return VPX_IMG_FMT_NONE;
     }
-    return 0;
 }
diff --git a/libavcodec/libvpx.h b/libavcodec/libvpx.h
index cb1ed09..b990b76 100644
--- a/libavcodec/libvpx.h
+++ b/libavcodec/libvpx.h
@@ -23,6 +23,7 @@
 
 #include "avcodec.h"
 
-int ff_vp9_check_experimental(AVCodecContext *avctx);
+enum AVPixelFormat ff_vpx_imgfmt_to_pixfmt(vpx_img_fmt_t img);
+vpx_img_fmt_t ff_vpx_pixfmt_to_imgfmt(enum AVPixelFormat pix);
 
 #endif /* AVCODEC_LIBVPX_H */
diff --git a/libavcodec/libvpxdec.c b/libavcodec/libvpxdec.c
index 6052207..47c8067 100644
--- a/libavcodec/libvpxdec.c
+++ b/libavcodec/libvpxdec.c
@@ -56,7 +56,6 @@ static av_cold int vpx_init(AVCodecContext *avctx,
         return AVERROR(EINVAL);
     }
 
-    avctx->pix_fmt = AV_PIX_FMT_YUV420P;
     return 0;
 }
 
@@ -82,7 +81,8 @@ static int vp8_decode(AVCodecContext *avctx,
     }
 
     if ((img = vpx_codec_get_frame(&ctx->decoder, &iter))) {
-        if (img->fmt != VPX_IMG_FMT_I420) {
+        avctx->pix_fmt = ff_vpx_imgfmt_to_pixfmt(img->fmt);
+        if (avctx->pix_fmt == AV_PIX_FMT_NONE) {
             av_log(avctx, AV_LOG_ERROR, "Unsupported output colorspace (%d)\n",
                    img->fmt);
             return AVERROR_INVALIDDATA;
@@ -133,9 +133,6 @@ AVCodec ff_libvpx_vp8_decoder = {
 #if CONFIG_LIBVPX_VP9_DECODER
 static av_cold int vp9_init(AVCodecContext *avctx)
 {
-    int ret;
-    if ((ret = ff_vp9_check_experimental(avctx)))
-        return ret;
     return vpx_init(avctx, &vpx_codec_vp9_dx_algo);
 }
 
diff --git a/libavcodec/libvpxenc.c b/libavcodec/libvpxenc.c
index 0f4bd61..f690de1 100644
--- a/libavcodec/libvpxenc.c
+++ b/libavcodec/libvpxenc.c
@@ -220,7 +220,7 @@ static av_cold int vpx_init(AVCodecContext *avctx,
                             const struct vpx_codec_iface *iface)
 {
     VP8Context *ctx = avctx->priv_data;
-    struct vpx_codec_enc_cfg enccfg;
+    struct vpx_codec_enc_cfg enccfg = { 0 };
     int res;
 
     av_log(avctx, AV_LOG_INFO, "%s\n", vpx_codec_version_str());
@@ -321,8 +321,12 @@ static av_cold int vpx_init(AVCodecContext *avctx,
     /* 0-3: For non-zero values the encoder increasingly optimizes for reduced
        complexity playback on low powered devices at the expense of encode
        quality. */
-   if (avctx->profile != FF_PROFILE_UNKNOWN)
-       enccfg.g_profile = avctx->profile;
+    if (avctx->profile != FF_PROFILE_UNKNOWN)
+        enccfg.g_profile = avctx->profile;
+    else if (avctx->pix_fmt == AV_PIX_FMT_YUV420P)
+        avctx->profile = enccfg.g_profile = FF_PROFILE_VP9_0;
+    else
+        avctx->profile = enccfg.g_profile = FF_PROFILE_VP9_1;
 
     enccfg.g_error_resilient = ctx->error_resilient;
 
@@ -364,8 +368,8 @@ static av_cold int vpx_init(AVCodecContext *avctx,
     codecctl_int(avctx, VP8E_SET_CQ_LEVEL,          ctx->crf);
 
     //provide dummy value to initialize wrapper, values will be updated each _encode()
-    vpx_img_wrap(&ctx->rawimg, VPX_IMG_FMT_I420, avctx->width, avctx->height, 1,
-                 (unsigned char*)1);
+    vpx_img_wrap(&ctx->rawimg, ff_vpx_pixfmt_to_imgfmt(avctx->pix_fmt),
+                 avctx->width, avctx->height, 1, (unsigned char *)1);
 
     avctx->coded_frame = av_frame_alloc();
     if (!avctx->coded_frame) {
@@ -623,9 +627,6 @@ AVCodec ff_libvpx_vp8_encoder = {
 #if CONFIG_LIBVPX_VP9_ENCODER
 static av_cold int vp9_init(AVCodecContext *avctx)
 {
-    int ret;
-    if ((ret = ff_vp9_check_experimental(avctx)))
-        return ret;
     return vpx_init(avctx, &vpx_codec_vp9_cx_algo);
 }
 
@@ -636,6 +637,14 @@ static const AVClass class_vp9 = {
     .version    = LIBAVUTIL_VERSION_INT,
 };
 
+static const AVProfile profiles[] = {
+    { FF_PROFILE_VP9_0, "Profile 0" },
+    { FF_PROFILE_VP9_1, "Profile 1" },
+    { FF_PROFILE_VP9_2, "Profile 2" },
+    { FF_PROFILE_VP9_3, "Profile 3" },
+    { FF_PROFILE_UNKNOWN },
+};
+
 AVCodec ff_libvpx_vp9_encoder = {
     .name           = "libvpx-vp9",
     .long_name      = NULL_IF_CONFIG_SMALL("libvpx VP9"),
@@ -646,7 +655,16 @@ AVCodec ff_libvpx_vp9_encoder = {
     .encode2        = vp8_encode,
     .close          = vp8_free,
     .capabilities   = CODEC_CAP_DELAY | CODEC_CAP_AUTO_THREADS,
-    .pix_fmts       = (const enum AVPixelFormat[]){ AV_PIX_FMT_YUV420P, AV_PIX_FMT_NONE },
+    .pix_fmts       = (const enum AVPixelFormat[]) {
+        AV_PIX_FMT_YUV420P,
+#if VPX_IMAGE_ABI_VERSION >= 3
+        AV_PIX_FMT_YUV422P,
+        AV_PIX_FMT_YUV444P,
+        AV_PIX_FMT_YUV440P,
+#endif
+        AV_PIX_FMT_NONE,
+    },
+    .profiles       = NULL_IF_CONFIG_SMALL(profiles),
     .priv_class     = &class_vp9,
     .defaults       = defaults,
 };
diff --git a/libavcodec/version.h b/libavcodec/version.h
index 6105a63..53f5f97 100644
--- a/libavcodec/version.h
+++ b/libavcodec/version.h
@@ -30,7 +30,7 @@
 
 #define LIBAVCODEC_VERSION_MAJOR 56
 #define LIBAVCODEC_VERSION_MINOR 26
-#define LIBAVCODEC_VERSION_MICRO  0
+#define LIBAVCODEC_VERSION_MICRO  1
 
 #define LIBAVCODEC_VERSION_INT  AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \
                                                LIBAVCODEC_VERSION_MINOR, \



More information about the ffmpeg-cvslog mailing list