]> git.sesse.net Git - ffmpeg/blobdiff - libavcodec/libx265.c
avformat/oggparsevorbis: check packet size before reading new_len from it
[ffmpeg] / libavcodec / libx265.c
index 3b9123704dd50914a41efbf8344829e1c3ce2744..2370601ed78fd713104447ddbed8bb5f71acdedf 100644 (file)
 #include "avcodec.h"
 #include "internal.h"
 
+#if defined(_MSC_VER)
+#define X265_API_IMPORTS 1
+#endif
+
 typedef struct libx265Context {
     const AVClass *class;
 
@@ -77,10 +81,20 @@ static av_cold int libx265_encode_init(AVCodecContext *avctx)
     libx265Context *ctx = avctx->priv_data;
     x265_nal *nal;
     uint8_t *buf;
+    int sar_num, sar_den;
     int nnal;
     int ret;
     int i;
 
+    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_h) {
+        av_log(avctx, AV_LOG_ERROR,
+               "4:4:4 support is not fully defined for HEVC yet. "
+               "Set -strict experimental to encode anyway.\n");
+        return AVERROR(ENOSYS);
+    }
+
     avctx->coded_frame = av_frame_alloc();
     if (!avctx->coded_frame) {
         av_log(avctx, AV_LOG_ERROR, "Could not allocate frame.\n");
@@ -99,10 +113,35 @@ static av_cold int libx265_encode_init(AVCodecContext *avctx)
     }
 
     ctx->params->frameNumThreads = avctx->thread_count;
-    ctx->params->frameRate       = (int) (avctx->time_base.den / avctx->time_base.num);
+    ctx->params->fpsNum          = avctx->time_base.den;
+    ctx->params->fpsDenom        = avctx->time_base.num * avctx->ticks_per_frame;
     ctx->params->sourceWidth     = avctx->width;
     ctx->params->sourceHeight    = avctx->height;
-    ctx->params->inputBitDepth   = av_pix_fmt_desc_get(avctx->pix_fmt)->comp[0].depth_minus1 + 1;
+
+    av_reduce(&sar_num, &sar_den,
+              avctx->sample_aspect_ratio.num,
+              avctx->sample_aspect_ratio.den, 4096);
+    ctx->params->bEnableVuiParametersPresentFlag = 1;
+    ctx->params->bEnableAspectRatioIdc           = 1;
+    ctx->params->aspectRatioIdc                  = 255;
+    ctx->params->sarWidth                        = sar_num;
+    ctx->params->sarHeight                       = sar_den;
+
+    if (x265_max_bit_depth == 8)
+        ctx->params->internalBitDepth = 8;
+    else if (x265_max_bit_depth == 12)
+        ctx->params->internalBitDepth = 10;
+
+    switch (avctx->pix_fmt) {
+    case AV_PIX_FMT_YUV420P:
+    case AV_PIX_FMT_YUV420P10:
+        ctx->params->internalCsp = X265_CSP_I420;
+        break;
+    case AV_PIX_FMT_YUV444P:
+    case AV_PIX_FMT_YUV444P10:
+        ctx->params->internalCsp = X265_CSP_I444;
+        break;
+    }
 
     if (avctx->bit_rate > 0) {
         ctx->params->rc.bitrate         = avctx->bit_rate / 1000;
@@ -189,13 +228,14 @@ static int libx265_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
            x265pic.stride[i] = pic->linesize[i];
         }
 
-        x265pic.pts = pic->pts;
+        x265pic.pts      = pic->pts;
+        x265pic.bitDepth = av_pix_fmt_desc_get(avctx->pix_fmt)->comp[0].depth_minus1 + 1;
     }
 
     ret = x265_encoder_encode(ctx->encoder, &nal, &nnal,
                               pic ? &x265pic : NULL, &x265pic_out);
     if (ret < 0)
-        return AVERROR_UNKNOWN;
+        return AVERROR_EXTERNAL;
 
     if (!nnal)
         return 0;
@@ -237,12 +277,15 @@ static int libx265_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
 
 static const enum AVPixelFormat x265_csp_eight[] = {
     AV_PIX_FMT_YUV420P,
+    AV_PIX_FMT_YUV444P,
     AV_PIX_FMT_NONE
 };
 
 static const enum AVPixelFormat x265_csp_twelve[] = {
     AV_PIX_FMT_YUV420P,
+    AV_PIX_FMT_YUV444P,
     AV_PIX_FMT_YUV420P10,
+    AV_PIX_FMT_YUV444P10,
     AV_PIX_FMT_NONE
 };