2005-03-09 05:04:56 +02:00
/*
* H .264 encoding using the x264 library
2007-07-05 23:08:51 +03:00
* Copyright ( C ) 2005 Mans Rullgard < mans @ mansr . com >
2005-03-09 05:04:56 +02:00
*
2006-10-07 18:30:46 +03:00
* This file is part of FFmpeg .
*
* FFmpeg is free software ; you can redistribute it and / or
2005-03-09 05:04:56 +02:00
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation ; either
2006-10-07 18:30:46 +03:00
* version 2.1 of the License , or ( at your option ) any later version .
2005-03-09 05:04:56 +02:00
*
2006-10-07 18:30:46 +03:00
* FFmpeg is distributed in the hope that it will be useful ,
2005-03-09 05:04:56 +02:00
* 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
2006-10-07 18:30:46 +03:00
* License along with FFmpeg ; if not , write to the Free Software
2006-01-13 00:43:26 +02:00
* Foundation , Inc . , 51 Franklin Street , Fifth Floor , Boston , MA 02110 - 1301 USA
2005-03-09 05:04:56 +02:00
*/
2022-02-23 14:56:49 +02:00
# include "config_components.h"
2014-04-12 05:23:20 +03:00
# include "libavutil/eval.h"
2012-08-06 16:49:32 +03:00
# include "libavutil/internal.h"
2011-04-17 02:50:50 +03:00
# include "libavutil/opt.h"
2012-08-06 16:49:32 +03:00
# include "libavutil/mem.h"
2011-10-05 22:09:51 +03:00
# include "libavutil/pixdesc.h"
2013-09-01 00:15:10 +03:00
# include "libavutil/stereo3d.h"
2019-10-04 16:55:09 +02:00
# include "libavutil/time.h"
2015-09-29 19:19:34 +02:00
# include "libavutil/intreadwrite.h"
2005-03-09 05:04:56 +02:00
# include "avcodec.h"
2022-03-16 19:18:28 +02:00
# include "codec_internal.h"
2021-04-25 01:43:26 +02:00
# include "encode.h"
2011-08-20 17:59:47 +03:00
# include "internal.h"
2020-06-02 23:38:33 +02:00
# include "packet_internal.h"
2020-08-09 19:01:16 +02:00
# include "atsc_a53.h"
2021-08-06 11:16:33 +02:00
# include "sei.h"
2013-07-19 21:25:57 +03:00
2005-03-09 05:04:56 +02:00
# include <x264.h>
2011-08-22 08:55:34 +03:00
# include <float.h>
2005-07-10 03:22:13 +03:00
# include <math.h>
2005-12-29 09:24:23 +02:00
# include <stdio.h>
# include <stdlib.h>
# include <string.h>
2005-03-09 05:04:56 +02:00
2019-01-10 10:54:30 +02:00
// from x264.h, for quant_offsets, Macroblocks are 16x16
// blocks of pixels (with respect to the luma plane)
# define MB_SIZE 16
2019-10-04 16:55:09 +02:00
typedef struct X264Opaque {
int64_t reordered_opaque ;
int64_t wallclock ;
} X264Opaque ;
2005-03-09 05:04:56 +02:00
typedef struct X264Context {
2011-04-17 02:50:50 +03:00
AVClass * class ;
2009-09-29 21:03:30 +03:00
x264_param_t params ;
x264_t * enc ;
x264_picture_t pic ;
uint8_t * sei ;
int sei_size ;
2011-05-11 02:40:21 +03:00
char * preset ;
char * tune ;
2022-06-24 10:22:05 +02:00
const char * profile ;
char * profile_opt ;
2011-05-11 02:40:21 +03:00
char * level ;
2011-04-17 02:50:50 +03:00
int fastfirstpass ;
2011-08-24 21:26:48 +03:00
char * wpredp ;
2011-05-18 16:39:40 +03:00
char * x264opts ;
2011-08-22 08:55:34 +03:00
float crf ;
2011-08-22 08:55:34 +03:00
float crf_max ;
2011-08-22 08:55:34 +03:00
int cqp ;
2011-08-22 08:55:34 +03:00
int aq_mode ;
2011-08-22 08:55:34 +03:00
float aq_strength ;
2011-08-27 08:52:03 +03:00
char * psy_rd ;
2011-08-27 11:16:14 +03:00
int psy ;
2011-08-22 08:55:34 +03:00
int rc_lookahead ;
2011-08-22 08:55:34 +03:00
int weightp ;
2011-08-22 08:55:34 +03:00
int weightb ;
2011-08-22 08:55:34 +03:00
int ssim ;
2011-08-22 08:55:34 +03:00
int intra_refresh ;
2013-08-05 14:23:52 +03:00
int bluray_compat ;
2011-09-01 14:15:09 +03:00
int b_bias ;
2011-08-22 08:55:34 +03:00
int b_pyramid ;
2011-08-22 08:55:34 +03:00
int mixed_refs ;
2011-08-22 08:55:34 +03:00
int dct8x8 ;
2011-08-22 08:55:34 +03:00
int fast_pskip ;
2011-08-22 08:55:34 +03:00
int aud ;
2011-08-27 11:16:14 +03:00
int mbtree ;
2011-09-01 14:15:09 +03:00
char * deblock ;
2011-09-01 14:15:09 +03:00
float cplxblur ;
2011-09-01 14:15:09 +03:00
char * partitions ;
2011-09-01 14:15:09 +03:00
int direct_pred ;
2011-09-16 05:30:10 +03:00
int slice_max_size ;
2012-03-12 19:20:20 +03:00
char * stats ;
2012-09-21 10:20:09 +03:00
int nal_hrd ;
2014-10-01 17:19:45 +03:00
int avcintra_class ;
2015-07-07 02:20:43 +02:00
int motion_est ;
2015-08-18 22:39:01 +02:00
int forced_idr ;
2015-11-30 19:17:31 +02:00
int coder ;
2015-09-29 19:19:34 +02:00
int a53_cc ;
2015-09-09 04:18:26 +02:00
int b_frame_strategy ;
2015-09-12 14:40:29 +02:00
int chroma_offset ;
2015-09-12 22:27:59 +02:00
int scenechange_threshold ;
2015-09-13 23:45:24 +02:00
int noise_reduction ;
2021-12-25 16:21:03 +02:00
int udu_sei ;
2015-11-30 19:17:31 +02:00
2019-12-25 02:46:37 +02:00
AVDictionary * x264_params ;
2018-10-11 15:03:10 +02:00
int nb_reordered_opaque , next_reordered_opaque ;
2019-10-04 16:55:09 +02:00
X264Opaque * reordered_opaque ;
2019-09-23 04:02:34 +02:00
/**
* If the encoder does not support ROI then warn the first time we
* encounter a frame with ROI side data .
*/
int roi_warned ;
2005-03-09 05:04:56 +02:00
} X264Context ;
2009-09-29 21:03:30 +03:00
static void X264_log ( void * p , int level , const char * fmt , va_list args )
2005-03-09 05:04:56 +02:00
{
static const int level_map [ ] = {
2005-12-22 03:10:11 +02:00
[ X264_LOG_ERROR ] = AV_LOG_ERROR ,
2007-07-12 11:22:28 +03:00
[ X264_LOG_WARNING ] = AV_LOG_WARNING ,
2012-09-13 01:01:22 +03:00
[ X264_LOG_INFO ] = AV_LOG_INFO ,
2005-12-22 03:10:11 +02:00
[ X264_LOG_DEBUG ] = AV_LOG_DEBUG
2005-03-09 05:04:56 +02:00
} ;
2009-09-29 21:03:30 +03:00
if ( level < 0 | | level > X264_LOG_DEBUG )
2005-12-22 03:10:11 +02:00
return ;
2005-03-09 05:04:56 +02:00
av_vlog ( p , level_map [ level ] , fmt , args ) ;
}
2012-02-06 09:39:23 +03:00
static int encode_nals ( AVCodecContext * ctx , AVPacket * pkt ,
2014-09-28 04:40:13 +03:00
const x264_nal_t * nals , int nnal )
2005-03-09 05:04:56 +02:00
{
2009-07-01 02:45:01 +03:00
X264Context * x4 = ctx - > priv_data ;
2012-02-06 09:39:23 +03:00
uint8_t * p ;
2021-11-07 15:50:27 +02:00
uint64_t size = x4 - > sei_size ;
int ret ;
2012-02-06 09:39:23 +03:00
if ( ! nnal )
return 0 ;
2021-11-07 15:50:27 +02:00
for ( int i = 0 ; i < nnal ; i + + ) {
2012-02-06 09:39:23 +03:00
size + = nals [ i ] . i_payload ;
2021-11-07 15:50:27 +02:00
/* ff_get_encode_buffer() accepts an int64_t and
* so we need to make sure that no overflow happens before
* that . With 32 bit ints this is automatically true . */
# if INT_MAX > INT64_MAX / INT_MAX - 1
if ( ( int64_t ) size < 0 )
return AVERROR ( ERANGE ) ;
# endif
}
2012-02-06 09:39:23 +03:00
2021-04-25 01:43:26 +02:00
if ( ( ret = ff_get_encode_buffer ( ctx , pkt , size , 0 ) ) < 0 )
2012-02-06 09:39:23 +03:00
return ret ;
p = pkt - > data ;
2009-07-01 02:45:01 +03:00
/* Write the SEI as part of the first frame. */
2021-11-07 15:56:01 +02:00
if ( x4 - > sei_size > 0 ) {
2009-07-01 02:45:01 +03:00
memcpy ( p , x4 - > sei , x4 - > sei_size ) ;
p + = x4 - > sei_size ;
2021-11-07 16:18:41 +02:00
size - = x4 - > sei_size ;
2009-07-01 02:45:01 +03:00
x4 - > sei_size = 0 ;
2011-09-26 19:53:12 +03:00
av_freep ( & x4 - > sei ) ;
2009-07-01 02:45:01 +03:00
}
2005-03-09 05:04:56 +02:00
2021-11-07 16:18:41 +02:00
/* x264 guarantees the payloads of the NALs
* to be sequential in memory . */
memcpy ( p , nals [ 0 ] . p_payload , size ) ;
2005-03-09 05:04:56 +02:00
2012-02-06 09:39:23 +03:00
return 1 ;
2005-03-09 05:04:56 +02:00
}
2011-10-08 13:16:43 +03:00
static int avfmt2_num_planes ( int avfmt )
{
switch ( avfmt ) {
2012-10-08 21:54:00 +03:00
case AV_PIX_FMT_YUV420P :
case AV_PIX_FMT_YUVJ420P :
case AV_PIX_FMT_YUV420P9 :
case AV_PIX_FMT_YUV420P10 :
case AV_PIX_FMT_YUV444P :
2011-10-08 13:16:43 +03:00
return 3 ;
2015-05-28 12:34:22 +02:00
case AV_PIX_FMT_BGR0 :
2012-10-08 21:54:00 +03:00
case AV_PIX_FMT_BGR24 :
case AV_PIX_FMT_RGB24 :
2018-08-07 20:41:02 +02:00
case AV_PIX_FMT_GRAY8 :
case AV_PIX_FMT_GRAY10 :
2011-10-08 13:16:43 +03:00
return 1 ;
default :
return 3 ;
}
}
2015-06-12 00:08:49 +02:00
static void reconfig_encoder ( AVCodecContext * ctx , const AVFrame * frame )
{
X264Context * x4 = ctx - > priv_data ;
AVFrameSideData * side_data ;
2020-05-26 18:42:12 +02:00
if ( x4 - > avcintra_class < 0 ) {
if ( x4 - > params . b_interlaced & & x4 - > params . b_tff ! = frame - > top_field_first ) {
2015-06-15 21:56:26 +02:00
2020-05-26 18:42:12 +02:00
x4 - > params . b_tff = frame - > top_field_first ;
x264_encoder_reconfig ( x4 - > enc , & x4 - > params ) ;
}
if ( x4 - > params . vui . i_sar_height * ctx - > sample_aspect_ratio . num ! = ctx - > sample_aspect_ratio . den * x4 - > params . vui . i_sar_width ) {
x4 - > params . vui . i_sar_height = ctx - > sample_aspect_ratio . den ;
x4 - > params . vui . i_sar_width = ctx - > sample_aspect_ratio . num ;
x264_encoder_reconfig ( x4 - > enc , & x4 - > params ) ;
}
2015-06-12 00:08:49 +02:00
2020-05-26 18:42:12 +02:00
if ( x4 - > params . rc . i_vbv_buffer_size ! = ctx - > rc_buffer_size / 1000 | |
x4 - > params . rc . i_vbv_max_bitrate ! = ctx - > rc_max_rate / 1000 ) {
x4 - > params . rc . i_vbv_buffer_size = ctx - > rc_buffer_size / 1000 ;
x4 - > params . rc . i_vbv_max_bitrate = ctx - > rc_max_rate / 1000 ;
x264_encoder_reconfig ( x4 - > enc , & x4 - > params ) ;
}
2015-06-12 00:08:49 +02:00
2020-05-26 18:42:12 +02:00
if ( x4 - > params . rc . i_rc_method = = X264_RC_ABR & &
x4 - > params . rc . i_bitrate ! = ctx - > bit_rate / 1000 ) {
x4 - > params . rc . i_bitrate = ctx - > bit_rate / 1000 ;
x264_encoder_reconfig ( x4 - > enc , & x4 - > params ) ;
}
2015-06-12 00:08:49 +02:00
2020-05-26 18:42:12 +02:00
if ( x4 - > crf > = 0 & &
x4 - > params . rc . i_rc_method = = X264_RC_CRF & &
x4 - > params . rc . f_rf_constant ! = x4 - > crf ) {
x4 - > params . rc . f_rf_constant = x4 - > crf ;
x264_encoder_reconfig ( x4 - > enc , & x4 - > params ) ;
}
2015-06-12 00:08:49 +02:00
2020-05-26 18:42:12 +02:00
if ( x4 - > params . rc . i_rc_method = = X264_RC_CQP & &
x4 - > cqp > = 0 & &
x4 - > params . rc . i_qp_constant ! = x4 - > cqp ) {
x4 - > params . rc . i_qp_constant = x4 - > cqp ;
x264_encoder_reconfig ( x4 - > enc , & x4 - > params ) ;
}
2015-06-12 00:08:49 +02:00
2020-05-26 18:42:12 +02:00
if ( x4 - > crf_max > = 0 & &
x4 - > params . rc . f_rf_constant_max ! = x4 - > crf_max ) {
x4 - > params . rc . f_rf_constant_max = x4 - > crf_max ;
x264_encoder_reconfig ( x4 - > enc , & x4 - > params ) ;
}
2015-06-12 00:08:49 +02:00
}
side_data = av_frame_get_side_data ( frame , AV_FRAME_DATA_STEREO3D ) ;
if ( side_data ) {
AVStereo3D * stereo = ( AVStereo3D * ) side_data - > data ;
int fpa_type ;
switch ( stereo - > type ) {
case AV_STEREO3D_CHECKERBOARD :
fpa_type = 0 ;
break ;
case AV_STEREO3D_COLUMNS :
fpa_type = 1 ;
break ;
case AV_STEREO3D_LINES :
fpa_type = 2 ;
break ;
case AV_STEREO3D_SIDEBYSIDE :
fpa_type = 3 ;
break ;
case AV_STEREO3D_TOPBOTTOM :
fpa_type = 4 ;
break ;
case AV_STEREO3D_FRAMESEQUENCE :
fpa_type = 5 ;
break ;
2016-04-11 23:28:25 +02:00
# if X264_BUILD >= 145
case AV_STEREO3D_2D :
fpa_type = 6 ;
break ;
# endif
2015-06-12 00:08:49 +02:00
default :
fpa_type = - 1 ;
break ;
}
2016-04-11 23:28:26 +02:00
/* Inverted mode is not supported by x264 */
if ( stereo - > flags & AV_STEREO3D_FLAG_INVERT ) {
av_log ( ctx , AV_LOG_WARNING ,
" Ignoring unsupported inverted stereo value %d \n " , fpa_type ) ;
fpa_type = - 1 ;
}
2015-06-12 00:08:49 +02:00
if ( fpa_type ! = x4 - > params . i_frame_packing ) {
x4 - > params . i_frame_packing = fpa_type ;
x264_encoder_reconfig ( x4 - > enc , & x4 - > params ) ;
}
}
}
2021-11-01 23:57:56 +02:00
static void free_picture ( AVCodecContext * ctx )
{
X264Context * x4 = ctx - > priv_data ;
x264_picture_t * pic = & x4 - > pic ;
for ( int i = 0 ; i < pic - > extra_sei . num_payloads ; i + + )
av_free ( pic - > extra_sei . payloads [ i ] . payload ) ;
av_freep ( & pic - > extra_sei . payloads ) ;
av_freep ( & pic - > prop . quant_offsets ) ;
pic - > extra_sei . num_payloads = 0 ;
}
2022-07-16 17:02:38 +02:00
static enum AVPixelFormat csp_to_pixfmt ( int csp )
{
switch ( csp ) {
# ifdef X264_CSP_I400
case X264_CSP_I400 : return AV_PIX_FMT_GRAY8 ;
case X264_CSP_I400 | X264_CSP_HIGH_DEPTH : return AV_PIX_FMT_GRAY10 ;
# endif
case X264_CSP_I420 : return AV_PIX_FMT_YUV420P ;
case X264_CSP_I420 | X264_CSP_HIGH_DEPTH : return AV_PIX_FMT_YUV420P10 ;
case X264_CSP_I422 : return AV_PIX_FMT_YUV422P ;
case X264_CSP_I422 | X264_CSP_HIGH_DEPTH : return AV_PIX_FMT_YUV422P10 ;
case X264_CSP_I444 : return AV_PIX_FMT_YUV444P ;
case X264_CSP_I444 | X264_CSP_HIGH_DEPTH : return AV_PIX_FMT_YUV444P10 ;
case X264_CSP_NV12 : return AV_PIX_FMT_NV12 ;
# ifdef X264_CSP_NV21
case X264_CSP_NV21 : return AV_PIX_FMT_NV21 ;
# endif
case X264_CSP_NV16 : return AV_PIX_FMT_NV16 ;
} ;
return AV_PIX_FMT_NONE ;
}
2012-02-06 09:39:23 +03:00
static int X264_frame ( AVCodecContext * ctx , AVPacket * pkt , const AVFrame * frame ,
int * got_packet )
2005-03-09 05:04:56 +02:00
{
X264Context * x4 = ctx - > priv_data ;
x264_nal_t * nal ;
2012-02-06 09:39:23 +03:00
int nnal , i , ret ;
2013-05-14 23:36:31 +03:00
x264_picture_t pic_out = { 0 } ;
2015-07-22 20:49:01 +02:00
int pict_type ;
2019-06-04 01:19:02 +02:00
int bit_depth ;
2019-10-04 16:55:09 +02:00
int64_t wallclock = 0 ;
X264Opaque * out_opaque ;
2019-01-10 10:54:30 +02:00
AVFrameSideData * sd ;
2005-03-09 05:04:56 +02:00
2010-06-02 23:05:27 +03:00
x264_picture_init ( & x4 - > pic ) ;
2011-10-09 20:34:20 +03:00
x4 - > pic . img . i_csp = x4 - > params . i_csp ;
2017-12-26 13:32:42 +02:00
# if X264_BUILD >= 153
2019-06-04 01:19:02 +02:00
bit_depth = x4 - > params . i_bitdepth ;
2017-12-26 13:32:42 +02:00
# else
2019-06-04 01:19:02 +02:00
bit_depth = x264_bit_depth ;
2017-12-26 13:32:42 +02:00
# endif
2019-06-04 01:19:02 +02:00
if ( bit_depth > 8 )
2011-10-05 22:09:51 +03:00
x4 - > pic . img . i_csp | = X264_CSP_HIGH_DEPTH ;
2011-10-08 13:16:43 +03:00
x4 - > pic . img . i_plane = avfmt2_num_planes ( ctx - > pix_fmt ) ;
2005-03-09 05:04:56 +02:00
2009-09-29 21:03:30 +03:00
if ( frame ) {
2021-08-06 11:16:33 +02:00
x264_sei_t * sei = & x4 - > pic . extra_sei ;
2021-10-20 05:21:44 +02:00
unsigned int sei_data_size = 0 ;
2021-08-06 11:16:33 +02:00
2011-10-08 13:16:43 +03:00
for ( i = 0 ; i < x4 - > pic . img . i_plane ; i + + ) {
2009-09-29 21:03:30 +03:00
x4 - > pic . img . plane [ i ] = frame - > data [ i ] ;
2006-11-01 20:19:20 +02:00
x4 - > pic . img . i_stride [ i ] = frame - > linesize [ i ] ;
}
2005-03-09 05:04:56 +02:00
2009-09-29 21:03:30 +03:00
x4 - > pic . i_pts = frame - > pts ;
2014-10-01 17:19:45 +03:00
2019-10-04 16:55:09 +02:00
x4 - > reordered_opaque [ x4 - > next_reordered_opaque ] . reordered_opaque = frame - > reordered_opaque ;
2020-01-29 16:12:18 +02:00
x4 - > reordered_opaque [ x4 - > next_reordered_opaque ] . wallclock = wallclock ;
if ( ctx - > export_side_data & AV_CODEC_EXPORT_DATA_PRFT )
x4 - > reordered_opaque [ x4 - > next_reordered_opaque ] . wallclock = av_gettime ( ) ;
2018-10-11 15:03:10 +02:00
x4 - > pic . opaque = & x4 - > reordered_opaque [ x4 - > next_reordered_opaque ] ;
x4 - > next_reordered_opaque + + ;
x4 - > next_reordered_opaque % = x4 - > nb_reordered_opaque ;
2015-08-31 15:34:54 +02:00
switch ( frame - > pict_type ) {
case AV_PICTURE_TYPE_I :
2016-10-12 21:54:52 +02:00
x4 - > pic . i_type = x4 - > forced_idr > 0 ? X264_TYPE_IDR
: X264_TYPE_KEYFRAME ;
2015-08-31 15:34:54 +02:00
break ;
case AV_PICTURE_TYPE_P :
x4 - > pic . i_type = X264_TYPE_P ;
break ;
case AV_PICTURE_TYPE_B :
x4 - > pic . i_type = X264_TYPE_B ;
break ;
default :
x4 - > pic . i_type = X264_TYPE_AUTO ;
break ;
}
2015-06-12 00:08:49 +02:00
reconfig_encoder ( ctx , frame ) ;
2015-09-29 19:19:34 +02:00
if ( x4 - > a53_cc ) {
2016-06-04 20:11:52 +02:00
void * sei_data ;
size_t sei_size ;
ret = ff_alloc_a53_sei ( frame , 0 , & sei_data , & sei_size ) ;
if ( ret < 0 ) {
av_log ( ctx , AV_LOG_ERROR , " Not enough memory for closed captions, skipping \n " ) ;
} else if ( sei_data ) {
2015-09-29 19:19:34 +02:00
x4 - > pic . extra_sei . payloads = av_mallocz ( sizeof ( x4 - > pic . extra_sei . payloads [ 0 ] ) ) ;
if ( x4 - > pic . extra_sei . payloads = = NULL ) {
av_log ( ctx , AV_LOG_ERROR , " Not enough memory for closed captions, skipping \n " ) ;
2016-06-04 20:11:52 +02:00
av_free ( sei_data ) ;
} else {
x4 - > pic . extra_sei . sei_free = av_free ;
x4 - > pic . extra_sei . payloads [ 0 ] . payload_size = sei_size ;
x4 - > pic . extra_sei . payloads [ 0 ] . payload = sei_data ;
x4 - > pic . extra_sei . num_payloads = 1 ;
x4 - > pic . extra_sei . payloads [ 0 ] . payload_type = 4 ;
2015-09-29 19:19:34 +02:00
}
}
}
2019-01-10 10:54:30 +02:00
sd = av_frame_get_side_data ( frame , AV_FRAME_DATA_REGIONS_OF_INTEREST ) ;
if ( sd ) {
if ( x4 - > params . rc . i_aq_mode = = X264_AQ_NONE ) {
2019-09-23 04:02:34 +02:00
if ( ! x4 - > roi_warned ) {
x4 - > roi_warned = 1 ;
av_log ( ctx , AV_LOG_WARNING , " Adaptive quantization must be enabled to use ROI encoding, skipping ROI. \n " ) ;
}
2019-01-10 10:54:30 +02:00
} else {
if ( frame - > interlaced_frame = = 0 ) {
int mbx = ( frame - > width + MB_SIZE - 1 ) / MB_SIZE ;
int mby = ( frame - > height + MB_SIZE - 1 ) / MB_SIZE ;
2019-06-04 01:19:02 +02:00
int qp_range = 51 + 6 * ( bit_depth - 8 ) ;
2019-01-10 10:54:30 +02:00
int nb_rois ;
2019-06-04 01:19:02 +02:00
const AVRegionOfInterest * roi ;
uint32_t roi_size ;
float * qoffsets ;
roi = ( const AVRegionOfInterest * ) sd - > data ;
roi_size = roi - > self_size ;
if ( ! roi_size | | sd - > size % roi_size ! = 0 ) {
2021-11-01 23:57:56 +02:00
free_picture ( ctx ) ;
2019-06-04 01:19:02 +02:00
av_log ( ctx , AV_LOG_ERROR , " Invalid AVRegionOfInterest.self_size. \n " ) ;
return AVERROR ( EINVAL ) ;
}
nb_rois = sd - > size / roi_size ;
2021-09-14 21:31:53 +02:00
qoffsets = av_calloc ( mbx * mby , sizeof ( * qoffsets ) ) ;
2021-11-01 23:57:56 +02:00
if ( ! qoffsets ) {
free_picture ( ctx ) ;
2019-01-10 10:54:30 +02:00
return AVERROR ( ENOMEM ) ;
2021-11-01 23:57:56 +02:00
}
2019-06-04 01:19:02 +02:00
// This list must be iterated in reverse because the first
// region in the list applies when regions overlap.
for ( int i = nb_rois - 1 ; i > = 0 ; i - - ) {
int startx , endx , starty , endy ;
2019-01-10 10:54:30 +02:00
float qoffset ;
2019-06-04 01:19:02 +02:00
roi = ( const AVRegionOfInterest * ) ( sd - > data + roi_size * i ) ;
starty = FFMIN ( mby , roi - > top / MB_SIZE ) ;
endy = FFMIN ( mby , ( roi - > bottom + MB_SIZE - 1 ) / MB_SIZE ) ;
startx = FFMIN ( mbx , roi - > left / MB_SIZE ) ;
endx = FFMIN ( mbx , ( roi - > right + MB_SIZE - 1 ) / MB_SIZE ) ;
2019-01-10 10:54:30 +02:00
if ( roi - > qoffset . den = = 0 ) {
av_free ( qoffsets ) ;
2021-11-01 23:57:56 +02:00
free_picture ( ctx ) ;
2019-06-04 01:19:02 +02:00
av_log ( ctx , AV_LOG_ERROR , " AVRegionOfInterest.qoffset.den must not be zero. \n " ) ;
2019-01-10 10:54:30 +02:00
return AVERROR ( EINVAL ) ;
}
qoffset = roi - > qoffset . num * 1.0f / roi - > qoffset . den ;
2019-06-04 01:19:02 +02:00
qoffset = av_clipf ( qoffset * qp_range , - qp_range , + qp_range ) ;
2019-01-10 10:54:30 +02:00
for ( int y = starty ; y < endy ; y + + ) {
for ( int x = startx ; x < endx ; x + + ) {
qoffsets [ x + y * mbx ] = qoffset ;
}
}
}
x4 - > pic . prop . quant_offsets = qoffsets ;
x4 - > pic . prop . quant_offsets_free = av_free ;
} else {
2019-09-23 04:02:34 +02:00
if ( ! x4 - > roi_warned ) {
x4 - > roi_warned = 1 ;
av_log ( ctx , AV_LOG_WARNING , " interlaced_frame not supported for ROI encoding yet, skipping ROI. \n " ) ;
}
2019-01-10 10:54:30 +02:00
}
}
}
2021-08-06 11:16:33 +02:00
2021-12-25 16:21:03 +02:00
if ( x4 - > udu_sei ) {
2021-12-25 16:28:30 +02:00
for ( int j = 0 ; j < frame - > nb_side_data ; j + + ) {
AVFrameSideData * side_data = frame - > side_data [ j ] ;
void * tmp ;
x264_sei_payload_t * sei_payload ;
if ( side_data - > type ! = AV_FRAME_DATA_SEI_UNREGISTERED )
continue ;
tmp = av_fast_realloc ( sei - > payloads , & sei_data_size , ( sei - > num_payloads + 1 ) * sizeof ( * sei_payload ) ) ;
if ( ! tmp ) {
free_picture ( ctx ) ;
return AVERROR ( ENOMEM ) ;
}
sei - > payloads = tmp ;
sei - > sei_free = av_free ;
sei_payload = & sei - > payloads [ sei - > num_payloads ] ;
sei_payload - > payload = av_memdup ( side_data - > data , side_data - > size ) ;
if ( ! sei_payload - > payload ) {
free_picture ( ctx ) ;
return AVERROR ( ENOMEM ) ;
}
sei_payload - > payload_size = side_data - > size ;
sei_payload - > payload_type = SEI_TYPE_USER_DATA_UNREGISTERED ;
sei - > num_payloads + + ;
2021-10-19 02:07:11 +02:00
}
2021-12-25 16:21:03 +02:00
}
2013-09-01 00:15:10 +03:00
}
2016-06-04 20:11:52 +02:00
2010-05-19 23:48:29 +03:00
do {
2012-02-01 12:56:14 +03:00
if ( x264_encoder_encode ( x4 - > enc , & nal , & nnal , frame ? & x4 - > pic : NULL , & pic_out ) < 0 )
2015-03-17 01:05:58 +02:00
return AVERROR_EXTERNAL ;
2005-03-09 05:04:56 +02:00
2022-07-16 17:02:38 +02:00
if ( nnal & & ( ctx - > flags & AV_CODEC_FLAG_RECON_FRAME ) ) {
AVCodecInternal * avci = ctx - > internal ;
av_frame_unref ( avci - > recon_frame ) ;
avci - > recon_frame - > format = csp_to_pixfmt ( pic_out . img . i_csp ) ;
if ( avci - > recon_frame - > format = = AV_PIX_FMT_NONE ) {
av_log ( ctx , AV_LOG_ERROR ,
" Unhandled reconstructed frame colorspace: %d \n " ,
pic_out . img . i_csp ) ;
return AVERROR ( ENOSYS ) ;
}
avci - > recon_frame - > width = ctx - > width ;
avci - > recon_frame - > height = ctx - > height ;
for ( int i = 0 ; i < pic_out . img . i_plane ; i + + ) {
avci - > recon_frame - > data [ i ] = pic_out . img . plane [ i ] ;
avci - > recon_frame - > linesize [ i ] = pic_out . img . i_stride [ i ] ;
}
ret = av_frame_make_writable ( avci - > recon_frame ) ;
if ( ret < 0 ) {
av_frame_unref ( avci - > recon_frame ) ;
return ret ;
}
}
2012-02-06 09:39:23 +03:00
ret = encode_nals ( ctx , pkt , nal , nnal ) ;
if ( ret < 0 )
2015-03-12 18:20:13 +02:00
return ret ;
2012-02-06 09:39:23 +03:00
} while ( ! ret & & ! frame & & x264_encoder_delayed_frames ( x4 - > enc ) ) ;
2005-03-09 05:04:56 +02:00
2020-04-18 06:52:48 +02:00
if ( ! ret )
return 0 ;
2012-02-06 09:39:23 +03:00
pkt - > pts = pic_out . i_pts ;
pkt - > dts = pic_out . i_dts ;
2005-03-09 05:04:56 +02:00
2018-10-11 15:03:10 +02:00
out_opaque = pic_out . opaque ;
if ( out_opaque > = x4 - > reordered_opaque & &
out_opaque < & x4 - > reordered_opaque [ x4 - > nb_reordered_opaque ] ) {
2019-10-04 16:55:09 +02:00
ctx - > reordered_opaque = out_opaque - > reordered_opaque ;
wallclock = out_opaque - > wallclock ;
2018-10-11 15:03:10 +02:00
} else {
// Unexpected opaque pointer on picture output
ctx - > reordered_opaque = 0 ;
}
2015-07-22 20:49:01 +02:00
2009-09-29 21:03:30 +03:00
switch ( pic_out . i_type ) {
2005-03-09 05:04:56 +02:00
case X264_TYPE_IDR :
case X264_TYPE_I :
2015-07-22 20:49:01 +02:00
pict_type = AV_PICTURE_TYPE_I ;
2005-03-09 05:04:56 +02:00
break ;
case X264_TYPE_P :
2015-07-22 20:49:01 +02:00
pict_type = AV_PICTURE_TYPE_P ;
2005-03-09 05:04:56 +02:00
break ;
case X264_TYPE_B :
case X264_TYPE_BREF :
2015-07-22 20:49:01 +02:00
pict_type = AV_PICTURE_TYPE_B ;
2005-03-09 05:04:56 +02:00
break ;
2015-07-22 20:49:01 +02:00
default :
2020-04-18 06:52:49 +02:00
av_log ( ctx , AV_LOG_ERROR , " Unknown picture type encountered. \n " ) ;
return AVERROR_EXTERNAL ;
2005-03-09 05:04:56 +02:00
}
2012-02-06 09:39:23 +03:00
pkt - > flags | = AV_PKT_FLAG_KEY * pic_out . b_keyframe ;
2015-07-15 19:41:21 +02:00
if ( ret ) {
2015-07-22 20:49:01 +02:00
ff_side_data_set_encoder_stats ( pkt , ( pic_out . i_qpplus1 - 1 ) * FF_QP2LAMBDA , NULL , 0 , pict_type ) ;
2019-10-04 16:55:09 +02:00
if ( wallclock )
ff_side_data_set_prft ( pkt , wallclock ) ;
2015-07-15 19:41:21 +02:00
}
2005-03-09 05:04:56 +02:00
2012-02-06 09:39:23 +03:00
* got_packet = ret ;
return 0 ;
2005-03-09 05:04:56 +02:00
}
2009-09-29 21:03:30 +03:00
static av_cold int X264_close ( AVCodecContext * avctx )
2005-03-09 05:04:56 +02:00
{
X264Context * x4 = avctx - > priv_data ;
2014-11-18 12:33:00 +02:00
av_freep ( & x4 - > sei ) ;
2018-10-11 15:03:10 +02:00
av_freep ( & x4 - > reordered_opaque ) ;
2008-10-13 16:47:05 +03:00
2020-07-10 22:47:57 +02:00
# if X264_BUILD >= 161
x264_param_cleanup ( & x4 - > params ) ;
# endif
2015-04-07 01:47:18 +02:00
if ( x4 - > enc ) {
2005-12-22 03:10:11 +02:00
x264_encoder_close ( x4 - > enc ) ;
2015-04-07 01:47:18 +02:00
x4 - > enc = NULL ;
}
2005-03-09 05:04:56 +02:00
return 0 ;
}
2020-07-10 22:10:33 +02:00
static int parse_opts ( AVCodecContext * avctx , const char * opt , const char * param )
{
X264Context * x4 = avctx - > priv_data ;
int ret ;
if ( ( ret = x264_param_parse ( & x4 - > params , opt , param ) ) < 0 ) {
if ( ret = = X264_PARAM_BAD_NAME ) {
av_log ( avctx , AV_LOG_ERROR ,
" bad option '%s': '%s' \n " , opt , param ) ;
ret = AVERROR ( EINVAL ) ;
2020-07-10 22:16:49 +02:00
# if X264_BUILD >= 161
} else if ( ret = = X264_PARAM_ALLOC_FAILED ) {
av_log ( avctx , AV_LOG_ERROR ,
" out of memory parsing option '%s': '%s' \n " , opt , param ) ;
ret = AVERROR ( ENOMEM ) ;
# endif
2020-07-10 22:10:33 +02:00
} else {
av_log ( avctx , AV_LOG_ERROR ,
" bad value for '%s': '%s' \n " , opt , param ) ;
ret = AVERROR ( EINVAL ) ;
}
}
return ret ;
}
2011-04-20 02:12:13 +03:00
2012-10-06 13:10:34 +03:00
static int convert_pix_fmt ( enum AVPixelFormat pix_fmt )
2011-10-09 20:34:20 +03:00
{
switch ( pix_fmt ) {
2012-10-06 13:10:34 +03:00
case AV_PIX_FMT_YUV420P :
case AV_PIX_FMT_YUVJ420P :
case AV_PIX_FMT_YUV420P9 :
case AV_PIX_FMT_YUV420P10 : return X264_CSP_I420 ;
case AV_PIX_FMT_YUV422P :
2013-09-21 10:52:47 +03:00
case AV_PIX_FMT_YUVJ422P :
2012-10-06 13:10:34 +03:00
case AV_PIX_FMT_YUV422P10 : return X264_CSP_I422 ;
case AV_PIX_FMT_YUV444P :
2013-09-21 10:52:47 +03:00
case AV_PIX_FMT_YUVJ444P :
2012-10-06 13:10:34 +03:00
case AV_PIX_FMT_YUV444P9 :
case AV_PIX_FMT_YUV444P10 : return X264_CSP_I444 ;
2015-05-28 12:34:22 +02:00
case AV_PIX_FMT_BGR0 :
return X264_CSP_BGRA ;
2012-10-08 21:54:00 +03:00
case AV_PIX_FMT_BGR24 :
2011-10-13 05:55:40 +03:00
return X264_CSP_BGR ;
2012-10-08 21:54:00 +03:00
case AV_PIX_FMT_RGB24 :
2011-10-13 05:55:40 +03:00
return X264_CSP_RGB ;
2013-09-22 18:54:47 +03:00
case AV_PIX_FMT_NV12 : return X264_CSP_NV12 ;
case AV_PIX_FMT_NV16 :
case AV_PIX_FMT_NV20 : return X264_CSP_NV16 ;
2015-08-01 00:42:15 +02:00
# ifdef X264_CSP_NV21
case AV_PIX_FMT_NV21 : return X264_CSP_NV21 ;
2018-08-07 20:41:02 +02:00
# endif
# ifdef X264_CSP_I400
case AV_PIX_FMT_GRAY8 :
case AV_PIX_FMT_GRAY10 : return X264_CSP_I400 ;
2015-08-01 00:42:15 +02:00
# endif
2011-10-09 20:34:20 +03:00
} ;
return 0 ;
}
2011-09-01 14:15:09 +03:00
# define PARSE_X264_OPT(name, var)\
if ( x4 - > var & & x264_param_parse ( & x4 - > params , name , x4 - > var ) < 0 ) { \
av_log ( avctx , AV_LOG_ERROR , " Error parsing option '%s' with value '%s'. \n " , name , x4 - > var ) ; \
return AVERROR ( EINVAL ) ; \
}
2009-09-29 21:03:30 +03:00
static av_cold int X264_init ( AVCodecContext * avctx )
2005-03-09 05:04:56 +02:00
{
X264Context * x4 = avctx - > priv_data ;
2015-10-03 15:19:10 +02:00
AVCPBProperties * cpb_props ;
2011-12-10 00:34:11 +03:00
int sw , sh ;
2020-07-10 22:10:33 +02:00
int ret ;
2005-03-09 05:04:56 +02:00
2014-03-22 11:48:52 +03:00
if ( avctx - > global_quality > 0 )
av_log ( avctx , AV_LOG_WARNING , " -qscale is ignored, -crf is recommended. \n " ) ;
2015-07-10 14:45:14 +02:00
# if CONFIG_LIBX262_ENCODER
if ( avctx - > codec_id = = AV_CODEC_ID_MPEG2VIDEO ) {
x4 - > params . b_mpeg2 = 1 ;
x264_param_default_mpeg2 ( & x4 - > params ) ;
} else
# endif
2015-07-17 22:10:58 +02:00
x264_param_default ( & x4 - > params ) ;
2005-03-09 05:04:56 +02:00
2015-06-29 21:59:37 +02:00
x4 - > params . b_deblocking_filter = avctx - > flags & AV_CODEC_FLAG_LOOP_FILTER ;
2005-03-16 15:09:30 +02:00
2011-04-17 02:50:50 +03:00
if ( x4 - > preset | | x4 - > tune )
if ( x264_param_default_preset ( & x4 - > params , x4 - > preset , x4 - > tune ) < 0 ) {
2012-07-14 01:34:50 +03:00
int i ;
2011-04-17 02:50:50 +03:00
av_log ( avctx , AV_LOG_ERROR , " Error setting preset/tune %s/%s. \n " , x4 - > preset , x4 - > tune ) ;
2012-07-14 01:34:50 +03:00
av_log ( avctx , AV_LOG_INFO , " Possible presets: " ) ;
for ( i = 0 ; x264_preset_names [ i ] ; i + + )
av_log ( avctx , AV_LOG_INFO , " %s " , x264_preset_names [ i ] ) ;
av_log ( avctx , AV_LOG_INFO , " \n " ) ;
av_log ( avctx , AV_LOG_INFO , " Possible tunes: " ) ;
for ( i = 0 ; x264_tune_names [ i ] ; i + + )
av_log ( avctx , AV_LOG_INFO , " %s " , x264_tune_names [ i ] ) ;
av_log ( avctx , AV_LOG_INFO , " \n " ) ;
2011-04-17 02:50:50 +03:00
return AVERROR ( EINVAL ) ;
}
2011-09-07 09:27:28 +03:00
if ( avctx - > level > 0 )
x4 - > params . i_level_idc = avctx - > level ;
2011-04-17 02:50:50 +03:00
x4 - > params . pf_log = X264_log ;
x4 - > params . p_log_private = avctx ;
x4 - > params . i_log_level = X264_LOG_DEBUG ;
2011-10-09 20:34:20 +03:00
x4 - > params . i_csp = convert_pix_fmt ( avctx - > pix_fmt ) ;
2017-12-26 13:32:42 +02:00
# if X264_BUILD >= 153
x4 - > params . i_bitdepth = av_pix_fmt_desc_get ( avctx - > pix_fmt ) - > comp [ 0 ] . depth ;
# endif
2011-04-17 02:50:50 +03:00
2015-10-07 04:48:13 +02:00
PARSE_X264_OPT ( " weightp " , wpredp ) ;
2011-04-30 00:13:19 +03:00
2011-08-20 17:59:47 +03:00
if ( avctx - > bit_rate ) {
2019-08-10 14:40:23 +02:00
if ( avctx - > bit_rate / 1000 > INT_MAX | | avctx - > rc_max_rate / 1000 > INT_MAX ) {
av_log ( avctx , AV_LOG_ERROR , " bit_rate and rc_max_rate > %d000 not supported by libx264 \n " , INT_MAX ) ;
return AVERROR ( EINVAL ) ;
}
2011-08-20 17:59:47 +03:00
x4 - > params . rc . i_bitrate = avctx - > bit_rate / 1000 ;
x4 - > params . rc . i_rc_method = X264_RC_ABR ;
}
2011-04-17 02:50:50 +03:00
x4 - > params . rc . i_vbv_buffer_size = avctx - > rc_buffer_size / 1000 ;
x4 - > params . rc . i_vbv_max_bitrate = avctx - > rc_max_rate / 1000 ;
2015-06-29 21:59:37 +02:00
x4 - > params . rc . b_stat_write = avctx - > flags & AV_CODEC_FLAG_PASS1 ;
if ( avctx - > flags & AV_CODEC_FLAG_PASS2 ) {
2011-04-17 02:50:50 +03:00
x4 - > params . rc . b_stat_read = 1 ;
} else {
2011-08-22 08:55:34 +03:00
if ( x4 - > crf > = 0 ) {
x4 - > params . rc . i_rc_method = X264_RC_CRF ;
x4 - > params . rc . f_rf_constant = x4 - > crf ;
2011-08-22 08:55:34 +03:00
} else if ( x4 - > cqp > = 0 ) {
x4 - > params . rc . i_rc_method = X264_RC_CQP ;
x4 - > params . rc . i_qp_constant = x4 - > cqp ;
2011-08-22 08:55:34 +03:00
}
2011-08-22 08:55:34 +03:00
if ( x4 - > crf_max > = 0 )
x4 - > params . rc . f_rf_constant_max = x4 - > crf_max ;
2011-04-17 02:50:50 +03:00
}
2013-01-14 07:32:39 +03:00
if ( avctx - > rc_buffer_size & & avctx - > rc_initial_buffer_occupancy > 0 & &
2009-09-29 21:03:30 +03:00
( avctx - > rc_initial_buffer_occupancy < = avctx - > rc_buffer_size ) ) {
2005-12-29 09:24:23 +02:00
x4 - > params . rc . f_vbv_buffer_init =
2009-09-29 21:03:30 +03:00
( float ) avctx - > rc_initial_buffer_occupancy / avctx - > rc_buffer_size ;
2011-02-06 15:10:15 +02:00
}
2005-12-29 09:24:23 +02:00
2015-10-07 04:48:13 +02:00
PARSE_X264_OPT ( " level " , level ) ;
2011-04-20 02:12:13 +03:00
2012-09-25 19:29:22 +03:00
if ( avctx - > i_quant_factor > 0 )
x4 - > params . rc . f_ip_factor = 1 / fabs ( avctx - > i_quant_factor ) ;
2014-08-26 09:55:14 +03:00
if ( avctx - > b_quant_factor > 0 )
x4 - > params . rc . f_pb_factor = avctx - > b_quant_factor ;
2015-09-12 14:40:29 +02:00
2020-07-28 14:22:02 +02:00
if ( x4 - > chroma_offset )
2016-01-28 17:21:21 +02:00
x4 - > params . analyse . i_chroma_qp_offset = x4 - > chroma_offset ;
2005-12-29 09:24:23 +02:00
2011-09-01 13:59:29 +03:00
if ( avctx - > gop_size > = 0 )
x4 - > params . i_keyint_max = avctx - > gop_size ;
if ( avctx - > max_b_frames > = 0 )
x4 - > params . i_bframe = avctx - > max_b_frames ;
2015-09-12 22:27:59 +02:00
2016-01-28 19:10:34 +02:00
if ( x4 - > scenechange_threshold > = 0 )
x4 - > params . i_scenecut_threshold = x4 - > scenechange_threshold ;
2015-09-12 22:27:59 +02:00
2011-09-01 13:59:29 +03:00
if ( avctx - > qmin > = 0 )
x4 - > params . rc . i_qp_min = avctx - > qmin ;
if ( avctx - > qmax > = 0 )
x4 - > params . rc . i_qp_max = avctx - > qmax ;
if ( avctx - > max_qdiff > = 0 )
x4 - > params . rc . i_qp_step = avctx - > max_qdiff ;
if ( avctx - > qblur > = 0 )
x4 - > params . rc . f_qblur = avctx - > qblur ; /* temporally blur quants */
if ( avctx - > qcompress > = 0 )
x4 - > params . rc . f_qcompress = avctx - > qcompress ; /* 0.0 => cbr, 1.0 => constant qp */
if ( avctx - > refs > = 0 )
x4 - > params . i_frame_reference = avctx - > refs ;
2020-04-16 22:50:29 +02:00
else if ( x4 - > params . i_level_idc > 0 ) {
2014-04-12 05:23:20 +03:00
int i ;
2016-01-27 17:19:38 +02:00
int mbn = AV_CEIL_RSHIFT ( avctx - > width , 4 ) * AV_CEIL_RSHIFT ( avctx - > height , 4 ) ;
2014-04-12 05:23:20 +03:00
int scale = X264_BUILD < 129 ? 384 : 1 ;
for ( i = 0 ; i < x264_levels [ i ] . level_idc ; i + + )
2020-04-16 22:50:29 +02:00
if ( x264_levels [ i ] . level_idc = = x4 - > params . i_level_idc )
2014-04-12 05:23:20 +03:00
x4 - > params . i_frame_reference = av_clip ( x264_levels [ i ] . dpb / mbn / scale , 1 , x4 - > params . i_frame_reference ) ;
}
2011-09-07 10:13:02 +03:00
if ( avctx - > trellis > = 0 )
x4 - > params . analyse . i_trellis = avctx - > trellis ;
if ( avctx - > me_range > = 0 )
x4 - > params . analyse . i_me_range = avctx - > me_range ;
2016-01-28 18:38:04 +02:00
if ( x4 - > noise_reduction > = 0 )
x4 - > params . analyse . i_noise_reduction = x4 - > noise_reduction ;
2011-09-07 10:13:02 +03:00
if ( avctx - > me_subpel_quality > = 0 )
x4 - > params . analyse . i_subpel_refine = avctx - > me_subpel_quality ;
if ( avctx - > keyint_min > = 0 )
x4 - > params . i_keyint_min = avctx - > keyint_min ;
if ( avctx - > me_cmp > = 0 )
x4 - > params . analyse . b_chroma_me = avctx - > me_cmp & FF_CMP_CHROMA ;
2011-09-01 13:59:29 +03:00
2011-08-22 08:55:34 +03:00
if ( x4 - > aq_mode > = 0 )
x4 - > params . rc . i_aq_mode = x4 - > aq_mode ;
2011-08-22 08:55:34 +03:00
if ( x4 - > aq_strength > = 0 )
x4 - > params . rc . f_aq_strength = x4 - > aq_strength ;
2011-09-01 14:15:09 +03:00
PARSE_X264_OPT ( " psy-rd " , psy_rd ) ;
PARSE_X264_OPT ( " deblock " , deblock ) ;
2011-09-01 14:15:09 +03:00
PARSE_X264_OPT ( " partitions " , partitions ) ;
2012-03-12 19:20:20 +03:00
PARSE_X264_OPT ( " stats " , stats ) ;
2011-08-27 11:16:14 +03:00
if ( x4 - > psy > = 0 )
x4 - > params . analyse . b_psy = x4 - > psy ;
2011-08-22 08:55:34 +03:00
if ( x4 - > rc_lookahead > = 0 )
x4 - > params . rc . i_lookahead = x4 - > rc_lookahead ;
2011-08-22 08:55:34 +03:00
if ( x4 - > weightp > = 0 )
x4 - > params . analyse . i_weighted_pred = x4 - > weightp ;
2011-08-22 08:55:34 +03:00
if ( x4 - > weightb > = 0 )
x4 - > params . analyse . b_weighted_bipred = x4 - > weightb ;
2011-09-01 14:15:09 +03:00
if ( x4 - > cplxblur > = 0 )
x4 - > params . rc . f_complexity_blur = x4 - > cplxblur ;
2011-08-22 08:55:34 +03:00
2011-08-22 08:55:34 +03:00
if ( x4 - > ssim > = 0 )
x4 - > params . analyse . b_ssim = x4 - > ssim ;
2011-08-22 08:55:34 +03:00
if ( x4 - > intra_refresh > = 0 )
x4 - > params . b_intra_refresh = x4 - > intra_refresh ;
2013-08-05 14:23:52 +03:00
if ( x4 - > bluray_compat > = 0 ) {
x4 - > params . b_bluray_compat = x4 - > bluray_compat ;
x4 - > params . b_vfr_input = 0 ;
}
2014-10-01 17:19:45 +03:00
if ( x4 - > avcintra_class > = 0 )
2014-10-04 18:42:45 +03:00
# if X264_BUILD >= 142
2014-10-01 17:19:45 +03:00
x4 - > params . i_avcintra_class = x4 - > avcintra_class ;
2014-10-04 18:42:45 +03:00
# else
av_log ( avctx , AV_LOG_ERROR ,
" x264 too old for AVC Intra, at least version 142 needed \n " ) ;
# endif
2021-06-22 12:40:03 +02:00
if ( x4 - > avcintra_class > 200 ) {
# if X264_BUILD < 164
av_log ( avctx , AV_LOG_ERROR ,
" x264 too old for AVC Intra 300/480, at least version 164 needed \n " ) ;
return AVERROR ( EINVAL ) ;
# else
/* AVC-Intra 300/480 only supported by Sony XAVC flavor */
x4 - > params . i_avcintra_flavor = X264_AVCINTRA_FLAVOR_SONY ;
# endif
}
2011-09-01 14:15:09 +03:00
if ( x4 - > b_bias ! = INT_MIN )
x4 - > params . i_bframe_bias = x4 - > b_bias ;
2011-08-22 08:55:34 +03:00
if ( x4 - > b_pyramid > = 0 )
x4 - > params . i_bframe_pyramid = x4 - > b_pyramid ;
2011-08-22 08:55:34 +03:00
if ( x4 - > mixed_refs > = 0 )
x4 - > params . analyse . b_mixed_references = x4 - > mixed_refs ;
2011-08-22 08:55:34 +03:00
if ( x4 - > dct8x8 > = 0 )
x4 - > params . analyse . b_transform_8x8 = x4 - > dct8x8 ;
2011-08-22 08:55:34 +03:00
if ( x4 - > fast_pskip > = 0 )
x4 - > params . analyse . b_fast_pskip = x4 - > fast_pskip ;
2011-08-22 08:55:34 +03:00
if ( x4 - > aud > = 0 )
x4 - > params . b_aud = x4 - > aud ;
2011-08-27 11:16:14 +03:00
if ( x4 - > mbtree > = 0 )
x4 - > params . rc . b_mb_tree = x4 - > mbtree ;
2011-09-01 14:15:09 +03:00
if ( x4 - > direct_pred > = 0 )
x4 - > params . analyse . i_direct_mv_pred = x4 - > direct_pred ;
2011-08-22 08:55:34 +03:00
2011-09-16 05:30:10 +03:00
if ( x4 - > slice_max_size > = 0 )
x4 - > params . i_slice_max_size = x4 - > slice_max_size ;
2011-04-20 01:23:36 +03:00
if ( x4 - > fastfirstpass )
x264_param_apply_fastfirstpass ( & x4 - > params ) ;
2022-06-24 10:22:05 +02:00
x4 - > profile = x4 - > profile_opt ;
2012-09-16 22:53:49 +03:00
/* Allow specifying the x264 profile through AVCodecContext. */
if ( ! x4 - > profile )
switch ( avctx - > profile ) {
case FF_PROFILE_H264_BASELINE :
2022-06-24 10:22:05 +02:00
x4 - > profile = " baseline " ;
2012-09-16 22:53:49 +03:00
break ;
case FF_PROFILE_H264_HIGH :
2022-06-24 10:22:05 +02:00
x4 - > profile = " high " ;
2012-09-16 22:53:49 +03:00
break ;
case FF_PROFILE_H264_HIGH_10 :
2022-06-24 10:22:05 +02:00
x4 - > profile = " high10 " ;
2012-09-16 22:53:49 +03:00
break ;
case FF_PROFILE_H264_HIGH_422 :
2022-06-24 10:22:05 +02:00
x4 - > profile = " high422 " ;
2012-09-16 22:53:49 +03:00
break ;
case FF_PROFILE_H264_HIGH_444 :
2022-06-24 10:22:05 +02:00
x4 - > profile = " high444 " ;
2012-09-16 22:53:49 +03:00
break ;
case FF_PROFILE_H264_MAIN :
2022-06-24 10:22:05 +02:00
x4 - > profile = " main " ;
2012-09-16 22:53:49 +03:00
break ;
default :
break ;
}
2012-09-20 22:46:35 +03:00
2012-09-19 20:51:29 +03:00
if ( x4 - > nal_hrd > = 0 )
x4 - > params . i_nal_hrd = x4 - > nal_hrd ;
2017-03-16 22:03:38 +02:00
if ( x4 - > motion_est > = 0 )
2015-07-07 02:20:43 +02:00
x4 - > params . analyse . i_me_method = x4 - > motion_est ;
2015-11-30 19:17:31 +02:00
if ( x4 - > coder > = 0 )
x4 - > params . b_cabac = x4 - > coder ;
2015-09-09 04:18:26 +02:00
if ( x4 - > b_frame_strategy > = 0 )
x4 - > params . i_bframe_adaptive = x4 - > b_frame_strategy ;
2011-04-20 01:23:36 +03:00
if ( x4 - > profile )
2011-04-17 02:50:50 +03:00
if ( x264_param_apply_profile ( & x4 - > params , x4 - > profile ) < 0 ) {
2012-07-28 19:29:28 +03:00
int i ;
2011-04-17 02:50:50 +03:00
av_log ( avctx , AV_LOG_ERROR , " Error setting profile %s. \n " , x4 - > profile ) ;
2012-07-28 19:29:28 +03:00
av_log ( avctx , AV_LOG_INFO , " Possible profiles: " ) ;
for ( i = 0 ; x264_profile_names [ i ] ; i + + )
2012-09-01 16:35:44 +03:00
av_log ( avctx , AV_LOG_INFO , " %s " , x264_profile_names [ i ] ) ;
2012-07-28 19:29:28 +03:00
av_log ( avctx , AV_LOG_INFO , " \n " ) ;
2011-04-17 02:50:50 +03:00
return AVERROR ( EINVAL ) ;
}
2011-04-20 01:23:36 +03:00
2011-04-17 02:50:50 +03:00
x4 - > params . i_width = avctx - > width ;
x4 - > params . i_height = avctx - > height ;
2011-12-10 00:34:11 +03:00
av_reduce ( & sw , & sh , avctx - > sample_aspect_ratio . num , avctx - > sample_aspect_ratio . den , 4096 ) ;
x4 - > params . vui . i_sar_width = sw ;
x4 - > params . vui . i_sar_height = sh ;
2014-01-25 18:19:39 +03:00
x4 - > params . i_timebase_den = avctx - > time_base . den ;
x4 - > params . i_timebase_num = avctx - > time_base . num ;
2019-04-27 12:45:23 +02:00
if ( avctx - > framerate . num > 0 & & avctx - > framerate . den > 0 ) {
x4 - > params . i_fps_num = avctx - > framerate . num ;
x4 - > params . i_fps_den = avctx - > framerate . den ;
} else {
x4 - > params . i_fps_num = avctx - > time_base . den ;
x4 - > params . i_fps_den = avctx - > time_base . num * avctx - > ticks_per_frame ;
}
2005-12-29 09:24:23 +02:00
2015-06-29 21:59:37 +02:00
x4 - > params . analyse . b_psnr = avctx - > flags & AV_CODEC_FLAG_PSNR ;
2005-12-29 09:24:23 +02:00
2009-09-29 21:03:30 +03:00
x4 - > params . i_threads = avctx - > thread_count ;
2012-03-05 22:54:17 +03:00
if ( avctx - > thread_type )
x4 - > params . b_sliced_threads = avctx - > thread_type = = FF_THREAD_SLICE ;
2005-05-30 23:34:02 +03:00
2015-06-29 21:59:37 +02:00
x4 - > params . b_interlaced = avctx - > flags & AV_CODEC_FLAG_INTERLACED_DCT ;
2008-06-04 03:56:36 +03:00
2015-06-29 21:59:37 +02:00
x4 - > params . b_open_gop = ! ( avctx - > flags & AV_CODEC_FLAG_CLOSED_GOP ) ;
2011-05-10 16:11:45 +03:00
2010-10-22 21:09:14 +03:00
x4 - > params . i_slice_count = avctx - > slices ;
2021-08-17 21:57:36 +02:00
if ( avctx - > color_range ! = AVCOL_RANGE_UNSPECIFIED )
x4 - > params . vui . b_fullrange = avctx - > color_range = = AVCOL_RANGE_JPEG ;
else if ( avctx - > pix_fmt = = AV_PIX_FMT_YUVJ420P | |
avctx - > pix_fmt = = AV_PIX_FMT_YUVJ422P | |
avctx - > pix_fmt = = AV_PIX_FMT_YUVJ444P )
x4 - > params . vui . b_fullrange = 1 ;
2013-12-16 18:59:02 +03:00
if ( avctx - > colorspace ! = AVCOL_SPC_UNSPECIFIED )
x4 - > params . vui . i_colmatrix = avctx - > colorspace ;
if ( avctx - > color_primaries ! = AVCOL_PRI_UNSPECIFIED )
x4 - > params . vui . i_colorprim = avctx - > color_primaries ;
if ( avctx - > color_trc ! = AVCOL_TRC_UNSPECIFIED )
x4 - > params . vui . i_transfer = avctx - > color_trc ;
2021-08-23 23:28:39 +02:00
if ( avctx - > chroma_sample_location ! = AVCHROMA_LOC_UNSPECIFIED )
x4 - > params . vui . i_chroma_loc = avctx - > chroma_sample_location - 1 ;
2010-12-07 11:51:27 +02:00
2015-06-29 21:59:37 +02:00
if ( avctx - > flags & AV_CODEC_FLAG_GLOBAL_HEADER )
2006-01-20 23:20:46 +02:00
x4 - > params . b_repeat_headers = 0 ;
2022-07-16 17:02:38 +02:00
if ( avctx - > flags & AV_CODEC_FLAG_RECON_FRAME )
x4 - > params . b_full_recon = 1 ;
2014-03-28 02:03:38 +03:00
if ( x4 - > x264opts ) {
const char * p = x4 - > x264opts ;
while ( p ) {
2016-07-22 03:52:41 +02:00
char param [ 4096 ] = { 0 } , val [ 4096 ] = { 0 } ;
if ( sscanf ( p , " %4095[^:=]=%4095[^:] " , param , val ) = = 1 ) {
2020-07-10 22:10:33 +02:00
ret = parse_opts ( avctx , param , " 1 " ) ;
if ( ret < 0 )
return ret ;
} else {
ret = parse_opts ( avctx , param , val ) ;
if ( ret < 0 )
return ret ;
}
2014-03-28 02:03:38 +03:00
p = strchr ( p , ' : ' ) ;
2022-06-16 17:52:56 +02:00
if ( p ) {
+ + p ;
}
2014-03-28 02:03:38 +03:00
}
}
2021-06-18 13:55:07 +02:00
# if X264_BUILD >= 142
/* Separate headers not supported in AVC-Intra mode */
2021-12-20 19:08:36 +02:00
if ( x4 - > avcintra_class > = 0 )
2021-06-18 13:55:07 +02:00
x4 - > params . b_repeat_headers = 1 ;
# endif
2013-01-23 10:21:55 +03:00
2019-12-25 02:46:37 +02:00
{
AVDictionaryEntry * en = NULL ;
while ( en = av_dict_get ( x4 - > x264_params , " " , en , AV_DICT_IGNORE_SUFFIX ) ) {
2020-07-10 22:16:49 +02:00
if ( ( ret = x264_param_parse ( & x4 - > params , en - > key , en - > value ) ) < 0 ) {
2019-12-25 02:46:37 +02:00
av_log ( avctx , AV_LOG_WARNING ,
" Error parsing option '%s = %s'. \n " ,
en - > key , en - > value ) ;
2020-07-10 22:16:49 +02:00
# if X264_BUILD >= 161
if ( ret = = X264_PARAM_ALLOC_FAILED )
return AVERROR ( ENOMEM ) ;
# endif
}
2013-01-23 10:21:55 +03:00
}
}
2011-04-17 02:50:50 +03:00
// update AVCodecContext with x264 parameters
2011-04-23 22:41:11 +03:00
avctx - > has_b_frames = x4 - > params . i_bframe ?
x4 - > params . i_bframe_pyramid ? 2 : 1 : 0 ;
2012-01-14 00:41:16 +03:00
if ( avctx - > max_b_frames < 0 )
avctx - > max_b_frames = 0 ;
2019-08-10 17:10:58 +02:00
avctx - > bit_rate = x4 - > params . rc . i_bitrate * 1000LL ;
2011-04-17 02:50:50 +03:00
2005-03-09 05:04:56 +02:00
x4 - > enc = x264_encoder_open ( & x4 - > params ) ;
2009-09-29 21:03:30 +03:00
if ( ! x4 - > enc )
2015-03-17 01:05:58 +02:00
return AVERROR_EXTERNAL ;
2005-03-09 05:04:56 +02:00
2015-06-29 21:59:37 +02:00
if ( avctx - > flags & AV_CODEC_FLAG_GLOBAL_HEADER ) {
2006-01-24 12:33:14 +02:00
x264_nal_t * nal ;
2012-02-06 09:34:57 +03:00
uint8_t * p ;
2010-03-25 21:25:21 +02:00
int nnal , s , i ;
2006-01-20 23:20:46 +02:00
2009-09-23 12:03:26 +03:00
s = x264_encoder_headers ( x4 - > enc , & nal , & nnal ) ;
2015-10-20 21:12:30 +02:00
avctx - > extradata = p = av_mallocz ( s + AV_INPUT_BUFFER_PADDING_SIZE ) ;
2015-02-22 03:49:33 +02:00
if ( ! p )
2015-04-24 22:46:06 +02:00
return AVERROR ( ENOMEM ) ;
2006-01-20 23:20:46 +02:00
2012-02-06 09:34:57 +03:00
for ( i = 0 ; i < nnal ; i + + ) {
/* Don't put the SEI in extradata. */
if ( nal [ i ] . i_type = = NAL_SEI ) {
2010-03-25 21:25:21 +02:00
av_log ( avctx , AV_LOG_INFO , " %s \n " , nal [ i ] . p_payload + 25 ) ;
2012-02-06 09:34:57 +03:00
x4 - > sei_size = nal [ i ] . i_payload ;
x4 - > sei = av_malloc ( x4 - > sei_size ) ;
2015-02-22 03:49:33 +02:00
if ( ! x4 - > sei )
2015-04-24 22:46:06 +02:00
return AVERROR ( ENOMEM ) ;
2012-02-06 09:34:57 +03:00
memcpy ( x4 - > sei , nal [ i ] . p_payload , nal [ i ] . i_payload ) ;
continue ;
}
memcpy ( p , nal [ i ] . p_payload , nal [ i ] . i_payload ) ;
p + = nal [ i ] . i_payload ;
}
avctx - > extradata_size = p - avctx - > extradata ;
2006-01-20 23:20:46 +02:00
}
2015-10-03 15:19:10 +02:00
cpb_props = ff_add_cpb_side_data ( avctx ) ;
if ( ! cpb_props )
return AVERROR ( ENOMEM ) ;
cpb_props - > buffer_size = x4 - > params . rc . i_vbv_buffer_size * 1000 ;
2019-08-10 23:52:59 +02:00
cpb_props - > max_bitrate = x4 - > params . rc . i_vbv_max_bitrate * 1000LL ;
cpb_props - > avg_bitrate = x4 - > params . rc . i_bitrate * 1000LL ;
2015-10-03 15:19:10 +02:00
2018-10-11 15:03:10 +02:00
// Overestimate the reordered opaque buffer size, in case a runtime
// reconfigure would increase the delay (which it shouldn't).
x4 - > nb_reordered_opaque = x264_encoder_maximum_delayed_frames ( x4 - > enc ) + 17 ;
x4 - > reordered_opaque = av_malloc_array ( x4 - > nb_reordered_opaque ,
sizeof ( * x4 - > reordered_opaque ) ) ;
if ( ! x4 - > reordered_opaque )
return AVERROR ( ENOMEM ) ;
2005-03-09 05:04:56 +02:00
return 0 ;
}
2012-10-06 13:10:34 +03:00
static const enum AVPixelFormat pix_fmts_8bit [ ] = {
2017-12-26 00:41:09 +02:00
AV_PIX_FMT_YUV420P ,
AV_PIX_FMT_YUVJ420P ,
AV_PIX_FMT_YUV422P ,
AV_PIX_FMT_YUVJ422P ,
AV_PIX_FMT_YUV444P ,
AV_PIX_FMT_YUVJ444P ,
AV_PIX_FMT_NV12 ,
AV_PIX_FMT_NV16 ,
# ifdef X264_CSP_NV21
AV_PIX_FMT_NV21 ,
# endif
AV_PIX_FMT_NONE
} ;
2012-10-06 13:10:34 +03:00
static const enum AVPixelFormat pix_fmts_9bit [ ] = {
AV_PIX_FMT_YUV420P9 ,
AV_PIX_FMT_YUV444P9 ,
AV_PIX_FMT_NONE
2011-10-05 22:09:51 +03:00
} ;
2012-10-06 13:10:34 +03:00
static const enum AVPixelFormat pix_fmts_10bit [ ] = {
AV_PIX_FMT_YUV420P10 ,
AV_PIX_FMT_YUV422P10 ,
AV_PIX_FMT_YUV444P10 ,
2013-09-22 18:54:47 +03:00
AV_PIX_FMT_NV20 ,
2012-10-06 13:10:34 +03:00
AV_PIX_FMT_NONE
2011-10-05 22:09:51 +03:00
} ;
2017-12-26 13:32:42 +02:00
static const enum AVPixelFormat pix_fmts_all [ ] = {
2012-10-06 13:10:34 +03:00
AV_PIX_FMT_YUV420P ,
AV_PIX_FMT_YUVJ420P ,
AV_PIX_FMT_YUV422P ,
2013-09-21 10:52:47 +03:00
AV_PIX_FMT_YUVJ422P ,
2012-10-06 13:10:34 +03:00
AV_PIX_FMT_YUV444P ,
2013-09-21 10:52:47 +03:00
AV_PIX_FMT_YUVJ444P ,
2013-09-22 18:54:47 +03:00
AV_PIX_FMT_NV12 ,
AV_PIX_FMT_NV16 ,
2015-08-01 00:42:15 +02:00
# ifdef X264_CSP_NV21
AV_PIX_FMT_NV21 ,
# endif
2012-10-06 13:10:34 +03:00
AV_PIX_FMT_YUV420P10 ,
AV_PIX_FMT_YUV422P10 ,
AV_PIX_FMT_YUV444P10 ,
2013-09-22 18:54:47 +03:00
AV_PIX_FMT_NV20 ,
2018-08-07 20:41:02 +02:00
# ifdef X264_CSP_I400
AV_PIX_FMT_GRAY8 ,
AV_PIX_FMT_GRAY10 ,
# endif
2012-10-06 13:10:34 +03:00
AV_PIX_FMT_NONE
2011-10-05 22:09:51 +03:00
} ;
2016-02-28 00:23:41 +02:00
# if CONFIG_LIBX264RGB_ENCODER
2012-10-08 21:54:00 +03:00
static const enum AVPixelFormat pix_fmts_8bit_rgb [ ] = {
2015-05-28 12:34:22 +02:00
AV_PIX_FMT_BGR0 ,
2012-10-08 21:54:00 +03:00
AV_PIX_FMT_BGR24 ,
AV_PIX_FMT_RGB24 ,
AV_PIX_FMT_NONE
2011-12-01 23:02:57 +03:00
} ;
2016-02-28 00:23:41 +02:00
# endif
2011-10-05 22:09:51 +03:00
2021-02-25 10:25:51 +02:00
# if X264_BUILD < 153
2022-03-16 22:09:54 +02:00
static av_cold void X264_init_static ( FFCodec * codec )
2011-10-05 22:09:51 +03:00
{
2017-12-27 00:40:27 +02:00
if ( x264_bit_depth = = 8 )
2022-03-16 22:09:54 +02:00
codec - > p . pix_fmts = pix_fmts_8bit ;
2017-12-27 00:40:27 +02:00
else if ( x264_bit_depth = = 9 )
2022-03-16 22:09:54 +02:00
codec - > p . pix_fmts = pix_fmts_9bit ;
2017-12-27 00:40:27 +02:00
else if ( x264_bit_depth = = 10 )
2022-03-16 22:09:54 +02:00
codec - > p . pix_fmts = pix_fmts_10bit ;
2011-10-05 22:09:51 +03:00
}
2021-02-25 10:25:51 +02:00
# endif
2011-10-05 22:09:51 +03:00
2011-04-17 02:50:50 +03:00
# define OFFSET(x) offsetof(X264Context, x)
2011-04-17 02:50:50 +03:00
# define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM
static const AVOption options [ ] = {
2011-10-04 08:38:01 +03:00
{ " preset " , " Set the encoding preset (cf. x264 --fullhelp) " , OFFSET ( preset ) , AV_OPT_TYPE_STRING , { . str = " medium " } , 0 , 0 , VE } ,
{ " tune " , " Tune the encoding params (cf. x264 --fullhelp) " , OFFSET ( tune ) , AV_OPT_TYPE_STRING , { 0 } , 0 , 0 , VE } ,
2022-06-24 10:22:05 +02:00
{ " profile " , " Set profile restrictions (cf. x264 --fullhelp) " , OFFSET ( profile_opt ) , AV_OPT_TYPE_STRING , { 0 } , 0 , 0 , VE } ,
2015-09-11 21:10:14 +02:00
{ " fastfirstpass " , " Use fast settings when encoding first pass " , OFFSET ( fastfirstpass ) , AV_OPT_TYPE_BOOL , { . i64 = 1 } , 0 , 1 , VE } ,
2011-10-13 05:55:40 +03:00
{ " level " , " Specify level (as defined by Annex A) " , OFFSET ( level ) , AV_OPT_TYPE_STRING , { . str = NULL } , 0 , 0 , VE } ,
{ " passlogfile " , " Filename for 2 pass stats " , OFFSET ( stats ) , AV_OPT_TYPE_STRING , { . str = NULL } , 0 , 0 , VE } ,
{ " wpredp " , " Weighted prediction for P-frames " , OFFSET ( wpredp ) , AV_OPT_TYPE_STRING , { . str = NULL } , 0 , 0 , VE } ,
2016-09-09 17:56:46 +02:00
{ " a53cc " , " Use A53 Closed Captions (if available) " , OFFSET ( a53_cc ) , AV_OPT_TYPE_BOOL , { . i64 = 1 } , 0 , 1 , VE } ,
2011-10-13 05:55:40 +03:00
{ " x264opts " , " x264 options " , OFFSET ( x264opts ) , AV_OPT_TYPE_STRING , { . str = NULL } , 0 , 0 , VE } ,
2012-08-31 13:34:23 +03:00
{ " crf " , " Select the quality for constant quality mode " , OFFSET ( crf ) , AV_OPT_TYPE_FLOAT , { . dbl = - 1 } , - 1 , FLT_MAX , VE } ,
{ " crf_max " , " In CRF mode, prevents VBV from lowering quality beyond this point. " , OFFSET ( crf_max ) , AV_OPT_TYPE_FLOAT , { . dbl = - 1 } , - 1 , FLT_MAX , VE } ,
2012-08-31 13:22:31 +03:00
{ " qp " , " Constant quantization parameter rate control method " , OFFSET ( cqp ) , AV_OPT_TYPE_INT , { . i64 = - 1 } , - 1 , INT_MAX , VE } ,
{ " aq-mode " , " AQ method " , OFFSET ( aq_mode ) , AV_OPT_TYPE_INT , { . i64 = - 1 } , - 1 , INT_MAX , VE , " aq_mode " } ,
2012-08-31 12:45:52 +03:00
{ " none " , NULL , 0 , AV_OPT_TYPE_CONST , { . i64 = X264_AQ_NONE } , INT_MIN , INT_MAX , VE , " aq_mode " } ,
{ " variance " , " Variance AQ (complexity mask) " , 0 , AV_OPT_TYPE_CONST , { . i64 = X264_AQ_VARIANCE } , INT_MIN , INT_MAX , VE , " aq_mode " } ,
2015-01-29 23:24:45 +02:00
{ " autovariance " , " Auto-variance AQ " , 0 , AV_OPT_TYPE_CONST , { . i64 = X264_AQ_AUTOVARIANCE } , INT_MIN , INT_MAX , VE , " aq_mode " } ,
# if X264_BUILD >= 144
{ " autovariance-biased " , " Auto-variance AQ with bias to dark scenes " , 0 , AV_OPT_TYPE_CONST , { . i64 = X264_AQ_AUTOVARIANCE_BIASED } , INT_MIN , INT_MAX , VE , " aq_mode " } ,
# endif
2012-08-31 13:34:23 +03:00
{ " aq-strength " , " AQ strength. Reduces blocking and blurring in flat and textured areas. " , OFFSET ( aq_strength ) , AV_OPT_TYPE_FLOAT , { . dbl = - 1 } , - 1 , FLT_MAX , VE } ,
2015-11-21 23:04:39 +02:00
{ " psy " , " Use psychovisual optimizations. " , OFFSET ( psy ) , AV_OPT_TYPE_BOOL , { . i64 = - 1 } , - 1 , 1 , VE } ,
2011-10-04 08:38:01 +03:00
{ " psy-rd " , " Strength of psychovisual optimization, in <psy-rd>:<psy-trellis> format. " , OFFSET ( psy_rd ) , AV_OPT_TYPE_STRING , { 0 } , 0 , 0 , VE } ,
2012-08-31 13:22:31 +03:00
{ " rc-lookahead " , " Number of frames to look ahead for frametype and ratecontrol " , OFFSET ( rc_lookahead ) , AV_OPT_TYPE_INT , { . i64 = - 1 } , - 1 , INT_MAX , VE } ,
2015-11-21 23:04:39 +02:00
{ " weightb " , " Weighted prediction for B-frames. " , OFFSET ( weightb ) , AV_OPT_TYPE_BOOL , { . i64 = - 1 } , - 1 , 1 , VE } ,
2012-08-31 13:22:31 +03:00
{ " weightp " , " Weighted prediction analysis method. " , OFFSET ( weightp ) , AV_OPT_TYPE_INT , { . i64 = - 1 } , - 1 , INT_MAX , VE , " weightp " } ,
2012-08-31 12:45:52 +03:00
{ " none " , NULL , 0 , AV_OPT_TYPE_CONST , { . i64 = X264_WEIGHTP_NONE } , INT_MIN , INT_MAX , VE , " weightp " } ,
{ " simple " , NULL , 0 , AV_OPT_TYPE_CONST , { . i64 = X264_WEIGHTP_SIMPLE } , INT_MIN , INT_MAX , VE , " weightp " } ,
{ " smart " , NULL , 0 , AV_OPT_TYPE_CONST , { . i64 = X264_WEIGHTP_SMART } , INT_MIN , INT_MAX , VE , " weightp " } ,
2015-11-21 23:04:39 +02:00
{ " ssim " , " Calculate and print SSIM stats. " , OFFSET ( ssim ) , AV_OPT_TYPE_BOOL , { . i64 = - 1 } , - 1 , 1 , VE } ,
{ " intra-refresh " , " Use Periodic Intra Refresh instead of IDR frames. " , OFFSET ( intra_refresh ) , AV_OPT_TYPE_BOOL , { . i64 = - 1 } , - 1 , 1 , VE } ,
{ " bluray-compat " , " Bluray compatibility workarounds. " , OFFSET ( bluray_compat ) , AV_OPT_TYPE_BOOL , { . i64 = - 1 } , - 1 , 1 , VE } ,
2012-08-31 13:22:31 +03:00
{ " b-bias " , " Influences how often B-frames are used " , OFFSET ( b_bias ) , AV_OPT_TYPE_INT , { . i64 = INT_MIN } , INT_MIN , INT_MAX , VE } ,
{ " b-pyramid " , " Keep some B-frames as references. " , OFFSET ( b_pyramid ) , AV_OPT_TYPE_INT , { . i64 = - 1 } , - 1 , INT_MAX , VE , " b_pyramid " } ,
2012-08-31 12:45:52 +03:00
{ " none " , NULL , 0 , AV_OPT_TYPE_CONST , { . i64 = X264_B_PYRAMID_NONE } , INT_MIN , INT_MAX , VE , " b_pyramid " } ,
{ " strict " , " Strictly hierarchical pyramid " , 0 , AV_OPT_TYPE_CONST , { . i64 = X264_B_PYRAMID_STRICT } , INT_MIN , INT_MAX , VE , " b_pyramid " } ,
{ " normal " , " Non-strict (not Blu-ray compatible) " , 0 , AV_OPT_TYPE_CONST , { . i64 = X264_B_PYRAMID_NORMAL } , INT_MIN , INT_MAX , VE , " b_pyramid " } ,
2015-11-21 23:04:39 +02:00
{ " mixed-refs " , " One reference per partition, as opposed to one reference per macroblock " , OFFSET ( mixed_refs ) , AV_OPT_TYPE_BOOL , { . i64 = - 1 } , - 1 , 1 , VE } ,
{ " 8x8dct " , " High profile 8x8 transform. " , OFFSET ( dct8x8 ) , AV_OPT_TYPE_BOOL , { . i64 = - 1 } , - 1 , 1 , VE } ,
{ " fast-pskip " , NULL , OFFSET ( fast_pskip ) , AV_OPT_TYPE_BOOL , { . i64 = - 1 } , - 1 , 1 , VE } ,
{ " aud " , " Use access unit delimiters. " , OFFSET ( aud ) , AV_OPT_TYPE_BOOL , { . i64 = - 1 } , - 1 , 1 , VE } ,
{ " mbtree " , " Use macroblock tree ratecontrol. " , OFFSET ( mbtree ) , AV_OPT_TYPE_BOOL , { . i64 = - 1 } , - 1 , 1 , VE } ,
2011-10-04 08:38:01 +03:00
{ " deblock " , " Loop filter parameters, in <alpha:beta> form. " , OFFSET ( deblock ) , AV_OPT_TYPE_STRING , { 0 } , 0 , 0 , VE } ,
2012-08-31 13:34:23 +03:00
{ " cplxblur " , " Reduce fluctuations in QP (before curve compression) " , OFFSET ( cplxblur ) , AV_OPT_TYPE_FLOAT , { . dbl = - 1 } , - 1 , FLT_MAX , VE } ,
2011-09-01 14:15:09 +03:00
{ " partitions " , " A comma-separated list of partitions to consider. "
2011-10-04 08:38:01 +03:00
" Possible values: p8x8, p4x4, b8x8, i8x8, i4x4, none, all " , OFFSET ( partitions ) , AV_OPT_TYPE_STRING , { 0 } , 0 , 0 , VE } ,
2012-08-31 13:22:31 +03:00
{ " direct-pred " , " Direct MV prediction mode " , OFFSET ( direct_pred ) , AV_OPT_TYPE_INT , { . i64 = - 1 } , - 1 , INT_MAX , VE , " direct-pred " } ,
2012-08-31 12:45:52 +03:00
{ " none " , NULL , 0 , AV_OPT_TYPE_CONST , { . i64 = X264_DIRECT_PRED_NONE } , 0 , 0 , VE , " direct-pred " } ,
{ " spatial " , NULL , 0 , AV_OPT_TYPE_CONST , { . i64 = X264_DIRECT_PRED_SPATIAL } , 0 , 0 , VE , " direct-pred " } ,
{ " temporal " , NULL , 0 , AV_OPT_TYPE_CONST , { . i64 = X264_DIRECT_PRED_TEMPORAL } , 0 , 0 , VE , " direct-pred " } ,
{ " auto " , NULL , 0 , AV_OPT_TYPE_CONST , { . i64 = X264_DIRECT_PRED_AUTO } , 0 , 0 , VE , " direct-pred " } ,
2012-08-31 13:22:31 +03:00
{ " slice-max-size " , " Limit the size of each slice in bytes " , OFFSET ( slice_max_size ) , AV_OPT_TYPE_INT , { . i64 = - 1 } , - 1 , INT_MAX , VE } ,
2012-03-12 19:20:20 +03:00
{ " stats " , " Filename for 2 pass stats " , OFFSET ( stats ) , AV_OPT_TYPE_STRING , { 0 } , 0 , 0 , VE } ,
2012-09-19 20:51:29 +03:00
{ " nal-hrd " , " Signal HRD information (requires vbv-bufsize; "
" cbr not allowed in .mp4) " , OFFSET ( nal_hrd ) , AV_OPT_TYPE_INT , { . i64 = - 1 } , - 1 , INT_MAX , VE , " nal-hrd " } ,
{ " none " , NULL , 0 , AV_OPT_TYPE_CONST , { . i64 = X264_NAL_HRD_NONE } , INT_MIN , INT_MAX , VE , " nal-hrd " } ,
{ " vbr " , NULL , 0 , AV_OPT_TYPE_CONST , { . i64 = X264_NAL_HRD_VBR } , INT_MIN , INT_MAX , VE , " nal-hrd " } ,
{ " cbr " , NULL , 0 , AV_OPT_TYPE_CONST , { . i64 = X264_NAL_HRD_CBR } , INT_MIN , INT_MAX , VE , " nal-hrd " } ,
2021-06-22 12:40:03 +02:00
{ " avcintra-class " , " AVC-Intra class 50/100/200/300/480 " , OFFSET ( avcintra_class ) , AV_OPT_TYPE_INT , { . i64 = - 1 } , - 1 , 480 , VE } ,
2017-10-23 19:34:15 +02:00
{ " me_method " , " Set motion estimation method " , OFFSET ( motion_est ) , AV_OPT_TYPE_INT , { . i64 = - 1 } , - 1 , X264_ME_TESA , VE , " motion-est " } ,
2015-07-07 02:20:43 +02:00
{ " motion-est " , " Set motion estimation method " , OFFSET ( motion_est ) , AV_OPT_TYPE_INT , { . i64 = - 1 } , - 1 , X264_ME_TESA , VE , " motion-est " } ,
{ " dia " , NULL , 0 , AV_OPT_TYPE_CONST , { . i64 = X264_ME_DIA } , INT_MIN , INT_MAX , VE , " motion-est " } ,
{ " hex " , NULL , 0 , AV_OPT_TYPE_CONST , { . i64 = X264_ME_HEX } , INT_MIN , INT_MAX , VE , " motion-est " } ,
{ " umh " , NULL , 0 , AV_OPT_TYPE_CONST , { . i64 = X264_ME_UMH } , INT_MIN , INT_MAX , VE , " motion-est " } ,
{ " esa " , NULL , 0 , AV_OPT_TYPE_CONST , { . i64 = X264_ME_ESA } , INT_MIN , INT_MAX , VE , " motion-est " } ,
{ " tesa " , NULL , 0 , AV_OPT_TYPE_CONST , { . i64 = X264_ME_TESA } , INT_MIN , INT_MAX , VE , " motion-est " } ,
2016-10-12 21:54:52 +02:00
{ " forced-idr " , " If forcing keyframes, force them as IDR frames. " , OFFSET ( forced_idr ) , AV_OPT_TYPE_BOOL , { . i64 = 0 } , - 1 , 1 , VE } ,
2015-11-30 19:17:31 +02:00
{ " coder " , " Coder type " , OFFSET ( coder ) , AV_OPT_TYPE_INT , { . i64 = - 1 } , - 1 , 1 , VE , " coder " } ,
{ " default " , NULL , 0 , AV_OPT_TYPE_CONST , { . i64 = - 1 } , INT_MIN , INT_MAX , VE , " coder " } ,
{ " cavlc " , NULL , 0 , AV_OPT_TYPE_CONST , { . i64 = 0 } , INT_MIN , INT_MAX , VE , " coder " } ,
{ " cabac " , NULL , 0 , AV_OPT_TYPE_CONST , { . i64 = 1 } , INT_MIN , INT_MAX , VE , " coder " } ,
2016-01-10 15:25:56 +02:00
{ " vlc " , NULL , 0 , AV_OPT_TYPE_CONST , { . i64 = 0 } , INT_MIN , INT_MAX , VE , " coder " } ,
{ " ac " , NULL , 0 , AV_OPT_TYPE_CONST , { . i64 = 1 } , INT_MIN , INT_MAX , VE , " coder " } ,
2015-09-09 04:18:26 +02:00
{ " b_strategy " , " Strategy to choose between I/P/B-frames " , OFFSET ( b_frame_strategy ) , AV_OPT_TYPE_INT , { . i64 = - 1 } , - 1 , 2 , VE } ,
2020-07-28 14:22:02 +02:00
{ " chromaoffset " , " QP difference between chroma and luma " , OFFSET ( chroma_offset ) , AV_OPT_TYPE_INT , { . i64 = 0 } , INT_MIN , INT_MAX , VE } ,
2016-01-28 18:38:27 +02:00
{ " sc_threshold " , " Scene change threshold " , OFFSET ( scenechange_threshold ) , AV_OPT_TYPE_INT , { . i64 = - 1 } , INT_MIN , INT_MAX , VE } ,
{ " noise_reduction " , " Noise reduction " , OFFSET ( noise_reduction ) , AV_OPT_TYPE_INT , { . i64 = - 1 } , INT_MIN , INT_MAX , VE } ,
2021-12-25 16:21:03 +02:00
{ " udu_sei " , " Use user data unregistered SEI if available " , OFFSET ( udu_sei ) , AV_OPT_TYPE_BOOL , { . i64 = 0 } , 0 , 1 , VE } ,
2019-12-25 02:46:37 +02:00
{ " x264-params " , " Override the x264 configuration using a :-separated list of key=value parameters " , OFFSET ( x264_params ) , AV_OPT_TYPE_DICT , { 0 } , 0 , 0 , VE } ,
2011-04-17 02:50:50 +03:00
{ NULL } ,
} ;
2022-03-16 22:26:11 +02:00
static const FFCodecDefault x264_defaults [ ] = {
2011-08-20 17:59:47 +03:00
{ " b " , " 0 " } ,
2011-09-01 13:59:29 +03:00
{ " bf " , " -1 " } ,
2011-09-12 22:55:34 +03:00
{ " flags2 " , " 0 " } ,
2011-09-01 13:59:29 +03:00
{ " g " , " -1 " } ,
2012-09-25 19:29:22 +03:00
{ " i_qfactor " , " -1 " } ,
2014-08-26 09:55:14 +03:00
{ " b_qfactor " , " -1 " } ,
2011-09-01 13:59:29 +03:00
{ " qmin " , " -1 " } ,
{ " qmax " , " -1 " } ,
{ " qdiff " , " -1 " } ,
{ " qblur " , " -1 " } ,
{ " qcomp " , " -1 " } ,
2012-01-28 06:23:26 +03:00
// { "rc_lookahead", "-1" },
2011-09-01 13:59:29 +03:00
{ " refs " , " -1 " } ,
2011-09-07 10:13:02 +03:00
{ " trellis " , " -1 " } ,
{ " me_range " , " -1 " } ,
{ " subq " , " -1 " } ,
{ " keyint_min " , " -1 " } ,
{ " cmp " , " -1 " } ,
2011-08-31 20:26:01 +03:00
{ " threads " , AV_STRINGIFY ( X264_THREADS_AUTO ) } ,
2012-03-05 22:54:17 +03:00
{ " thread_type " , " 0 " } ,
2012-09-22 21:41:16 +03:00
{ " flags " , " +cgop " } ,
2013-01-14 07:32:39 +03:00
{ " rc_init_occupancy " , " -1 " } ,
2011-08-20 17:59:47 +03:00
{ NULL } ,
} ;
2015-07-10 14:45:14 +02:00
# if CONFIG_LIBX264_ENCODER
2015-07-17 21:21:03 +02:00
static const AVClass x264_class = {
2015-07-10 14:45:14 +02:00
. class_name = " libx264 " ,
. item_name = av_default_item_name ,
. option = options ,
. version = LIBAVUTIL_VERSION_INT ,
} ;
2021-02-25 11:50:26 +02:00
# if X264_BUILD >= 153
const
# endif
2022-03-16 22:09:54 +02:00
FFCodec ff_libx264_encoder = {
. p . name = " libx264 " ,
2022-08-29 13:38:02 +02:00
CODEC_LONG_NAME ( " libx264 H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10 " ) ,
2022-03-16 22:09:54 +02:00
. p . type = AVMEDIA_TYPE_VIDEO ,
. p . id = AV_CODEC_ID_H264 ,
. p . capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_DELAY |
2021-04-25 01:43:26 +02:00
AV_CODEC_CAP_OTHER_THREADS |
2022-07-16 17:02:38 +02:00
AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE |
AV_CODEC_CAP_ENCODER_RECON_FRAME ,
2022-03-16 22:09:54 +02:00
. p . priv_class = & x264_class ,
. p . wrapper_name = " libx264 " ,
2012-04-06 19:19:39 +03:00
. priv_data_size = sizeof ( X264Context ) ,
. init = X264_init ,
2022-03-30 23:28:24 +02:00
FF_CODEC_ENCODE_CB ( X264_frame ) ,
2012-04-06 19:19:39 +03:00
. close = X264_close ,
. defaults = x264_defaults ,
2021-02-25 10:25:51 +02:00
# if X264_BUILD < 153
2011-10-05 22:09:51 +03:00
. init_static_data = X264_init_static ,
2021-02-25 10:25:51 +02:00
# else
2022-03-16 22:09:54 +02:00
. p . pix_fmts = pix_fmts_all ,
2021-02-25 10:25:51 +02:00
# endif
2021-03-09 19:00:44 +02:00
. caps_internal = FF_CODEC_CAP_INIT_CLEANUP | FF_CODEC_CAP_AUTO_THREADS
2022-07-10 00:05:45 +02:00
# if X264_BUILD < 158
2022-07-09 22:25:41 +02:00
| FF_CODEC_CAP_NOT_INIT_THREADSAFE
2019-08-25 16:12:28 +02:00
# endif
2021-03-09 19:00:44 +02:00
,
2005-03-09 05:04:56 +02:00
} ;
2016-02-28 00:23:41 +02:00
# endif
# if CONFIG_LIBX264RGB_ENCODER
static const AVClass rgbclass = {
. class_name = " libx264rgb " ,
. item_name = av_default_item_name ,
. option = options ,
. version = LIBAVUTIL_VERSION_INT ,
} ;
2011-12-01 23:02:57 +03:00
2022-03-16 22:09:54 +02:00
const FFCodec ff_libx264rgb_encoder = {
. p . name = " libx264rgb " ,
2022-08-29 13:38:02 +02:00
CODEC_LONG_NAME ( " libx264 H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10 RGB " ) ,
2022-03-16 22:09:54 +02:00
. p . type = AVMEDIA_TYPE_VIDEO ,
. p . id = AV_CODEC_ID_H264 ,
. p . capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_DELAY |
2021-04-25 01:43:26 +02:00
AV_CODEC_CAP_OTHER_THREADS |
AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE ,
2022-03-16 22:09:54 +02:00
. p . pix_fmts = pix_fmts_8bit_rgb ,
. p . priv_class = & rgbclass ,
. p . wrapper_name = " libx264 " ,
2011-12-01 23:02:57 +03:00
. priv_data_size = sizeof ( X264Context ) ,
. init = X264_init ,
2022-03-30 23:28:24 +02:00
FF_CODEC_ENCODE_CB ( X264_frame ) ,
2011-12-01 23:02:57 +03:00
. close = X264_close ,
. defaults = x264_defaults ,
2021-03-09 19:00:44 +02:00
. caps_internal = FF_CODEC_CAP_INIT_CLEANUP | FF_CODEC_CAP_AUTO_THREADS
2022-07-10 00:05:45 +02:00
# if X264_BUILD < 158
2022-07-09 22:25:41 +02:00
| FF_CODEC_CAP_NOT_INIT_THREADSAFE
2019-08-25 16:12:28 +02:00
# endif
2021-03-09 19:00:44 +02:00
,
2011-12-01 23:02:57 +03:00
} ;
2015-07-10 14:45:14 +02:00
# endif
# if CONFIG_LIBX262_ENCODER
static const AVClass X262_class = {
. class_name = " libx262 " ,
. item_name = av_default_item_name ,
. option = options ,
. version = LIBAVUTIL_VERSION_INT ,
} ;
2022-03-16 22:09:54 +02:00
const FFCodec ff_libx262_encoder = {
. p . name = " libx262 " ,
2022-08-29 13:38:02 +02:00
CODEC_LONG_NAME ( " libx262 MPEG2VIDEO " ) ,
2022-03-16 22:09:54 +02:00
. p . type = AVMEDIA_TYPE_VIDEO ,
. p . id = AV_CODEC_ID_MPEG2VIDEO ,
. p . capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_DELAY |
2021-04-25 01:43:26 +02:00
AV_CODEC_CAP_OTHER_THREADS |
AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE ,
2022-03-16 22:09:54 +02:00
. p . pix_fmts = pix_fmts_8bit ,
. p . priv_class = & X262_class ,
. p . wrapper_name = " libx264 " ,
2015-07-10 14:45:14 +02:00
. priv_data_size = sizeof ( X264Context ) ,
. init = X264_init ,
2022-03-30 23:28:24 +02:00
FF_CODEC_ENCODE_CB ( X264_frame ) ,
2015-07-10 14:45:14 +02:00
. close = X264_close ,
. defaults = x264_defaults ,
2022-07-09 22:25:41 +02:00
. caps_internal = FF_CODEC_CAP_NOT_INIT_THREADSAFE |
FF_CODEC_CAP_INIT_CLEANUP | FF_CODEC_CAP_AUTO_THREADS ,
2015-07-10 14:45:14 +02:00
} ;
# endif