fi
+dnl
+dnl xvid decoder plugin
+dnl
+AC_ARG_ENABLE(xvid,
+[ --enable-xvid xvid codec (default disabled)])
+if test "x${enable_xvid}" = "xyes"
+then
+ AC_ARG_WITH(xvid,
+ [ --with-xvid=PATH path to xvid installation],[],[])
+ if test "x${with_xvid}" != "xno" -a "x${with_xvid}" != "x"
+ then
+ CPPFLAGS_xvid="${CPPFLAGS_xvid} -I${with_xvid}/include"
+ LDFLAGS_xvid="${LDFLAGS_xvid} -L${with_xvid}/lib"
+ fi
+ LDFLAGS_xvid="${LDFLAGS_xvid}"
+
+ AC_ARG_WITH(xvid-tree,
+ [ --with-xvid-tree=PATH xvid tree for static linking])
+ if test "x${with_xvid_tree}" != "x"
+ then
+ AC_MSG_CHECKING(for libxvidcore.a in ${with_xvid_tree})
+ real_xvid_tree="`cd ${with_xvid_tree} 2>/dev/null && pwd`"
+ if test "x${real_xvid_tree}" = x
+ then
+ dnl The given directory can't be found
+ AC_MSG_RESULT(no)
+ AC_MSG_ERROR([cannot cd to ${with_xvid_tree}])
+ fi
+ if test -f "${real_xvid_tree}/build/generic/libxvidcore.a"
+ then
+ dnl Use a custom xvid
+ AC_MSG_RESULT(${real_xvid_tree}/build/generic/libxvidcore.a)
+ BUILTINS="${BUILTINS} xvid"
+ LDFLAGS_xvid="${LDFLAGS_xvid} ${real_xvid_tree}/build/generic/libxvidcore.a"
+ CPPFLAGS_xvid="${CPPFLAGS_xvid} -I${real_xvid_tree}/src"
+ else
+ dnl The given libxvidcore wasn't built
+ AC_MSG_RESULT(no)
+ AC_MSG_ERROR([cannot find ${real_xvid_tree}/build/generic/libxvidcore.a, make sure you compiled libxvidcore in ${with_xvid_tree}])
+ fi
+ else
+ CPPFLAGS="${CPPFLAGS_save} ${CPPFLAGS_xvid}"
+ LDFLAGS="${LDFLAGS_save} ${LDFLAGS_xvid}"
+ AC_CHECK_HEADERS(xvid.h, ,
+ [ AC_MSG_ERROR([Cannot find development headers for libxvidcore...]) ])
+ AC_CHECK_LIB(xvid, xvid_init, [
+ PLUGINS="${PLUGINS} xvid"
+ LDFLAGS_xvid="${LDFLAGS_xvid} -lxvid" ],
+ [ AC_MSG_ERROR([Cannot find libxvidcore library...]) ])
+ LDFLAGS="${LDFLAGS_save}"
+ CPPFLAGS="${CPPFLAGS_save}"
+ fi
+fi
+
+
dnl
dnl MP4 module
--- /dev/null
+/*****************************************************************************
+ * xvid.c: a decoder for libxvidcore, the Xvid video codec
+ *****************************************************************************
+ * Copyright (C) 2002 VideoLAN
+ * $Id: xvid.c,v 1.1 2002/11/05 22:53:21 sam Exp $
+ *
+ * Authors: Samuel Hocevar <sam@zoy.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY 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, USA.
+ *****************************************************************************/
+
+/*****************************************************************************
+ * Preamble
+ *****************************************************************************/
+#include <vlc/vlc.h>
+#include <vlc/vout.h>
+#include <vlc/input.h>
+#include <vlc/decoder.h>
+
+#include <stdlib.h>
+
+#include "codecs.h"
+
+#include <xvid.h>
+
+/*****************************************************************************
+ * Local prototypes
+ *****************************************************************************/
+static int RunDecoder ( decoder_fifo_t * );
+static int OpenDecoder ( vlc_object_t * );
+
+/*****************************************************************************
+ * Module descriptor
+ *****************************************************************************/
+vlc_module_begin();
+ set_description( _("Xvid video decoder") );
+ set_capability( "decoder", 50 );
+ set_callbacks( OpenDecoder, NULL );
+vlc_module_end();
+
+/*****************************************************************************
+ * OpenDecoder: probe the decoder and return score
+ *****************************************************************************
+ * The fourcc format for DV is "dvsd"
+ *****************************************************************************/
+static int OpenDecoder ( vlc_object_t *p_this )
+{
+ decoder_fifo_t *p_fifo = (decoder_fifo_t*) p_this;
+
+ if( p_fifo->i_fourcc != VLC_FOURCC('x','v','i','d')
+ && p_fifo->i_fourcc != VLC_FOURCC('X','V','I','D')
+ && p_fifo->i_fourcc != VLC_FOURCC('D','I','V','X') )
+ {
+ return VLC_EGENERIC;
+ }
+
+ p_fifo->pf_run = RunDecoder;
+ return VLC_SUCCESS;
+}
+
+/*****************************************************************************
+ * RunDecoder: this function is called just after the thread is created
+ *****************************************************************************/
+static int RunDecoder ( decoder_fifo_t *p_fifo )
+{
+ XVID_INIT_PARAM xinit;
+ XVID_DEC_PARAM xparam;
+ BITMAPINFOHEADER * p_format;
+ void * p_xvid;
+
+ pes_packet_t * p_pes = NULL;
+ bit_stream_t bit_stream;
+ vout_thread_t * p_vout;
+
+ uint8_t * p_buffer, * p_image;
+ int i_ret;
+ int i_width, i_height, i_chroma, i_aspect;
+ int i_size, i_offset;
+
+ if( InitBitstream( &bit_stream, p_fifo, NULL, NULL ) != VLC_SUCCESS )
+ {
+ msg_Err( p_fifo, "cannot initialise bitstream" );
+ p_fifo->b_error = VLC_TRUE;
+ DecoderError( p_fifo );
+ return VLC_EGENERIC;
+ }
+
+ p_format = (BITMAPINFOHEADER *)p_fifo->p_demux_data;
+
+ /* Guess picture properties from the BIH */
+ i_width = p_format->biWidth;
+ i_height = p_format->biHeight;
+ i_chroma = VLC_FOURCC('Y','V','1','2');
+ i_aspect = VOUT_ASPECT_FACTOR * i_width / i_height;
+
+ /* XXX: Completely arbitrary buffer size */
+ i_size = i_width * i_height / 4;
+ i_offset = 0;
+ p_buffer = malloc( i_size + 4 * i_width * i_height );
+ p_image = p_buffer + 4 * i_width * i_height;
+
+ if( !p_buffer )
+ {
+ msg_Err( p_fifo, "out of memory" );
+ p_fifo->b_error = VLC_TRUE;
+ CloseBitstream( &bit_stream );
+ DecoderError( p_fifo );
+ return VLC_EGENERIC;
+ }
+
+ xinit.cpu_flags = 0;
+ xvid_init( NULL, 0, &xinit, NULL );
+
+ xparam.width = i_width;
+ xparam.height = i_height;
+ i_ret = xvid_decore( NULL, XVID_DEC_CREATE, &xparam, NULL );
+
+ if( i_ret )
+ {
+ msg_Err( p_fifo, "cannot create xvid decoder" );
+ p_fifo->b_error = VLC_TRUE;
+ free( p_buffer );
+ CloseBitstream( &bit_stream );
+ DecoderError( p_fifo );
+ return VLC_EGENERIC;
+ }
+
+ p_xvid = xparam.handle;
+
+ /* Spawn a video output if there is none. First we look amongst our
+ * children, then we look for any other vout that might be available */
+ p_vout = vlc_object_find( p_fifo, VLC_OBJECT_VOUT, FIND_CHILD );
+ if( !p_vout )
+ {
+ p_vout = vlc_object_find( p_fifo, VLC_OBJECT_VOUT, FIND_ANYWHERE );
+ }
+
+ if( p_vout )
+ {
+ if( p_vout->render.i_width != i_width
+ || p_vout->render.i_height != i_height
+ || p_vout->render.i_chroma != i_chroma
+ || p_vout->render.i_aspect != i_aspect )
+ {
+ /* We are not interested in this format, close this vout */
+ vlc_object_detach( p_vout );
+ vlc_object_release( p_vout );
+ vout_DestroyThread( p_vout );
+ p_vout = NULL;
+ }
+ else
+ {
+ /* This video output is cool! Hijack it. */
+ vlc_object_detach( p_vout );
+ vlc_object_attach( p_vout, p_fifo );
+ vlc_object_release( p_vout );
+ }
+ }
+
+ if( !p_vout )
+ {
+ msg_Dbg( p_fifo, "no vout present, spawning one" );
+
+ p_vout = vout_CreateThread( p_fifo,
+ i_width, i_height,
+ i_chroma, i_aspect );
+ if( !p_vout )
+ {
+ msg_Err( p_fifo, "could not spawn vout" );
+ p_fifo->b_error = VLC_TRUE;
+ xvid_decore( p_xvid, XVID_DEC_DESTROY, NULL, NULL );
+ free( p_buffer );
+ CloseBitstream( &bit_stream );
+ DecoderError( p_fifo );
+ return VLC_EGENERIC;
+ }
+ }
+
+ /* Main loop */
+ while( !p_fifo->b_die && !p_fifo->b_error )
+ {
+ XVID_DEC_FRAME xframe;
+ mtime_t i_pts = 0;
+
+ GetChunk( &bit_stream, p_buffer + i_offset, i_size - i_offset );
+
+ if( p_pes )
+ {
+ input_DeletePES( p_fifo->p_packets_mgt, p_pes );
+ }
+
+ input_ExtractPES( p_fifo, &p_pes );
+ if( p_pes )
+ {
+ /* Don't trust the sucker */
+ //i_pts = p_pes->i_pts + DEFAULT_PTS_DELAY;
+ i_pts = mdate() + DEFAULT_PTS_DELAY;
+ }
+
+ if( p_fifo->b_die || p_fifo->b_error )
+ {
+ break;
+ }
+
+ /* Decode the stuff */
+ xframe.bitstream = p_buffer;
+ xframe.length = i_size;
+ xframe.image = p_image;
+ xframe.stride = i_width;
+ xframe.colorspace = XVID_CSP_YV12;
+ i_ret = xvid_decore( p_xvid, XVID_DEC_DECODE, &xframe, NULL );
+ /* FIXME: check i_ret */
+
+ if( p_vout )
+ {
+ picture_t *p_pic;
+
+ while( !(p_pic = vout_CreatePicture( p_vout, 0, 0, 0 ) ) )
+ {
+ if( p_fifo->b_die || p_fifo->b_error )
+ {
+ break;
+ }
+ msleep( VOUT_OUTMEM_SLEEP );
+ }
+
+ if( !p_pic )
+ {
+ break;
+ }
+
+ /* TODO: use pf_memcpy when this is stable. */
+ memcpy( p_pic->p[0].p_pixels,
+ p_image,
+ i_width * i_height );
+ memcpy( p_pic->p[2].p_pixels,
+ p_image + i_width * i_height,
+ i_width * i_height / 4 );
+ memcpy( p_pic->p[1].p_pixels,
+ p_image + i_width * i_height + i_width * i_height / 4,
+ i_width * i_height / 4 );
+
+ vout_DatePicture( p_vout, p_pic, i_pts );
+ vout_DisplayPicture( p_vout, p_pic );
+ }
+
+ /* Move the remaining data. TODO: only do this when necessary. */
+ memmove( p_buffer, p_buffer + xframe.length, i_size - xframe.length );
+ i_offset = i_size - xframe.length;
+ }
+
+ /* Clean up everything */
+ vlc_object_detach( p_vout );
+ vout_DestroyThread( p_vout );
+
+ xvid_decore( p_xvid, XVID_DEC_DESTROY, NULL, NULL );
+
+ if( p_pes )
+ {
+ input_DeletePES( p_fifo->p_packets_mgt, p_pes );
+ }
+
+ free( p_buffer );
+ CloseBitstream( &bit_stream );
+
+ if( p_fifo->b_error )
+ {
+ DecoderError( p_fifo );
+ return VLC_EGENERIC;
+ }
+
+ return VLC_SUCCESS;
+}
+