Commit 8655c541 authored by Luca Barbato's avatar 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: 's avatarVittorio Giovara <vittorio.giovara@gmail.com>
Signed-off-by: 's avatarLuca Barbato <lu_zero@gentoo.org>
parent 05bf3f54
......@@ -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:
......
......@@ -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 &&
......
......@@ -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
......
......@@ -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;
}
......@@ -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 */
......@@ -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);
}
......
......@@ -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,
};
......
......@@ -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, \
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment