[MPlayer-dev-eng] [PATCH] H.264 encoding in mencoder

snacky at ikaruga.co.uk snacky at ikaruga.co.uk
Mon Aug 23 04:57:38 CEST 2004


On Sat, Aug 21, 2004 at 09:55:44AM +0900, Attila Kinali wrote:
> On Thu, Aug 05, 2004 at 01:09:39PM +0800, Bernhard Rosenkraenzer wrote:
> [snipsnap]
> 
> Another orphan. Someone dare to comment ?

I've been keeping up with this patch. There's A LOT I could say about it,
but I'll try to keep it as short as I can.

x264's interface is still changing. I'm attaching a patch which contains
my current version of Bernhard Rosenkraenzer's original work. The patch
he submitted doesn't work with x264's new ratecontrol stuff, and therein
lie most of my (small) changes.

My patch is fully-synched with revision 26 of x264. You can get that using:

svn co svn://svn.videolan.org/x264/trunk x264 --revision 26

It doesn't work with the latest version of x264 because they changed a
framerate variable which is used for ratecontrol. The change makes it a
fraction rather than a float. So far this, and the other changes since
then, don't seem to be especially useful, so I haven't gotten around to
addressing the issue.

Incidentally, if any of you happen to think it'd be interesting to toy
with h.264, please try this out and maybe even tweak it. The framerate
fix is a very trivial change which anyone could do. It might also be
nice if someone more experienced than me (i.e., practically anyone)
would look after this patch while x264 matures.

This is the first time I've ever generated a patch; let me know if I
did something wrongly.
-------------- next part --------------
diff -urN main/DOCS/man/en/mplayer.1 my/DOCS/man/en/mplayer.1
--- main/DOCS/man/en/mplayer.1	2004-08-22 20:31:33.000000000 -0400
+++ my/DOCS/man/en/mplayer.1	2004-08-22 22:16:47.000000000 -0400
@@ -4288,7 +4288,7 @@
 .RE
 .br
 .PP
-Where <codec> may be: lavc, xvidenc, divx4, lame
+Where <codec> may be: lavc, xvidenc, divx4, lame, h264
 .
 .
 .SS divx4 (\-divx4opts)
@@ -5706,6 +5706,68 @@
 the current directory.
 Returned values are in dB (decibel), the higher the better.
 .
+.SS h264enc (\-h264encopts)
+.
+.TP
+.B bitrate=<value>
+Sets the bitrate to be used in kbits/\:second (default: 3000). In order for
+this to take effect, you must set cbr=1
+.TP
+.B iframe=<value>
+Frequency of I frames (default: 60)
+.TP
+.B iframeref=<value>
+Reference I-Frame (default: 1 - usually should not be changed)
+.TP
+.B idrframe=<value>
+Each <value> I-Frames are IDR-Frames
+.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
+.TP
+.B deblockbeta=<-6-6>
+Beta parameter of deblocking filter
+.TP
+.B cabac=<0|1>
+Use CABAC (Context-Adaptive Binary Arithmetic Coding) (default: off)
+.TP
+.B cabacidc=<value>
+Initial value of CABAC IDC
+.TP
+.B qp_constant=<value>
+QP value (default: 26)
+.TP
+.B cbr=<0:1>
+Use constant bitrate. If set to 1, ratecontrol options are enabled. Otherwise,
+a constant quantizer is used. (default: 0)
+.TP
+.B qp_min=<2-51>
+Minimum quantizer. Requires cbr=1. 25-35 seems to be a useful range (default: 2)
+.TP
+.B qp_max=<2-51>
+Maximum quantizer. Requires cbr=1
+.TP
+.B qp_step=<value>
+Value by which the quantizer may be incremented/decremented between frames.
+.TP
+.B rc_buffer_size=<value>
+Size of the ratecontrol buffer.
+.TP
+.B rc_sens=<0-100>
+Ratecontrol sensitivity (default: 100)
+.TP 
+.B fullinter
+Use all available interframe analyse methods (i4x4, psub8x8, psub16x16) (default: 4x4, psub8x8) 
+.TP
+.B fullintra
+Use all available intraframe analyse methods (i4x4, psub8x8, psub16x16) (default: 4x4) 
+.
 .
 .\" --------------------------------------------------------------------------
 .\" Files
diff -urN main/Makefile my/Makefile
--- main/Makefile	2004-08-22 20:25:19.000000000 -0400
+++ my/Makefile	2004-08-22 21:28:48.000000000 -0400
@@ -32,7 +32,7 @@
 
 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
diff -urN main/cfg-mencoder.h my/cfg-mencoder.h
--- main/cfg-mencoder.h	2004-05-19 00:33:00.000000000 -0400
+++ my/cfg-mencoder.h	2004-08-22 21:26:14.000000000 -0400
@@ -63,6 +63,10 @@
 extern m_option_t xvidencopts_conf[];
 #endif
 
