Commit 08a2b6ba authored by Gildas Bazin's avatar Gildas Bazin

* configure.ac.in, modules/codec/Modules.am, modules/codec/libmpeg2.c:
   Added a simple mpeg video decoder based on libmpeg2. It is mainly useful
   for comparing the performance against our custom decoder as it is currently
   missing some important features like the synchro stuff.
parent 75292afe
......@@ -171,7 +171,7 @@ dnl
dnl Gettext stuff
dnl
ALL_LINGUAS="de en_GB fr it ja no ru nl pl sv"
AM_GNU_GETTEXT_VERSION(0.10.40)
AM_GNU_GETTEXT_VERSION(0.11.5)
AM_GNU_GETTEXT
if test "${nls_cv_force_use_gnu_gettext}" = "yes"; then
AC_DEFINE(HAVE_INCLUDED_GETTEXT, 1, Define if we use the local libintl)
......@@ -1756,7 +1756,7 @@ dnl
dnl Flac plugin
dnl
AC_ARG_ENABLE(flac,
[ --enable-falc flac decoder support (default disabled)])
[ --enable-flac flac decoder support (default disabled)])
if test "x${enable_flac}" = "xyes"
then
AC_CHECK_HEADERS(FLAC/stream_decoder.h, [
......@@ -1765,6 +1765,19 @@ then
],[])
fi
dnl
dnl Libmpeg2 plugin
dnl
AC_ARG_ENABLE(libmpeg2,
[ --enable-libmpeg2 libmpeg2 decoder support (default disabled)])
if test "x${enable_libmpeg2}" = "xyes"
then
AC_CHECK_HEADERS(mpeg2dec/mpeg2.h, [
PLUGINS="${PLUGINS} libmpeg2"
LDFLAGS_libmpeg2="${LDFLAGS_libmpeg2} -lmpeg2"
],[])
fi
dnl
dnl Vorbis plugin
dnl
......
......@@ -10,3 +10,4 @@ SOURCES_dv = modules/codec/dv.c
SOURCES_xvid = modules/codec/xvid.c
SOURCES_adpcm = modules/codec/adpcm.c
SOURCES_mpeg_audio = modules/codec/mpeg_audio.c
SOURCES_libmpeg2 = modules/codec/libmpeg2.c
/*****************************************************************************
* libmpeg2.c: mpeg2 video decoder module making use of libmpeg2.
*****************************************************************************
* Copyright (C) 1999-2001 VideoLAN
* $Id: libmpeg2.c,v 1.1 2003/02/25 17:15:32 gbazin Exp $
*
* Authors: Gildas Bazin <gbazin@netcourrier.com>
*
* 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> /* malloc(), free() */
#include <string.h> /* memcpy(), memset() */
#include <mpeg2dec/mpeg2.h>
/*****************************************************************************
* dec_thread_t : libmpeg2 decoder thread descriptor
*****************************************************************************/
typedef struct dec_thread_t
{
/*
* libmpeg2 properties
*/
mpeg2dec_t *p_mpeg2dec;
const mpeg2_info_t *p_info;
/*
* Input properties
*/
decoder_fifo_t *p_fifo; /* stores the PES stream data */
pes_packet_t *p_pes; /* current PES we are decoding */
mtime_t i_pts;
/*
* Output properties
*/
vout_thread_t *p_vout;
} dec_thread_t;
/*****************************************************************************
* Local prototypes
*****************************************************************************/
static int OpenDecoder ( vlc_object_t * );
static int RunDecoder ( decoder_fifo_t * );
static void CloseDecoder ( dec_thread_t * );
/*****************************************************************************
* Module descriptor
*****************************************************************************/
vlc_module_begin();
set_description( _("libmpeg2 decoder module") );
set_capability( "decoder", 40 );
set_callbacks( OpenDecoder, NULL );
add_shortcut( "libmpeg2" );
vlc_module_end();
/*****************************************************************************
* OpenDecoder: probe the decoder and return score
*****************************************************************************/
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','g','v') )
{
return VLC_EGENERIC;
}
p_fifo->pf_run = RunDecoder;
return VLC_SUCCESS;
}
/*****************************************************************************
* RunDecoder: the libmpeg2 decoder
*****************************************************************************/
static int RunDecoder( decoder_fifo_t *p_fifo )
{
dec_thread_t *p_dec;
data_packet_t *p_data = NULL;
mpeg2_state_t state;
picture_t *p_pic;
int i_aspect, i_chroma;
/* Allocate the memory needed to store the thread's structure */
if( (p_dec = (dec_thread_t *)malloc (sizeof(dec_thread_t)) )
== NULL)
{
msg_Err( p_fifo, "out of memory" );
goto error;
}
/* Initialize the thread properties */
memset( p_dec, 0, sizeof(dec_thread_t) );
p_dec->p_fifo = p_fifo;
p_dec->p_pes = NULL;
p_dec->p_vout = NULL;
p_dec->p_mpeg2dec = NULL;
p_dec->p_info = NULL;
p_dec->i_pts = 0;
/* Initialize decoder */
p_dec->p_mpeg2dec = mpeg2_init();
if( p_dec->p_mpeg2dec == NULL)
goto error;
p_dec->p_info = mpeg2_info( p_dec->p_mpeg2dec );
/* libmpeg2 decoder thread's main loop */
while( (!p_dec->p_fifo->b_die) && (!p_dec->p_fifo->b_error) )
{
state = mpeg2_parse( p_dec->p_mpeg2dec );
switch( state )
{
case STATE_BUFFER:
/* Feed libmpeg2 a data packet at a time */
if( p_data == NULL )
{
/* Get the next PES */
if( p_dec->p_pes )
input_DeletePES( p_dec->p_fifo->p_packets_mgt,
p_dec->p_pes );
input_ExtractPES( p_dec->p_fifo, &p_dec->p_pes );
if( !p_dec->p_pes )
{
p_dec->p_fifo->b_error = 1;
break;
}
if( p_dec->p_pes->i_pts )
{
mpeg2_pts( p_dec->p_mpeg2dec,
p_dec->p_pes->i_pts * 9 / 100 );
}
p_data = p_dec->p_pes->p_first;
}
if( p_data != NULL )
{
mpeg2_buffer( p_dec->p_mpeg2dec,
p_data->p_payload_start,
p_data->p_payload_end );
p_data = p_data->p_next;
}
break;
case STATE_SEQUENCE:
/* Initialize video output */
i_aspect = p_dec->p_info->sequence->width *
p_dec->p_info->sequence->pixel_width /
p_dec->p_info->sequence->height * VOUT_ASPECT_FACTOR /
p_dec->p_info->sequence->pixel_height;
i_chroma = VLC_FOURCC('Y','V','1','2');
p_dec->p_vout = vout_Request( p_dec->p_fifo, p_dec->p_vout,
p_dec->p_info->sequence->width,
p_dec->p_info->sequence->height,
i_chroma, i_aspect );
break;
case STATE_PICTURE:
{
uint8_t * buf[3];
/* Get a new picture */
while( !(p_pic = vout_CreatePicture( p_dec->p_vout, 0, 0, 0 ) ) )
{
if( p_dec->p_fifo->b_die || p_dec->p_fifo->b_error )
break;
msleep( VOUT_OUTMEM_SLEEP );
}
if( p_pic == NULL )
break;
buf[0] = p_pic->p[0].p_pixels;
buf[1] = p_pic->p[1].p_pixels;
buf[2] = p_pic->p[2].p_pixels;
mpeg2_set_buf( p_dec->p_mpeg2dec, buf, p_pic );
}
break;
case STATE_END:
msg_Err( p_dec->p_fifo, "STATE_END" );
case STATE_SLICE:
#if 0
msg_Err( p_dec->p_fifo, "STATE_SLICE: %i",
p_dec->p_info->display_fbuf ?
p_dec->p_info->display_fbuf->id : -1 );
#endif
if( p_dec->p_info->display_fbuf
&& p_dec->p_info->display_fbuf->id )
{
p_pic = (picture_t *)p_dec->p_info->display_fbuf->id;
if( p_dec->p_info->display_picture->flags & PIC_FLAG_PTS )
{
p_dec->i_pts =
((mtime_t)p_dec->p_info->display_picture->pts)
* 100 / 9;
}
else
{
p_dec->i_pts += (p_dec->p_info->sequence->frame_period/27);
}
vout_DatePicture( p_dec->p_vout, p_pic, p_dec->i_pts );
vout_DisplayPicture( p_dec->p_vout, p_pic );
}
break;
default:
break;
}
}
/* If b_error is set, the libmpeg2 decoder thread enters the error loop */
if( p_dec->p_fifo->b_error )
{
DecoderError( p_dec->p_fifo );
}
/* End of the libmpeg2 decoder thread */
CloseDecoder( p_dec );
return 0;
error:
DecoderError( p_fifo );
if( p_dec )
{
if( p_dec->p_fifo )
p_dec->p_fifo->b_error = 1;
/* End of the libmpeg2 decoder thread */
CloseDecoder( p_dec );
}
return -1;
}
/*****************************************************************************
* CloseDecoder: libmpeg2 decoder destruction
*****************************************************************************/
static void CloseDecoder( dec_thread_t * p_dec )
{
if( p_dec )
{
if( p_dec->p_pes )
input_DeletePES( p_dec->p_fifo->p_packets_mgt, p_dec->p_pes );
vout_Request( p_dec->p_fifo, p_dec->p_vout, 0, 0, 0, 0 );
if( p_dec->p_mpeg2dec ) mpeg2_close( p_dec->p_mpeg2dec );
free( p_dec );
}
}
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