[vlc-devel] [PATCH] Add x265 params support to VLC streaming module
Hugo Beauzée-Luyssen
hugo at beauzee.fr
Wed Jun 8 14:18:18 CEST 2016
Hi,
On 06/08/2016 01:55 PM, Mahesh wrote:
> ---
> modules/codec/Makefile.am | 4 +-
> modules/codec/x265.c | 1072 +++++++++++++++++---
> .../gui/qt/components/sout/profile_selector.cpp | 20 +-
UI changes should be in a separate patch
> 3 files changed, 975 insertions(+), 121 deletions(-)
>
> diff --git a/modules/codec/Makefile.am b/modules/codec/Makefile.am
> index c0f8d32..94ceaf2 100644
> --- a/modules/codec/Makefile.am
> +++ b/modules/codec/Makefile.am
> @@ -450,10 +450,10 @@ endif
> ### X26x encoders ###
>
> libx265_plugin_la_SOURCES = codec/x265.c
> -libx265_plugin_la_CPPFLAGS = $(AM_CPPFLAGS)
> +libx265_plugin_la_CPPFLAGS = $(AM_CPPFLAGS) -DMODULE_NAME_IS_x265
Why? As far as I can see this file is only used by the x265 module
> libx265_plugin_la_CFLAGS = $(AM_CFLAGS) $(CFLAGS_x265)
> libx265_plugin_la_LDFLAGS = $(AM_LDFLAGS) $(LDFLAGS_x265) -rpath '$(codecdir)'
> -libx265_plugin_la_LIBADD = $(LIBS_x265)
> +libx265_plugin_la_LIBADD = $(LIBS_x265) $(LIBM)
> EXTRA_LTLIBRARIES += libx265_plugin.la
> codec_LTLIBRARIES += $(LTLIBx265)
>
> diff --git a/modules/codec/x265.c b/modules/codec/x265.c
> index 2fac637..0b76b3f 100644
> --- a/modules/codec/x265.c
> +++ b/modules/codec/x265.c
> @@ -4,6 +4,8 @@
> * Copyright (C) 2013 Rafaël Carré
> *
> * Authors: Rafaël Carré <funman at videolanorg>
> + * Mahesh Pittala <mahesh at multicorewareinc.com>
> + * Gopi Akisetty <gopi.satykrishna at multicorewareinc.com>
> *
> * This program is free software; you can redistribute it and/or modify
> * it under the terms of the GNU General Public License as published by
> @@ -23,6 +25,7 @@
> /*****************************************************************************
> * Preamble
> *****************************************************************************/
> +
> #ifdef HAVE_CONFIG_H
> # include "config.h"
> #endif
> @@ -30,47 +33,966 @@
> #define VLC_MODULE_LICENSE VLC_LICENSE_GPL_2_PLUS
> #include <vlc_common.h>
> #include <vlc_plugin.h>
> -#include <vlc_threads.h>
> #include <vlc_sout.h>
> #include <vlc_codec.h>
> +#include <vlc_charset.h>
> +#include <vlc_cpu.h>
> +#include <math.h>
> +#include <stdio.h>
> +#ifdef PTW32_STATIC_LIB
> +#include <pthread.h>
Is there a valid reason for not using libblvcore's threads?
> +#endif
>
> +#include <assert.h>
> #include <x265.h>
>
> +#ifdef MODULE_NAME_IS_x265
> +#define SOUT_CFG_PREFIX "sout-x265-"
> +#endif
> +
> +#define INT_MAX 2147483647
> +
> /*****************************************************************************
> * Module descriptor
> *****************************************************************************/
> -static int Open (vlc_object_t *);
> -static void Close(vlc_object_t *);
> +static int Open ( vlc_object_t * );
> +static void Close( vlc_object_t * );
> +static void x265_log( void *, int i_level, const char *psz, va_list );
> +
> +#define LONGTEXT N_( "Please go through x265 readthedocs for full " \
> + "information - https://x265.readthedocs.org/en/default/cli.html " )
> +
> +/* Frame-type options */
> +
> +#define KEYINT_TEXT N_("Max intra period in frames")
> +
> +#define MIN_KEYINT_TEXT N_("Minimum GOP size")
> +
> +#define OPENGOP_TEXT N_("Enable open GOP, allow I-slices to be non-IDR")
> +
> +#define SCENE_TEXT N_("Extra I-frames aggressivity")
> +
> +#define BFRAMES_TEXT N_("Maxinum number of consecutive B-frames")
> +
> +#define B_ADAPT_TEXT N_("Set the level of effort in determining B frame " \
> + "placement")
> +
> +#define B_BIAS_TEXT N_("Bias towards B frames in slicetype decision")
> +
> +#define BPYRAMID_TEXT N_("Use B-frames as references, when possible")
> +
> +#define REF_TEXT N_("Max number of L0 references to be allowed")
> +
> +#define FILTER_TEXT N_("Loop filter AlphaC0 and Beta parameters alpha:beta")
> +
> +#define LEVEL_TEXT N_("HEVC level")
> +
> +#define PROFILE_TEXT N_("HEVC profile")
> +
> +#define INTERLACED_TEXT N_("Interlaced mode")
> +
> +#define INTRAREFRESH_TEXT N_("Enables Periodic Intra Refresh(PIR) instead of" \
> + "keyframe insertion")
> +
> +#define REPEATHEADERS_TEXT N_("If enabled, x265 will emit VPS, SPS, and PPS " \
> + "headers with every keyframe")
> +
> +/* Ratecontrol */
> +
> +#define QP_TEXT N_("Set QP")
> +
> +#define CRF_TEXT N_("Quality-controlled variable bitrate")
> +
> +#define BITRATE_TEXT N_("Bitrate")
> +
> +#define VBV_MAXRATE_TEXT N_("Max local bitrate")
> +
> +#define VBV_BUFSIZE_TEXT N_("VBV buffer")
> +
> +#define VBV_INIT_TEXT N_("Initial VBV buffer occupancy")
> +
> +#define AQ_MODE_TEXT N_("Adaptive Quantization operating mode")
> +
> +#define AQ_STRENGTH_TEXT N_("Adjust the strength of the adaptive " \
> + "quantization offsets")
> +
> +#define IPRATIO_TEXT N_("QP factor between I and P")
> +
> +#define PBRATIO_TEXT N_("QP factor between P and B")
> +
> +#define CHROMAB_QP_OFFSET_TEXT N_("Offset of Cb chroma QP from the luma " \
> + "QP selected by rate control")
> +
> +#define CHROMAR_QP_OFFSET_TEXT N_("Offset of Cr chroma QP from the luma " \
> + "QP selected by rate contro")
> +
> +#define PASS_TEXT N_("Enable multi-pass rate control mode")
> +
> +#define QCOMP_TEXT N_("qComp sets the quantizer curve compression factor")
> +
> +#define CPLXBLUR_TEXT N_("Reduce fluctuations in QP")
> +
> +#define QBLUR_TEXT N_("temporally blur complexity")
> +
> +/* Analysis */
> +
> +#define WEIGHTB_TEXT N_("Enable weighted prediction in B slices")
> +
> +#define WEIGHTP_TEXT N_("Enable weighted prediction in P slices")
> +
> +
> +#define ME_TEXT N_("Integer pixel motion estimation method")
> +
> +#define MERANGE_TEXT N_("Maximum motion vector search range")
> +
> +#define PSY_RD_TEXT N_("Strength of psychovisual optimization")
> +
> +#define SUBME_TEXT N_("Amount of subpel refinement to perform")
> +
> +#define NRINTRA_TEXT N_("Noise reduction")
> +
> +#define NRINTER_TEXT N_("Noise reduction")
> +
> +#define TSKIPFAST_TEXT N_("Only evaluate transform skip for NxN intra " \
> + "predictions (4x4 blocks)")
> +
> +#define CTU_TEXT N_("Maximum CU size (width and height)")
> +
> +#define MINCUSIZE_TEXT N_("Minimum CU size (width and height)")
> +
> +#define RCLOOKAHEAD_TEXT N_("Number of frames for slice-type decision" \
> + "lookahead")
> +
> +#define LIMITREFS_TEXT N_("limit the references analyzed")
> +
> +#define RECT_TEXT N_("Enable analysis of rectangular motion partitions" \
> + "Nx2N and 2NxN")
> +
> +#define AMP_TEXT N_("Enable analysis of asymmetric motion partitions " \
> + "(75/25 splits, four directions)")
> +
> +#define LIMITMODES_TEXT N_("limit-modes will limit modes analyzed for " \
> + "each CU using cost metrics from the 4 sub-CUs")
> +
> +#define MAXMERGE_TEXT N_("Maximum number of neighbor (spatial and temporal)" \
> + "candidate blocks")
> +
> +#define EARLYSKIP_TEXT N_("Measure 2Nx2N merge candidates first, if no" \
> + "residual is found, additional modes at that depth are not analysed")
> +
> +#define FASTINTRA_TEXT N_("Perform an initial scan of every fifth intra")
> +
> +#define BINTRA_TEXT N_("Evaluation of intra modes in B slices")
> +
> +#define SAO_TEXT N_("Toggle Sample Adaptive Offset loop filter")
> +
> +#define SIGNHIDE_TEXT N_("Hide sign bit of one coeff per TU (rdo)")
> +
> +#define CUTREE_TEXT N_("Enable the use of lookaheads lowres motion" \
> + "vector fields")
> +
> +#define RD_TEXT N_("Level of RDO in mode decision")
> +
> +#define RDOQLEVEL_TEXT N_("amount of rate-distortion analysis to use within" \
> + "quantization")
> +
> +#define TUINTRA_TEXT N_("Limits the number of extra recursion depth which" \
> + "can be attempted for intra coded units")
> +
> +#define TUINTER_TEXT N_("Limits the number of extra recursion depth which" \
> + "can be attempted for inter coded units")
> +
> +#define QPSTEP_TEXT N_("The maximum single adjustment in QP allowed")
> +
> +#define PSYRDOQ_TEXT N_("Influence rate distortion optimized quantization by" \
> + "favoring higher energy in the reconstructed image")
> +
> +#define FRAMETHREADS_TEXT N_("Number of concurrently encoded frames")
> +
> +#define PMODE_TEXT N_("Parallel mode decision, or distributed mode analysis")
> +
> +#define PME_TEXT N_("Parallel motion estimation")
> +
> +#define QGSIZE_TEXT N_("Minimum CU size at which QP can be adjusted")
> +
> +
> +/* Input/Output */
> +
> +#define ASM_TEXT N_("CPU optimizations")
> +
> +#define PSNR_TEXT N_("PSNR computation")
> +
> +#define SSIM_TEXT N_("SSIM computation")
> +
> +#define AUD_TEXT N_("Access unit delimiters")
> +
> +#define LOOKAHEAD_SLICES_TEXT N_("Use multiple worker threads to measure the estimated cost " \
> + "of each frame within the lookahead")
> +
> +#define HRD_TEXT N_("HRD-timing information")
> +
> +#define TUNE_TEXT N_("Default tune setting used" )
> +
> +#define PRESET_TEXT N_("Default preset setting used" )
> +
> +
> +static const char *const enc_me_list[] =
> + { "dia", "hex", "umh", "star", "full" };
> +static const char *const enc_me_list_text[] =
> + { N_("dia"), N_("hex"), N_("umh"), N_("star"), N_("full") };
>
> vlc_module_begin ()
> - set_description(N_("H.265/HEVC encoder (x265)"))
> - set_capability("encoder", 200)
> - set_callbacks(Open, Close)
> - set_category(CAT_INPUT)
> - set_subcategory(SUBCAT_INPUT_VCODEC)
> +
> +#ifdef MODULE_NAME_IS_x265
> + set_description( N_("H.265/HEVC encoder (x265)"))
> + set_capability( "encoder", 200 )
> + set_callbacks( Open, Close )
> + set_category( CAT_INPUT )
> + set_subcategory( SUBCAT_INPUT_VCODEC )
> +#endif
> +/* Frame-type options */
> +
> + add_integer( SOUT_CFG_PREFIX "keyint", 250, KEYINT_TEXT,
> + LONGTEXT, false )
> +
> + add_integer( SOUT_CFG_PREFIX "min-keyint", 25, MIN_KEYINT_TEXT,
> + LONGTEXT, true )
> +
> + add_bool( SOUT_CFG_PREFIX "open-gop", true, OPENGOP_TEXT,
> + LONGTEXT, true )
> +
> + add_integer( SOUT_CFG_PREFIX "scenecut", 40, SCENE_TEXT,
> + LONGTEXT, true )
> + change_integer_range( -1, 100 )
> +
> + add_integer( SOUT_CFG_PREFIX "bframes", 4, BFRAMES_TEXT,
> + LONGTEXT, true )
> + change_integer_range( 0, 16 )
> +
> + add_integer( SOUT_CFG_PREFIX "b-adapt", 2, B_ADAPT_TEXT,
> + LONGTEXT, true )
> + change_integer_range( 0, 2 )
> +
> + add_integer( SOUT_CFG_PREFIX "bframe-bias", 0, B_BIAS_TEXT,
> + LONGTEXT, true )
> + change_integer_range( -100, 100 )
> +
> + add_bool( SOUT_CFG_PREFIX "b-pyramid", true, BPYRAMID_TEXT,
> + LONGTEXT, true )
> +
> + add_bool( SOUT_CFG_PREFIX "b-pyramid", true, BPYRAMID_TEXT,
> + LONGTEXT, true )
> +
> + add_integer( SOUT_CFG_PREFIX "ref", 3, REF_TEXT,
> + LONGTEXT, true )
> + change_integer_range( 1, 16 )
> +
> + add_string( SOUT_CFG_PREFIX "deblock", "0:0", FILTER_TEXT,
> + LONGTEXT, true )
> +
> + add_float( SOUT_CFG_PREFIX "psy-rd", 1.0, PSY_RD_TEXT,
> + LONGTEXT, true )
> +
> + add_string( SOUT_CFG_PREFIX "level-idc", "0", LEVEL_TEXT,
> + LONGTEXT, false )
> +
> + add_string( SOUT_CFG_PREFIX "profile", "main", PROFILE_TEXT,
> + LONGTEXT, false )
> + vlc_config_set (VLC_CONFIG_LIST,
> + (sizeof(x265_profile_names) / sizeof (char*)) - 1,
> + x265_profile_names, x265_profile_names);
> +
> + add_bool( SOUT_CFG_PREFIX "interlace", false, INTERLACED_TEXT, LONGTEXT,
> + true )
> +
> + add_bool( SOUT_CFG_PREFIX "hrd", false, HRD_TEXT, LONGTEXT, true )
> +
> + add_bool( SOUT_CFG_PREFIX "repeat-headers", false, REPEATHEADERS_TEXT,
> + LONGTEXT, true )
> +
> +
> +
> +/* Ratecontrol */
> +
> + add_integer( SOUT_CFG_PREFIX "qp", 0, QP_TEXT, LONGTEXT,
> + true )
> + change_integer_range( 0, 51 ) /* QP 0 -> lossless encoding */
> +
> + add_integer( SOUT_CFG_PREFIX "bitrate", 0, BITRATE_TEXT,
> + LONGTEXT, true )
> +
> + add_integer( SOUT_CFG_PREFIX "crf", 28, CRF_TEXT,
> + LONGTEXT, true )
> + change_integer_range( 0, 51 )
> +
> + add_integer( SOUT_CFG_PREFIX "vbv-maxrate", 0, VBV_MAXRATE_TEXT,
> + LONGTEXT, true )
> +
> + add_integer( SOUT_CFG_PREFIX "vbv-bufsize", 0, VBV_BUFSIZE_TEXT,
> + LONGTEXT, true )
> +
> + add_float( SOUT_CFG_PREFIX "vbv-init", 0.9, VBV_INIT_TEXT,
> + LONGTEXT, true )
> + change_float_range( 0, 1 )
> +
> + add_integer( SOUT_CFG_PREFIX "cbqpoffs", 0, CHROMAB_QP_OFFSET_TEXT,
> + LONGTEXT, true )
> +
> + add_integer( SOUT_CFG_PREFIX "crqpoffs", 0, CHROMAR_QP_OFFSET_TEXT,
> + LONGTEXT, true )
> +
> + add_float( SOUT_CFG_PREFIX "ipratio", 1.40, IPRATIO_TEXT,
> + LONGTEXT, true )
> + change_float_range( 1, 2 )
> +
> + add_float( SOUT_CFG_PREFIX "pbratio", 1.30, PBRATIO_TEXT,
> + LONGTEXT, true )
> + change_float_range( 1, 2 )
> +
> + add_integer( SOUT_CFG_PREFIX "pass", 0, PASS_TEXT,
> + LONGTEXT, false )
> + change_integer_range( 0, 3 )
> +
> + add_float( SOUT_CFG_PREFIX "qcomp", 0.60, QCOMP_TEXT,
> + LONGTEXT, true )
> + change_float_range( 0, 1 )
> +
> + add_integer( SOUT_CFG_PREFIX "aq-mode", X265_AQ_VARIANCE, AQ_MODE_TEXT,
> + LONGTEXT, true )
> + change_integer_range( 0, 3)
> +
> + add_float( SOUT_CFG_PREFIX "aq-strength", 1.0, AQ_STRENGTH_TEXT,
> + LONGTEXT, true )
> +
> + add_float( SOUT_CFG_PREFIX "cplxblur", 20.0, CPLXBLUR_TEXT,
> + LONGTEXT, true )
> +
> + add_float( SOUT_CFG_PREFIX "qblur", 0.5, QBLUR_TEXT,
> + LONGTEXT, true )
> +
> +/* Analysis */
> +
> +
> + add_bool( SOUT_CFG_PREFIX "weightb", false, WEIGHTB_TEXT,
> + LONGTEXT, true )
> +
> + add_bool( SOUT_CFG_PREFIX "tskip-fast", false, TSKIPFAST_TEXT,
> + LONGTEXT, true )
> +
> + add_bool( SOUT_CFG_PREFIX "tskip-fast", false, TSKIPFAST_TEXT,
> + LONGTEXT, true )
> +
> + add_bool( SOUT_CFG_PREFIX "weightp", true, WEIGHTP_TEXT,
> + LONGTEXT, true )
> +
> + add_string( SOUT_CFG_PREFIX "me", "hex", ME_TEXT,
> + LONGTEXT, true )
> + change_string_list( enc_me_list, enc_me_list_text )
> +
> + add_integer( SOUT_CFG_PREFIX "merange", 57, MERANGE_TEXT,
> + LONGTEXT, true )
> +
> + add_integer( SOUT_CFG_PREFIX "subme", 2, SUBME_TEXT,
> + LONGTEXT, true )
> +
> + add_integer( SOUT_CFG_PREFIX "lookahead-slices", 0, LOOKAHEAD_SLICES_TEXT,
> + LONGTEXT, true )
> +
> + add_bool( SOUT_CFG_PREFIX "intra-refresh", false, INTRAREFRESH_TEXT,
> + LONGTEXT, true )
> +
> + add_integer( SOUT_CFG_PREFIX "nr-intra", 0, NRINTRA_TEXT,
> + LONGTEXT, true )
> +
> + add_integer( SOUT_CFG_PREFIX "nr-inter", 0, NRINTER_TEXT,
> + LONGTEXT, true )
> +
> + add_integer( SOUT_CFG_PREFIX "ctu", 64, CTU_TEXT,
> + LONGTEXT, true )
> +
> + add_integer( SOUT_CFG_PREFIX "min-cu-size", 8, MINCUSIZE_TEXT,
> + LONGTEXT, true )
> +
> + add_integer( SOUT_CFG_PREFIX "rc-lookahead", 20, RCLOOKAHEAD_TEXT,
> + LONGTEXT, true )
> +
> + add_integer( SOUT_CFG_PREFIX "limit-refs", 3, LIMITREFS_TEXT,
> + LONGTEXT, true )
> +
> + add_bool( SOUT_CFG_PREFIX "rect", false, RECT_TEXT,
> + LONGTEXT, true )
> +
> + add_bool( SOUT_CFG_PREFIX "amp", false, AMP_TEXT,
> + LONGTEXT, true )
> +
> + add_bool( SOUT_CFG_PREFIX "limit-modes", false, LIMITMODES_TEXT,
> + LONGTEXT, true )
> +
> + add_integer( SOUT_CFG_PREFIX "max-merge", 2, MAXMERGE_TEXT,
> + LONGTEXT, true )
> +
> + add_bool( SOUT_CFG_PREFIX "early-skip", false, EARLYSKIP_TEXT,
> + LONGTEXT, true )
> +
> + add_bool( SOUT_CFG_PREFIX "fast-intra", false, FASTINTRA_TEXT,
> + LONGTEXT, true )
> +
> + add_bool( SOUT_CFG_PREFIX "b-intra", false, BINTRA_TEXT,
> + LONGTEXT, true )
> +
> + add_bool( SOUT_CFG_PREFIX "sao", true, SAO_TEXT,
> + LONGTEXT, true )
> +
> + add_bool( SOUT_CFG_PREFIX "signhide", true, SIGNHIDE_TEXT,
> + LONGTEXT, true )
> +
> + add_bool( SOUT_CFG_PREFIX "cutree", true, CUTREE_TEXT,
> + LONGTEXT, true )
> +
> + add_integer( SOUT_CFG_PREFIX "rd", 3, RD_TEXT,
> + LONGTEXT, true )
> +
> + add_integer( SOUT_CFG_PREFIX "rdoq-level", 0, RDOQLEVEL_TEXT,
> + LONGTEXT, true )
> +
> + add_integer( SOUT_CFG_PREFIX "tu-intra", 1, TUINTRA_TEXT,
> + LONGTEXT, true )
> +
> + add_integer( SOUT_CFG_PREFIX "tu-inter", 1, TUINTER_TEXT,
> + LONGTEXT, true )
> +
> + add_integer( SOUT_CFG_PREFIX "qpstep", 4, QPSTEP_TEXT,
> + LONGTEXT, true )
> +
> + add_float( SOUT_CFG_PREFIX "psy-rdoq", 0.0, PSYRDOQ_TEXT,
> + LONGTEXT, true )
> +
> + add_integer( SOUT_CFG_PREFIX "frame-threads", 0, FRAMETHREADS_TEXT,
> + LONGTEXT, true )
> +
> + add_bool( SOUT_CFG_PREFIX "pmode", false, PMODE_TEXT,
> + LONGTEXT, true )
> +
> + add_bool( SOUT_CFG_PREFIX "pme", false, PME_TEXT,
> + LONGTEXT, true )
> +
> + add_integer( SOUT_CFG_PREFIX "qg-size", 32, QGSIZE_TEXT,
> + LONGTEXT, true )
> +
> +
> +/* Input/Output */
> +
> + add_bool( SOUT_CFG_PREFIX "asm", true, ASM_TEXT,
> + LONGTEXT, true )
> +
> + //x265 psnr = 1 (default). disable PSNR computation for speed.
> + add_bool( SOUT_CFG_PREFIX "psnr", false, PSNR_TEXT,
> + LONGTEXT, true )
> +
> + /* x265 ssim = 1 (default). disable SSIM computation for speed. */
> + add_bool( SOUT_CFG_PREFIX "ssim", false, SSIM_TEXT,
> + LONGTEXT, true )
> +
> + add_bool( SOUT_CFG_PREFIX "aud", false, AUD_TEXT,
> + LONGTEXT, true )
> +
> + add_string( SOUT_CFG_PREFIX "preset", NULL , PRESET_TEXT , PRESET_TEXT, false )
> + vlc_config_set (VLC_CONFIG_LIST,
> + (sizeof(x265_preset_names) / sizeof (char*)) - 1,
> + x265_preset_names, x265_preset_names);
> +
> + add_string( SOUT_CFG_PREFIX "tune", NULL , TUNE_TEXT, TUNE_TEXT, false )
> + vlc_config_set (VLC_CONFIG_LIST,
> + (sizeof(x265_tune_names) / sizeof (char*)) - 1,
> + x265_tune_names, x265_tune_names);
> +
> vlc_module_end ()
>
> +/*****************************************************************************
> + * Local prototypes
> + *****************************************************************************/
> +static const char *const ppsz_sout_options[] = {
> + "aud", "bframes", "b-pyramid", "b-adapt", "bframe-bias", "cbqpoffs",
> + "crqpoffs", "cplxblur", "crf", "deblock", "interlace", "ipratio", "keyint",
> + "level-idc", "me", "merange", "min-keyint", "pass", "pbratio", "psnr",
> + "qblur", "qp", "qcomp", "ref", "scenecut", "ssim", "subme", "vbv-bufsize",
> + "vbv-init", "vbv-maxrate", "weightb", "weightp", "aq-mode", "aq-strength",
> + "psy-rd", "profile", "lookahead-slices", "intra-refresh", "hrd", "tune",
> + "preset", "open-gop", "bitrate", "nr-intra", "nr-inter", "tskip-fast",
> + "repeat-headers", "ctu", "min-cu-size", "rc-lookahead", "limit-refs",
> + "rect", "amp", "limit-modes", "max-merge", "early-skip", "fast-intra",
> + "b-intra", "sao", "signhide", "cutree", "rd", "rdoq-level",
> + "tu-intra", "tu-inter", "tune", "qpstep", "psy-rdoq", "frame-threads",
> + "pmode", "pme", "qg-size",
> + NULL
> +};
> +
> +static block_t *Encode( encoder_t *, picture_t * );
> +
> struct encoder_sys_t
> {
> x265_encoder *h;
> x265_param param;
> -
> mtime_t i_initial_delay;
> -
> - mtime_t dts;
> - mtime_t initial_date;
> + char *psz_stat_name;
> + int i_sei_size;
> + uint32_t i_colorspace;
> + uint8_t *p_sei;
> +
> + mtime_t dts;
> + mtime_t initial_date;
Unrelated whitespace changes & unrequired reordering
> #ifndef NDEBUG
> mtime_t start;
> +#endif
> +
> +};
> +
> +#ifdef PTW32_STATIC_LIB
> +static vlc_mutex_t pthread_win32_mutex = VLC_STATIC_MUTEX;
> +static int pthread_win32_count = 0;
> #endif
> +
> +/*****************************************************************************
> + * Open: probe the encoder
> + *****************************************************************************/
> +static int Open ( vlc_object_t *p_this )
> +{
> + encoder_t *p_enc = (encoder_t *)p_this;
> + encoder_sys_t *p_sys;
> + int i_val, j_val;
> + char *psz_val;
> + int i_qmin = 0, i_qmax = 0;
> + x265_nal *nal;
> + int i, i_nal;
> + bool fullrange = false;
> + if( p_enc->fmt_out.i_codec != VLC_CODEC_HEVC && !p_enc->b_force )
> + {
> + return VLC_EGENERIC;
> + }
> +
> + config_ChainParse( p_enc, SOUT_CFG_PREFIX, ppsz_sout_options, p_enc->p_cfg );
> +
> + p_enc->fmt_out.i_cat = VIDEO_ES;
> +
> + p_enc->fmt_out.i_codec = VLC_CODEC_HEVC;
> +
> + p_enc->p_sys = p_sys = malloc( sizeof( encoder_sys_t ) );
> + if( !p_sys )
> + return VLC_ENOMEM;
> +
> + p_enc->fmt_in.i_codec = VLC_CODEC_I420;
> + p_sys->i_colorspace = X265_CSP_I420;
> +
> + p_enc->pf_encode_video = Encode;
> + p_enc->pf_encode_audio = NULL;
> + p_sys->i_initial_delay = 0;
> + p_sys->psz_stat_name = NULL;
> + p_sys->i_sei_size = 0;
> + p_sys->p_sei = NULL;
> +
> + char *psz_preset = var_GetString( p_enc, SOUT_CFG_PREFIX "preset" );
> + char *psz_tune = var_GetString( p_enc, SOUT_CFG_PREFIX "tune" );
> + if( *psz_preset == '\0' )
What happens if psz_preset is NULL?
Also, see var_GetNonEmptyString
> + {
> + free(psz_preset);
Potentially leaking psz_tune
> + psz_preset = NULL;
> + }
> +
> + x265_param_default_preset( &p_sys->param, psz_preset, psz_tune );
> +
> + free( psz_preset );
> + free( psz_tune );
> + p_sys->param.internalCsp = p_sys->i_colorspace;
> +
> + if( fabs(var_GetFloat( p_enc, SOUT_CFG_PREFIX "qcomp" ) - 0.60) > 0.005 )
> + p_sys->param.rc.qCompress = var_GetFloat( p_enc, SOUT_CFG_PREFIX "qcomp" );
> +
> + /* transcode-default bitrate is 0,
> + * set more to ABR if user specifies bitrate */
> + i_val = var_GetInteger( p_enc, SOUT_CFG_PREFIX "bitrate" );
> + j_val = var_GetInteger( p_enc, SOUT_CFG_PREFIX "qp" );
> + if( i_val > 0 || p_enc->fmt_out.i_bitrate > 0)
> + {
> + p_sys->param.rc.bitrate = ((i_val > 0) ? i_val : p_enc->fmt_out.i_bitrate/1000);
> + p_sys->param.rc.rateControlMode = X265_RC_ABR;
> + }
> + else if( j_val > 0)
> + {
> + if( j_val > 0 && j_val <= 51 )
> + {
> + p_sys->param.rc.qp = j_val;
> + p_sys->param.rc.rateControlMode = X265_RC_CQP;
> + }
> + }
> + else /* Set default to CRF */
> + {
> + i_val = var_GetInteger( p_enc, SOUT_CFG_PREFIX "crf" );
> + if( i_val > 0 && i_val <= 51 )
> + {
> + p_sys->param.rc.rfConstant = i_val;
> + p_sys->param.rc.rateControlMode = X265_RC_CRF;
> + }
> + }
> +
> + p_sys->param.rc.vbvBufferInit = var_GetFloat( p_enc,
> + SOUT_CFG_PREFIX "vbv-init" );
> + p_sys->param.rc.vbvBufferSize = var_GetInteger( p_enc,
> + SOUT_CFG_PREFIX "vbv-bufsize" );
> +
> + /* max bitrate = average bitrate -> CBR */
> + p_sys->param.rc.vbvMaxBitrate = var_GetInteger( p_enc, SOUT_CFG_PREFIX "vbv-maxrate" );
> + if( p_sys->param.rc.vbvMaxBitrate && p_sys->param.rc.rateControlMode != X265_RC_ABR )
> + p_enc->fmt_out.i_bitrate = p_sys->param.rc.vbvMaxBitrate * 1000;
> +
> + psz_val = var_GetString( p_enc, SOUT_CFG_PREFIX "deblock" );
> + if( psz_val )
> + {
> + if( atoi( psz_val ) != 0 )
> + {
> + char *p = strchr( psz_val, ':' );
> + p_sys->param.deblockingFilterTCOffset = atoi( psz_val );
> + p_sys->param.deblockingFilterBetaOffset = p ?
> + atoi( p+1 ) : p_sys->param.deblockingFilterTCOffset;
> + }
> + free( psz_val );
> + }
> + p_sys->param.psyRd = var_GetFloat( p_enc, SOUT_CFG_PREFIX "psy-rd" );
> +
> + psz_val = var_GetString( p_enc, SOUT_CFG_PREFIX "level-idc" );
> + if( psz_val )
> + {
> + if( us_atof (psz_val) < 6 && us_atof (psz_val) > 0 )
> + p_sys->param.levelIdc = (int) (10 * us_atof (psz_val)
> + + .5);
> + else if( atoi(psz_val) >= 10 && atoi(psz_val) <= 51 )
> + p_sys->param.levelIdc = atoi (psz_val);
> + free( psz_val );
> + }
> +
> + p_sys->param.interlaceMode = var_GetBool( p_enc, SOUT_CFG_PREFIX "interlace" );
> +
> + if( fabs(var_GetFloat( p_enc, SOUT_CFG_PREFIX "ipratio" ) - 1.4) > 0.005 )
> + p_sys->param.rc.ipFactor = var_GetFloat( p_enc, SOUT_CFG_PREFIX "ipratio" );
> +
> + if( fabs(var_GetFloat( p_enc, SOUT_CFG_PREFIX "pbratio" ) - 1.3 ) > 0.005 )
> + p_sys->param.rc.pbFactor = var_GetFloat( p_enc, SOUT_CFG_PREFIX "pbratio" );
> +
> + p_sys->param.rc.complexityBlur = var_GetFloat( p_enc, SOUT_CFG_PREFIX "cplxblur" );
> +
> + p_sys->param.rc.qblur = var_GetFloat( p_enc, SOUT_CFG_PREFIX "qblur" );
> +
> + if( var_GetInteger( p_enc, SOUT_CFG_PREFIX "aq-mode" ) != X265_AQ_VARIANCE )
> + p_sys->param.rc.aqMode = var_GetInteger( p_enc, SOUT_CFG_PREFIX "aq-mode" );
> +
> + if( fabs( var_GetFloat( p_enc, SOUT_CFG_PREFIX "aq-strength" ) - 1.0) > 0.005 )
> + p_sys->param.rc.aqStrength = var_GetFloat( p_enc, SOUT_CFG_PREFIX "aq-strength" );
> +
> +
> + if( var_GetBool( p_enc, SOUT_CFG_PREFIX "aud" ) )
> + p_sys->param.bEnableAccessUnitDelimiters = true;
> +
> + i_val = var_GetInteger( p_enc, SOUT_CFG_PREFIX "keyint" );
> + if( i_val > -1 && i_val < INT_MAX )
> + {
> + p_sys->param.keyframeMax = i_val;
> + }
> +
> + i_val = var_GetInteger( p_enc, SOUT_CFG_PREFIX "min-keyint" );
> + if( i_val > 0 && i_val != 25 ) p_sys->param.keyframeMin = i_val;
> +
> + if (var_GetBool( p_enc, SOUT_CFG_PREFIX "open-gop" ))
> + p_sys->param.bOpenGOP = true;
> +
> + i_val = var_GetInteger( p_enc, SOUT_CFG_PREFIX "bframes" );
> + if( i_val >= 0 && i_val <= 16 && i_val != 3 )
> + p_sys->param.bframes = i_val;
> +
> + p_sys->param.bIntraRefresh = var_GetBool( p_enc, SOUT_CFG_PREFIX "intra-refresh" );
> +
> + if (var_GetBool( p_enc, SOUT_CFG_PREFIX "b-pyramid" ))
> + p_sys->param.bBPyramid = true;
> +
> + i_val = var_GetInteger( p_enc, SOUT_CFG_PREFIX "ref" );
> + if( i_val > 0 && i_val <= 16 && i_val != 3 )
> + p_sys->param.maxNumReferences = i_val;
> +
> + i_val = var_GetInteger( p_enc, SOUT_CFG_PREFIX "scenecut" );
> + if( i_val >= -1 && i_val <= 100 && i_val != 40 )
> + p_sys->param.scenecutThreshold = i_val;
> +
> +
> + i_val = var_GetInteger( p_enc, SOUT_CFG_PREFIX "subme" );
> + if( i_val >= 1 && i_val != 7 )
> + p_sys->param.subpelRefine = i_val;
> +
> +
> + if (var_GetBool( p_enc, SOUT_CFG_PREFIX "hrd"))
> + p_sys->param.bEmitHRDSEI = true;
> +
> +
> + psz_val = var_GetString( p_enc, SOUT_CFG_PREFIX "me" );
> + if( psz_val && strcmp( psz_val, "hex" ) )
> + {
> + if( !strcmp( psz_val, "dia" ) )
> + {
> + p_sys->param.searchMethod = X265_DIA_SEARCH;
> + }
> + else if( !strcmp( psz_val, "umh" ) )
> + {
> + p_sys->param.searchMethod = X265_UMH_SEARCH;
> + }
> + else if( !strcmp( psz_val, "star" ) )
> + {
> + p_sys->param.searchMethod = X265_STAR_SEARCH;
> + }
> + else if( !strcmp( psz_val, "full" ) )
> + {
> + p_sys->param.searchMethod = X265_FULL_SEARCH;
> + }
> + }
> + free( psz_val );
> +
> + i_val = var_GetInteger( p_enc, SOUT_CFG_PREFIX "merange" );
> + if( i_val >= 0 && i_val <= 64 && i_val != 16 )
> + p_sys->param.searchRange = i_val;
> +
> + p_sys->param.bEnablePsnr = var_GetBool( p_enc, SOUT_CFG_PREFIX "psnr" );
> +
> + p_sys->param.bEnableSsim = var_GetBool( p_enc, SOUT_CFG_PREFIX "ssim" );
> +
> + if(var_GetBool( p_enc, SOUT_CFG_PREFIX "weightb" ) )
> + p_sys->param.bEnableWeightedBiPred = true;
> +
> + if( var_GetBool( p_enc, SOUT_CFG_PREFIX "weightp" ) )
> + p_sys->param.bEnableWeightedPred = true;
> +
> + i_val = var_GetInteger( p_enc, SOUT_CFG_PREFIX "b-adapt" );
> + if( i_val != 1 )
> + p_sys->param.bFrameAdaptive = i_val;
> +
> + i_val = var_GetInteger( p_enc, SOUT_CFG_PREFIX "bframe-bias" );
> + if( i_val >= -100 && i_val <= 100 && i_val != 0)
> + p_sys->param.bFrameBias = i_val;
> +
> + p_sys->param.cbQpOffset = var_GetInteger( p_enc,
> + SOUT_CFG_PREFIX "cbqpoffs" );
> +
> + p_sys->param.crQpOffset = var_GetInteger( p_enc,
> + SOUT_CFG_PREFIX "crqpoffs" );
> +
> +
> + if( var_GetBool( p_enc, SOUT_CFG_PREFIX "tskip-fast" ) )
> + p_sys->param.bEnableTSkipFast = true;
> +
> + i_val = var_GetInteger( p_enc, SOUT_CFG_PREFIX "nr-inter" );
> + if( i_val > 0 && i_val <= 2000 )
> + p_sys->param.noiseReductionInter = i_val;
> +
> + i_val = var_GetInteger( p_enc, SOUT_CFG_PREFIX "nr-intra" );
> + if( i_val > 0 && i_val <= 2000 )
> + p_sys->param.noiseReductionIntra = i_val;
> +
> + i_val = var_GetInteger( p_enc, SOUT_CFG_PREFIX "ctu" );
> + if( i_val == 16 || i_val == 32 || i_val == 64 )
> + p_sys->param.maxCUSize = i_val;
> +
> + i_val = var_GetInteger( p_enc, SOUT_CFG_PREFIX "min-cu-size" );
> + if( i_val == 8 || i_val == 16 || i_val == 32 || i_val == 64 )
> + p_sys->param.minCUSize = i_val;
> +
> + i_val = var_GetInteger( p_enc, SOUT_CFG_PREFIX "rc-lookahead" );
> + if( i_val >= 0 && i_val <= 250 )
> + p_sys->param.lookaheadDepth = i_val;
> +
> + i_val = var_GetInteger( p_enc, SOUT_CFG_PREFIX "limit-refs" );
> + if( i_val == 0 || i_val == 1 || i_val == 2 || i_val == 3 )
> + p_sys->param.limitReferences = i_val;
> +
> + p_sys->param.bEnableRectInter = var_GetBool( p_enc, SOUT_CFG_PREFIX "rect" );
> +
> + p_sys->param.bEnableAMP = var_GetBool( p_enc, SOUT_CFG_PREFIX "amp" );
> +
> + p_sys->param.limitModes = var_GetBool( p_enc, SOUT_CFG_PREFIX "limit-modes" );
> +
> + i_val = var_GetInteger( p_enc, SOUT_CFG_PREFIX "max-merge" );
> + if( i_val >= 1 && i_val <= 5 )
> + p_sys->param.maxNumMergeCand = i_val;
> +
> + p_sys->param.bEnableEarlySkip = var_GetBool( p_enc, SOUT_CFG_PREFIX "early-skip" );
> +
> + p_sys->param.bEnableFastIntra = var_GetBool( p_enc, SOUT_CFG_PREFIX "fast-intra" );
> +
> + p_sys->param.bIntraInBFrames = var_GetBool( p_enc, SOUT_CFG_PREFIX "b-intra" );
> +
> + p_sys->param.bEnableSAO = var_GetBool( p_enc, SOUT_CFG_PREFIX "sao" );
> +
> + p_sys->param.bEnableSignHiding = var_GetBool( p_enc, SOUT_CFG_PREFIX "signhide" );
> +
> + p_sys->param.rc.cuTree = var_GetBool( p_enc, SOUT_CFG_PREFIX "cutree" );
> +
> + i_val = var_GetInteger( p_enc, SOUT_CFG_PREFIX "rd" );
> + if( i_val >= 1 && i_val <= 6 )
> + p_sys->param.rdLevel = i_val;
> +
> + i_val = var_GetInteger( p_enc, SOUT_CFG_PREFIX "rdoq-level" );
> + if( i_val == 0 || i_val == 1 || i_val == 2 )
> + p_sys->param.rdoqLevel = i_val;
> +
> + i_val = var_GetInteger( p_enc, SOUT_CFG_PREFIX "tu-intra" );
> + if( i_val >= 1 && i_val <= 4 )
> + p_sys->param.tuQTMaxIntraDepth = i_val;
> +
> + i_val = var_GetInteger( p_enc, SOUT_CFG_PREFIX "tu-inter" );
> + if( i_val >= 1 && i_val <= 4 )
> + p_sys->param.tuQTMaxInterDepth = i_val;
> +
> + p_sys->param.rc.qpStep = var_GetInteger( p_enc, SOUT_CFG_PREFIX "qpstep" );
> +
> + p_sys->param.psyRdoq = var_GetFloat( p_enc, SOUT_CFG_PREFIX "psy-rdoq" );
> +
> + i_val = var_GetInteger( p_enc, SOUT_CFG_PREFIX "frame-threads" );
> + if( i_val >= 1 && i_val <= 16 )
> + p_sys->param.frameNumThreads = i_val;
> +
> + p_sys->param.bDistributeModeAnalysis = var_GetBool( p_enc, SOUT_CFG_PREFIX "pmode" );
> +
> + p_sys->param.bDistributeMotionEstimation = var_GetBool( p_enc, SOUT_CFG_PREFIX "pme" );
> +
> + i_val = var_GetInteger( p_enc, SOUT_CFG_PREFIX "qg-size" );
> + if( i_val == 16 || i_val == 32 || i_val == 64)
> + p_sys->param.rc.qgSize = i_val;
> +
> + if( var_GetBool( p_enc, SOUT_CFG_PREFIX "asm" ) )
> + p_sys->param.cpuid = 1;
> +
> + /* Check slice-options */
> + i_val = var_GetInteger( p_enc, SOUT_CFG_PREFIX "lookahead-slices" );
> + if( i_val > 0 )
> + p_sys->param.lookaheadSlices = i_val;
> +
> + /* Check if user has given some profile (baseline,main,high) to limit
> + * settings, and apply those*/
> + psz_val = var_GetString( p_enc, SOUT_CFG_PREFIX "profile" );
ditto about GetNonEmptyString
> + if( psz_val && *psz_val )
> + x265_param_apply_profile( &p_sys->param, psz_val );
> + free( psz_val );
> +
> + i_val = var_GetInteger( p_enc, SOUT_CFG_PREFIX "pass" );
> + if( i_val > 0 && i_val <= 3 )
> + {
> + p_sys->param.rc.bStatWrite = i_val & 1;
> + p_sys->param.rc.bStatRead = i_val & 2;
> + }
> +
> +
> + /* We need to initialize pthreadw32 before we open the encoder,
> + but only once for the whole application. Since pthreadw32
> + doesn't keep a refcount, do it ourselves. */
> +#ifdef PTW32_STATIC_LIB
That feels really wrong, but I might be mistaking
> + vlc_mutex_lock( &pthread_win32_mutex );
> +
> + if( pthread_win32_count == 0 )
> + {
> + if( !pthread_win32_process_attach_np() || !pthread_win32_thread_attach_np() )
> + {
> + msg_Warn( p_enc, "pthread Win32 Initialization failed" );
> + vlc_mutex_unlock( &pthread_win32_mutex );
> + return VLC_EGENERIC;
> + }
> + }
> +
> + pthread_win32_count++;
> + vlc_mutex_unlock( &pthread_win32_mutex );
> +#endif
> +
> + if (var_GetBool( p_enc, SOUT_CFG_PREFIX "repeat-headers" ))
> + p_sys->param.bRepeatHeaders = true;
> +
> + p_sys->param.fpsNum = p_enc->fmt_in.video.i_frame_rate;
> + p_sys->param.fpsDenom = p_enc->fmt_in.video.i_frame_rate_base;
> + if (!p_sys->param.fpsNum)
> + {
> + p_sys->param.fpsNum = 25;
> + p_sys->param.fpsDenom = 1;
> + }
> + p_sys->param.sourceWidth = p_enc->fmt_in.video.i_visible_width;
> + p_sys->param.sourceHeight = p_enc->fmt_in.video.i_visible_height;
> +
> + /* Open the encoder */
> + p_sys->h = x265_encoder_open( &p_sys->param );
> + if( p_sys->h == NULL )
> + {
> + msg_Err( p_enc, "cannot open x265 encoder" );
> + Close( VLC_OBJECT(p_enc) );
> + return VLC_EGENERIC;
> + }
> +
> + if (x265_encoder_headers(p_sys->h, &nal, &i_nal) < 0) {
> + msg_Err(p_enc, "cannot get x265 headers");
> + Close(VLC_OBJECT(p_enc));
> + return VLC_EGENERIC;
> + }
> +
> + size_t i_extra = 0;
> + for (uint32_t i = 0; i < i_nal; i++)
> + i_extra += nal[i].sizeBytes;
> +
> + p_enc->fmt_out.i_extra = i_extra;
> +
> + uint8_t *p_extra = p_enc->fmt_out.p_extra = malloc(i_extra);
> + if (!p_extra) {
> + Close(VLC_OBJECT(p_enc));
> + return VLC_ENOMEM;
> + }
> +
> + for (uint32_t i = 0; i < i_nal; i++) {
> + memcpy(p_extra, nal[i].payload, nal[i].sizeBytes);
> + p_extra += nal[i].sizeBytes;
> + }
> +
> + p_sys->dts = 0;
> + p_sys->initial_date = 0;
> + p_sys->i_initial_delay = 0;
> +
> + p_enc->pf_encode_video = Encode;
> + p_enc->pf_encode_audio = NULL;
> + return VLC_SUCCESS;
> +}
> +
> +/****************************************************************************
> + * Logging
> + ****************************************************************************/
> +static void x265_log( void *data, int i_level, const char *psz, va_list args)
> +{
> + encoder_t *p_enc = (encoder_t *)data;
> +
> + switch( i_level )
> + {
> + case X265_LOG_ERROR:
> + i_level = VLC_MSG_ERR;
> + break;
> + case X265_LOG_WARNING:
> + i_level = VLC_MSG_WARN;
> + break;
> + case X265_LOG_INFO:
> + i_level = VLC_MSG_INFO;
> + break;
> + case X265_LOG_DEBUG:
> + default:
> + i_level = VLC_MSG_DBG;
> + }
> +
> + msg_GenericVa( p_enc, i_level, psz, args );
> };
>
> +/****************************************************************************
> + * Encode:
> + ****************************************************************************/
> static block_t *Encode(encoder_t *p_enc, picture_t *p_pict)
> {
> encoder_sys_t *p_sys = p_enc->p_sys;
> x265_picture pic;
> -
Unrelated whitespace change
> x265_picture_init(&p_sys->param, &pic);
> -
Ditto
> if (likely(p_pict)) {
> pic.pts = p_pict->date;
> if (unlikely(p_sys->initial_date == 0)) {
> @@ -85,12 +1007,11 @@ static block_t *Encode(encoder_t *p_enc, picture_t *p_pict)
> pic.stride[i] = p_pict->p[i].i_pitch;
> }
> }
> -
Ditto
> x265_nal *nal;
> uint32_t i_nal = 0;
> x265_encoder_encode(p_sys->h, &nal, &i_nal,
> likely(p_pict) ? &pic : NULL, &pic);
> -
> +
Please do not add trailing whitespaces
> if (!i_nal)
> return NULL;
>
> @@ -136,112 +1057,35 @@ static block_t *Encode(encoder_t *p_enc, picture_t *p_pict)
> return p_block;
> }
>
> -static int Open (vlc_object_t *p_this)
Why moving the Open function up?
> +/*****************************************************************************
> + * CloseEncoder: x265 encoder destruction
> + *****************************************************************************/
> +static void Close( vlc_object_t *p_this )
> {
> encoder_t *p_enc = (encoder_t *)p_this;
> - encoder_sys_t *p_sys;
> -
> - if (p_enc->fmt_out.i_codec != VLC_CODEC_HEVC && !p_enc->b_force)
> - return VLC_EGENERIC;
> -
> - p_enc->fmt_out.i_cat = VIDEO_ES;
> - p_enc->fmt_out.i_codec = VLC_CODEC_HEVC;
> - p_enc->p_sys = p_sys = malloc(sizeof(encoder_sys_t));
> - if (!p_sys)
> - return VLC_ENOMEM;
> -
> - p_enc->fmt_in.i_codec = VLC_CODEC_I420;
> -
> - x265_param *param = &p_sys->param;
> - x265_param_default(param);
> -
> - param->frameNumThreads = vlc_GetCPUCount();
> - param->bEnableWavefront = 0; // buggy in x265, use frame threading for now
> - param->maxCUSize = 16; /* use smaller macroblock */
> -
> -#if X265_BUILD >= 6
> - param->fpsNum = p_enc->fmt_in.video.i_frame_rate;
> - param->fpsDenom = p_enc->fmt_in.video.i_frame_rate_base;
> - if (!param->fpsNum) {
> - param->fpsNum = 25;
> - param->fpsDenom = 1;
> - }
> -#else
> - if (p_enc->fmt_in.video.i_frame_rate_base) {
> - param->frameRate = p_enc->fmt_in.video.i_frame_rate /
> - p_enc->fmt_in.video.i_frame_rate_base;
> - } else {
> - param->frameRate = 25;
> - }
> -#endif
> - param->sourceWidth = p_enc->fmt_in.video.i_visible_width;
> - param->sourceHeight = p_enc->fmt_in.video.i_visible_height;
> -
> - if (param->sourceWidth & (param->maxCUSize - 1)) {
> - msg_Err(p_enc, "Width (%d) must be a multiple of %d",
> - param->sourceWidth, param->maxCUSize);
> - free(p_sys);
> - return VLC_EGENERIC;
> - }
> - if (param->sourceHeight & 7) {
> - msg_Err(p_enc, "Height (%d) must be a multiple of 8", param->sourceHeight);
> - free(p_sys);
> - return VLC_EGENERIC;
> - }
> -
> - if (p_enc->fmt_out.i_bitrate > 0) {
> - param->rc.bitrate = p_enc->fmt_out.i_bitrate / 1000;
> - param->rc.rateControlMode = X265_RC_ABR;
> - }
> + encoder_sys_t *p_sys = p_enc->p_sys;
>
> - p_sys->h = x265_encoder_open(param);
> - if (p_sys->h == NULL) {
> - msg_Err(p_enc, "cannot open x265 encoder");
> - free(p_sys);
> - return VLC_EGENERIC;
> - }
> + free( p_sys->psz_stat_name );
> + free( p_sys->p_sei );
>
> - x265_nal *nal;
> - uint32_t i_nal;
> - if (x265_encoder_headers(p_sys->h, &nal, &i_nal) < 0) {
> - msg_Err(p_enc, "cannot get x265 headers");
> - Close(VLC_OBJECT(p_enc));
> - return VLC_EGENERIC;
> + if( p_sys->h )
> + {
> + x265_encoder_close( p_sys->h );
> }
>
> - size_t i_extra = 0;
> - for (uint32_t i = 0; i < i_nal; i++)
> - i_extra += nal[i].sizeBytes;
> -
> - p_enc->fmt_out.i_extra = i_extra;
> +#ifdef PTW32_STATIC_LIB
> + vlc_mutex_lock( &pthread_win32_mutex );
> + pthread_win32_count--;
>
> - uint8_t *p_extra = p_enc->fmt_out.p_extra = malloc(i_extra);
> - if (!p_extra) {
> - Close(VLC_OBJECT(p_enc));
> - return VLC_ENOMEM;
> - }
> -
> - for (uint32_t i = 0; i < i_nal; i++) {
> - memcpy(p_extra, nal[i].payload, nal[i].sizeBytes);
> - p_extra += nal[i].sizeBytes;
> + if( pthread_win32_count == 0 )
> + {
> + pthread_win32_thread_detach_np();
> + pthread_win32_process_detach_np();
> + msg_Dbg( p_enc, "pthread-win32 deinitialized" );
> }
>
> - p_sys->dts = 0;
> - p_sys->initial_date = 0;
> - p_sys->i_initial_delay = 0;
> -
> - p_enc->pf_encode_video = Encode;
> - p_enc->pf_encode_audio = NULL;
> -
> - return VLC_SUCCESS;
> -}
> -
> -static void Close(vlc_object_t *p_this)
> -{
> - encoder_t *p_enc = (encoder_t *)p_this;
> - encoder_sys_t *p_sys = p_enc->p_sys;
> -
> - x265_encoder_close(p_sys->h);
> + vlc_mutex_unlock( &pthread_win32_mutex );
> +#endif
>
> - free(p_sys);
> + free( p_sys );
> }
> diff --git a/modules/gui/qt/components/sout/profile_selector.cpp b/modules/gui/qt/components/sout/profile_selector.cpp
> index cfb1882..2fe35c5 100644
> --- a/modules/gui/qt/components/sout/profile_selector.cpp
> +++ b/modules/gui/qt/components/sout/profile_selector.cpp
> @@ -257,8 +257,9 @@ void VLCProfileSelector::updateOptions( int i )
>
> if ( !value.isEmpty() )
> {
> + QString encoder;
> smrl.option( "vcodec", value );
> -
> + encoder = value;
> HASHPICK( "vcodec", "bitrate" );
> if ( value.toInt() > 0 )
> {
> @@ -272,7 +273,7 @@ void VLCProfileSelector::updateOptions( int i )
> smrl.option( "vfilter", valuesList.join( ":" ) );
> }
>
> - /*if ( codec is h264 )*/
> +
> {
> /* special handling */
> QStringList codecoptions;
> @@ -285,9 +286,18 @@ void VLCProfileSelector::updateOptions( int i )
> if( !value.isEmpty() )
> codecoptions << QUrl::fromPercentEncoding( value.toLatin1() );
>
> - if ( codecoptions.count() )
> - smrl.option( "venc",
> - QString("x264{%1}").arg( codecoptions.join(",") ) );
> + if ( encoder == "hevc" )
> + {
> + if ( codecoptions.count() )
> + smrl.option( "venc",
> + QString("x265{%1}").arg( codecoptions.join(",") ) );
> + }
> + else
> + {
> + if ( codecoptions.count() )
> + smrl.option( "venc",
> + QString("x264{%1}").arg( codecoptions.join(",") ) );
> + }
> }
>
> HASHPICK( "vcodec", "framerate" );
>
>
>
> _______________________________________________
> vlc-devel mailing list
> To unsubscribe or modify your subscription options:
> https://mailman.videolan.org/listinfo/vlc-devel
>
Regards,
More information about the vlc-devel
mailing list