+#if defined(HAVE_X264)
+extern m_option_t h264encopts_conf[];
+#endif
+
 extern m_option_t nuvopts_conf[];
 
 m_option_t ovc_conf[]={
@@ -78,6 +82,7 @@
 	{"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},
+	{"h264", &out_video_codec, CONF_TYPE_FLAG, 0, 0, VCODEC_H264, 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"
@@ -103,6 +108,9 @@
 #if defined(HAVE_XVID3) || defined(HAVE_XVID4)
 	"   xvid     - XviD encoding\n"
 #endif
+#ifdef HAVE_X264
+	"   h264     - 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 @@
 #if defined(HAVE_XVID3) || defined(HAVE_XVID4)
 	{"xvidencopts", xvidencopts_conf, CONF_TYPE_SUBCONFIG, 0, 0, 0, NULL},
 #endif
+#if defined(HAVE_X264)
+	{"h264encopts", h264encopts_conf, CONF_TYPE_SUBCONFIG, 0, 0, 0, NULL},
+#endif
 
 	{"nuvopts",  nuvopts_conf, CONF_TYPE_SUBCONFIG, 0, 0, 0, NULL},
 
diff -urN main/configure my/configure
--- main/configure	2004-08-20 14:29:25.000000000 -0400
+++ my/configure	2004-08-22 21:31:34.000000000 -0400
@@ -198,6 +198,7 @@
   --disable-xanim        disable XAnim DLL support [autodetect]
   --disable-real         disable RealPlayer DLL support [autodetect]
   --disable-xvid         disable XviD codec [autodetect]
+  --disable-h264         disable H.264 encoder [autodetect]
   --disable-divx4linux   disable DivX4linux/Divx5linux codec [autodetect]
   --enable-opendivx      enable _old_ OpenDivx codec [disable]
   --disable-libavcodec   disable libavcodec [autodetect]
@@ -319,6 +320,8 @@
   --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    path to LIVE.COM Streaming Media libraries
@@ -1286,6 +1289,7 @@
 _vidix=auto
 _joystick=no
 _xvid=auto
+_x264=auto
 _divx4linux=auto
 _opendivx=no
 _lirc=auto
@@ -1490,6 +1494,8 @@
   --disable-joystick)	_joystick=no	;;
   --enable-xvid)	_xvid=yes	;;
   --disable-xvid)	_xvid=no	;;
+  --enable-h264)        _x264=yes       ;;
+  --disable-h264)       _x264=no        ;;
   --enable-divx4linux)	_divx4linux=yes	;;
   --disable-divx4linux)	_divx4linux=no	;;
   --enable-opendivx)	_opendivx=yes	;;
