X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavcodec%2Flibx265.c;h=686c205b6b5fba9115f3b2320a086240f2cd1437;hb=cba716f55e79ebb2db9627c6e3e11d6fc77ae737;hp=f2e7d9232930feabf99a2677441b76f2b531f65d;hpb=3670a10c2d69dfb125ad1fe53fe8eddd9a687166;p=ffmpeg diff --git a/libavcodec/libx265.c b/libavcodec/libx265.c index f2e7d923293..686c205b6b5 100644 --- a/libavcodec/libx265.c +++ b/libavcodec/libx265.c @@ -33,6 +33,7 @@ #include "libavutil/pixdesc.h" #include "avcodec.h" #include "internal.h" +#include "packet_internal.h" typedef struct libx265Context { const AVClass *class; @@ -47,7 +48,7 @@ typedef struct libx265Context { char *preset; char *tune; char *profile; - char *x265_opts; + AVDictionary *x265_opts; /** * If the encoder does not support ROI then warn the first time we @@ -309,8 +310,8 @@ static av_cold int libx265_encode_init(AVCodecContext *avctx) if (!cpb_props) return AVERROR(ENOMEM); cpb_props->buffer_size = ctx->params->rc.vbvBufferSize * 1000; - cpb_props->max_bitrate = ctx->params->rc.vbvMaxBitrate * 1000; - cpb_props->avg_bitrate = ctx->params->rc.bitrate * 1000; + cpb_props->max_bitrate = ctx->params->rc.vbvMaxBitrate * 1000LL; + cpb_props->avg_bitrate = ctx->params->rc.bitrate * 1000LL; if (!(avctx->flags & AV_CODEC_FLAG_GLOBAL_HEADER)) ctx->params->bRepeatHeaders = 1; @@ -336,28 +337,23 @@ static av_cold int libx265_encode_init(AVCodecContext *avctx) return ret; } - if (ctx->x265_opts) { - AVDictionary *dict = NULL; + { AVDictionaryEntry *en = NULL; - - if (!av_dict_parse_string(&dict, ctx->x265_opts, "=", ":", 0)) { - while ((en = av_dict_get(dict, "", en, AV_DICT_IGNORE_SUFFIX))) { - int parse_ret = ctx->api->param_parse(ctx->params, en->key, en->value); - - switch (parse_ret) { - case X265_PARAM_BAD_NAME: - av_log(avctx, AV_LOG_WARNING, - "Unknown option: %s.\n", en->key); - break; - case X265_PARAM_BAD_VALUE: - av_log(avctx, AV_LOG_WARNING, - "Invalid value for %s: %s.\n", en->key, en->value); - break; - default: - break; - } + while ((en = av_dict_get(ctx->x265_opts, "", en, AV_DICT_IGNORE_SUFFIX))) { + int parse_ret = ctx->api->param_parse(ctx->params, en->key, en->value); + + switch (parse_ret) { + case X265_PARAM_BAD_NAME: + av_log(avctx, AV_LOG_WARNING, + "Unknown option: %s.\n", en->key); + break; + case X265_PARAM_BAD_VALUE: + av_log(avctx, AV_LOG_WARNING, + "Invalid value for %s: %s.\n", en->key, en->value); + break; + default: + break; } - av_dict_free(&dict); } } @@ -405,6 +401,7 @@ static av_cold int libx265_encode_init(AVCodecContext *avctx) } memcpy(avctx->extradata, nal[0].payload, avctx->extradata_size); + memset(avctx->extradata + avctx->extradata_size, 0, AV_INPUT_BUFFER_PADDING_SIZE); } return 0; @@ -508,6 +505,16 @@ static int libx265_encode_frame(AVCodecContext *avctx, AVPacket *pkt, ret = libx265_encode_set_roi(ctx, pic, &x265pic); if (ret < 0) return ret; + + if (pic->reordered_opaque) { + x265pic.userData = av_malloc(sizeof(pic->reordered_opaque)); + if (!x265pic.userData) { + av_freep(&x265pic.quantOffsets); + return AVERROR(ENOMEM); + } + + memcpy(x265pic.userData, &pic->reordered_opaque, sizeof(pic->reordered_opaque)); + } } ret = ctx->api->encoder_encode(ctx->encoder, &nal, &nnal, @@ -554,6 +561,9 @@ static int libx265_encode_frame(AVCodecContext *avctx, AVPacket *pkt, case X265_TYPE_BREF: pict_type = AV_PICTURE_TYPE_B; break; + default: + av_log(avctx, AV_LOG_ERROR, "Unknown picture type encountered.\n"); + return AVERROR_EXTERNAL; } #if FF_API_CODED_FRAME @@ -571,6 +581,12 @@ FF_ENABLE_DEPRECATION_WARNINGS ff_side_data_set_encoder_stats(pkt, x265pic_out.frameData.qp * FF_QP2LAMBDA, NULL, 0, pict_type); + if (x265pic_out.userData) { + memcpy(&avctx->reordered_opaque, x265pic_out.userData, sizeof(avctx->reordered_opaque)); + av_freep(&x265pic_out.userData); + } else + avctx->reordered_opaque = 0; + *got_packet = 1; return 0; } @@ -645,7 +661,7 @@ static const AVOption options[] = { { "preset", "set the x265 preset", OFFSET(preset), AV_OPT_TYPE_STRING, { 0 }, 0, 0, VE }, { "tune", "set the x265 tune parameter", OFFSET(tune), AV_OPT_TYPE_STRING, { 0 }, 0, 0, VE }, { "profile", "set the x265 profile", OFFSET(profile), AV_OPT_TYPE_STRING, { 0 }, 0, 0, VE }, - { "x265-params", "set the x265 configuration using a :-separated list of key=value parameters", OFFSET(x265_opts), AV_OPT_TYPE_STRING, { 0 }, 0, 0, VE }, + { "x265-params", "set the x265 configuration using a :-separated list of key=value parameters", OFFSET(x265_opts), AV_OPT_TYPE_DICT, { 0 }, 0, 0, VE }, { NULL } }; @@ -684,6 +700,7 @@ AVCodec ff_libx265_encoder = { .priv_data_size = sizeof(libx265Context), .priv_class = &class, .defaults = x265_defaults, - .capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_AUTO_THREADS, + .capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_AUTO_THREADS | + AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE, .wrapper_name = "libx265", };