]> git.sesse.net Git - ffmpeg/blobdiff - libavcodec/libx265.c
avformat/mpegtsenc: move is_dvb_subtitle/is_dvb_teletext initialization upwards
[ffmpeg] / libavcodec / libx265.c
index 3c3deb2bdb55c80534eb569bc4e7ff24b16c6aa7..a1bd205201d3c18d50658597089ec64a03d77818 100644 (file)
@@ -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;
@@ -482,6 +479,7 @@ static int libx265_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
     x265_picture x265pic_out = { 0 };
     x265_nal *nal;
     uint8_t *dst;
+    int pict_type;
     int payload = 0;
     int nnal;
     int ret;
@@ -507,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,
@@ -541,22 +549,22 @@ static int libx265_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
     pkt->pts = x265pic_out.pts;
     pkt->dts = x265pic_out.dts;
 
-#if FF_API_CODED_FRAME
-FF_DISABLE_DEPRECATION_WARNINGS
     switch (x265pic_out.sliceType) {
     case X265_TYPE_IDR:
     case X265_TYPE_I:
-        avctx->coded_frame->pict_type = AV_PICTURE_TYPE_I;
+        pict_type = AV_PICTURE_TYPE_I;
         break;
     case X265_TYPE_P:
-        avctx->coded_frame->pict_type = AV_PICTURE_TYPE_P;
+        pict_type = AV_PICTURE_TYPE_P;
         break;
     case X265_TYPE_B:
-        avctx->coded_frame->pict_type = AV_PICTURE_TYPE_B;
+    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;
     }
-FF_ENABLE_DEPRECATION_WARNINGS
-#endif
 
 #if X265_BUILD >= 130
     if (x265pic_out.sliceType == X265_TYPE_B)
@@ -565,6 +573,14 @@ FF_ENABLE_DEPRECATION_WARNINGS
 #endif
         pkt->flags |= AV_PKT_FLAG_DISPOSABLE;
 
+    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;
 }
@@ -639,7 +655,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 }
 };
 
@@ -678,6 +694,8 @@ 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_OTHER_THREADS |
+                        AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
+    .caps_internal    = FF_CODEC_CAP_AUTO_THREADS,
     .wrapper_name     = "libx265",
 };