@@ -1696,6 +1702,12 @@
   --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`
     ;;
@@ -5458,6 +5470,24 @@
   echores "$_xvidcompat"
 fi
 
+echocheck "H.264"
+cat > $TMPC << EOF
+#include <stdint.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="h264 $_codecmodules"
+else
+  _x264=no
+  _ld_x264=''
+  _def_x264='#undef HAVE_X264'
+  _nocodecmodules="h264 $_nocodecmodules"
+fi
+echores "$_x264"
 
 echocheck "DivX4linux/DivX5linux/OpenDivX decore"
 # DivX5: DEC_OPT_MEMORY_REQS - DivX4: DEC_OPT_FRAME_311
@@ -6256,6 +6286,9 @@
 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
@@ -6398,6 +6431,9 @@
 $_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
 
Binary files main/libmpcodecs/.ve_h264.c.swp and my/libmpcodecs/.ve_h264.c.swp differ
diff -urN main/libmpcodecs/Makefile my/libmpcodecs/Makefile
--- main/libmpcodecs/Makefile	2004-07-15 16:36:04.000000000 -0400
+++ my/libmpcodecs/Makefile	2004-08-22 21:26:14.000000000 -0400
@@ -19,7 +19,7 @@
 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_h264.c
 
 NATIVE_SRCS=native/RTjpegN.c native/minilzo.c native/nuppelvideo.c native/xa_gsm.c native/decode144.c native/decode288.c
 
diff -urN main/libmpcodecs/ve.c my/libmpcodecs/ve.c
--- main/libmpcodecs/ve.c	2004-02-17 07:43:07.000000000 -0500
+++ my/libmpcodecs/ve.c	2004-08-22 21:26:14.000000000 -0400
@@ -17,6 +17,7 @@
 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_h264;
 
 static vf_info_t* encoder_list[]={
 #ifdef HAVE_DIVX4ENCORE
@@ -37,6 +38,9 @@
     &ve_info_xvid,
 #endif
     &ve_info_nuv,
+#ifdef HAVE_X264
+    &ve_info_h264,
+#endif
     NULL
 };
 
diff -urN main/libmpcodecs/ve_h264.c my/libmpcodecs/ve_h264.c
--- main/libmpcodecs/ve_h264.c	1969-12-31 19:00:00.000000000 -0500
+++ my/libmpcodecs/ve_h264.c	2004-08-11 17:26:58.000000000 -0400
@@ -0,0 +1,291 @@
+/*****************************************************************************
+ *
+ * - H.264 encoder for mencoder using x264 -
+ *
+ * Copyright (C) 2004 LINUX4MEDIA GmbH
+ * Copyright (C) 2004 Ark Linux
+ *
+ * Written by Bernhard Rosenkraenzer <bero at 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;
+
+static int iframe = 60;
+static int iframe_ref = 1;
+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 qp_constant = 26;
+static int qp_min = 2;
+static int qp_max = 51;
+static int qp_step = 4;
+
+static int cbr = 0;
+static int bitrate = 3000;
+static int rc_buffer_size = 0;
+static int rc_init_buffer = 0;
+static int rc_sens = 100;
+static float ip_factor = 2.0;
+static float pb_factor = 2.0;
+
+static int fullinter = 0;
+static int fullintra = 0;
+
+m_option_t h264encopts_conf[] = {
+	{"iframeref", &iframe_ref, CONF_TYPE_INT, 0, 0, 0, NULL},
+	{"idrframe", &idrframe, CONF_TYPE_INT, 0, 0, 0, NULL},
+	{"iframe", &iframe, CONF_TYPE_INT, 0, 0, 0, NULL},
+	{"bframe", &bframe, CONF_TYPE_INT, 0, 0, 0, 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_INT, CONF_RANGE, 0, 1, NULL},
+	{"cabacidc", &cabacidc, CONF_TYPE_INT, 0, 0, 0, NULL},
+	{"qp_constant", &qp_constant, CONF_TYPE_INT, CONF_RANGE, 1, 51, 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, 0, 0, 0, NULL},
+	{"cbr", &cbr, CONF_TYPE_INT, CONF_RANGE, 0, 1, NULL},
+	{"bitrate", &bitrate, CONF_TYPE_INT, CONF_RANGE, 4, 24000000, NULL},
+	{"rc_buffer_size", &rc_buffer_size, CONF_TYPE_INT, CONF_RANGE, 4, 24000000, NULL},
+	{"rc_init_buffer", &rc_init_buffer, CONF_TYPE_INT, 0, 0, 0, NULL},
+	{"rc_sens", &rc_sens, CONF_TYPE_INT, CONF_RANGE, 0, 100, NULL},
+	{"ip_factor", &ip_factor, CONF_TYPE_FLOAT, 0, 0, 0, NULL},
+	{"pb_factor", &pb_factor, CONF_TYPE_FLOAT, 0, 0, 0, NULL},
+	{"fullinter", &fullinter, CONF_TYPE_FLAG, 0, 0, 1, NULL},
+	{"fullintra", &fullintra, CONF_TYPE_FLAG, 0, 0, 1, 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 = iframe_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;
+	mod->param.i_qp_min = qp_min;
+	mod->param.i_qp_max = qp_max;
+	mod->param.i_qp_step = qp_step;
+
+	mod->param.b_cbr = cbr;
+	mod->param.i_bitrate = bitrate;
+	mod->param.i_rc_buffer_size = rc_buffer_size;
+	mod->param.i_rc_sens = rc_sens;
+	mod->param.f_ip_factor = ip_factor;
+	mod->param.f_pb_factor = pb_factor;
+	
+	if(fullinter)
+		mod->param.analyse.inter = X264_ANALYSE_I4x4 | X264_ANALYSE_PSUB16x16 | X264_ANALYSE_PSUB8x8;
+	if(fullintra)
+		mod->param.analyse.intra = X264_ANALYSE_I4x4 | X264_ANALYSE_PSUB16x16 | X264_ANALYSE_PSUB8x8;
+
+	mod->param.i_width = width;
+	mod->param.i_height = height;
+	mod->param.f_fps = mod->mux->h.dwRate;
+	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:
+		return 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)
+{
+	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_h264 = {
+	"H.264 encoder",
+	"h264",
+	"Bernhard Rosenkraenzer <bero at arklinux.org>",
+	"(C) 2004 LINUX4MEDIA GmbH; (C) 2004 Ark Linux",
+	vf_open
+};
+#endif
diff -urN main/mencoder.c my/mencoder.c
--- main/mencoder.c	2004-07-16 16:31:16.000000000 -0400
+++ my/mencoder.c	2004-08-22 21:26:14.000000000 -0400
@@ -9,6 +9,7 @@
 #define VCODEC_QTVIDEO 10
 #define VCODEC_NUV 11
 #define VCODEC_RAW 12
+#define VCODEC_H264 13
 
 #define ACODEC_COPY 0
 #define ACODEC_PCM 1
@@ -708,7 +709,8 @@
         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_H264:
+        sh_video->vfilter=vf_open_encoder(NULL,"h264",(char *)mux_v); break;
     }
     if(!mux_v->bih || !sh_video->vfilter){
         mp_msg(MSGT_MENCODER,MSGL_FATAL,MSGTR_EncoderOpenFailed);
diff -urN main/version.h my/version.h
--- main/version.h	1969-12-31 19:00:00.000000000 -0500
+++ my/version.h	2004-08-22 22:10:23.000000000 -0400
@@ -0,0 +1 @@
+#define VERSION "dev-CVS-040822-21:25-3.3.4"


More information about the MPlayer-dev-eng mailing list