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:
iive 2004-08-27 20:43:05 +00:00
parent 8596930cc0
commit 6379fb900a
8 changed files with 515 additions and 4 deletions

View File

@ -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.
.
.
.\" --------------------------------------------------------------------------

View File

@ -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

View File

@ -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
View File

@ -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

View File

@ -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

View File

@ -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
View 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

View File

@ -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);