Message ID | 1479482749-9868-1-git-send-email-matteo.naccari@bbc.co.uk |
---|---|
State | New |
Headers | show |
On 18/11/2016 15:25, Matteo Naccari wrote: > - The Turing codec is an open source HEVC encoder licensed under GPLv2 > - More information at http://turingcodec.org/ > --- > LICENSE.md | 1 + > configure | 5 ++ > libavcodec/Makefile | 1 + > libavcodec/allcodecs.c | 1 + > libavcodec/libturing.c | 229 +++++++++++++++++++++++++++++++++++++++++++++++++ > 5 files changed, 237 insertions(+) > create mode 100644 libavcodec/libturing.c > > diff --git a/LICENSE.md b/LICENSE.md > index a384fa0..6f9fab8 100644 > --- a/LICENSE.md > +++ b/LICENSE.md > @@ -86,6 +86,7 @@ The following libraries are under GPL: > - frei0r > - libcdio > - librubberband > +- libturing > - libvidstab > - libx264 > - libx265 > diff --git a/configure b/configure > index b5bfad6..47d6b93 100755 > --- a/configure > +++ b/configure > @@ -255,6 +255,7 @@ External library support: > --enable-libssh enable SFTP protocol via libssh [no] > --enable-libtesseract enable Tesseract, needed for ocr filter [no] > --enable-libtheora enable Theora encoding via libtheora [no] > + --enable-libturing enable HEVC encoding via libturing [no] > --enable-libtwolame enable MP2 encoding via libtwolame [no] > --enable-libv4l2 enable libv4l2/v4l-utils [no] > --enable-libvidstab enable video stabilization using vid.stab [no] > @@ -1521,6 +1522,7 @@ EXTERNAL_LIBRARY_LIST=" > libssh > libtesseract > libtheora > + libturing > libtwolame > libv4l2 > libvidstab > @@ -2814,6 +2816,7 @@ libspeex_decoder_deps="libspeex" > libspeex_encoder_deps="libspeex" > libspeex_encoder_select="audio_frame_queue" > libtheora_encoder_deps="libtheora" > +libturing_encoder_deps="libturing" > libtwolame_encoder_deps="libtwolame" > libvo_amrwbenc_encoder_deps="libvo_amrwbenc" > libvorbis_decoder_deps="libvorbis" > @@ -5072,6 +5075,7 @@ die_license_disabled gpl frei0r > die_license_disabled gpl libcdio > die_license_disabled gpl librubberband > die_license_disabled gpl libsmbclient > +die_license_disabled gpl libturing > die_license_disabled gpl libvidstab > die_license_disabled gpl libx264 > die_license_disabled gpl libx265 > @@ -5735,6 +5739,7 @@ enabled libssh && require_pkg_config libssh libssh/sftp.h sftp_init > enabled libspeex && require_pkg_config speex speex/speex.h speex_decoder_init -lspeex > enabled libtesseract && require_pkg_config tesseract tesseract/capi.h TessBaseAPICreate > enabled libtheora && require libtheora theora/theoraenc.h th_info_init -ltheoraenc -ltheoradec -logg > +enabled libturing && require libturing turing.h turing_version -lturing -lstdc++ -lboost_chrono -lboost_program_options -lboost_timer -lboost_system -lboost_filesystem -lhavoc > enabled libtwolame && require libtwolame twolame.h twolame_init -ltwolame && > { check_lib twolame.h twolame_encode_buffer_float32_interleaved -ltwolame || > die "ERROR: libtwolame must be installed and version must be >= 0.3.10"; } > diff --git a/libavcodec/Makefile b/libavcodec/Makefile > index 82f7fa2..cadefdc 100644 > --- a/libavcodec/Makefile > +++ b/libavcodec/Makefile > @@ -880,6 +880,7 @@ OBJS-$(CONFIG_LIBSPEEX_DECODER) += libspeexdec.o > OBJS-$(CONFIG_LIBSPEEX_ENCODER) += libspeexenc.o > OBJS-$(CONFIG_LIBTHEORA_ENCODER) += libtheoraenc.o > OBJS-$(CONFIG_LIBTWOLAME_ENCODER) += libtwolame.o > +OBJS-$(CONFIG_LIBTURING_ENCODER) += libturing.o > OBJS-$(CONFIG_LIBVO_AMRWBENC_ENCODER) += libvo-amrwbenc.o > OBJS-$(CONFIG_LIBVORBIS_DECODER) += libvorbisdec.o > OBJS-$(CONFIG_LIBVORBIS_ENCODER) += libvorbisenc.o \ > diff --git a/libavcodec/allcodecs.c b/libavcodec/allcodecs.c > index ada9481..0e61a4a 100644 > --- a/libavcodec/allcodecs.c > +++ b/libavcodec/allcodecs.c > @@ -610,6 +610,7 @@ void avcodec_register_all(void) > REGISTER_ENCDEC (LIBSPEEX, libspeex); > REGISTER_ENCODER(LIBTHEORA, libtheora); > REGISTER_ENCODER(LIBTWOLAME, libtwolame); > + REGISTER_ENCODER(LIBTURING, libturing); > REGISTER_ENCODER(LIBVO_AMRWBENC, libvo_amrwbenc); > REGISTER_ENCDEC (LIBVORBIS, libvorbis); > REGISTER_ENCDEC (LIBVPX_VP8, libvpx_vp8); > diff --git a/libavcodec/libturing.c b/libavcodec/libturing.c > new file mode 100644 > index 0000000..3191a41 > --- /dev/null > +++ b/libavcodec/libturing.c > @@ -0,0 +1,229 @@ > +/* > + * libturing encoder > + * > + * Copyright (c) 2016 Turing Codec contributors > + * > + * This file is part of FFmpeg. > + * > + * FFmpeg is free software; you can redistribute it and/or > + * modify it under the terms of the GNU Lesser General Public > + * License as published by the Free Software Foundation; either > + * version 2.1 of the License, or (at your option) any later version. > + * > + * FFmpeg is distributed in the hope that it will be useful, > + * but WITHOUT ANY WARRANTY; without even the implied warranty of > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU > + * Lesser General Public License for more details. > + * > + * You should have received a copy of the GNU Lesser General Public > + * License along with FFmpeg; if not, write to the Free Software > + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA > + */ > + > +#include <turing.h> > +#include <float.h> > +#include "libavutil/internal.h" > +#include "libavutil/common.h" > +#include "libavutil/opt.h" > +#include "libavutil/pixdesc.h" > +#include "avcodec.h" > +#include "internal.h" > + > +typedef struct libturingEncodeContext { > + const AVClass *class; > + turing_encoder *encoder; > + const char *options; > +} libturingEncodeContext; > + > +static av_cold int libturing_encode_close(AVCodecContext *avctx) > +{ > + libturingEncodeContext *ctx = avctx->priv_data; > + > + if (ctx->encoder) > + turing_destroy_encoder(ctx->encoder); > + > + return 0; > +} > + > +static av_cold int libturing_encode_init(AVCodecContext *avctx) > +{ > + libturingEncodeContext *ctx = avctx->priv_data; > + > + char options[1024]; > + char* s = options; > + char *end = &options[sizeof(options)]; > + > + char const* argv[32]; > + char const** p = argv; > + turing_encoder_settings settings; > + > + *p++ = s; > + *p++ = s += 1 + snprintf(s, end - s, "turing"); > + *p++ = s += 1 + snprintf(s, end - s, "--input-res=%dx%d", avctx->width, avctx->height); > + *p++ = s += 1 + snprintf(s, end - s, "--frame-rate=%f", (double)avctx->time_base.den / (avctx->time_base.num * avctx->ticks_per_frame)); > + *p++ = s += 1 + snprintf(s, end - s, "--frames=0"); > + > + { > + int const bit_depth = av_pix_fmt_desc_get(avctx->pix_fmt)->comp[0].depth; > + if (bit_depth != 8 && bit_depth != 10) { > + av_log(avctx, AV_LOG_ERROR, "Encoder input must be 8- or 10-bit.\n"); > + turing_destroy_encoder(ctx->encoder); > + return AVERROR_INVALIDDATA; > + } > + *p++ = s += 1 + snprintf(s, end - s, "--bit-depth=%d", bit_depth); > + *p++ = s += 1 + snprintf(s, end - s, "--internal-bit-depth=%d", bit_depth); > + } > + > + if (avctx->sample_aspect_ratio.num > 0 && avctx->sample_aspect_ratio.den > 0) { > + int sar_num, sar_den; > + > + av_reduce(&sar_num, &sar_den, > + avctx->sample_aspect_ratio.num, > + avctx->sample_aspect_ratio.den, 65535); > + > + *p++ = s += 1 + snprintf(s, end - s, "--sar=%d:%d", sar_num, sar_den); > + } > + > + if (ctx->options) { > + AVDictionary *dict = NULL; > + AVDictionaryEntry *en = NULL; > + > + if (!av_dict_parse_string(&dict, ctx->options, "=", ":", 0)) { > + while ((en = av_dict_get(dict, "", en, AV_DICT_IGNORE_SUFFIX))) { > + int const illegal_option = > + !strcmp("input-res", en->key) || > + !strcmp("frame-rate", en->key) || > + !strcmp("f", en->key) || > + !strcmp("frames", en->key) || > + !strcmp("sar", en->key) || > + !strcmp("bit-depth", en->key) || > + !strcmp("internal-bit-depth", en->key); > + if (illegal_option) > + av_log(avctx, AV_LOG_WARNING, "%s=%s ignored.\n", en->key, en->value); > + else > + *p++ = s += 1 + snprintf(s, end - s, "--%s=%s", en->key, en->value); > + } > + av_dict_free(&dict); > + } > + } > + > + *p++ = s += 1 + snprintf(s, end - s, "dummy-input-filename"); > + > + settings.argv = argv; > + settings.argc = p - argv - 1; > + > + for (int i=0; i<settings.argc; ++i) > + av_log(avctx, AV_LOG_INFO, "arg %d: %s\n", i, settings.argv[i]); > + > + ctx->encoder = turing_create_encoder(settings); > + > + if (!ctx->encoder) { > + av_log(avctx, AV_LOG_ERROR, "Failed to create libturing encoder.\n"); > + return AVERROR_INVALIDDATA; > + } > + > + if (avctx->flags & AV_CODEC_FLAG_GLOBAL_HEADER) { > + turing_bitstream const *bitstream; > + bitstream = turing_encode_headers(ctx->encoder); > + if (bitstream->size <= 0) { > + av_log(avctx, AV_LOG_ERROR, "Failed to encode headers.\n"); > + turing_destroy_encoder(ctx->encoder); > + return AVERROR_INVALIDDATA; > + } > + > + avctx->extradata_size = bitstream->size; > + > + avctx->extradata = av_malloc(avctx->extradata_size + AV_INPUT_BUFFER_PADDING_SIZE); > + if (!avctx->extradata) { > + av_log(avctx, AV_LOG_ERROR, "Failed to allocate HEVC extradata %d bytes\n", avctx->extradata_size); > + turing_destroy_encoder(ctx->encoder); > + return AVERROR(ENOMEM); > + } > + > + memcpy(avctx->extradata, bitstream->p, bitstream->size); > + } > + > + return 0; > +} > + > +static int libturing_encode_frame(AVCodecContext *avctx, AVPacket *pkt, const AVFrame *pic, int *got_packet) > +{ > + libturingEncodeContext *ctx = avctx->priv_data; > + turing_encoder_output const *output; > + int ret = 0; > + > + if (pic) { > + turing_picture picture; > + > + picture.image[0].p = pic->data[0]; > + picture.image[1].p = pic->data[1]; > + picture.image[2].p = pic->data[2]; > + picture.image[0].stride = pic->linesize[0]; > + picture.image[1].stride = pic->linesize[1]; > + picture.image[2].stride = pic->linesize[2]; > + picture.pts = pic->pts; > + > + output = turing_encode_picture(ctx->encoder, &picture); > + } else { > + output = turing_encode_picture(ctx->encoder, 0); > + } > + > + if (output->bitstream.size < 0) > + return AVERROR_EXTERNAL; > + > + if (output->bitstream.size ==0) > + return 0; > + > + ret = ff_alloc_packet(pkt, output->bitstream.size); > + if (ret < 0) { > + av_log(avctx, AV_LOG_ERROR, "Error getting output packet.\n"); > + return ret; > + } > + > + memcpy(pkt->data, output->bitstream.p, output->bitstream.size); > + > + pkt->pts = output->pts; > + pkt->dts = output->dts; > + if (output->keyframe) > + pkt->flags |= AV_PKT_FLAG_KEY; > + > + *got_packet = 1; > + return 0; > +} > + > +static const enum AVPixelFormat turing_csp[] = { > + AV_PIX_FMT_YUV420P10, > + AV_PIX_FMT_YUV420P, > + AV_PIX_FMT_NONE > +}; > + > +static av_cold void libturing_encode_init_csp(AVCodec *codec) > +{ > + codec->pix_fmts = turing_csp; > +} > + > +static const AVOption options[] = { > + { "turing-params", "configure additional turing encoder paremeters", offsetof(libturingEncodeContext, options), AV_OPT_TYPE_STRING,{ 0 }, 0, 0, AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM }, > + { NULL } > +}; > + > +static const AVClass class = { > + .class_name = "libturing", > + .item_name = av_default_item_name, > + .option = options, > + .version = LIBAVUTIL_VERSION_INT, > +}; > + > +AVCodec ff_libturing_encoder = { > + .name = "libturing", > + .long_name = NULL_IF_CONFIG_SMALL("libturing HEVC"), > + .type = AVMEDIA_TYPE_VIDEO, > + .id = AV_CODEC_ID_HEVC, > + .init = libturing_encode_init, > + .init_static_data = libturing_encode_init_csp, > + .encode2 = libturing_encode_frame, > + .close = libturing_encode_close, > + .priv_data_size = sizeof(libturingEncodeContext), > + .priv_class = &class, > + .capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_AUTO_THREADS, > +}; > Can't currently test on macOS as libturing doesn't have macOS support (https://github.com/bbc/turingcodec/issues/5), but it is being worked on (supposedly), so it may make sense to wait until then before this is applied.
> Can't currently test on macOS as libturing doesn't have macOS support > (https://github.com/bbc/turingcodec/issues/5), but it is being worked on > (supposedly), so it may make sense to wait until then before this is applied. > Ok we'll try to get this sorted out and then get back to you. Thanks for your reply. Best regards, Matteo ----------------------------- http://www.bbc.co.uk This e-mail (and any attachments) is confidential and may contain personal views which are not the views of the BBC unless specifically stated. If you have received it in error, please delete it from your system. Do not use, copy or disclose the information in any way nor act in reliance on it and notify the sender immediately. Please note that the BBC monitors e-mails sent or received. Further communication will signify your consent to this. -----------------------------
On Fri, Nov 18, 2016 at 4:25 PM, Matteo Naccari <matteo.naccari@bbc.co.uk> wrote: > - The Turing codec is an open source HEVC encoder licensed under GPLv2 > - More information at http://turingcodec.org/ > --- > LICENSE.md | 1 + > configure | 5 ++ > libavcodec/Makefile | 1 + > libavcodec/allcodecs.c | 1 + > libavcodec/libturing.c | 229 +++++++++++++++++++++++++++++++++++++++++++++++++ > 5 files changed, 237 insertions(+) > create mode 100644 libavcodec/libturing.c > > diff --git a/LICENSE.md b/LICENSE.md > index a384fa0..6f9fab8 100644 > --- a/LICENSE.md > +++ b/LICENSE.md > @@ -86,6 +86,7 @@ The following libraries are under GPL: > - frei0r > - libcdio > - librubberband > +- libturing > - libvidstab > - libx264 > - libx265 > diff --git a/configure b/configure > index b5bfad6..47d6b93 100755 > --- a/configure > +++ b/configure > @@ -255,6 +255,7 @@ External library support: > --enable-libssh enable SFTP protocol via libssh [no] > --enable-libtesseract enable Tesseract, needed for ocr filter [no] > --enable-libtheora enable Theora encoding via libtheora [no] > + --enable-libturing enable HEVC encoding via libturing [no] > --enable-libtwolame enable MP2 encoding via libtwolame [no] > --enable-libv4l2 enable libv4l2/v4l-utils [no] > --enable-libvidstab enable video stabilization using vid.stab [no] > @@ -1521,6 +1522,7 @@ EXTERNAL_LIBRARY_LIST=" > libssh > libtesseract > libtheora > + libturing > libtwolame > libv4l2 > libvidstab > @@ -2814,6 +2816,7 @@ libspeex_decoder_deps="libspeex" > libspeex_encoder_deps="libspeex" > libspeex_encoder_select="audio_frame_queue" > libtheora_encoder_deps="libtheora" > +libturing_encoder_deps="libturing" > libtwolame_encoder_deps="libtwolame" > libvo_amrwbenc_encoder_deps="libvo_amrwbenc" > libvorbis_decoder_deps="libvorbis" > @@ -5072,6 +5075,7 @@ die_license_disabled gpl frei0r > die_license_disabled gpl libcdio > die_license_disabled gpl librubberband > die_license_disabled gpl libsmbclient > +die_license_disabled gpl libturing > die_license_disabled gpl libvidstab > die_license_disabled gpl libx264 > die_license_disabled gpl libx265 > @@ -5735,6 +5739,7 @@ enabled libssh && require_pkg_config libssh libssh/sftp.h sftp_init > enabled libspeex && require_pkg_config speex speex/speex.h speex_decoder_init -lspeex > enabled libtesseract && require_pkg_config tesseract tesseract/capi.h TessBaseAPICreate > enabled libtheora && require libtheora theora/theoraenc.h th_info_init -ltheoraenc -ltheoradec -logg > +enabled libturing && require libturing turing.h turing_version -lturing -lstdc++ -lboost_chrono -lboost_program_options -lboost_timer -lboost_system -lboost_filesystem -lhavoc These dependencies are kind of a mess. Maybe you can make libturning include a pkg_config file so we don't have to maintain your library list here? - Hendrik
On Fri, 18 Nov 2016 15:25:49 +0000 Matteo Naccari <matteo.naccari@bbc.co.uk> wrote: > - The Turing codec is an open source HEVC encoder licensed under GPLv2 > - More information at http://turingcodec.org/ > --- > LICENSE.md | 1 + > configure | 5 ++ > libavcodec/Makefile | 1 + > libavcodec/allcodecs.c | 1 + > libavcodec/libturing.c | 229 +++++++++++++++++++++++++++++++++++++++++++++++++ > 5 files changed, 237 insertions(+) > create mode 100644 libavcodec/libturing.c > > diff --git a/LICENSE.md b/LICENSE.md > index a384fa0..6f9fab8 100644 > --- a/LICENSE.md > +++ b/LICENSE.md > @@ -86,6 +86,7 @@ The following libraries are under GPL: > - frei0r > - libcdio > - librubberband > +- libturing > - libvidstab > - libx264 > - libx265 > diff --git a/configure b/configure > index b5bfad6..47d6b93 100755 > --- a/configure > +++ b/configure > @@ -255,6 +255,7 @@ External library support: > --enable-libssh enable SFTP protocol via libssh [no] > --enable-libtesseract enable Tesseract, needed for ocr filter [no] > --enable-libtheora enable Theora encoding via libtheora [no] > + --enable-libturing enable HEVC encoding via libturing [no] > --enable-libtwolame enable MP2 encoding via libtwolame [no] > --enable-libv4l2 enable libv4l2/v4l-utils [no] > --enable-libvidstab enable video stabilization using vid.stab [no] > @@ -1521,6 +1522,7 @@ EXTERNAL_LIBRARY_LIST=" > libssh > libtesseract > libtheora > + libturing > libtwolame > libv4l2 > libvidstab > @@ -2814,6 +2816,7 @@ libspeex_decoder_deps="libspeex" > libspeex_encoder_deps="libspeex" > libspeex_encoder_select="audio_frame_queue" > libtheora_encoder_deps="libtheora" > +libturing_encoder_deps="libturing" > libtwolame_encoder_deps="libtwolame" > libvo_amrwbenc_encoder_deps="libvo_amrwbenc" > libvorbis_decoder_deps="libvorbis" > @@ -5072,6 +5075,7 @@ die_license_disabled gpl frei0r > die_license_disabled gpl libcdio > die_license_disabled gpl librubberband > die_license_disabled gpl libsmbclient > +die_license_disabled gpl libturing > die_license_disabled gpl libvidstab > die_license_disabled gpl libx264 > die_license_disabled gpl libx265 > @@ -5735,6 +5739,7 @@ enabled libssh && require_pkg_config libssh libssh/sftp.h sftp_init > enabled libspeex && require_pkg_config speex speex/speex.h speex_decoder_init -lspeex > enabled libtesseract && require_pkg_config tesseract tesseract/capi.h TessBaseAPICreate > enabled libtheora && require libtheora theora/theoraenc.h th_info_init -ltheoraenc -ltheoradec -logg > +enabled libturing && require libturing turing.h turing_version -lturing -lstdc++ -lboost_chrono -lboost_program_options -lboost_timer -lboost_system -lboost_filesystem -lhavoc > enabled libtwolame && require libtwolame twolame.h twolame_init -ltwolame && > { check_lib twolame.h twolame_encode_buffer_float32_interleaved -ltwolame || > die "ERROR: libtwolame must be installed and version must be >= 0.3.10"; } > diff --git a/libavcodec/Makefile b/libavcodec/Makefile > index 82f7fa2..cadefdc 100644 > --- a/libavcodec/Makefile > +++ b/libavcodec/Makefile > @@ -880,6 +880,7 @@ OBJS-$(CONFIG_LIBSPEEX_DECODER) += libspeexdec.o > OBJS-$(CONFIG_LIBSPEEX_ENCODER) += libspeexenc.o > OBJS-$(CONFIG_LIBTHEORA_ENCODER) += libtheoraenc.o > OBJS-$(CONFIG_LIBTWOLAME_ENCODER) += libtwolame.o > +OBJS-$(CONFIG_LIBTURING_ENCODER) += libturing.o > OBJS-$(CONFIG_LIBVO_AMRWBENC_ENCODER) += libvo-amrwbenc.o > OBJS-$(CONFIG_LIBVORBIS_DECODER) += libvorbisdec.o > OBJS-$(CONFIG_LIBVORBIS_ENCODER) += libvorbisenc.o \ > diff --git a/libavcodec/allcodecs.c b/libavcodec/allcodecs.c > index ada9481..0e61a4a 100644 > --- a/libavcodec/allcodecs.c > +++ b/libavcodec/allcodecs.c > @@ -610,6 +610,7 @@ void avcodec_register_all(void) > REGISTER_ENCDEC (LIBSPEEX, libspeex); > REGISTER_ENCODER(LIBTHEORA, libtheora); > REGISTER_ENCODER(LIBTWOLAME, libtwolame); > + REGISTER_ENCODER(LIBTURING, libturing); > REGISTER_ENCODER(LIBVO_AMRWBENC, libvo_amrwbenc); > REGISTER_ENCDEC (LIBVORBIS, libvorbis); > REGISTER_ENCDEC (LIBVPX_VP8, libvpx_vp8); > diff --git a/libavcodec/libturing.c b/libavcodec/libturing.c > new file mode 100644 > index 0000000..3191a41 > --- /dev/null > +++ b/libavcodec/libturing.c > @@ -0,0 +1,229 @@ > +/* > + * libturing encoder > + * > + * Copyright (c) 2016 Turing Codec contributors > + * > + * This file is part of FFmpeg. > + * > + * FFmpeg is free software; you can redistribute it and/or > + * modify it under the terms of the GNU Lesser General Public > + * License as published by the Free Software Foundation; either > + * version 2.1 of the License, or (at your option) any later version. > + * > + * FFmpeg is distributed in the hope that it will be useful, > + * but WITHOUT ANY WARRANTY; without even the implied warranty of > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU > + * Lesser General Public License for more details. > + * > + * You should have received a copy of the GNU Lesser General Public > + * License along with FFmpeg; if not, write to the Free Software > + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA > + */ > + > +#include <turing.h> > +#include <float.h> > +#include "libavutil/internal.h" > +#include "libavutil/common.h" > +#include "libavutil/opt.h" > +#include "libavutil/pixdesc.h" > +#include "avcodec.h" > +#include "internal.h" > + > +typedef struct libturingEncodeContext { > + const AVClass *class; > + turing_encoder *encoder; > + const char *options; > +} libturingEncodeContext; > + > +static av_cold int libturing_encode_close(AVCodecContext *avctx) > +{ > + libturingEncodeContext *ctx = avctx->priv_data; > + > + if (ctx->encoder) > + turing_destroy_encoder(ctx->encoder); > + > + return 0; > +} > + > +static av_cold int libturing_encode_init(AVCodecContext *avctx) > +{ > + libturingEncodeContext *ctx = avctx->priv_data; > + > + char options[1024]; > + char* s = options; > + char *end = &options[sizeof(options)]; > + > + char const* argv[32]; > + char const** p = argv; > + turing_encoder_settings settings; > + > + *p++ = s; > + *p++ = s += 1 + snprintf(s, end - s, "turing"); > + *p++ = s += 1 + snprintf(s, end - s, "--input-res=%dx%d", avctx->width, avctx->height); > + *p++ = s += 1 + snprintf(s, end - s, "--frame-rate=%f", (double)avctx->time_base.den / (avctx->time_base.num * avctx->ticks_per_frame)); > + *p++ = s += 1 + snprintf(s, end - s, "--frames=0"); > + > + { > + int const bit_depth = av_pix_fmt_desc_get(avctx->pix_fmt)->comp[0].depth; > + if (bit_depth != 8 && bit_depth != 10) { > + av_log(avctx, AV_LOG_ERROR, "Encoder input must be 8- or 10-bit.\n"); > + turing_destroy_encoder(ctx->encoder); > + return AVERROR_INVALIDDATA; > + } > + *p++ = s += 1 + snprintf(s, end - s, "--bit-depth=%d", bit_depth); > + *p++ = s += 1 + snprintf(s, end - s, "--internal-bit-depth=%d", bit_depth); > + } > + > + if (avctx->sample_aspect_ratio.num > 0 && avctx->sample_aspect_ratio.den > 0) { > + int sar_num, sar_den; > + > + av_reduce(&sar_num, &sar_den, > + avctx->sample_aspect_ratio.num, > + avctx->sample_aspect_ratio.den, 65535); > + > + *p++ = s += 1 + snprintf(s, end - s, "--sar=%d:%d", sar_num, sar_den); > + } > + > + if (ctx->options) { > + AVDictionary *dict = NULL; > + AVDictionaryEntry *en = NULL; > + > + if (!av_dict_parse_string(&dict, ctx->options, "=", ":", 0)) { > + while ((en = av_dict_get(dict, "", en, AV_DICT_IGNORE_SUFFIX))) { > + int const illegal_option = > + !strcmp("input-res", en->key) || > + !strcmp("frame-rate", en->key) || > + !strcmp("f", en->key) || > + !strcmp("frames", en->key) || > + !strcmp("sar", en->key) || > + !strcmp("bit-depth", en->key) || > + !strcmp("internal-bit-depth", en->key); > + if (illegal_option) > + av_log(avctx, AV_LOG_WARNING, "%s=%s ignored.\n", en->key, en->value); > + else > + *p++ = s += 1 + snprintf(s, end - s, "--%s=%s", en->key, en->value); > + } > + av_dict_free(&dict); > + } > + } This lib has a really weird API... Anyway, access to p++ seems unbounded and could go past the argv array. The string overflow checks also look questionable. snprintf() returns the size the string would have had and isn't limited by the buffer passed to it, so the s pointer can go out of bounds (which is undefined behavior). Also, "end - s" will underflow, making the attempt to avoid a buffer overflow pointless.
On Fri, Nov 18, 2016 at 20:15:30 +0100, wm4 wrote:
> This lib has a really weird API...
I can't judge the algorithms or the development direction and stuff -
I'm sure it's all state of the art. But the API sure gives me
goosebumps, and I don't mean the sexy feelgood type.
Sure, it has all the flexibility, but also almost all the disadvantages
of calling an external program. This makes it look so much like a proof
of concept.
But I'm sure that's not the point. If it turns out to be here to stay,
to compete with x265 in one or the other way, it's probably worth
integrating.
Back to the review: From first glance, the libturing codec/library (or
the executable only???) seems to have speed presets. Why are these not
exposed to the libavcodec user?
Furthermore: Documentation is missing.
£0.02,
Moritz
On 2016-11-19 14:29 +0100, Moritz Barsnick wrote: > On Fri, Nov 18, 2016 at 20:15:30 +0100, wm4 wrote: > > This lib has a really weird API... > > I can't judge the algorithms or the development direction and stuff - > I'm sure it's all state of the art. But the API sure gives me > goosebumps, and I don't mean the sexy feelgood type. > > Sure, it has all the flexibility, but also almost all the disadvantages > of calling an external program. This makes it look so much like a proof > of concept. I looked at the source for fun yesterday to find out what that was about. IMHO it is that the real encoder class takes C++ arguments (boost variables map) and they have a CLI program which also needs to create that variables map for the encoder. Thus it seems the quickest way to make a C interface was to use that argument parsing code for initializing the encoder. I hope it copes well with multiple definitions of the same option, like the last overwriting the previous ones. [...] Alexander
2016-11-18 17:45 GMT+01:00 Josh de Kock <josh@itanimul.li>: > Can't currently test on macOS as libturing doesn't have macOS > support (https://github.com/bbc/turingcodec/issues/5), but it is > being worked on (supposedly), so it may make sense to wait until > then before this is applied. I don't know if we should add support for libturing or not but I wonder why this is related to libturing working on osx or not... Or to say it differently: If libturing really is better than libx265 at least in some situations (this is claimed afaiu), it should imo be added no matter if it works on osx or not. Carl Eugen
> These dependencies are kind of a mess. Maybe you can make libturning > include a pkg_config file so we don't have to maintain your library list here? The new patch we just submitted addresses this point: the Turing codec will install a pkg-config file to list the dependencies as suggested Matteo Naccari > -----Original Message----- > From: ffmpeg-devel [mailto:ffmpeg-devel-bounces@ffmpeg.org] On Behalf > Of Hendrik Leppkes > Sent: 18 November 2016 18:51 > To: FFmpeg development discussions and patches <ffmpeg- > devel@ffmpeg.org> > Subject: Re: [FFmpeg-devel] [PATCH] Added the interface for the Turing > codec > > On Fri, Nov 18, 2016 at 4:25 PM, Matteo Naccari <matteo.naccari@bbc.co.uk> > wrote: > > - The Turing codec is an open source HEVC encoder licensed under GPLv2 > > - More information at http://turingcodec.org/ > > --- > > LICENSE.md | 1 + > > configure | 5 ++ > > libavcodec/Makefile | 1 + > > libavcodec/allcodecs.c | 1 + > > libavcodec/libturing.c | 229 > > +++++++++++++++++++++++++++++++++++++++++++++++++ > > 5 files changed, 237 insertions(+) > > create mode 100644 libavcodec/libturing.c > > > > diff --git a/LICENSE.md b/LICENSE.md > > index a384fa0..6f9fab8 100644 > > --- a/LICENSE.md > > +++ b/LICENSE.md > > @@ -86,6 +86,7 @@ The following libraries are under GPL: > > - frei0r > > - libcdio > > - librubberband > > +- libturing > > - libvidstab > > - libx264 > > - libx265 > > diff --git a/configure b/configure > > index b5bfad6..47d6b93 100755 > > --- a/configure > > +++ b/configure > > @@ -255,6 +255,7 @@ External library support: > > --enable-libssh enable SFTP protocol via libssh [no] > > --enable-libtesseract enable Tesseract, needed for ocr filter [no] > > --enable-libtheora enable Theora encoding via libtheora [no] > > + --enable-libturing enable HEVC encoding via libturing [no] > > --enable-libtwolame enable MP2 encoding via libtwolame [no] > > --enable-libv4l2 enable libv4l2/v4l-utils [no] > > --enable-libvidstab enable video stabilization using vid.stab [no] > > @@ -1521,6 +1522,7 @@ EXTERNAL_LIBRARY_LIST=" > > libssh > > libtesseract > > libtheora > > + libturing > > libtwolame > > libv4l2 > > libvidstab > > @@ -2814,6 +2816,7 @@ libspeex_decoder_deps="libspeex" > > libspeex_encoder_deps="libspeex" > > libspeex_encoder_select="audio_frame_queue" > > libtheora_encoder_deps="libtheora" > > +libturing_encoder_deps="libturing" > > libtwolame_encoder_deps="libtwolame" > > libvo_amrwbenc_encoder_deps="libvo_amrwbenc" > > libvorbis_decoder_deps="libvorbis" > > @@ -5072,6 +5075,7 @@ die_license_disabled gpl frei0r > > die_license_disabled gpl libcdio die_license_disabled gpl > > librubberband die_license_disabled gpl libsmbclient > > +die_license_disabled gpl libturing > > die_license_disabled gpl libvidstab > > die_license_disabled gpl libx264 > > die_license_disabled gpl libx265 > > @@ -5735,6 +5739,7 @@ enabled libssh && require_pkg_config libssh > libssh/sftp.h sftp_init > > enabled libspeex && require_pkg_config speex speex/speex.h > speex_decoder_init -lspeex > > enabled libtesseract && require_pkg_config tesseract tesseract/capi.h > TessBaseAPICreate > > enabled libtheora && require libtheora theora/theoraenc.h > th_info_init -ltheoraenc -ltheoradec -logg > > +enabled libturing && require libturing turing.h turing_version -lturing - > lstdc++ -lboost_chrono -lboost_program_options -lboost_timer - > lboost_system -lboost_filesystem -lhavoc > > These dependencies are kind of a mess. Maybe you can make libturning > include a pkg_config file so we don't have to maintain your library list here? > > - Hendrik > _______________________________________________ > ffmpeg-devel mailing list > ffmpeg-devel@ffmpeg.org > http://ffmpeg.org/mailman/listinfo/ffmpeg-devel ----------------------------- http://www.bbc.co.uk This e-mail (and any attachments) is confidential and may contain personal views which are not the views of the BBC unless specifically stated. If you have received it in error, please delete it from your system. Do not use, copy or disclose the information in any way nor act in reliance on it and notify the sender immediately. Please note that the BBC monitors e-mails sent or received. Further communication will signify your consent to this. -----------------------------
> This lib has a really weird API... Anyway, access to p++ seems unbounded and > could go past the argv array. The string overflow checks also look > questionable. snprintf() returns the size the string would have had and isn't > limited by the buffer passed to it, so the s pointer can go out of bounds > (which is undefined behavior). Also, "end - s" > will underflow, making the attempt to avoid a buffer overflow pointless. The patch we just submitted should address this point: now the buffer size for the command line option depends on the actual number of options passed by the user for the Turing codec. Matteo Naccari ----------------------------- http://www.bbc.co.uk This e-mail (and any attachments) is confidential and may contain personal views which are not the views of the BBC unless specifically stated. If you have received it in error, please delete it from your system. Do not use, copy or disclose the information in any way nor act in reliance on it and notify the sender immediately. Please note that the BBC monitors e-mails sent or received. Further communication will signify your consent to this. -----------------------------
> Back to the review: From first glance, the libturing codec/library (or the > executable only???) seems to have speed presets. Why are these not > exposed to the libavcodec user? All options, including the speed presets, can be specified using -turing-params (e.g. -turing-params speed=value). The reason why we decided to go for this option is because we want to be as less invasive as possible so that if we decide to change the name for a given option the changes will be transparent to FFmpeg. Matteo Naccari > -----Original Message----- > From: ffmpeg-devel [mailto:ffmpeg-devel-bounces@ffmpeg.org] On Behalf > Of Moritz Barsnick > Sent: 19 November 2016 13:29 > To: FFmpeg development discussions and patches <ffmpeg- > devel@ffmpeg.org> > Subject: Re: [FFmpeg-devel] [PATCH] Added the interface for the Turing > codec > > On Fri, Nov 18, 2016 at 20:15:30 +0100, wm4 wrote: > > This lib has a really weird API... > > I can't judge the algorithms or the development direction and stuff - I'm sure > it's all state of the art. But the API sure gives me goosebumps, and I don't > mean the sexy feelgood type. > > Sure, it has all the flexibility, but also almost all the disadvantages of calling an > external program. This makes it look so much like a proof of concept. > > But I'm sure that's not the point. If it turns out to be here to stay, to compete > with x265 in one or the other way, it's probably worth integrating. > > Back to the review: From first glance, the libturing codec/library (or the > executable only???) seems to have speed presets. Why are these not > exposed to the libavcodec user? > > Furthermore: Documentation is missing. > > £0.02, > Moritz > _______________________________________________ > ffmpeg-devel mailing list > ffmpeg-devel@ffmpeg.org > http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
> I hope it copes well with multiple definitions of the same option, like the last > overwriting the previous ones. The latest stable version of the Turing codec deals correctly with multiple definitions of the same option. Matteo Naccari
diff --git a/LICENSE.md b/LICENSE.md index a384fa0..6f9fab8 100644 --- a/LICENSE.md +++ b/LICENSE.md @@ -86,6 +86,7 @@ The following libraries are under GPL: - frei0r - libcdio - librubberband +- libturing - libvidstab - libx264 - libx265 diff --git a/configure b/configure index b5bfad6..47d6b93 100755 --- a/configure +++ b/configure @@ -255,6 +255,7 @@ External library support: --enable-libssh enable SFTP protocol via libssh [no] --enable-libtesseract enable Tesseract, needed for ocr filter [no] --enable-libtheora enable Theora encoding via libtheora [no] + --enable-libturing enable HEVC encoding via libturing [no] --enable-libtwolame enable MP2 encoding via libtwolame [no] --enable-libv4l2 enable libv4l2/v4l-utils [no] --enable-libvidstab enable video stabilization using vid.stab [no] @@ -1521,6 +1522,7 @@ EXTERNAL_LIBRARY_LIST=" libssh libtesseract libtheora + libturing libtwolame libv4l2 libvidstab @@ -2814,6 +2816,7 @@ libspeex_decoder_deps="libspeex" libspeex_encoder_deps="libspeex" libspeex_encoder_select="audio_frame_queue" libtheora_encoder_deps="libtheora" +libturing_encoder_deps="libturing" libtwolame_encoder_deps="libtwolame" libvo_amrwbenc_encoder_deps="libvo_amrwbenc" libvorbis_decoder_deps="libvorbis" @@ -5072,6 +5075,7 @@ die_license_disabled gpl frei0r die_license_disabled gpl libcdio die_license_disabled gpl librubberband die_license_disabled gpl libsmbclient +die_license_disabled gpl libturing die_license_disabled gpl libvidstab die_license_disabled gpl libx264 die_license_disabled gpl libx265 @@ -5735,6 +5739,7 @@ enabled libssh && require_pkg_config libssh libssh/sftp.h sftp_init enabled libspeex && require_pkg_config speex speex/speex.h speex_decoder_init -lspeex enabled libtesseract && require_pkg_config tesseract tesseract/capi.h TessBaseAPICreate enabled libtheora && require libtheora theora/theoraenc.h th_info_init -ltheoraenc -ltheoradec -logg +enabled libturing && require libturing turing.h turing_version -lturing -lstdc++ -lboost_chrono -lboost_program_options -lboost_timer -lboost_system -lboost_filesystem -lhavoc enabled libtwolame && require libtwolame twolame.h twolame_init -ltwolame && { check_lib twolame.h twolame_encode_buffer_float32_interleaved -ltwolame || die "ERROR: libtwolame must be installed and version must be >= 0.3.10"; } diff --git a/libavcodec/Makefile b/libavcodec/Makefile index 82f7fa2..cadefdc 100644 --- a/libavcodec/Makefile +++ b/libavcodec/Makefile @@ -880,6 +880,7 @@ OBJS-$(CONFIG_LIBSPEEX_DECODER) += libspeexdec.o OBJS-$(CONFIG_LIBSPEEX_ENCODER) += libspeexenc.o OBJS-$(CONFIG_LIBTHEORA_ENCODER) += libtheoraenc.o OBJS-$(CONFIG_LIBTWOLAME_ENCODER) += libtwolame.o +OBJS-$(CONFIG_LIBTURING_ENCODER) += libturing.o OBJS-$(CONFIG_LIBVO_AMRWBENC_ENCODER) += libvo-amrwbenc.o OBJS-$(CONFIG_LIBVORBIS_DECODER) += libvorbisdec.o OBJS-$(CONFIG_LIBVORBIS_ENCODER) += libvorbisenc.o \ diff --git a/libavcodec/allcodecs.c b/libavcodec/allcodecs.c index ada9481..0e61a4a 100644 --- a/libavcodec/allcodecs.c +++ b/libavcodec/allcodecs.c @@ -610,6 +610,7 @@ void avcodec_register_all(void) REGISTER_ENCDEC (LIBSPEEX, libspeex); REGISTER_ENCODER(LIBTHEORA, libtheora); REGISTER_ENCODER(LIBTWOLAME, libtwolame); + REGISTER_ENCODER(LIBTURING, libturing); REGISTER_ENCODER(LIBVO_AMRWBENC, libvo_amrwbenc); REGISTER_ENCDEC (LIBVORBIS, libvorbis); REGISTER_ENCDEC (LIBVPX_VP8, libvpx_vp8); diff --git a/libavcodec/libturing.c b/libavcodec/libturing.c new file mode 100644 index 0000000..3191a41 --- /dev/null +++ b/libavcodec/libturing.c @@ -0,0 +1,229 @@ +/* + * libturing encoder + * + * Copyright (c) 2016 Turing Codec contributors + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include <turing.h> +#include <float.h> +#include "libavutil/internal.h" +#include "libavutil/common.h" +#include "libavutil/opt.h" +#include "libavutil/pixdesc.h" +#include "avcodec.h" +#include "internal.h" + +typedef struct libturingEncodeContext { + const AVClass *class; + turing_encoder *encoder; + const char *options; +} libturingEncodeContext; + +static av_cold int libturing_encode_close(AVCodecContext *avctx) +{ + libturingEncodeContext *ctx = avctx->priv_data; + + if (ctx->encoder) + turing_destroy_encoder(ctx->encoder); + + return 0; +} + +static av_cold int libturing_encode_init(AVCodecContext *avctx) +{ + libturingEncodeContext *ctx = avctx->priv_data; + + char options[1024]; + char* s = options; + char *end = &options[sizeof(options)]; + + char const* argv[32]; + char const** p = argv; + turing_encoder_settings settings; + + *p++ = s; + *p++ = s += 1 + snprintf(s, end - s, "turing"); + *p++ = s += 1 + snprintf(s, end - s, "--input-res=%dx%d", avctx->width, avctx->height); + *p++ = s += 1 + snprintf(s, end - s, "--frame-rate=%f", (double)avctx->time_base.den / (avctx->time_base.num * avctx->ticks_per_frame)); + *p++ = s += 1 + snprintf(s, end - s, "--frames=0"); + + { + int const bit_depth = av_pix_fmt_desc_get(avctx->pix_fmt)->comp[0].depth; + if (bit_depth != 8 && bit_depth != 10) { + av_log(avctx, AV_LOG_ERROR, "Encoder input must be 8- or 10-bit.\n"); + turing_destroy_encoder(ctx->encoder); + return AVERROR_INVALIDDATA; + } + *p++ = s += 1 + snprintf(s, end - s, "--bit-depth=%d", bit_depth); + *p++ = s += 1 + snprintf(s, end - s, "--internal-bit-depth=%d", bit_depth); + } + + if (avctx->sample_aspect_ratio.num > 0 && avctx->sample_aspect_ratio.den > 0) { + int sar_num, sar_den; + + av_reduce(&sar_num, &sar_den, + avctx->sample_aspect_ratio.num, + avctx->sample_aspect_ratio.den, 65535); + + *p++ = s += 1 + snprintf(s, end - s, "--sar=%d:%d", sar_num, sar_den); + } + + if (ctx->options) { + AVDictionary *dict = NULL; + AVDictionaryEntry *en = NULL; + + if (!av_dict_parse_string(&dict, ctx->options, "=", ":", 0)) { + while ((en = av_dict_get(dict, "", en, AV_DICT_IGNORE_SUFFIX))) { + int const illegal_option = + !strcmp("input-res", en->key) || + !strcmp("frame-rate", en->key) || + !strcmp("f", en->key) || + !strcmp("frames", en->key) || + !strcmp("sar", en->key) || + !strcmp("bit-depth", en->key) || + !strcmp("internal-bit-depth", en->key); + if (illegal_option) + av_log(avctx, AV_LOG_WARNING, "%s=%s ignored.\n", en->key, en->value); + else + *p++ = s += 1 + snprintf(s, end - s, "--%s=%s", en->key, en->value); + } + av_dict_free(&dict); + } + } + + *p++ = s += 1 + snprintf(s, end - s, "dummy-input-filename"); + + settings.argv = argv; + settings.argc = p - argv - 1; + + for (int i=0; i<settings.argc; ++i) + av_log(avctx, AV_LOG_INFO, "arg %d: %s\n", i, settings.argv[i]); + + ctx->encoder = turing_create_encoder(settings); + + if (!ctx->encoder) { + av_log(avctx, AV_LOG_ERROR, "Failed to create libturing encoder.\n"); + return AVERROR_INVALIDDATA; + } + + if (avctx->flags & AV_CODEC_FLAG_GLOBAL_HEADER) { + turing_bitstream const *bitstream; + bitstream = turing_encode_headers(ctx->encoder); + if (bitstream->size <= 0) { + av_log(avctx, AV_LOG_ERROR, "Failed to encode headers.\n"); + turing_destroy_encoder(ctx->encoder); + return AVERROR_INVALIDDATA; + } + + avctx->extradata_size = bitstream->size; + + avctx->extradata = av_malloc(avctx->extradata_size + AV_INPUT_BUFFER_PADDING_SIZE); + if (!avctx->extradata) { + av_log(avctx, AV_LOG_ERROR, "Failed to allocate HEVC extradata %d bytes\n", avctx->extradata_size); + turing_destroy_encoder(ctx->encoder); + return AVERROR(ENOMEM); + } + + memcpy(avctx->extradata, bitstream->p, bitstream->size); + } + + return 0; +} + +static int libturing_encode_frame(AVCodecContext *avctx, AVPacket *pkt, const AVFrame *pic, int *got_packet) +{ + libturingEncodeContext *ctx = avctx->priv_data; + turing_encoder_output const *output; + int ret = 0; + + if (pic) { + turing_picture picture; + + picture.image[0].p = pic->data[0]; + picture.image[1].p = pic->data[1]; + picture.image[2].p = pic->data[2]; + picture.image[0].stride = pic->linesize[0]; + picture.image[1].stride = pic->linesize[1]; + picture.image[2].stride = pic->linesize[2]; + picture.pts = pic->pts; + + output = turing_encode_picture(ctx->encoder, &picture); + } else { + output = turing_encode_picture(ctx->encoder, 0); + } + + if (output->bitstream.size < 0) + return AVERROR_EXTERNAL; + + if (output->bitstream.size ==0) + return 0; + + ret = ff_alloc_packet(pkt, output->bitstream.size); + if (ret < 0) { + av_log(avctx, AV_LOG_ERROR, "Error getting output packet.\n"); + return ret; + } + + memcpy(pkt->data, output->bitstream.p, output->bitstream.size); + + pkt->pts = output->pts; + pkt->dts = output->dts; + if (output->keyframe) + pkt->flags |= AV_PKT_FLAG_KEY; + + *got_packet = 1; + return 0; +} + +static const enum AVPixelFormat turing_csp[] = { + AV_PIX_FMT_YUV420P10, + AV_PIX_FMT_YUV420P, + AV_PIX_FMT_NONE +}; + +static av_cold void libturing_encode_init_csp(AVCodec *codec) +{ + codec->pix_fmts = turing_csp; +} + +static const AVOption options[] = { + { "turing-params", "configure additional turing encoder paremeters", offsetof(libturingEncodeContext, options), AV_OPT_TYPE_STRING,{ 0 }, 0, 0, AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM }, + { NULL } +}; + +static const AVClass class = { + .class_name = "libturing", + .item_name = av_default_item_name, + .option = options, + .version = LIBAVUTIL_VERSION_INT, +}; + +AVCodec ff_libturing_encoder = { + .name = "libturing", + .long_name = NULL_IF_CONFIG_SMALL("libturing HEVC"), + .type = AVMEDIA_TYPE_VIDEO, + .id = AV_CODEC_ID_HEVC, + .init = libturing_encode_init, + .init_static_data = libturing_encode_init_csp, + .encode2 = libturing_encode_frame, + .close = libturing_encode_close, + .priv_data_size = sizeof(libturingEncodeContext), + .priv_class = &class, + .capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_AUTO_THREADS, +};