Commit 94c20de4 authored by Gopu Govindaswamy's avatar Gopu Govindaswamy Committed by Derek Buitenhuis

avcodec/libx265: use x265 Multi-library Interface to query the API

ffmpeg can now use the x265 multi-library interface to make a runtime
selection between a number of libx265 libraries (perhaps 8bpp and 16bpp).

ffmpeg will link to one build of libx265 (statically or
dynamically) and this linked version of libx265 will support one
bit-depth (8 or 10 bits). At runtime, ffmpeg now has the option to request the
encoder to use a different bit depth(8 or 10). If the requested bitdepth
is zero, or if it matches the bitdepth of the system default libx265 (the
currently linked library), then this library will be used for encode.
If ffmpeg requests a different bit-depth, the linked libx265 will attempt
to dynamically bind a shared library with the requested bit-depth from the install
location (default or user-specified).

new x265 API:
     const x265_api* api = x265_api_get(int bitDepth);
     x265_api - holds the libx265 public API functions
     bitDepth - requested API for 8bpp or 16bpp

     note: Use 0 to indicate native bit depth of the linked libx265 and
           x265_api_get(0) is guaranteed to return a non-null pointer
Signed-off-by: 's avatarGopu Govindaswamy <gopu@multicorewareinc.com>
Signed-off-by: 's avatarDerek Buitenhuis <derek.buitenhuis@gmail.com>
parent ab6dc863
...@@ -5110,8 +5110,8 @@ enabled libx264 && { use_pkg_config x264 "stdint.h x264.h" x264_encode ...@@ -5110,8 +5110,8 @@ enabled libx264 && { use_pkg_config x264 "stdint.h x264.h" x264_encode
{ check_cpp_condition x264.h "X264_BUILD >= 118" || { check_cpp_condition x264.h "X264_BUILD >= 118" ||
die "ERROR: libx264 must be installed and version must be >= 0.118."; } die "ERROR: libx264 must be installed and version must be >= 0.118."; }
enabled libx265 && require_pkg_config x265 x265.h x265_encoder_encode && enabled libx265 && require_pkg_config x265 x265.h x265_encoder_encode &&
{ check_cpp_condition x265.h "X265_BUILD >= 17" || { check_cpp_condition x265.h "X265_BUILD >= 57" ||
die "ERROR: libx265 version must be >= 17."; } die "ERROR: libx265 version must be >= 57."; }
enabled libxavs && require libxavs xavs.h xavs_encoder_encode -lxavs enabled libxavs && require libxavs xavs.h xavs_encoder_encode -lxavs
enabled libxvid && require libxvid xvid.h xvid_global -lxvidcore enabled libxvid && require libxvid xvid.h xvid_global -lxvidcore
enabled libzmq && require_pkg_config libzmq zmq.h zmq_ctx_new enabled libzmq && require_pkg_config libzmq zmq.h zmq_ctx_new
......
...@@ -39,6 +39,7 @@ typedef struct libx265Context { ...@@ -39,6 +39,7 @@ typedef struct libx265Context {
x265_encoder *encoder; x265_encoder *encoder;
x265_param *params; x265_param *params;
const x265_api *api;
float crf; float crf;
char *preset; char *preset;
...@@ -67,10 +68,10 @@ static av_cold int libx265_encode_close(AVCodecContext *avctx) ...@@ -67,10 +68,10 @@ static av_cold int libx265_encode_close(AVCodecContext *avctx)
av_frame_free(&avctx->coded_frame); av_frame_free(&avctx->coded_frame);
x265_param_free(ctx->params); ctx->api->param_free(ctx->params);
if (ctx->encoder) if (ctx->encoder)
x265_encoder_close(ctx->encoder); ctx->api->encoder_close(ctx->encoder);
return 0; return 0;
} }
...@@ -79,6 +80,10 @@ static av_cold int libx265_encode_init(AVCodecContext *avctx) ...@@ -79,6 +80,10 @@ static av_cold int libx265_encode_init(AVCodecContext *avctx)
{ {
libx265Context *ctx = avctx->priv_data; libx265Context *ctx = avctx->priv_data;
ctx->api = x265_api_get(av_pix_fmt_desc_get(avctx->pix_fmt)->comp[0].depth_minus1 + 1);
if (!ctx->api)
ctx->api = x265_api_get(0);
if (avctx->strict_std_compliance > FF_COMPLIANCE_EXPERIMENTAL && if (avctx->strict_std_compliance > FF_COMPLIANCE_EXPERIMENTAL &&
!av_pix_fmt_desc_get(avctx->pix_fmt)->log2_chroma_w) { !av_pix_fmt_desc_get(avctx->pix_fmt)->log2_chroma_w) {
av_log(avctx, AV_LOG_ERROR, av_log(avctx, AV_LOG_ERROR,
...@@ -93,13 +98,13 @@ static av_cold int libx265_encode_init(AVCodecContext *avctx) ...@@ -93,13 +98,13 @@ static av_cold int libx265_encode_init(AVCodecContext *avctx)
return AVERROR(ENOMEM); return AVERROR(ENOMEM);
} }
ctx->params = x265_param_alloc(); ctx->params = ctx->api->param_alloc();
if (!ctx->params) { if (!ctx->params) {
av_log(avctx, AV_LOG_ERROR, "Could not allocate x265 param structure.\n"); av_log(avctx, AV_LOG_ERROR, "Could not allocate x265 param structure.\n");
return AVERROR(ENOMEM); return AVERROR(ENOMEM);
} }
if (x265_param_default_preset(ctx->params, ctx->preset, ctx->tune) < 0) { if (ctx->api->param_default_preset(ctx->params, ctx->preset, ctx->tune) < 0) {
int i; int i;
av_log(avctx, AV_LOG_ERROR, "Error setting preset/tune %s/%s.\n", ctx->preset, ctx->tune); av_log(avctx, AV_LOG_ERROR, "Error setting preset/tune %s/%s.\n", ctx->preset, ctx->tune);
...@@ -148,7 +153,7 @@ static av_cold int libx265_encode_init(AVCodecContext *avctx) ...@@ -148,7 +153,7 @@ static av_cold int libx265_encode_init(AVCodecContext *avctx)
avctx->sample_aspect_ratio.num, avctx->sample_aspect_ratio.num,
avctx->sample_aspect_ratio.den, 65535); avctx->sample_aspect_ratio.den, 65535);
snprintf(sar, sizeof(sar), "%d:%d", sar_num, sar_den); snprintf(sar, sizeof(sar), "%d:%d", sar_num, sar_den);
if (x265_param_parse(ctx->params, "sar", sar) == X265_PARAM_BAD_VALUE) { if (ctx->api->param_parse(ctx->params, "sar", sar) == X265_PARAM_BAD_VALUE) {
av_log(avctx, AV_LOG_ERROR, "Invalid SAR: %d:%d.\n", sar_num, sar_den); av_log(avctx, AV_LOG_ERROR, "Invalid SAR: %d:%d.\n", sar_num, sar_den);
return AVERROR_INVALIDDATA; return AVERROR_INVALIDDATA;
} }
...@@ -173,7 +178,7 @@ static av_cold int libx265_encode_init(AVCodecContext *avctx) ...@@ -173,7 +178,7 @@ static av_cold int libx265_encode_init(AVCodecContext *avctx)
char crf[6]; char crf[6];
snprintf(crf, sizeof(crf), "%2.2f", ctx->crf); snprintf(crf, sizeof(crf), "%2.2f", ctx->crf);
if (x265_param_parse(ctx->params, "crf", crf) == X265_PARAM_BAD_VALUE) { if (ctx->api->param_parse(ctx->params, "crf", crf) == X265_PARAM_BAD_VALUE) {
av_log(avctx, AV_LOG_ERROR, "Invalid crf: %2.2f.\n", ctx->crf); av_log(avctx, AV_LOG_ERROR, "Invalid crf: %2.2f.\n", ctx->crf);
return AVERROR(EINVAL); return AVERROR(EINVAL);
} }
...@@ -191,7 +196,7 @@ static av_cold int libx265_encode_init(AVCodecContext *avctx) ...@@ -191,7 +196,7 @@ static av_cold int libx265_encode_init(AVCodecContext *avctx)
if (!av_dict_parse_string(&dict, ctx->x265_opts, "=", ":", 0)) { if (!av_dict_parse_string(&dict, ctx->x265_opts, "=", ":", 0)) {
while ((en = av_dict_get(dict, "", en, AV_DICT_IGNORE_SUFFIX))) { while ((en = av_dict_get(dict, "", en, AV_DICT_IGNORE_SUFFIX))) {
int parse_ret = x265_param_parse(ctx->params, en->key, en->value); int parse_ret = ctx->api->param_parse(ctx->params, en->key, en->value);
switch (parse_ret) { switch (parse_ret) {
case X265_PARAM_BAD_NAME: case X265_PARAM_BAD_NAME:
...@@ -210,7 +215,7 @@ static av_cold int libx265_encode_init(AVCodecContext *avctx) ...@@ -210,7 +215,7 @@ static av_cold int libx265_encode_init(AVCodecContext *avctx)
} }
} }
ctx->encoder = x265_encoder_open(ctx->params); ctx->encoder = ctx->api->encoder_open(ctx->params);
if (!ctx->encoder) { if (!ctx->encoder) {
av_log(avctx, AV_LOG_ERROR, "Cannot open libx265 encoder.\n"); av_log(avctx, AV_LOG_ERROR, "Cannot open libx265 encoder.\n");
libx265_encode_close(avctx); libx265_encode_close(avctx);
...@@ -221,7 +226,7 @@ static av_cold int libx265_encode_init(AVCodecContext *avctx) ...@@ -221,7 +226,7 @@ static av_cold int libx265_encode_init(AVCodecContext *avctx)
x265_nal *nal; x265_nal *nal;
int nnal; int nnal;
avctx->extradata_size = x265_encoder_headers(ctx->encoder, &nal, &nnal); avctx->extradata_size = ctx->api->encoder_headers(ctx->encoder, &nal, &nnal);
if (avctx->extradata_size <= 0) { if (avctx->extradata_size <= 0) {
av_log(avctx, AV_LOG_ERROR, "Cannot encode headers.\n"); av_log(avctx, AV_LOG_ERROR, "Cannot encode headers.\n");
libx265_encode_close(avctx); libx265_encode_close(avctx);
...@@ -255,7 +260,7 @@ static int libx265_encode_frame(AVCodecContext *avctx, AVPacket *pkt, ...@@ -255,7 +260,7 @@ static int libx265_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
int ret; int ret;
int i; int i;
x265_picture_init(ctx->params, &x265pic); ctx->api->picture_init(ctx->params, &x265pic);
if (pic) { if (pic) {
for (i = 0; i < 3; i++) { for (i = 0; i < 3; i++) {
...@@ -272,7 +277,7 @@ static int libx265_encode_frame(AVCodecContext *avctx, AVPacket *pkt, ...@@ -272,7 +277,7 @@ static int libx265_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
X265_TYPE_AUTO; X265_TYPE_AUTO;
} }
ret = x265_encoder_encode(ctx->encoder, &nal, &nnal, ret = ctx->api->encoder_encode(ctx->encoder, &nal, &nnal,
pic ? &x265pic : NULL, &x265pic_out); pic ? &x265pic : NULL, &x265pic_out);
if (ret < 0) if (ret < 0)
return AVERROR_EXTERNAL; return AVERROR_EXTERNAL;
......
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