Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  1. /*
  2.  * libx265 encoder
  3.  *
  4.  * Copyright (c) 2013-2014 Derek Buitenhuis
  5.  *
  6.  * This file is part of FFmpeg.
  7.  *
  8.  * FFmpeg is free software; you can redistribute it and/or
  9.  * modify it under the terms of the GNU Lesser General Public
  10.  * License as published by the Free Software Foundation; either
  11.  * version 2.1 of the License, or (at your option) any later version.
  12.  *
  13.  * FFmpeg is distributed in the hope that it will be useful,
  14.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  16.  * Lesser General Public License for more details.
  17.  *
  18.  * You should have received a copy of the GNU Lesser General Public
  19.  * License along with FFmpeg; if not, write to the Free Software
  20.  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  21.  */
  22.  
  23. #if defined(_MSC_VER)
  24. #define X265_API_IMPORTS 1
  25. #endif
  26.  
  27. #include <x265.h>
  28. #include <float.h>
  29.  
  30. #include "libavutil/internal.h"
  31. #include "libavutil/common.h"
  32. #include "libavutil/opt.h"
  33. #include "libavutil/pixdesc.h"
  34. #include "avcodec.h"
  35. #include "internal.h"
  36.  
  37. typedef struct libx265Context {
  38.     const AVClass *class;
  39.  
  40.     x265_encoder *encoder;
  41.     x265_param   *params;
  42.     const x265_api *api;
  43.  
  44.     float crf;
  45.     char *preset;
  46.     char *tune;
  47.     char *x265_opts;
  48. } libx265Context;
  49.  
  50. static int is_keyframe(NalUnitType naltype)
  51. {
  52.     switch (naltype) {
  53.     case NAL_UNIT_CODED_SLICE_BLA_W_LP:
  54.     case NAL_UNIT_CODED_SLICE_BLA_W_RADL:
  55.     case NAL_UNIT_CODED_SLICE_BLA_N_LP:
  56.     case NAL_UNIT_CODED_SLICE_IDR_W_RADL:
  57.     case NAL_UNIT_CODED_SLICE_IDR_N_LP:
  58.     case NAL_UNIT_CODED_SLICE_CRA:
  59.         return 1;
  60.     default:
  61.         return 0;
  62.     }
  63. }
  64.  
  65. static av_cold int libx265_encode_close(AVCodecContext *avctx)
  66. {
  67.     libx265Context *ctx = avctx->priv_data;
  68.  
  69.     ctx->api->param_free(ctx->params);
  70.  
  71.     if (ctx->encoder)
  72.         ctx->api->encoder_close(ctx->encoder);
  73.  
  74.     return 0;
  75. }
  76.  
  77. static av_cold int libx265_encode_init(AVCodecContext *avctx)
  78. {
  79.     libx265Context *ctx = avctx->priv_data;
  80.  
  81.     ctx->api = x265_api_get(av_pix_fmt_desc_get(avctx->pix_fmt)->comp[0].depth_minus1 + 1);
  82.     if (!ctx->api)
  83.         ctx->api = x265_api_get(0);
  84.  
  85.     if (avctx->strict_std_compliance > FF_COMPLIANCE_EXPERIMENTAL &&
  86.         !av_pix_fmt_desc_get(avctx->pix_fmt)->log2_chroma_w) {
  87.         av_log(avctx, AV_LOG_ERROR,
  88.                "4:2:2 and 4:4:4 support is not fully defined for HEVC yet. "
  89.                "Set -strict experimental to encode anyway.\n");
  90.         return AVERROR(ENOSYS);
  91.     }
  92.  
  93.     ctx->params = ctx->api->param_alloc();
  94.     if (!ctx->params) {
  95.         av_log(avctx, AV_LOG_ERROR, "Could not allocate x265 param structure.\n");
  96.         return AVERROR(ENOMEM);
  97.     }
  98.  
  99.     if (ctx->api->param_default_preset(ctx->params, ctx->preset, ctx->tune) < 0) {
  100.         int i;
  101.  
  102.         av_log(avctx, AV_LOG_ERROR, "Error setting preset/tune %s/%s.\n", ctx->preset, ctx->tune);
  103.         av_log(avctx, AV_LOG_INFO, "Possible presets:");
  104.         for (i = 0; x265_preset_names[i]; i++)
  105.             av_log(avctx, AV_LOG_INFO, " %s", x265_preset_names[i]);
  106.  
  107.         av_log(avctx, AV_LOG_INFO, "\n");
  108.         av_log(avctx, AV_LOG_INFO, "Possible tunes:");
  109.         for (i = 0; x265_tune_names[i]; i++)
  110.             av_log(avctx, AV_LOG_INFO, " %s", x265_tune_names[i]);
  111.  
  112.         av_log(avctx, AV_LOG_INFO, "\n");
  113.  
  114.         return AVERROR(EINVAL);
  115.     }
  116.  
  117.     ctx->params->frameNumThreads = avctx->thread_count;
  118.     ctx->params->fpsNum          = avctx->time_base.den;
  119.     ctx->params->fpsDenom        = avctx->time_base.num * avctx->ticks_per_frame;
  120.     ctx->params->sourceWidth     = avctx->width;
  121.     ctx->params->sourceHeight    = avctx->height;
  122.     ctx->params->bEnablePsnr     = !!(avctx->flags & AV_CODEC_FLAG_PSNR);
  123.  
  124.     if ((avctx->color_primaries <= AVCOL_PRI_BT2020 &&
  125.          avctx->color_primaries != AVCOL_PRI_UNSPECIFIED) ||
  126.         (avctx->color_trc <= AVCOL_TRC_BT2020_12 &&
  127.          avctx->color_trc != AVCOL_TRC_UNSPECIFIED) ||
  128.         (avctx->colorspace <= AVCOL_SPC_BT2020_CL &&
  129.          avctx->colorspace != AVCOL_SPC_UNSPECIFIED)) {
  130.  
  131.         ctx->params->vui.bEnableVideoSignalTypePresentFlag  = 1;
  132.         ctx->params->vui.bEnableColorDescriptionPresentFlag = 1;
  133.  
  134.         // x265 validates the parameters internally
  135.         ctx->params->vui.colorPrimaries          = avctx->color_primaries;
  136.         ctx->params->vui.transferCharacteristics = avctx->color_trc;
  137.         ctx->params->vui.matrixCoeffs            = avctx->colorspace;
  138.     }
  139.  
  140.     if (avctx->sample_aspect_ratio.num > 0 && avctx->sample_aspect_ratio.den > 0) {
  141.         char sar[12];
  142.         int sar_num, sar_den;
  143.  
  144.         av_reduce(&sar_num, &sar_den,
  145.                   avctx->sample_aspect_ratio.num,
  146.                   avctx->sample_aspect_ratio.den, 65535);
  147.         snprintf(sar, sizeof(sar), "%d:%d", sar_num, sar_den);
  148.         if (ctx->api->param_parse(ctx->params, "sar", sar) == X265_PARAM_BAD_VALUE) {
  149.             av_log(avctx, AV_LOG_ERROR, "Invalid SAR: %d:%d.\n", sar_num, sar_den);
  150.             return AVERROR_INVALIDDATA;
  151.         }
  152.     }
  153.  
  154.     switch (avctx->pix_fmt) {
  155.     case AV_PIX_FMT_YUV420P:
  156.     case AV_PIX_FMT_YUV420P10:
  157.         ctx->params->internalCsp = X265_CSP_I420;
  158.         break;
  159.     case AV_PIX_FMT_YUV422P:
  160.     case AV_PIX_FMT_YUV422P10:
  161.         ctx->params->internalCsp = X265_CSP_I422;
  162.         break;
  163.     case AV_PIX_FMT_YUV444P:
  164.     case AV_PIX_FMT_YUV444P10:
  165.         ctx->params->internalCsp = X265_CSP_I444;
  166.         break;
  167.     }
  168.  
  169.     if (ctx->crf >= 0) {
  170.         char crf[6];
  171.  
  172.         snprintf(crf, sizeof(crf), "%2.2f", ctx->crf);
  173.         if (ctx->api->param_parse(ctx->params, "crf", crf) == X265_PARAM_BAD_VALUE) {
  174.             av_log(avctx, AV_LOG_ERROR, "Invalid crf: %2.2f.\n", ctx->crf);
  175.             return AVERROR(EINVAL);
  176.         }
  177.     } else if (avctx->bit_rate > 0) {
  178.         ctx->params->rc.bitrate         = avctx->bit_rate / 1000;
  179.         ctx->params->rc.rateControlMode = X265_RC_ABR;
  180.     }
  181.  
  182.     if (!(avctx->flags & AV_CODEC_FLAG_GLOBAL_HEADER))
  183.         ctx->params->bRepeatHeaders = 1;
  184.  
  185.     if (ctx->x265_opts) {
  186.         AVDictionary *dict    = NULL;
  187.         AVDictionaryEntry *en = NULL;
  188.  
  189.         if (!av_dict_parse_string(&dict, ctx->x265_opts, "=", ":", 0)) {
  190.             while ((en = av_dict_get(dict, "", en, AV_DICT_IGNORE_SUFFIX))) {
  191.                 int parse_ret = ctx->api->param_parse(ctx->params, en->key, en->value);
  192.  
  193.                 switch (parse_ret) {
  194.                 case X265_PARAM_BAD_NAME:
  195.                     av_log(avctx, AV_LOG_WARNING,
  196.                           "Unknown option: %s.\n", en->key);
  197.                     break;
  198.                 case X265_PARAM_BAD_VALUE:
  199.                     av_log(avctx, AV_LOG_WARNING,
  200.                           "Invalid value for %s: %s.\n", en->key, en->value);
  201.                     break;
  202.                 default:
  203.                     break;
  204.                 }
  205.             }
  206.             av_dict_free(&dict);
  207.         }
  208.     }
  209.  
  210.     ctx->encoder = ctx->api->encoder_open(ctx->params);
  211.     if (!ctx->encoder) {
  212.         av_log(avctx, AV_LOG_ERROR, "Cannot open libx265 encoder.\n");
  213.         libx265_encode_close(avctx);
  214.         return AVERROR_INVALIDDATA;
  215.     }
  216.  
  217.     if (avctx->flags & AV_CODEC_FLAG_GLOBAL_HEADER) {
  218.         x265_nal *nal;
  219.         int nnal;
  220.  
  221.         avctx->extradata_size = ctx->api->encoder_headers(ctx->encoder, &nal, &nnal);
  222.         if (avctx->extradata_size <= 0) {
  223.             av_log(avctx, AV_LOG_ERROR, "Cannot encode headers.\n");
  224.             libx265_encode_close(avctx);
  225.             return AVERROR_INVALIDDATA;
  226.         }
  227.  
  228.         avctx->extradata = av_malloc(avctx->extradata_size + AV_INPUT_BUFFER_PADDING_SIZE);
  229.         if (!avctx->extradata) {
  230.             av_log(avctx, AV_LOG_ERROR,
  231.                    "Cannot allocate HEVC header of size %d.\n", avctx->extradata_size);
  232.             libx265_encode_close(avctx);
  233.             return AVERROR(ENOMEM);
  234.         }
  235.  
  236.         memcpy(avctx->extradata, nal[0].payload, avctx->extradata_size);
  237.     }
  238.  
  239.     return 0;
  240. }
  241.  
  242. static int libx265_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
  243.                                 const AVFrame *pic, int *got_packet)
  244. {
  245.     libx265Context *ctx = avctx->priv_data;
  246.     x265_picture x265pic;
  247.     x265_picture x265pic_out = { 0 };
  248.     x265_nal *nal;
  249.     uint8_t *dst;
  250.     int payload = 0;
  251.     int nnal;
  252.     int ret;
  253.     int i;
  254.  
  255.     ctx->api->picture_init(ctx->params, &x265pic);
  256.  
  257.     if (pic) {
  258.         for (i = 0; i < 3; i++) {
  259.            x265pic.planes[i] = pic->data[i];
  260.            x265pic.stride[i] = pic->linesize[i];
  261.         }
  262.  
  263.         x265pic.pts      = pic->pts;
  264.         x265pic.bitDepth = av_pix_fmt_desc_get(avctx->pix_fmt)->comp[0].depth_minus1 + 1;
  265.  
  266.         x265pic.sliceType = pic->pict_type == AV_PICTURE_TYPE_I ? X265_TYPE_I :
  267.                             pic->pict_type == AV_PICTURE_TYPE_P ? X265_TYPE_P :
  268.                             pic->pict_type == AV_PICTURE_TYPE_B ? X265_TYPE_B :
  269.                             X265_TYPE_AUTO;
  270.     }
  271.  
  272.     ret = ctx->api->encoder_encode(ctx->encoder, &nal, &nnal,
  273.                                    pic ? &x265pic : NULL, &x265pic_out);
  274.     if (ret < 0)
  275.         return AVERROR_EXTERNAL;
  276.  
  277.     if (!nnal)
  278.         return 0;
  279.  
  280.     for (i = 0; i < nnal; i++)
  281.         payload += nal[i].sizeBytes;
  282.  
  283.     ret = ff_alloc_packet(pkt, payload);
  284.     if (ret < 0) {
  285.         av_log(avctx, AV_LOG_ERROR, "Error getting output packet.\n");
  286.         return ret;
  287.     }
  288.     dst = pkt->data;
  289.  
  290.     for (i = 0; i < nnal; i++) {
  291.         memcpy(dst, nal[i].payload, nal[i].sizeBytes);
  292.         dst += nal[i].sizeBytes;
  293.  
  294.         if (is_keyframe(nal[i].type))
  295.             pkt->flags |= AV_PKT_FLAG_KEY;
  296.     }
  297.  
  298.     pkt->pts = x265pic_out.pts;
  299.     pkt->dts = x265pic_out.dts;
  300.  
  301. #if FF_API_CODED_FRAME
  302. FF_DISABLE_DEPRECATION_WARNINGS
  303.     switch (x265pic_out.sliceType) {
  304.     case X265_TYPE_IDR:
  305.     case X265_TYPE_I:
  306.         avctx->coded_frame->pict_type = AV_PICTURE_TYPE_I;
  307.         break;
  308.     case X265_TYPE_P:
  309.         avctx->coded_frame->pict_type = AV_PICTURE_TYPE_P;
  310.         break;
  311.     case X265_TYPE_B:
  312.         avctx->coded_frame->pict_type = AV_PICTURE_TYPE_B;
  313.         break;
  314.     }
  315. FF_ENABLE_DEPRECATION_WARNINGS
  316. #endif
  317.  
  318.     *got_packet = 1;
  319.     return 0;
  320. }
  321.  
  322. static const enum AVPixelFormat x265_csp_eight[] = {
  323.     AV_PIX_FMT_YUV420P,
  324.     AV_PIX_FMT_YUV422P,
  325.     AV_PIX_FMT_YUV444P,
  326.     AV_PIX_FMT_NONE
  327. };
  328.  
  329. static const enum AVPixelFormat x265_csp_twelve[] = {
  330.     AV_PIX_FMT_YUV420P,
  331.     AV_PIX_FMT_YUV422P,
  332.     AV_PIX_FMT_YUV444P,
  333.     AV_PIX_FMT_YUV420P10,
  334.     AV_PIX_FMT_YUV422P10,
  335.     AV_PIX_FMT_YUV444P10,
  336.     AV_PIX_FMT_NONE
  337. };
  338.  
  339. static av_cold void libx265_encode_init_csp(AVCodec *codec)
  340. {
  341.     if (x265_api_get(10))
  342.         codec->pix_fmts = x265_csp_twelve;
  343.     else if (x265_api_get(8))
  344.         codec->pix_fmts = x265_csp_eight;
  345. }
  346.  
  347. #define OFFSET(x) offsetof(libx265Context, x)
  348. #define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM
  349. static const AVOption options[] = {
  350.     { "crf",         "set the x265 crf",                                                            OFFSET(crf),       AV_OPT_TYPE_FLOAT,  { .dbl = -1 }, -1, FLT_MAX, VE },
  351.     { "preset",      "set the x265 preset",                                                         OFFSET(preset),    AV_OPT_TYPE_STRING, { 0 }, 0, 0, VE },
  352.     { "tune",        "set the x265 tune parameter",                                                 OFFSET(tune),      AV_OPT_TYPE_STRING, { 0 }, 0, 0, VE },
  353.     { "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 },
  354.     { NULL }
  355. };
  356.  
  357. static const AVClass class = {
  358.     .class_name = "libx265",
  359.     .item_name  = av_default_item_name,
  360.     .option     = options,
  361.     .version    = LIBAVUTIL_VERSION_INT,
  362. };
  363.  
  364. static const AVCodecDefault x265_defaults[] = {
  365.     { "b", "0" },
  366.     { NULL },
  367. };
  368.  
  369. AVCodec ff_libx265_encoder = {
  370.     .name             = "libx265",
  371.     .long_name        = NULL_IF_CONFIG_SMALL("libx265 H.265 / HEVC"),
  372.     .type             = AVMEDIA_TYPE_VIDEO,
  373.     .id               = AV_CODEC_ID_HEVC,
  374.     .init             = libx265_encode_init,
  375.     .init_static_data = libx265_encode_init_csp,
  376.     .encode2          = libx265_encode_frame,
  377.     .close            = libx265_encode_close,
  378.     .priv_data_size   = sizeof(libx265Context),
  379.     .priv_class       = &class,
  380.     .defaults         = x265_defaults,
  381.     .capabilities     = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_AUTO_THREADS,
  382. };
  383.