libvpx: Support the vp9 extended profiles
authorLuca Barbato <lu_zero@gentoo.org>
Thu, 11 Jun 2015 14:56:31 +0000 (16:56 +0200)
committerLuca Barbato <lu_zero@gentoo.org>
Sun, 21 Jun 2015 13:27:18 +0000 (16:27 +0300)
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@gmail.com>
Signed-off-by: Luca Barbato <lu_zero@gentoo.org>
Changelog
configure
libavcodec/avcodec.h
libavcodec/libvpx.c
libavcodec/libvpx.h
libavcodec/libvpxdec.c
libavcodec/libvpxenc.c
libavcodec/version.h

index 0628666..5d37006 100644 (file)
--- 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:
index b10715f..90e5787 100755 (executable)
--- 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 &&
index 7edea2c..e82867e 100644 (file)
@@ -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
index 20f4484..4cc050d 100644 (file)
 
 #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;
 }
index cb1ed09..b990b76 100644 (file)
@@ -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 */
index 6052207..47c8067 100644 (file)
@@ -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);
 }
 
index 0f4bd61..f690de1 100644 (file)
@@ -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,
 };
index 6105a63..53f5f97 100644 (file)
@@ -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, \