|
|
|
@@ -39,6 +39,7 @@ typedef struct libx265Context { |
|
|
|
|
|
|
|
x265_encoder *encoder; |
|
|
|
x265_param *params; |
|
|
|
const x265_api *api; |
|
|
|
|
|
|
|
float crf; |
|
|
|
char *preset; |
|
|
|
@@ -67,10 +68,10 @@ static av_cold int libx265_encode_close(AVCodecContext *avctx) |
|
|
|
|
|
|
|
av_frame_free(&avctx->coded_frame); |
|
|
|
|
|
|
|
x265_param_free(ctx->params); |
|
|
|
ctx->api->param_free(ctx->params); |
|
|
|
|
|
|
|
if (ctx->encoder) |
|
|
|
x265_encoder_close(ctx->encoder); |
|
|
|
ctx->api->encoder_close(ctx->encoder); |
|
|
|
|
|
|
|
return 0; |
|
|
|
} |
|
|
|
@@ -79,6 +80,10 @@ static av_cold int libx265_encode_init(AVCodecContext *avctx) |
|
|
|
{ |
|
|
|
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 && |
|
|
|
!av_pix_fmt_desc_get(avctx->pix_fmt)->log2_chroma_w) { |
|
|
|
av_log(avctx, AV_LOG_ERROR, |
|
|
|
@@ -93,13 +98,13 @@ static av_cold int libx265_encode_init(AVCodecContext *avctx) |
|
|
|
return AVERROR(ENOMEM); |
|
|
|
} |
|
|
|
|
|
|
|
ctx->params = x265_param_alloc(); |
|
|
|
ctx->params = ctx->api->param_alloc(); |
|
|
|
if (!ctx->params) { |
|
|
|
av_log(avctx, AV_LOG_ERROR, "Could not allocate x265 param structure.\n"); |
|
|
|
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; |
|
|
|
|
|
|
|
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) |
|
|
|
avctx->sample_aspect_ratio.num, |
|
|
|
avctx->sample_aspect_ratio.den, 65535); |
|
|
|
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); |
|
|
|
return AVERROR_INVALIDDATA; |
|
|
|
} |
|
|
|
@@ -173,7 +178,7 @@ static av_cold int libx265_encode_init(AVCodecContext *avctx) |
|
|
|
char crf[6]; |
|
|
|
|
|
|
|
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); |
|
|
|
return AVERROR(EINVAL); |
|
|
|
} |
|
|
|
@@ -191,7 +196,7 @@ static av_cold int libx265_encode_init(AVCodecContext *avctx) |
|
|
|
|
|
|
|
if (!av_dict_parse_string(&dict, ctx->x265_opts, "=", ":", 0)) { |
|
|
|
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) { |
|
|
|
case X265_PARAM_BAD_NAME: |
|
|
|
@@ -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) { |
|
|
|
av_log(avctx, AV_LOG_ERROR, "Cannot open libx265 encoder.\n"); |
|
|
|
libx265_encode_close(avctx); |
|
|
|
@@ -221,7 +226,7 @@ static av_cold int libx265_encode_init(AVCodecContext *avctx) |
|
|
|
x265_nal *nal; |
|
|
|
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) { |
|
|
|
av_log(avctx, AV_LOG_ERROR, "Cannot encode headers.\n"); |
|
|
|
libx265_encode_close(avctx); |
|
|
|
@@ -255,7 +260,7 @@ static int libx265_encode_frame(AVCodecContext *avctx, AVPacket *pkt, |
|
|
|
int ret; |
|
|
|
int i; |
|
|
|
|
|
|
|
x265_picture_init(ctx->params, &x265pic); |
|
|
|
ctx->api->picture_init(ctx->params, &x265pic); |
|
|
|
|
|
|
|
if (pic) { |
|
|
|
for (i = 0; i < 3; i++) { |
|
|
|
@@ -272,8 +277,8 @@ static int libx265_encode_frame(AVCodecContext *avctx, AVPacket *pkt, |
|
|
|
X265_TYPE_AUTO; |
|
|
|
} |
|
|
|
|
|
|
|
ret = x265_encoder_encode(ctx->encoder, &nal, &nnal, |
|
|
|
pic ? &x265pic : NULL, &x265pic_out); |
|
|
|
ret = ctx->api->encoder_encode(ctx->encoder, &nal, &nnal, |
|
|
|
pic ? &x265pic : NULL, &x265pic_out); |
|
|
|
if (ret < 0) |
|
|
|
return AVERROR_UNKNOWN; |
|
|
|
|
|
|
|
|