mirror of
https://github.com/mpv-player/mpv
synced 2025-03-11 08:37:59 +00:00
x264 encoder support. Original patch send by Bernhard Rosenkraenzer <bero at arklinux dot org>, modifications by Loren Merritt <lorenm at u.washington dot edu>, Jeff Clagg <snacky at ikaruga.co dot uk> and me
git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@13167 b3059339-0415-0410-9bf9-f77b7e298cf2
This commit is contained in:
parent
8596930cc0
commit
6379fb900a
@ -4308,7 +4308,7 @@ syntax:
|
||||
.RE
|
||||
.br
|
||||
.PP
|
||||
Where <codec> may be: lavc, xvidenc, divx4, lame
|
||||
Where <codec> may be: lavc, xvidenc, divx4, lame, x264
|
||||
.
|
||||
.
|
||||
.SS divx4 (\-divx4opts)
|
||||
@ -5725,6 +5725,141 @@ Print the psnr (peak signal to noise ratio) for the whole video after encoding
|
||||
and store the per frame psnr in a file with a name like 'psnr_hhmmss.log' in
|
||||
the current directory.
|
||||
Returned values are in dB (decibel), the higher the better.
|
||||
.SS x264enc (\-x264encopts)
|
||||
.TP
|
||||
.B bitrate=<value>
|
||||
Sets the bitrate to be used in kbits/\:second (default: off).
|
||||
This is required if you want a CBR (constant bitrate) encode.
|
||||
.TP
|
||||
.B iframe=<value>
|
||||
Frequency of I frames (default: 60)
|
||||
.TP
|
||||
.B frameref=<value>
|
||||
Number of previous frames used as predictors in a P-frame (default: 1)
|
||||
.br
|
||||
.I NOTE:
|
||||
The current version of x264 (r38) hasn't yet implemented this feature.
|
||||
.TP
|
||||
.B idrframe=<value>
|
||||
Each <value> I-Frames are IDR-Frames.
|
||||
In H.264, I-Frames do not necessarily bound a closed GOP because it is
|
||||
allowable for a P-frame to be predicted from more frames than just the one
|
||||
frame before it (see the frameref option).
|
||||
Therefore, I-frames are not necessarily seekable. IDR-Frames restrict
|
||||
subsequent P-frames from referring to any frame prior to the IDR-Frame
|
||||
(default: 2)
|
||||
.TP
|
||||
.B bframe=<value>
|
||||
Number of B-Frames between I- and P-Frames (default: 0)
|
||||
.TP
|
||||
.B deblock=<0|1>
|
||||
Use deblocking filter (default: on)
|
||||
.TP
|
||||
.B deblockalpha=<-6-6>
|
||||
AlphaC0 parameter of deblocking filter.
|
||||
This adjusts thresholds for the H.264 deblocking filter.
|
||||
First, this parameter adjusts the maximum amount of change that the filter is
|
||||
allowed to cause on any one pixel.
|
||||
Secondly, this parameter affects the threshold for difference across the
|
||||
edge being filtered.
|
||||
A positive value reduces blocking artifacts more, but will also smear details
|
||||
(default: 0)
|
||||
.TP
|
||||
.B deblockbeta=<-6-6>
|
||||
Beta parameter of deblocking filter.
|
||||
Affects the maximum allowed gradient within two adjacent blocks (default: 0)
|
||||
.TP
|
||||
.B cabac
|
||||
Use CABAC (Context-Adaptive Binary Arithmetic Coding) (default: off)
|
||||
.TP
|
||||
.B cabacidc=<value>
|
||||
Initial value of CABAC IDC.
|
||||
The encoder must choose a context for each block it encodes, but for the
|
||||
first block in a frame, there are no prior blocks to predict the context.
|
||||
Adjusting this may affect bitrate by a fraction of a percent, but it doesn't
|
||||
directly affect distortion.
|
||||
.RSs
|
||||
-1: Let the encoder decide which context (default) (it usually chooses 0)
|
||||
.br
|
||||
0: low complexity
|
||||
.br
|
||||
1: medium complexity
|
||||
.br
|
||||
2: high complexity
|
||||
.REss
|
||||
.TP
|
||||
.B qp_constant=<2-51>
|
||||
This selects the quantizer to use.
|
||||
Lower values result in better fidelity, but higher bitrates.
|
||||
Note that quantization in H.264 works differently from mpeg[124].
|
||||
H.264's QP is on a logarithmic scale. As an example, the bitrate difference
|
||||
between QP=20 and QP=40 is about a factor of 10.
|
||||
Useful quantizers in H.264 tend to be very large compared to mpeg[124].
|
||||
20-40 is a useful range (default: 26)
|
||||
.br
|
||||
.I NOTE:
|
||||
This option takes effect even if you specify a cbr encode.
|
||||
In such a case, the first frame encoded will use the quantization factor you
|
||||
specified, but in later frames, the ratecontrol decides what quants to use.
|
||||
.TP
|
||||
.B qp_min=<2-51>
|
||||
Minimum quantizer. CBR only. 20-40 seems to be a useful range (default: 2)
|
||||
.TP
|
||||
.B qp_max=<2-51>
|
||||
Maximum quantizer. CBR only.
|
||||
.TP
|
||||
.B qp_step=<value>
|
||||
Maximum Value by which the quantizer may be incremented/decremented between
|
||||
frames.
|
||||
.TP
|
||||
.B rc_buffer_size=<value>
|
||||
Size of the ratecontrol buffer. (default: 1 second's worth at the bitrate you
|
||||
specified)
|
||||
.TP
|
||||
.B rc_init_buffer=<value>
|
||||
Set the initial size of ratecontrol buffer (default: 1/4 of rc_buffer_size)
|
||||
.B rc_sens=<0-100>
|
||||
Ratecontrol sensitivity (default: 100)
|
||||
.TP
|
||||
.B ip_factor=<value>
|
||||
Quantizer factor between I amd P frames (default: 2.0)
|
||||
.TP
|
||||
.B pb_factor=<value>
|
||||
Quantizer factor between P and B frames (default: 2.0)
|
||||
.TP
|
||||
.B pass=<1|2>
|
||||
For 2-pass mode. The first pass saves statistics.
|
||||
.TP
|
||||
.B qcompress=<0-1>
|
||||
Quantizer compression. This affects the ratecontrol: a lower value makes the
|
||||
bitrate more constant, while a higher value makes the quantization parameter
|
||||
more constant (default: 0.6)
|
||||
.TP
|
||||
.B qblur=<0-1>
|
||||
Temporal blur of the quantization parameter. Lower values allow the quantizer
|
||||
value to jump around more; higher values force it to vary more smoothly
|
||||
(default: 0.5)
|
||||
.TP
|
||||
.B fullinter
|
||||
Use all available interframe analyse methods (i4x4, psub8x8, psub16x16)
|
||||
(default: 4x4, psub16x16)
|
||||
.TP
|
||||
.B log=<-1-3>
|
||||
Adjust the amount of logging info printed to the screen.
|
||||
.RSs
|
||||
-1: none
|
||||
.br
|
||||
0: errors (for debugging x264)
|
||||
.br
|
||||
1: warnings
|
||||
.br
|
||||
2: PSNR and other analysis stats when the encode finishes (default)
|
||||
.br
|
||||
3: PSNR, qp, frametype, size, and other stats for every frame
|
||||
.REss
|
||||
.TP
|
||||
.B psnr
|
||||
Print signal-to-noise ratio statistics.
|
||||
.
|
||||
.
|
||||
.\" --------------------------------------------------------------------------
|
||||
|
2
Makefile
2
Makefile
@ -32,7 +32,7 @@ OBJS_MPLAYER = $(SRCS_MPLAYER:.c=.o)
|
||||
|
||||
VO_LIBS = $(AA_LIB) $(X_LIB) $(SDL_LIB) $(GGI_LIB) $(MP1E_LIB) $(MLIB_LIB) $(SVGA_LIB) $(DIRECTFB_LIB) $(CACA_LIB)
|
||||
AO_LIBS = $(ARTS_LIB) $(ESD_LIB) $(JACK_LIB) $(NAS_LIB) $(SGIAUDIO_LIB)
|
||||
CODEC_LIBS = $(AV_LIB) $(FAME_LIB) $(MAD_LIB) $(VORBIS_LIB) $(THEORA_LIB) $(FAAD_LIB) $(LIBLZO_LIB) $(DECORE_LIB) $(XVID_LIB) $(DTS_LIB) $(PNG_LIB) $(Z_LIB) $(JPEG_LIB) $(ALSA_LIB) $(XMMS_LIB)
|
||||
CODEC_LIBS = $(AV_LIB) $(FAME_LIB) $(MAD_LIB) $(VORBIS_LIB) $(THEORA_LIB) $(FAAD_LIB) $(LIBLZO_LIB) $(DECORE_LIB) $(XVID_LIB) $(DTS_LIB) $(PNG_LIB) $(Z_LIB) $(JPEG_LIB) $(ALSA_LIB) $(XMMS_LIB) $(X264_LIB)
|
||||
COMMON_LIBS = libmpcodecs/libmpcodecs.a mp3lib/libMP3.a liba52/liba52.a libmpeg2/libmpeg2.a $(W32_LIB) $(DS_LIB) libaf/libaf.a libmpdemux/libmpdemux.a input/libinput.a postproc/libswscale.a osdep/libosdep.a $(DVDREAD_LIB) $(CODEC_LIBS) $(FREETYPE_LIB) $(TERMCAP_LIB) $(CDPARANOIA_LIB) $(MPLAYER_NETWORK_LIB) $(WIN32_LIB) $(GIF_LIB) $(MACOSX_FRAMEWORKS) $(SMBSUPPORT_LIB) $(FRIBIDI_LIB) $(FONTCONFIG_LIB) $(ENCA_LIB)
|
||||
|
||||
CFLAGS = $(OPTFLAGS) -Ilibmpdemux -Iloader -Ilibvo $(FREETYPE_INC) $(EXTRA_INC) $(CDPARANOIA_INC) $(SDL_INC) $(X11_INC) $(FRIBIDI_INC) $(DVB_INC) $(XVID_INC) $(FONTCONFIG_INC) $(CACA_INC) # -Wall
|
||||
|
@ -63,6 +63,10 @@ extern m_option_t vfwopts_conf[];
|
||||
extern m_option_t xvidencopts_conf[];
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_X264)
|
||||
extern m_option_t x264encopts_conf[];
|
||||
#endif
|
||||
|
||||
extern m_option_t nuvopts_conf[];
|
||||
|
||||
m_option_t ovc_conf[]={
|
||||
@ -78,6 +82,7 @@ m_option_t ovc_conf[]={
|
||||
{"xvid", &out_video_codec, CONF_TYPE_FLAG, 0, 0, VCODEC_XVID, NULL},
|
||||
{"qtvideo", &out_video_codec, CONF_TYPE_FLAG, 0, 0, VCODEC_QTVIDEO, NULL},
|
||||
{"nuv", &out_video_codec, CONF_TYPE_FLAG, 0, 0, VCODEC_NUV, NULL},
|
||||
{"x264", &out_video_codec, CONF_TYPE_FLAG, 0, 0, VCODEC_X264, NULL},
|
||||
{"help", "\nAvailable codecs:\n"
|
||||
" copy - frame copy, without re-encoding. Doesn't work with filters.\n"
|
||||
" frameno - special audio-only file for 3-pass encoding, see DOCS.\n"
|
||||
@ -102,6 +107,9 @@ m_option_t ovc_conf[]={
|
||||
#endif
|
||||
#if defined(HAVE_XVID3) || defined(HAVE_XVID4)
|
||||
" xvid - XviD encoding\n"
|
||||
#endif
|
||||
#ifdef HAVE_X264
|
||||
" x264 - H.264 encoding\n"
|
||||
#endif
|
||||
"\n", CONF_TYPE_PRINT, CONF_NOCFG, 0, 0, NULL},
|
||||
{NULL, NULL, 0, 0, 0, 0, NULL}
|
||||
@ -239,6 +247,9 @@ m_option_t mencoder_opts[]={
|
||||
#if defined(HAVE_XVID3) || defined(HAVE_XVID4)
|
||||
{"xvidencopts", xvidencopts_conf, CONF_TYPE_SUBCONFIG, 0, 0, 0, NULL},
|
||||
#endif
|
||||
#if defined(HAVE_X264)
|
||||
{"x264encopts", x264encopts_conf, CONF_TYPE_SUBCONFIG, 0, 0, 0, NULL},
|
||||
#endif
|
||||
|
||||
{"nuvopts", nuvopts_conf, CONF_TYPE_SUBCONFIG, 0, 0, 0, NULL},
|
||||
|
||||
|
37
configure
vendored
37
configure
vendored
@ -198,6 +198,7 @@ Codecs:
|
||||
--disable-xanim disable XAnim DLL support [autodetect]
|
||||
--disable-real disable RealPlayer DLL support [autodetect]
|
||||
--disable-xvid disable XviD codec [autodetect]
|
||||
--disable-x264 disable H.264 encoder [autodetect]
|
||||
--disable-divx4linux disable DivX4linux/Divx5linux codec [autodetect]
|
||||
--enable-opendivx enable _old_ OpenDivx codec [disable]
|
||||
--disable-libavcodec disable libavcodec [autodetect]
|
||||
@ -320,6 +321,8 @@ multiple paths separated by ':'):
|
||||
--with-reallibdir=DIR RealPlayer DLL files in DIR
|
||||
--with-xvidlibdir=DIR libxvidcore (XviD) in DIR (*)
|
||||
--with-xvidincdir=DIR XviD header in DIR (*)
|
||||
--with-x264libdir=DIR libx264 in DIR
|
||||
--with-x264incdir=DIR x264 header in DIR
|
||||
--with-dtslibdir=DIR libdts library in DIR (*)
|
||||
--with-dtsincdir=DIR libdts header in DIR (*)
|
||||
--with-livelibdir=DIR LIVE.COM Streaming Media libraries in DIR
|
||||
@ -1298,6 +1301,7 @@ _smbsupport=auto
|
||||
_vidix=auto
|
||||
_joystick=no
|
||||
_xvid=auto
|
||||
_x264=auto
|
||||
_divx4linux=auto
|
||||
_opendivx=no
|
||||
_lirc=auto
|
||||
@ -1502,6 +1506,8 @@ for ac_option do
|
||||
--disable-joystick) _joystick=no ;;
|
||||
--enable-xvid) _xvid=yes ;;
|
||||
--disable-xvid) _xvid=no ;;
|
||||
--enable-x264) _x264=yes ;;
|
||||
--disable-x264) _x264=no ;;
|
||||
--enable-divx4linux) _divx4linux=yes ;;
|
||||
--disable-divx4linux) _divx4linux=no ;;
|
||||
--enable-opendivx) _opendivx=yes ;;
|
||||
@ -1708,6 +1714,12 @@ for ac_option do
|
||||
--with-dtsincdir=*)
|
||||
_inc_libdts=-I`echo $ac_option | cut -d '=' -f 2 | sed 's,:, -I,g'`
|
||||
;;
|
||||
--with-x264libdir=*)
|
||||
_ld_x264=-L`echo $ac_option | cut -d '=' -f 2 | sed 's,:, -L,g'`
|
||||
;;
|
||||
--with-x264incdir=*)
|
||||
_inc_x264=-I`echo $ac_option | cut -d '=' -f 2 |sed 's,:, -I,g'`
|
||||
;;
|
||||
--with-sdl-config=*)
|
||||
_sdlconfig=`echo $ac_option | cut -d '=' -f 2`
|
||||
;;
|
||||
@ -5474,6 +5486,25 @@ EOF
|
||||
echores "$_xvidcompat"
|
||||
fi
|
||||
|
||||
echocheck "x264"
|
||||
cat > $TMPC << EOF
|
||||
#include <stdint.h>
|
||||
#include <stdarg.h>
|
||||
#include <x264.h>
|
||||
int main(void) { x264_encoder_open((void*)0); return 0; }
|
||||
EOF
|
||||
_ld_x264="$_ld_x264 -lx264 -lm"
|
||||
if test "$_x264" != no && cc_check $_inc_x264 $_ld_x264 ; then
|
||||
_x264=yes
|
||||
_def_x264='#define HAVE_X264 1'
|
||||
_codecmodules="x264 $_codecmodules"
|
||||
else
|
||||
_x264=no
|
||||
_ld_x264=''
|
||||
_def_x264='#undef HAVE_X264'
|
||||
_nocodecmodules="x264 $_nocodecmodules"
|
||||
fi
|
||||
echores "$_x264"
|
||||
|
||||
echocheck "DivX4linux/DivX5linux/OpenDivX decore"
|
||||
# DivX5: DEC_OPT_MEMORY_REQS - DivX4: DEC_OPT_FRAME_311
|
||||
@ -6268,6 +6299,9 @@ ARCH_LIB = $_ld_arch $_ld_iconv
|
||||
XVID = $_xvid
|
||||
XVID_INC = $_inc_xvid
|
||||
XVID_LIB = $_ld_xvid
|
||||
X264 = $_x264
|
||||
X264_INC = $_inc_x264
|
||||
X264_LIB = $_ld_x264
|
||||
CONFIG_DTS = $_libdts
|
||||
DTS_INC = $_inc_libdts
|
||||
DTS_LIB = $_ld_libdts
|
||||
@ -6410,6 +6444,9 @@ $_def_xvid4
|
||||
$_def_decore_xvid
|
||||
$_def_encore_xvid
|
||||
|
||||
/* Define if you are using the X.264 library */
|
||||
$_def_x264
|
||||
|
||||
/* Define to include support for libdv-0.9.5 */
|
||||
$_def_libdv
|
||||
|
||||
|
@ -19,7 +19,7 @@ ifeq ($(HAVE_FFPOSTPROCESS),yes)
|
||||
VFILTER_SRCS += vf_pp.c
|
||||
endif
|
||||
|
||||
ENCODER_SRCS=ve.c ve_divx4.c ve_lavc.c ve_vfw.c ve_raw.c ve_libdv.c ve_xvid.c ve_xvid4.c ve_qtvideo.c ve_nuv.c
|
||||
ENCODER_SRCS=ve.c ve_divx4.c ve_lavc.c ve_vfw.c ve_raw.c ve_libdv.c ve_xvid.c ve_xvid4.c ve_qtvideo.c ve_nuv.c ve_x264.c
|
||||
|
||||
NATIVE_SRCS=native/RTjpegN.c native/minilzo.c native/nuppelvideo.c native/xa_gsm.c native/decode144.c native/decode288.c
|
||||
|
||||
|
@ -17,6 +17,7 @@ extern vf_info_t ve_info_libdv;
|
||||
extern vf_info_t ve_info_xvid;
|
||||
extern vf_info_t ve_info_qtvideo;
|
||||
extern vf_info_t ve_info_nuv;
|
||||
extern vf_info_t ve_info_x264;
|
||||
|
||||
static vf_info_t* encoder_list[]={
|
||||
#ifdef HAVE_DIVX4ENCORE
|
||||
@ -37,6 +38,9 @@ static vf_info_t* encoder_list[]={
|
||||
&ve_info_xvid,
|
||||
#endif
|
||||
&ve_info_nuv,
|
||||
#ifdef HAVE_X264
|
||||
&ve_info_x264,
|
||||
#endif
|
||||
NULL
|
||||
};
|
||||
|
||||
|
322
libmpcodecs/ve_x264.c
Normal file
322
libmpcodecs/ve_x264.c
Normal file
@ -0,0 +1,322 @@
|
||||
/*****************************************************************************
|
||||
*
|
||||
* - H.264 encoder for mencoder using x264 -
|
||||
*
|
||||
* Copyright (C) 2004 LINUX4MEDIA GmbH
|
||||
* Copyright (C) 2004 Ark Linux
|
||||
*
|
||||
* Written by Bernhard Rosenkraenzer <bero@arklinux.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation, or if, and only if,
|
||||
* version 2 is ruled invalid in a court of law, any later version
|
||||
* of the GNU General Public License published by the Free Software
|
||||
* Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTIBILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "../config.h"
|
||||
#include "../mp_msg.h"
|
||||
|
||||
#ifdef HAVE_X264
|
||||
|
||||
#include "m_option.h"
|
||||
#include "codec-cfg.h"
|
||||
#include "stream.h"
|
||||
#include "demuxer.h"
|
||||
#include "stheader.h"
|
||||
|
||||
#include "muxer.h"
|
||||
|
||||
#include "img_format.h"
|
||||
#include "mp_image.h"
|
||||
#include "vf.h"
|
||||
|
||||
#include <x264.h>
|
||||
|
||||
typedef struct _h264_module_t {
|
||||
muxer_stream_t *mux;
|
||||
x264_param_t param;
|
||||
x264_t * x264;
|
||||
x264_picture_t pic;
|
||||
} h264_module_t;
|
||||
|
||||
extern char* passtmpfile;
|
||||
|
||||
static int bitrate = -1;
|
||||
static int qp_constant = 26;
|
||||
static int frame_ref = 1;
|
||||
static int iframe = 60;
|
||||
static int idrframe = 2;
|
||||
static int bframe = 0;
|
||||
static int deblock = 1;
|
||||
static int deblockalpha = 0;
|
||||
static int deblockbeta = 0;
|
||||
static int cabac = 0;
|
||||
static int cabacidc = -1;
|
||||
static int fullinter = 0;
|
||||
static float ip_factor = 2.0;
|
||||
static float pb_factor = 2.0;
|
||||
static int rc_buffer_size = -1;
|
||||
static int rc_init_buffer = -1;
|
||||
static int rc_sens = 4;
|
||||
static int qp_min = 10;
|
||||
static int qp_max = 51;
|
||||
static int qp_step = 1;
|
||||
static int pass = 0;
|
||||
static float qcomp = 0.6;
|
||||
static float qblur = 0.5;
|
||||
static char *rc_eq = "(tex^qComp)*(avgTex^(1-qComp))";
|
||||
static int psnr = 0;
|
||||
static int log_level = 2;
|
||||
|
||||
m_option_t x264encopts_conf[] = {
|
||||
{"bitrate", &bitrate, CONF_TYPE_INT, CONF_RANGE, 0, 24000000, NULL},
|
||||
{"qp_constant", &qp_constant, CONF_TYPE_INT, CONF_RANGE, 1, 51, NULL},
|
||||
{"frameref", &frame_ref, CONF_TYPE_INT, CONF_RANGE, 1, 100, NULL},
|
||||
{"iframe", &iframe, CONF_TYPE_INT, CONF_RANGE, 1, 24000000, NULL},
|
||||
{"idrframe", &idrframe, CONF_TYPE_INT, CONF_RANGE, 1, 24000000, NULL},
|
||||
{"bframe", &bframe, CONF_TYPE_INT, CONF_RANGE, 0, 10, NULL},
|
||||
{"deblock", &deblock, CONF_TYPE_INT, CONF_RANGE, 0, 1, NULL},
|
||||
{"deblockalpha", &deblockalpha, CONF_TYPE_INT, CONF_RANGE, -6, 6, NULL},
|
||||
{"deblockbeta", &deblockbeta, CONF_TYPE_INT, CONF_RANGE, -6, 6, NULL},
|
||||
{"cabac", &cabac, CONF_TYPE_FLAG, 0, 0, 1, NULL},
|
||||
{"cabacidc", &cabacidc, CONF_TYPE_INT, CONF_RANGE, -1, 2, NULL},
|
||||
{"fullinter", &fullinter, CONF_TYPE_FLAG, 0, 0, 1, NULL},
|
||||
{"ip_factor", &ip_factor, CONF_TYPE_FLOAT, CONF_RANGE, -10.0, 10.0, NULL},
|
||||
{"pb_factor", &pb_factor, CONF_TYPE_FLOAT, CONF_RANGE, -10.0, 10.0, NULL},
|
||||
{"rc_buffer_size", &rc_buffer_size, CONF_TYPE_INT, CONF_RANGE, 0, 24000000, NULL},
|
||||
{"rc_init_buffer", &rc_init_buffer, CONF_TYPE_INT, CONF_RANGE, 0, 24000000, NULL},
|
||||
{"rc_sens", &rc_sens, CONF_TYPE_INT, CONF_RANGE, 0, 100, NULL},
|
||||
{"qp_min", &qp_min, CONF_TYPE_INT, CONF_RANGE, 1, 51, NULL},
|
||||
{"qp_max", &qp_max, CONF_TYPE_INT, CONF_RANGE, 1, 51, NULL},
|
||||
{"qp_step", &qp_step, CONF_TYPE_INT, CONF_RANGE, 0, 50, NULL},
|
||||
{"pass", &pass, CONF_TYPE_INT, CONF_RANGE, 1, 3, NULL},
|
||||
{"rc_eq", &rc_eq, CONF_TYPE_STRING, 0, 0, 0, NULL},
|
||||
{"qcomp", &qcomp, CONF_TYPE_FLOAT, CONF_RANGE, 0, 1, NULL},
|
||||
{"qblur", &qblur, CONF_TYPE_FLOAT, CONF_RANGE, 0, 99, NULL},
|
||||
{"psnr", &psnr, CONF_TYPE_FLAG, 0, 0, 1, NULL},
|
||||
{"log", &log_level, CONF_TYPE_INT, CONF_RANGE, -1, 3, NULL},
|
||||
{NULL, NULL, 0, 0, 0, 0, NULL}
|
||||
};
|
||||
|
||||
|
||||
static int config(struct vf_instance_s* vf, int width, int height, int d_width, int d_height, unsigned int flags, unsigned int outfmt) {
|
||||
h264_module_t *mod=(h264_module_t*)vf->priv;
|
||||
mod->mux->bih->biWidth = width;
|
||||
mod->mux->bih->biHeight = height;
|
||||
mod->mux->aspect = (float)d_width/d_height;
|
||||
|
||||
x264_param_default(&mod->param);
|
||||
mod->param.i_frame_reference = frame_ref;
|
||||
mod->param.i_idrframe = idrframe;
|
||||
mod->param.i_iframe = iframe;
|
||||
mod->param.i_bframe = bframe;
|
||||
mod->param.b_deblocking_filter = deblock;
|
||||
mod->param.i_deblocking_filter_alphac0 = deblockalpha;
|
||||
mod->param.i_deblocking_filter_beta = deblockbeta;
|
||||
mod->param.b_cabac = cabac;
|
||||
mod->param.i_cabac_init_idc = cabacidc;
|
||||
mod->param.i_qp_constant = qp_constant;
|
||||
if(qp_min > qp_constant)
|
||||
qp_min = qp_constant;
|
||||
if(qp_max < qp_constant)
|
||||
qp_max = qp_constant;
|
||||
mod->param.i_qp_min = qp_min;
|
||||
mod->param.i_qp_max = qp_max;
|
||||
mod->param.i_qp_step = qp_step;
|
||||
#if 0
|
||||
mod->param.i_pass = pass;
|
||||
mod->param.s_rc_eq = rc_eq;
|
||||
mod->param.f_qcompress = qcomp;
|
||||
mod->param.f_qblur = qblur;
|
||||
mod->param.s_2pass_file_out = passtmpfile;
|
||||
mod->param.s_2pass_file_in = passtmpfile;
|
||||
if((pass & 2) && bitrate <= 0)
|
||||
{
|
||||
mp_msg(MSGT_MENCODER, MSGL_ERR,
|
||||
"2 pass encoding enabled, but no bitrate specified.\n");
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
if(bitrate > 0) {
|
||||
if(rc_buffer_size <= 0)
|
||||
rc_buffer_size = bitrate;
|
||||
if(rc_init_buffer < 0)
|
||||
rc_init_buffer = rc_buffer_size/4;
|
||||
mod->param.b_cbr = 1;
|
||||
mod->param.i_bitrate = bitrate;
|
||||
mod->param.i_rc_buffer_size = rc_buffer_size;
|
||||
mod->param.i_rc_init_buffer = rc_init_buffer;
|
||||
mod->param.i_rc_sens = rc_sens;
|
||||
}
|
||||
if(fullinter)
|
||||
mod->param.analyse.inter = X264_ANALYSE_I4x4 | X264_ANALYSE_PSUB16x16 | X264_ANALYSE_PSUB8x8;
|
||||
mod->param.f_ip_factor = ip_factor;
|
||||
mod->param.f_pb_factor = pb_factor;
|
||||
|
||||
mod->param.i_width = width;
|
||||
mod->param.i_height = height;
|
||||
mod->param.i_fps_num = mod->mux->h.dwRate;
|
||||
mod->param.i_fps_den = mod->mux->h.dwScale;
|
||||
mod->param.analyse.b_psnr = psnr;
|
||||
mod->param.i_log_level = log_level;
|
||||
|
||||
switch(outfmt) {
|
||||
case IMGFMT_I420:
|
||||
mod->param.i_csp = X264_CSP_I420;
|
||||
mod->mux->bih->biSizeImage = width * height * 3;
|
||||
break;
|
||||
case IMGFMT_YV12:
|
||||
mod->param.i_csp = X264_CSP_YV12;
|
||||
mod->mux->bih->biSizeImage = width * height * 3;
|
||||
break;
|
||||
case IMGFMT_422P:
|
||||
mod->param.i_csp = X264_CSP_I422;
|
||||
mod->mux->bih->biSizeImage = width * height * 3;
|
||||
break;
|
||||
case IMGFMT_444P:
|
||||
mod->param.i_csp = X264_CSP_I444;
|
||||
mod->mux->bih->biSizeImage = width * height * 3;
|
||||
break;
|
||||
case IMGFMT_YVYU:
|
||||
mod->param.i_csp = X264_CSP_YUYV;
|
||||
mod->mux->bih->biSizeImage = width * height * 3;
|
||||
break;
|
||||
case IMGFMT_RGB:
|
||||
mod->param.i_csp = X264_CSP_RGB;
|
||||
mod->mux->bih->biSizeImage = width * height * 3;
|
||||
break;
|
||||
case IMGFMT_BGR:
|
||||
mod->param.i_csp = X264_CSP_BGR;
|
||||
mod->mux->bih->biSizeImage = width * height * 3;
|
||||
break;
|
||||
case IMGFMT_BGR32:
|
||||
mod->param.i_csp = X264_CSP_BGRA;
|
||||
mod->mux->bih->biSizeImage = width * height * 4;
|
||||
break;
|
||||
default:
|
||||
mp_msg(MSGT_MENCODER, MSGL_ERR, "Wrong colorspace.\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
mod->x264 = x264_encoder_open(&mod->param);
|
||||
if(!mod->x264) {
|
||||
mp_msg(MSGT_MENCODER, MSGL_ERR, "x264_encoder_open failed.\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
x264_picture_alloc(&mod->pic, mod->param.i_csp, mod->param.i_width, mod->param.i_height);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int control(struct vf_instance_s* vf, int request, void *data)
|
||||
{
|
||||
return CONTROL_UNKNOWN;
|
||||
}
|
||||
|
||||
static int query_format(struct vf_instance_s* vf, unsigned int fmt)
|
||||
{
|
||||
switch(fmt) {
|
||||
case IMGFMT_I420:
|
||||
return (VFCAP_CSP_SUPPORTED|VFCAP_CSP_SUPPORTED_BY_HW);
|
||||
case IMGFMT_YV12:
|
||||
case IMGFMT_422P:
|
||||
case IMGFMT_444P:
|
||||
case IMGFMT_YVYU:
|
||||
case IMGFMT_RGB:
|
||||
case IMGFMT_BGR:
|
||||
case IMGFMT_BGR32:
|
||||
/* 2004/08/05: There seems to be some, but not complete,
|
||||
support for these colorspaces in X264. Better to stay
|
||||
on the safe side for now. */
|
||||
return 0; /* VFCAP_CSP_SUPPORTED */
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int put_image(struct vf_instance_s *vf, mp_image_t *mpi)
|
||||
{
|
||||
h264_module_t *mod=(h264_module_t*)vf->priv;
|
||||
int i_nal;
|
||||
x264_nal_t *nal;
|
||||
int i;
|
||||
|
||||
int csp=mod->pic.img.i_csp;
|
||||
memset(&mod->pic, 0, sizeof(x264_picture_t));
|
||||
mod->pic.img.i_csp=csp;
|
||||
mod->pic.img.i_plane=3;
|
||||
for(i=0; i<4; i++) {
|
||||
mod->pic.img.plane[i] = mpi->planes[i];
|
||||
mod->pic.img.i_stride[i] = mpi->stride[i];
|
||||
}
|
||||
|
||||
mod->pic.i_type = X264_TYPE_AUTO;
|
||||
if(x264_encoder_encode(mod->x264, &nal, &i_nal, &mod->pic) < 0) {
|
||||
mp_msg(MSGT_MENCODER, MSGL_ERR, "x264_encoder_encode failed\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
int i_size = 0;
|
||||
for(i=0; i < i_nal; i++) {
|
||||
int i_data = mod->mux->buffer_size - i_size;
|
||||
i_size += x264_nal_encode(mod->mux->buffer + i_size, &i_data, 1, &nal[i]);
|
||||
}
|
||||
if(i_size>0) {
|
||||
muxer_write_chunk(mod->mux, i_size, (mod->pic.i_type == X264_TYPE_I)?0x10:0);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void uninit(struct vf_instance_s *vf)
|
||||
{
|
||||
// FIXME: flush delayed frames
|
||||
h264_module_t *mod=(h264_module_t*)vf->priv;
|
||||
x264_encoder_close(mod->x264);
|
||||
//x264_picture_clean(&mod->pic);
|
||||
}
|
||||
|
||||
static int vf_open(vf_instance_t *vf, char *args) {
|
||||
vf->config = config;
|
||||
vf->control = control;
|
||||
vf->query_format = query_format;
|
||||
vf->put_image = put_image;
|
||||
vf->uninit = uninit;
|
||||
vf->priv = malloc(sizeof(h264_module_t));
|
||||
|
||||
h264_module_t *mod=(h264_module_t*)vf->priv;
|
||||
mod->mux = (muxer_stream_t*)args;
|
||||
mod->mux->bih = malloc(sizeof(BITMAPINFOHEADER));
|
||||
memset(mod->mux->bih, 0, sizeof(BITMAPINFOHEADER));
|
||||
mod->mux->bih->biSize = sizeof(BITMAPINFOHEADER);
|
||||
mod->mux->bih->biPlanes = 1;
|
||||
mod->mux->bih->biBitCount = 24;
|
||||
mod->mux->bih->biCompression = mmioFOURCC('h', '2', '6', '4');
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
vf_info_t ve_info_x264 = {
|
||||
"H.264 encoder",
|
||||
"x264",
|
||||
"Bernhard Rosenkraenzer <bero@arklinux.org>",
|
||||
"(C) 2004 LINUX4MEDIA GmbH; (C) 2004 Ark Linux",
|
||||
vf_open
|
||||
};
|
||||
#endif
|
@ -9,6 +9,7 @@
|
||||
#define VCODEC_QTVIDEO 10
|
||||
#define VCODEC_NUV 11
|
||||
#define VCODEC_RAW 12
|
||||
#define VCODEC_X264 13
|
||||
|
||||
#define ACODEC_COPY 0
|
||||
#define ACODEC_PCM 1
|
||||
@ -708,7 +709,8 @@ default:
|
||||
sh_video->vfilter=vf_open_encoder(NULL,"qtvideo",(char *)mux_v); break;
|
||||
case VCODEC_NUV:
|
||||
sh_video->vfilter=vf_open_encoder(NULL,"nuv",(char *)mux_v); break;
|
||||
|
||||
case VCODEC_X264:
|
||||
sh_video->vfilter=vf_open_encoder(NULL,"x264",(char *)mux_v); break;
|
||||
}
|
||||
if(!mux_v->bih || !sh_video->vfilter){
|
||||
mp_msg(MSGT_MENCODER,MSGL_FATAL,MSGTR_EncoderOpenFailed);
|
||||
|
Loading…
Reference in New Issue
Block a user