Commit 37e30b12 authored by Laurent Aimar's avatar Laurent Aimar

* modules/codec/faad : an AAC decoder module using libfaad library

(faad2).
 * modules/demux/mp4/libmp4.c : could compile without zlib.
 * modules/codec/ffmpeg/* : set error resilience to -1 by default.(in
order to decode more files, but it could produce segfaults ... )
 * Makefile.*, configure.in : enable mp4 by default, add faad
module (disabled by default ).
parent 7acb51f9
......@@ -67,6 +67,7 @@ dvdread_CFLAGS = @dvdread_CFLAGS@
dvdplay_CFLAGS = @dvdplay_CFLAGS@
esd_CFLAGS = @esd_CFLAGS@
familiar_CFLAGS = @familiar_CFLAGS@
faad_CFLAGS = @faad_CFLAGS@
ffmpeg_CFLAGS = @ffmpeg_CFLAGS@
glide_CFLAGS = @glide_CFLAGS@
gnome_CFLAGS = @gnome_CFLAGS@
......@@ -105,6 +106,7 @@ dvdplay_LDFLAGS = @dvdplay_LDFLAGS@
esd_LDFLAGS = @esd_LDFLAGS@
familiar_LDFLAGS = @familiar_LDFLAGS@
distort_LDFLAGS = @distort_LDFLAGS@
faad_LDFLAGS = @faad_LDFLAGS@
ffmpeg_LDFLAGS = @ffmpeg_LDFLAGS@
mp4_LDFLAGS = @mp4_LDFLAGS@
ggi_LDFLAGS = @ggi_LDFLAGS@
......
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -1057,19 +1057,73 @@ then
fi
fi
dnl
dnl faad decoder plugin
dnl
AC_ARG_ENABLE(faad,
[ --enable-faad faad codec (default disabled)])
if test "x${enable_faad}" = "xyes"
then
AC_ARG_WITH(faad,
[ --with-faad=PATH path to faad installation],[],[])
if test "x${with_faad}" != "xno" -a "x${with_faad}" != "x"
then
faad_CFLAGS="${faad_CFLAGS} -I${with_faad}/include"
faad_LDFLAGS="${faad_LDFLAGS} -L${with_faad}/lib"
fi
faad_LDFLAGS="${faad_LDFLAGS} -lm"
AC_ARG_WITH(faad-tree,
[ --with-faad-tree=PATH faad tree for static linking])
if test "x${with_faad_tree}" != "x"
then
AC_MSG_CHECKING(for libfaad.a in ${with_faad_tree})
real_faad_tree="`cd ${with_faad_tree} 2>/dev/null && pwd`"
if test "x${real_faad_tree}" = x
then
dnl The given directory can't be found
AC_MSG_RESULT(no)
AC_MSG_ERROR([cannot cd to ${with_faad_tree}])
fi
if test -f "${real_faad_tree}/libfaad/.libs/libfaad.a"
then
dnl Use a custom faad
AC_MSG_RESULT(${real_faad_tree}/libfaad/.libs/libfaad.a)
BUILTINS="${BUILTINS} codec/faad/faad"
faad_LDFLAGS="${faad_LDFLAGS} ${real_faad_tree}/libfaad/.libs/libfaad.a"
faad_CFLAGS="${faad_CFLAGS} -I${real_faad_tree}/include"
else
dnl The given libfaad wasn't built
AC_MSG_RESULT(no)
AC_MSG_ERROR([cannot find ${real_faad_tree}/.libs/libfaad.a, make sure you compiled libfaad in ${with_faad_tree}])
fi
else
CFLAGS="${save_CFLAGS} ${faad_CFLAGS}"
LDFLAGS="${save_LDFLAGS} ${faad_LDFLAGS}"
AC_CHECK_HEADERS(faad.h, ,
[ AC_MSG_ERROR([Cannot find development headers for libfaad...]) ])
AC_CHECK_LIB(faad, faacDecOpen, [
PLUGINS="${PLUGINS} codec/faad/faad"
faad_LDFLAGS="${faad_LDFLAGS} -lfaad" ],
[ AC_MSG_ERROR([Cannot find libfaad library...]) ])
LDFLAGS="${save_LDFLAGS}"
CFLAGS="${save_CFLAGS}"
fi
fi
dnl
dnl MP4 module
dnl
AC_ARG_ENABLE(mp4,
[ --enable-mp4 MP4 demux module (default disabled)])
if test "x${enable_mp4}" = "xyes"
[ --enable-mp4 MP4 demux module (default enabled)])
if test "x${enable_mp4}" != "xno"
then
AC_CHECK_HEADER(zlib.h,
AC_CHECK_LIB(z, inflateEnd,
[ PLUGINS="${PLUGINS} demux/mp4/mp4"
mp4_LDFLAGS="${mp4_LDFLAGS} -lz" ],
[ AC_MSG_ERROR([cannot find zlib library...]) ]),
[ AC_MSG_ERROR([cannot find zlib header...]) ])
PLUGINS="${PLUGINS} demux/mp4/mp4"
AC_CHECK_HEADERS(zlib.h,
[ mp4_LDFLAGS="${mp4_LDFLAGS} -lz" ] )
fi
dnl
......@@ -1978,6 +2032,7 @@ AC_SUBST(ts_dvbpsi_CFLAGS)
AC_SUBST(directx_CFLAGS)
AC_SUBST(esd_CFLAGS)
AC_SUBST(familiar_CFLAGS)
AC_SUBST(faad_CFLAGS)
AC_SUBST(ffmpeg_CFLAGS)
AC_SUBST(glide_CFLAGS)
AC_SUBST(gnome_CFLAGS)
......@@ -2014,6 +2069,7 @@ AC_SUBST(ts_dvbpsi_LDFLAGS)
AC_SUBST(esd_LDFLAGS)
AC_SUBST(familiar_LDFLAGS)
AC_SUBST(distort_LDFLAGS)
AC_SUBST(faad_LDFLAGS)
AC_SUBST(ffmpeg_LDFLAGS)
AC_SUBST(mp4_LDFLAGS)
AC_SUBST(ggi_LDFLAGS)
......
/* include/defs.h.in. Generated automatically from configure.in by autoheader. */
/* include/defs.h.in. Generated automatically from configure.in by autoheader 2.13. */
/* Define if using alloca.c. */
#undef C_ALLOCA
......@@ -205,6 +205,9 @@
/* Define if you have the <dvdread/dvd_reader.h> header file. */
#undef HAVE_DVDREAD_DVD_READER_H
/* Define if you have the <faad.h> header file. */
#undef HAVE_FAAD_H
/* Define if you have the <fcntl.h> header file. */
#undef HAVE_FCNTL_H
......@@ -328,6 +331,9 @@
/* Define if you have the <unistd.h> header file. */
#undef HAVE_UNISTD_H
/* Define if you have the <zlib.h> header file. */
#undef HAVE_ZLIB_H
/* Define if you have the pth library (-lpth). */
#undef HAVE_LIBPTH
......
.dep
*.lo
*.o.*
*.lo.*
faad_SOURCES = decoder.c
/*****************************************************************************
* decoder.c: AAC decoder using libfaad2
*****************************************************************************
* Copyright (C) 2001, 2002 VideoLAN
* $Id: decoder.c,v 1.1 2002/08/10 20:05:21 fenrir Exp $
*
* Authors: Laurent Aimar <fenrir@via.ecp.fr>
*
* 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/aout.h>
#include <vlc/decoder.h>
#include <vlc/input.h>
#include <stdlib.h> /* malloc(), free() */
#include <string.h> /* strdup() */
#include <faad.h>
#include "decoder.h"
/*****************************************************************************
* Local prototypes
*****************************************************************************/
static int OpenDecoder ( vlc_object_t * );
static int RunDecoder ( decoder_fifo_t * );
static int InitThread ( adec_thread_t * );
static void DecodeThread ( adec_thread_t * );
static void EndThread ( adec_thread_t * );
/*****************************************************************************
* Module descriptor
*****************************************************************************/
vlc_module_begin();
set_description( _("AAC decoder module (libfaad2)") );
set_capability( "decoder", 60 );
set_callbacks( OpenDecoder, NULL );
vlc_module_end();
/*****************************************************************************
* OpenDecoder: probe the decoder and return score
*****************************************************************************
* Tries to launch a decoder and return score so that the interface is able
* to choose.
*****************************************************************************/
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('m','p','4','a') )
{
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 )
{
adec_thread_t *p_adec;
int b_error;
if( !( p_adec = malloc( sizeof( adec_thread_t ) ) ) )
{
msg_Err( p_fifo, "out of memory" );
DecoderError( p_fifo );
return( -1 );
}
memset( p_adec, 0, sizeof( adec_thread_t ) );
p_adec->p_fifo = p_fifo;
if( InitThread( p_adec ) != 0 )
{
DecoderError( p_fifo );
return( -1 );
}
while( ( !p_adec->p_fifo->b_die )&&( !p_adec->p_fifo->b_error ) )
{
DecodeThread( p_adec );
}
if( ( b_error = p_adec->p_fifo->b_error ) )
{
DecoderError( p_adec->p_fifo );
}
EndThread( p_adec );
if( b_error )
{
return( -1 );
}
return( 0 );
}
#define FREE( p ) if( p ) free( p ); p = NULL
#define GetWLE( p ) \
( *(u8*)(p) + ( *((u8*)(p)+1) << 8 ) )
#define GetDWLE( p ) \
( *(u8*)(p) + ( *((u8*)(p)+1) << 8 ) + \
( *((u8*)(p)+2) << 16 ) + ( *((u8*)(p)+3) << 24 ) )
static void faac_GetWaveFormatEx( waveformatex_t *p_wh,
u8 *p_data )
{
p_wh->i_formattag = GetWLE( p_data );
p_wh->i_channels = GetWLE( p_data + 2 );
p_wh->i_samplespersec = GetDWLE( p_data + 4 );
p_wh->i_avgbytespersec= GetDWLE( p_data + 8 );
p_wh->i_blockalign = GetWLE( p_data + 12 );
p_wh->i_bitspersample = GetWLE( p_data + 14 );
p_wh->i_size = GetWLE( p_data + 16 );
if( p_wh->i_size )
{
p_wh->p_data = malloc( p_wh->i_size );
memcpy( p_wh->p_data, p_data + 18, p_wh->i_size );
}
}
/* get the first pes from fifo */
static pes_packet_t *__PES_GET( decoder_fifo_t *p_fifo )
{
pes_packet_t *p_pes;
vlc_mutex_lock( &p_fifo->data_lock );
/* if fifo is emty wait */
while( !p_fifo->p_first )
{
if( p_fifo->b_die )
{
vlc_mutex_unlock( &p_fifo->data_lock );
return( NULL );
}
vlc_cond_wait( &p_fifo->data_wait, &p_fifo->data_lock );
}
p_pes = p_fifo->p_first;
vlc_mutex_unlock( &p_fifo->data_lock );
return( p_pes );
}
/* free the first pes and go to next */
static void __PES_NEXT( decoder_fifo_t *p_fifo )
{
pes_packet_t *p_next;
vlc_mutex_lock( &p_fifo->data_lock );
p_next = p_fifo->p_first->p_next;
p_fifo->p_first->p_next = NULL;
input_DeletePES( p_fifo->p_packets_mgt, p_fifo->p_first );
p_fifo->p_first = p_next;
p_fifo->i_depth--;
if( !p_fifo->p_first )
{
/* No PES in the fifo */
/* pp_last no longer valid */
p_fifo->pp_last = &p_fifo->p_first;
while( !p_fifo->p_first )
{
vlc_cond_signal( &p_fifo->data_wait );
vlc_cond_wait( &p_fifo->data_wait, &p_fifo->data_lock );
}
}
vlc_mutex_unlock( &p_fifo->data_lock );
}
static inline void __GetFrame( adec_thread_t *p_adec )
{
pes_packet_t *p_pes;
data_packet_t *p_data;
byte_t *p_buffer;
p_pes = __PES_GET( p_adec->p_fifo );
if( p_pes->i_pts > 0 )
{
p_adec->i_pts = p_pes->i_pts;
}
while( ( !p_pes->i_nb_data )||( !p_pes->i_pes_size ) )
{
__PES_NEXT( p_adec->p_fifo );
p_pes = __PES_GET( p_adec->p_fifo );
}
p_adec->i_framesize = p_pes->i_pes_size;
if( p_pes->i_nb_data == 1 )
{
p_adec->p_framedata = p_pes->p_first->p_payload_start;
return;
}
/* get a buffer and gather all data packet */
if( p_adec->i_buffer_size < p_pes->i_pes_size )
{
p_adec->i_buffer_size = 3 * p_pes->i_pes_size / 2;
if( p_adec->p_buffer )
{
p_adec->p_buffer = realloc( p_adec->p_buffer,
p_adec->i_buffer_size );
}
else
{
p_adec->p_buffer = malloc( p_adec->i_buffer_size );
}
}
p_buffer = p_adec->p_framedata = p_adec->p_buffer;
p_data = p_pes->p_first;
do
{
p_adec->p_fifo->p_vlc->pf_memcpy( p_buffer, p_data->p_payload_start,
p_data->p_payload_end - p_data->p_payload_start );
p_buffer += p_data->p_payload_end - p_data->p_payload_start;
p_data = p_data->p_next;
} while( p_data );
}
static inline void __NextFrame( adec_thread_t *p_adec )
{
__PES_NEXT( p_adec->p_fifo );
}
/*****************************************************************************
* InitThread: initialize data before entering main loop
*****************************************************************************/
static int InitThread( adec_thread_t * p_adec )
{
int i_status;
unsigned long i_rate;
unsigned char i_channels;
faacDecConfiguration *p_faad_config;
if( !p_adec->p_fifo->p_demux_data )
{
msg_Warn( p_adec->p_fifo,
"cannot load stream informations" );
}
else
{
faac_GetWaveFormatEx( &p_adec->format,
(u8*)p_adec->p_fifo->p_demux_data );
}
if( !( p_adec->p_handle = faacDecOpen() ) )
{
msg_Err( p_adec->p_fifo,
"cannot initialize faad" );
FREE( p_adec->format.p_data );
return( -1 );
}
if( !p_adec->format.p_data )
{
msg_Warn( p_adec->p_fifo,
"DecoderSpecificInfo missing, trying with first frame" );
__GetFrame( p_adec );
i_status = faacDecInit( p_adec->p_handle,
p_adec->p_framedata,
&i_rate,
&i_channels );
// __NextFrame( p_adec );
}
else
{
i_status = faacDecInit2( p_adec->p_handle,
p_adec->format.p_data,
p_adec->format.i_size,
&i_rate,
&i_channels );
}
if( i_status < 0 )
{
msg_Err( p_adec->p_fifo,
"failed to initialize faad" );
faacDecClose( p_adec->p_handle );
return( -1 );
}
msg_Dbg( p_adec->p_fifo,
"faad intitialized, samplerate:%dHz channels:%d",
i_rate,
i_channels );
/* set default configuration */
p_faad_config = faacDecGetCurrentConfiguration( p_adec->p_handle );
p_faad_config->outputFormat = FAAD_FMT_FLOAT;
faacDecSetConfiguration( p_adec->p_handle, p_faad_config );
/* Initialize the thread properties */
p_adec->output_format.i_format = AOUT_FMT_FLOAT32;
p_adec->output_format.i_rate = i_rate;
p_adec->output_format.i_channels = i_channels;
#if 0
if( !p_adec->format.p_data )
{
/* Init the BitStream */
InitBitstream( &p_adec->bit_stream, p_adec->p_fifo,
NULL, NULL );
p_adec->p_framedata = malloc( AAC_MAXCHANNELS * FAAD_MIN_STREAMSIZE );
p_adec->i_framesize = 0;
}
#endif
return( 0 );
}
/*****************************************************************************
* DecodeThread: decodes a frame
*****************************************************************************
* XXX it will work only for frame based streams like from mp4 file
* but it's the only way to use libfaad2 without having segfault
* after 1 or 2 frames
*****************************************************************************/
static void DecodeThread( adec_thread_t *p_adec )
{
aout_buffer_t *p_aout_buffer;
void *p_faad_buffer;
faacDecFrameInfo faad_frame;
/* **** Get a new frames from streams **** */
__GetFrame( p_adec );
/* **** decode this frame **** */
p_faad_buffer = faacDecDecode( p_adec->p_handle,
&faad_frame,
p_adec->p_framedata );
/* **** switch to the next frame **** */
__NextFrame( p_adec );
#if 0
/*
* XXX don't work ! XXX
*
* first even without format.p_data stream can be frame based
* and it make libfaad segfault
*
*/
if( p_adec->format.p_data )
{
__GetFrame( p_adec );
/* Now decode data */
p_faad_buffer = faacDecDecode( p_adec->p_handle,
&faad_frame,
p_adec->p_framedata );
__NextFrame( p_adec );
}
else
{
int i_count;
/* fill buffer */
i_count = __MAX( 1, p_adec->output_format.i_channels ) * FAAD_MIN_STREAMSIZE -
p_adec->i_framesize;
GetChunk( &p_adec->bit_stream,
p_adec->p_framedata + p_adec->i_framesize,
i_count );
p_adec->i_framesize += i_count;
p_faad_buffer = faacDecDecode( p_adec->p_handle,
&faad_frame,
p_adec->p_framedata );
/* update data buffer pos */
i_count = __MIN( p_adec->i_framesize,
__MAX( 1, faad_frame.bytesconsumed ) );
memcpy( p_adec->p_framedata,
p_adec->p_framedata + i_count,
p_adec->i_framesize - i_count );
p_adec->i_framesize -= i_count;
}
#endif
/* **** some sanity checks to see if we have samples to out **** */
if( faad_frame.error > 0 )
{
msg_Warn( p_adec->p_fifo, "%s",
faacDecGetErrorMessage(faad_frame.error) );
return;
}
if( ( faad_frame.channels <= 0 )||
( faad_frame.channels > AAC_MAXCHANNELS) )
{
msg_Warn( p_adec->p_fifo,
"invalid channels count(%d)", faad_frame.channels );
return;
}
if( faad_frame.samples <= 0 )
{
msg_Warn( p_adec->p_fifo, "decoded zero sample !" );
return;
}
#if 0
msg_Dbg( p_adec->p_fifo,
"decoded frame samples:%d, channels:%d, consumed:%d",
faad_frame.samples,
faad_frame.channels,
faad_frame.bytesconsumed );
#endif
/* **** Now we can output these samples **** */
/* **** First check if we have a valid output **** */
if( ( !p_adec->p_aout_input )||
( p_adec->output_format.i_channels != faad_frame.channels ) )
{
if( p_adec->p_aout_input )
{
/* **** Delete the old **** */
aout_InputDelete( p_adec->p_aout, p_adec->p_aout_input );
}
/* **** Create a new audio output **** */
p_adec->output_format.i_channels = faad_frame.channels;
p_adec->p_aout_input = aout_InputNew( p_adec->p_fifo,
&p_adec->p_aout,
&p_adec->output_format );
}
if( !p_adec->p_aout_input )
{
msg_Err( p_adec->p_fifo,
"cannot create aout" );
return;
}
p_aout_buffer = aout_BufferNew( p_adec->p_aout,
p_adec->p_aout_input,
faad_frame.samples /
faad_frame.channels );
if( !p_aout_buffer )
{
msg_Err( p_adec->p_fifo,
"cannot get aout buffer" );
p_adec->p_fifo->b_error = 1;
return;
}
p_aout_buffer->start_date = p_adec->i_pts;
p_adec->i_pts += (mtime_t)1000000 * (mtime_t)faad_frame.samples /
(mtime_t)p_adec->output_format.i_channels /
(mtime_t)p_adec->output_format.i_rate;
p_aout_buffer->end_date = p_adec->i_pts;
/*
* FIXME for FAAD_FMT_FLOAT *only*
* test if it works on big endian machine
* ( I don't know if float have endian issue )
*
*/
memcpy( p_aout_buffer->p_buffer,
p_faad_buffer,
faad_frame.samples * 4 ); /* FIXME for FAAD_FMT_FLOAT *only* */
aout_BufferPlay( p_adec->p_aout, p_adec->p_aout_input, p_aout_buffer );
}
/*****************************************************************************
* EndThread : faad decoder thread destruction
*****************************************************************************/
static void EndThread (adec_thread_t *p_adec)
{
if( p_adec->p_aout_input )
{
aout_InputDelete( p_adec->p_aout, p_adec->p_aout_input );
}
if( p_adec->p_handle )
{
faacDecClose( p_adec->p_handle );
}
FREE( p_adec->format.p_data );
FREE( p_adec->p_buffer );
msg_Dbg( p_adec->p_fifo, "faad decoder closed" );
free( p_adec );
}
/*****************************************************************************
* decoder.h: faad decoder modules
*
*****************************************************************************
* Copyright (C) 2001 VideoLAN
* $Id: decoder.h,v 1.1 2002/08/10 20:05:21 fenrir Exp $
*
* Authors: Laurent Aimar <fenrir@via.ecp.fr>
*
* 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.
*****************************************************************************/
#define AAC_MAXCHANNELS 64
typedef struct waveformatex_s
{
u16 i_formattag;
u16 i_channels;
u32 i_samplespersec;
u32 i_avgbytespersec;
u16 i_blockalign;
u16 i_bitspersample;
u16 i_size; /* the extra size in bytes */
u8 *p_data; /* The extra data */
} waveformatex_t;
typedef struct adec_thread_s
{
waveformatex_t format;
/*
* faad decoder session
*/
/* faad stuff */
faacDecHandle *p_handle;
/* The bit stream structure handles the PES stream at the bit level */
bit_stream_t bit_stream;
/*
* Input properties
*/
decoder_fifo_t *p_fifo;
u8 *p_framedata;
int i_framesize;
u8 *p_buffer;
int i_buffer_size;
/*
* Output properties
*/
mtime_t i_pts;
aout_instance_t * p_aout; /* opaque */
aout_input_t * p_aout_input; /* opaque */
audio_sample_format_t output_format;
} adec_thread_t;
......@@ -2,7 +2,7 @@
* ffmpeg.c: video decoder using ffmpeg library
*****************************************************************************
* Copyright (C) 1999-2001 VideoLAN
* $Id: ffmpeg.c,v 1.3 2002/08/04 22:13:05 fenrir Exp $
* $Id: ffmpeg.c,v 1.4 2002/08/10 20:05:21 fenrir Exp $
*
* Authors: Laurent Aimar <fenrir@via.ecp.fr>
*
......@@ -88,7 +88,7 @@ static int b_ffmpeginit = 0;
vlc_module_begin();
add_category_hint( N_("Miscellaneous"), NULL );
#if LIBAVCODEC_BUILD >= 4611
add_integer ( "ffmpeg-error-resilience", 0, NULL,
add_integer ( "ffmpeg-error-resilience", -1, NULL,
"error resilience", ERROR_RESILIENCE_LONGTEXT );
add_integer ( "ffmpeg-workaround-bugs", 0, NULL,
"workaround bugs", "0-99, seems to be for msmpeg v3\n" );
......@@ -431,16 +431,10 @@ static vout_thread_t *ffmpeg_CreateVout( videodec_thread_t *p_vdec,
{
msg_Dbg( p_vdec->p_fifo, "no vout present, spawning one" );
if( !( p_vout = vout_CreateThread( p_vdec->p_fifo,
i_width,
i_height,
i_chroma,
i_aspect ) ) )
{
return( NULL ); /* everythings have failed */
}
p_vout = vout_CreateThread( p_vdec->p_fifo,
i_width, i_height,
i_chroma, i_aspect );
}
/* up to now, all this stuff is used for post-processing */
return( p_vout );
}
......@@ -633,8 +627,6 @@ static int InitThread( videodec_thread_t *p_vdec )
{
int i_ffmpeg_codec;
int i_tmp;
int i_use_pp;
if( p_vdec->p_fifo->p_demux_data )
{
......@@ -696,9 +688,42 @@ static int InitThread( videodec_thread_t *p_vdec )
#endif
p_vdec->b_hurry_up = config_GetInt(p_vdec->p_fifo, "ffmpeg-hurry-up");
/* ***** Load for post processing ***** */
/* get overridden settings */
/* ***** Open the codec ***** */
if (avcodec_open(p_vdec->p_context, p_vdec->p_codec) < 0)
{
msg_Err( p_vdec->p_fifo, "cannot open codec (%s)",
p_vdec->psz_namecodec );
return( -1 );
}
else
{
msg_Dbg( p_vdec->p_fifo, "ffmpeg codec (%s) started",
p_vdec->psz_namecodec );
}
/* ***** init this codec with special data(up to now MPEG4 only) ***** */
if( p_vdec->format.i_data )
{
AVPicture avpicture;
int b_gotpicture;
switch( i_ffmpeg_codec )
{
case( CODEC_ID_MPEG4 ):
avcodec_decode_video( p_vdec->p_context, &avpicture,
&b_gotpicture,
p_vdec->format.p_data,
p_vdec->format.i_data );
break;
default:
break;
}
}
/* ***** Load post processing ***** */
/* get overridding settings */
p_vdec->i_pp_mode = 0;
if( config_GetInt( p_vdec->p_fifo, "ffmpeg-db-yv" ) )
p_vdec->i_pp_mode |= PP_DEBLOCK_Y_V;
......@@ -714,17 +739,10 @@ static int InitThread( videodec_thread_t *p_vdec )
p_vdec->i_pp_mode |= PP_DERING_C;
if( ( config_GetInt( p_vdec->p_fifo, "ffmpeg-pp-q" ) > 0 )||
( config_GetInt( p_vdec->p_fifo, "ffmpeg-pp-auto" ) )||
( p_vdec->i_pp_mode != 0 ) )
{
i_use_pp = 1;
}
else
{
i_use_pp = 0;
}
if( i_use_pp )
{
/* check if the codec support postproc. */
switch( i_ffmpeg_codec )
{
#if LIBAVCODEC_BUILD > 4608
......@@ -739,91 +757,52 @@ static int InitThread( videodec_thread_t *p_vdec )
// case( CODEC_ID_H263P ): I don't use it up to now
case( CODEC_ID_H263I ):
/* Ok we can make postprocessing :)) */
break;
default:
p_vdec->i_pp_mode = 0;
i_use_pp = 0;
msg_Warn( p_vdec->p_fifo,
"Post processing unsupported for this codec" );
break;
}
}
if( i_use_pp )
{
/* first try to get a postprocess module */
#if LIBAVCODEC_BUILD > 4613
char *psz_name;
/* first try to get a postprocess module */
p_vdec->p_pp = vlc_object_create( p_vdec->p_fifo,
sizeof( postprocessing_t ) );
p_vdec->p_pp->psz_object_name = "postprocessing";
psz_name = config_GetPsz( p_vdec->p_pp, "ffmpeg-pp" );
p_vdec->p_pp->p_module =
module_Need( p_vdec->p_pp, "postprocessing", psz_name );
FREE( psz_name );
if( !p_vdec->p_pp->p_module )
{
msg_Warn( p_vdec->p_fifo, "no suitable postprocessing module" );
vlc_object_destroy( p_vdec->p_pp );
p_vdec->p_pp = NULL;
p_vdec->i_pp_mode = 0;
}
else
{
/* get mode upon quality */
p_vdec->i_pp_mode |=
p_vdec->p_pp->pf_getmode( config_GetInt( p_vdec->p_fifo,
"ffmpeg-pp-q" ),
config_GetInt( p_vdec->p_fifo,
"ffmpeg-pp-auto" ) );
/* allocate table for postprocess */
p_vdec->p_context->quant_store =
malloc( sizeof( int ) * ( MBR + 1 ) * ( MBC + 1 ) );
p_vdec->p_context->qstride = MBC + 1;
}
p_vdec->p_pp = vlc_object_create( p_vdec->p_fifo,
sizeof( postprocessing_t ) );
p_vdec->p_pp->psz_object_name = "postprocessing";
p_vdec->p_pp->p_module =
module_Need( p_vdec->p_pp, "postprocessing", "$ffmpeg-pp" );
if( !p_vdec->p_pp->p_module )
{
msg_Warn( p_vdec->p_fifo,
"no suitable postprocessing module" );
vlc_object_destroy( p_vdec->p_pp );
p_vdec->p_pp = NULL;
p_vdec->i_pp_mode = 0;
}
else
{
/* get mode upon quality */
p_vdec->i_pp_mode |=
p_vdec->p_pp->pf_getmode(
config_GetInt( p_vdec->p_fifo, "ffmpeg-pp-q" ),
config_GetInt( p_vdec->p_fifo, "ffmpeg-pp-auto" )
);
/* allocate table for postprocess */
p_vdec->p_context->quant_store =
malloc( sizeof( int ) * ( MBR + 1 ) * ( MBC + 1 ) );
p_vdec->p_context->qstride = MBC + 1;
}
#else
msg_Warn( p_vdec->p_fifo,
"post-processing not supported, upgrade ffmpeg" );
p_vdec->i_pp_mode = 0;
p_vdec->i_pp_mode = 0;
msg_Warn( p_vdec->p_fifo,
"post-processing not supported, upgrade ffmpeg" );
#endif
}
/* ***** Open the codec ***** */
if (avcodec_open(p_vdec->p_context, p_vdec->p_codec) < 0)
{
msg_Err( p_vdec->p_fifo, "cannot open codec (%s)",
p_vdec->psz_namecodec );
return( -1 );
}
else
{
msg_Dbg( p_vdec->p_fifo, "ffmpeg codec (%s) started",
p_vdec->psz_namecodec );
}
/* ***** init this codec with special data(up to now MPEG4 only) ***** */
if( p_vdec->format.i_data )
{
AVPicture avpicture;
int b_gotpicture;
switch( i_ffmpeg_codec )
{
case( CODEC_ID_MPEG4 ):
avcodec_decode_video( p_vdec->p_context, &avpicture,
&b_gotpicture,
p_vdec->format.p_data,
p_vdec->format.i_data );
break;
default:
p_vdec->i_pp_mode = 0;
msg_Warn( p_vdec->p_fifo,
"Post processing unsupported for this codec" );
break;
}
}
// memset( &p_vdec->statistic, 0, sizeof( statistic_t ) );
return( 0 );
}
......
......@@ -2,7 +2,7 @@
* ffmpeg_vdec.h: video decoder using ffmpeg library
*****************************************************************************
* Copyright (C) 2001 VideoLAN
* $Id: ffmpeg.h,v 1.2 2002/08/04 22:13:05 fenrir Exp $
* $Id: ffmpeg.h,v 1.3 2002/08/10 20:05:21 fenrir Exp $
*
* Authors: Laurent Aimar <fenrir@via.ecp.fr>
*
......@@ -38,9 +38,21 @@ typedef struct bitmapinfoheader_s
int i_data;
u8 *p_data;
} bitmapinfoheader_t;
#if 0
typedef struct statistic_s
{
mtime_t i_frame_time[3]; /* total time to decode frame */
int i_frame_count[3]; /* number of frame to calculate frame_time */
int i_frame_late[3]; /* number of frame consecutively late */
int i_frame_skip[3]; /* number of frame skip */
} statistic_t;
#endif
typedef struct videodec_thread_s
{
decoder_fifo_t *p_fifo;
......@@ -58,6 +70,8 @@ typedef struct videodec_thread_s
char *psz_namecodec;
/* for frame skipping algo */
// statistic_s statistic;
int b_hurry_up;
int i_frame_error;
int i_frame_skip;
......
......@@ -2,7 +2,7 @@
* libmp4.c : LibMP4 library for mp4 module for vlc
*****************************************************************************
* Copyright (C) 2001 VideoLAN
* $Id: libmp4.c,v 1.1 2002/08/04 17:23:42 sam Exp $
* $Id: libmp4.c,v 1.2 2002/08/10 20:05:21 fenrir Exp $
* Authors: Laurent Aimar <fenrir@via.ecp.fr>
*
* This program is free software; you can redistribute it and/or modify
......@@ -27,7 +27,10 @@
#include <vlc/vlc.h>
#include <vlc/input.h>
#include <zlib.h> /* for compressed moov */
#ifdef HAVE_ZLIB_H
# include <zlib.h> /* for compressed moov */
#endif
#include "libmp4.h"
/*****************************************************************************
......@@ -1749,6 +1752,7 @@ void MP4_FreeBox_cmvd( input_thread_t *p_input, MP4_Box_t *p_box )
FREE( p_box->data.p_cmvd->p_data );
}
int MP4_ReadBox_cmov( MP4_Stream_t *p_stream, MP4_Box_t *p_box )
{
MP4_Stream_t *p_stream_memory;
......@@ -1797,7 +1801,12 @@ int MP4_ReadBox_cmov( MP4_Stream_t *p_stream, MP4_Box_t *p_box )
( p_dcom->data.p_dcom->i_algorithm >> 24 )&0xff );
return( 1 );
}
#ifndef HAVE_ZLIB_H
msg_Dbg( p_stream->p_input,
"Read Box: \"cmov\" zlib unsupported" );
return( 1 );
#else
/* decompress data */
/* allocate a new buffer */
if( !( p_data = malloc( p_cmvd->data.p_cmvd->i_uncompressed_size ) ) )
......@@ -1875,6 +1884,7 @@ int MP4_ReadBox_cmov( MP4_Stream_t *p_stream, MP4_Box_t *p_box )
"Read Box: \"cmov\" compressed movie header completed" );
#endif
return( i_result );
#endif /* HAVE_ZLIB_H */
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment