Commit a7fa4779 authored by Laurent Aimar's avatar Laurent Aimar

* ffmpeg : new way to gather a frame

 * input_ext-dec.c : add a call to GetPES in NextPES when fifo is empty.
parent 2175bb5b
......@@ -2,7 +2,7 @@
* ffmpeg.c: video decoder using ffmpeg library
*****************************************************************************
* Copyright (C) 1999-2001 VideoLAN
* $Id: ffmpeg.c,v 1.9 2002/10/24 09:37:47 gbazin Exp $
* $Id: ffmpeg.c,v 1.10 2002/10/24 10:33:09 fenrir Exp $
*
* Authors: Laurent Aimar <fenrir@via.ecp.fr>
*
......@@ -85,13 +85,23 @@ static int b_ffmpeginit = 0;
"but no more than requested quality\n" \
"Not yet implemented !"
#define WORAROUND_BUG_LONGTEXT \
"Try to fix some bugs\n" \
"1 autodetect\n" \
"2 old msmpeg4\n" \
"4 xvid interlaced\n" \
"8 ump4 \n" \
"16 no padding\n" \
"32 ac vlc" \
"64 Qpel chroma"
vlc_module_begin();
add_category_hint( N_("Ffmpeg"), NULL );
#if LIBAVCODEC_BUILD >= 4611
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" );
"workaround bugs", WORAROUND_BUG_LONGTEXT );
#endif
add_bool( "ffmpeg-hurry-up", 0, NULL, "hurry up", HURRY_UP_LONGTEXT );
......@@ -238,57 +248,39 @@ static void ffmpeg_ParseBitMapInfoHeader( bitmapinfoheader_t *p_bh,
}
static void __GetFrame( videodec_thread_t *p_vdec )
{
pes_packet_t *p_pes;
data_packet_t *p_data;
byte_t *p_buffer;
static void GetPESData( u8 *p_buf, int i_max, pes_packet_t *p_pes )
{
int i_copy;
int i_count;
p_pes = GetPES( p_vdec->p_fifo );
p_vdec->i_pts = p_pes->i_pts;
data_packet_t *p_data;
while( ( !p_pes->i_nb_data )||( !p_pes->i_pes_size ) )
{
p_pes = NextPES( p_vdec->p_fifo );
}
p_vdec->i_framesize = p_pes->i_pes_size;
if( p_pes->i_nb_data == 1 )
{
p_vdec->p_framedata = p_pes->p_first->p_payload_start;
return;
}
/* get a buffer and gather all data packet */
if( p_vdec->i_buffer_size < p_pes->i_pes_size )
i_count = 0;
p_data = p_pes->p_first;
while( p_data != NULL && i_count < i_max )
{
if( p_vdec->p_buffer )
{
p_vdec->p_buffer = realloc( p_vdec->p_buffer,
p_pes->i_pes_size );
}
else
i_copy = __MIN( p_data->p_payload_end - p_data->p_payload_start,
i_max - i_count );
if( i_copy > 0 )
{
p_vdec->p_buffer = malloc( p_pes->i_pes_size );
memcpy( p_buf,
p_data->p_payload_start,
i_copy );
}
p_vdec->i_buffer_size = p_pes->i_pes_size;
}
p_buffer = p_vdec->p_framedata = p_vdec->p_buffer;
p_data = p_pes->p_first;
do
{
p_vdec->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 );
}
i_count += i_copy;
p_buf += i_copy;
}
static void __NextFrame( videodec_thread_t *p_vdec )
{
NextPES( p_vdec->p_fifo );
if( i_count < i_max )
{
memset( p_buf, 0, i_max - i_count );
}
}
/* Check if we have a Vout with good parameters */
static int ffmpeg_CheckVout( vout_thread_t *p_vout,
int i_width,
......@@ -615,13 +607,13 @@ static int InitThread( videodec_thread_t *p_vdec )
}
/* ***** Fill p_context with init values ***** */
//#if LIBAVCODEC_BUILD >= 4624
// p_vdec->p_context = avcodec_alloc_context();
//#else
#if LIBAVCODEC_BUILD >= 4624
p_vdec->p_context = avcodec_alloc_context();
#else
p_vdec->p_context = malloc( sizeof( AVCodecContext ) );
memset( p_vdec->p_context, 0, sizeof( AVCodecContext ) );
#endif
//#endif
p_vdec->p_context->width = p_vdec->format.i_width;
p_vdec->p_context->height = p_vdec->format.i_height;
......@@ -655,7 +647,7 @@ static int InitThread( videodec_thread_t *p_vdec )
p_vdec->psz_namecodec );
}
/* ***** init this codec with special data(up to now MPEG4 only) ***** */
/* ***** init this codec with special data ***** */
if( p_vdec->format.i_data )
{
AVPicture avpicture;
......@@ -670,6 +662,18 @@ static int InitThread( videodec_thread_t *p_vdec )
p_vdec->format.i_data );
break;
default:
if( p_vdec->p_fifo->i_fourcc == FOURCC_MP4S ||
p_vdec->p_fifo->i_fourcc == FOURCC_mp4s ||
p_vdec->p_fifo->i_fourcc == FOURCC_M4S2 ||
p_vdec->p_fifo->i_fourcc == FOURCC_m4s2 )
{
p_vdec->p_context->extradata_size = p_vdec->format.i_data;
p_vdec->p_context->extradata = malloc( p_vdec->format.i_data );
memcpy( p_vdec->p_context->extradata,
p_vdec->format.p_data,
p_vdec->format.i_data );
}
break;
}
}
......@@ -764,6 +768,8 @@ static int InitThread( videodec_thread_t *p_vdec )
*****************************************************************************/
static void DecodeThread( videodec_thread_t *p_vdec )
{
pes_packet_t *p_pes;
int i_frame_size;
int i_status;
int b_drawpicture;
int b_gotpicture;
......@@ -815,20 +821,42 @@ static void DecodeThread( videodec_thread_t *p_vdec )
#endif
}
__GetFrame( p_vdec );
do
{
if( !( p_pes = GetPES( p_vdec->p_fifo ) ) )
{
p_vdec->p_fifo->b_error = 1;
return;
}
p_vdec->i_pts = p_pes->i_pts;
i_frame_size = p_pes->i_pes_size;
if( i_frame_size > 0 )
{
if( p_vdec->i_buffer < i_frame_size + 16 )
{
FREE( p_vdec->p_buffer );
p_vdec->p_buffer = malloc( i_frame_size + 16 );
p_vdec->i_buffer = i_frame_size + 16;
}
GetPESData( p_vdec->p_buffer, p_vdec->i_buffer, p_pes );
}
NextPES( p_vdec->p_fifo );
} while( i_frame_size <= 0 );
i_status = avcodec_decode_video( p_vdec->p_context,
&avpicture,
&b_gotpicture,
p_vdec->p_framedata,
p_vdec->i_framesize);
p_vdec->p_buffer,
i_frame_size );
__NextFrame( p_vdec );
if( i_status < 0 )
{
msg_Warn( p_vdec->p_fifo, "cannot decode one frame (%d bytes)",
p_vdec->i_framesize );
i_frame_size );
p_vdec->i_frame_error++;
return;
}
......@@ -916,6 +944,7 @@ static void EndThread( videodec_thread_t *p_vdec )
if( p_vdec->p_context != NULL)
{
FREE( p_vdec->p_context->quant_store );
FREE( p_vdec->p_context->extradata );
avcodec_close( p_vdec->p_context );
msg_Dbg( p_vdec->p_fifo, "ffmpeg codec (%s) stopped",
p_vdec->psz_namecodec );
......
......@@ -2,7 +2,7 @@
* ffmpeg_vdec.h: video decoder using ffmpeg library
*****************************************************************************
* Copyright (C) 2001 VideoLAN
* $Id: ffmpeg.h,v 1.5 2002/10/20 17:28:01 fenrir Exp $
* $Id: ffmpeg.h,v 1.6 2002/10/24 10:33:09 fenrir Exp $
*
* Authors: Laurent Aimar <fenrir@via.ecp.fr>
*
......@@ -79,11 +79,9 @@ typedef struct videodec_thread_s
/* private */
mtime_t i_pts;
int i_framesize;
u8 *p_framedata;
u8 *p_buffer; /* buffer for gather pes */
int i_buffer_size; /* size of allocated p_framedata */
u8 *p_buffer; /* buffer for gather pes */
int i_buffer; /* size of allocated p_framedata */
} videodec_thread_t;
......
......@@ -2,7 +2,7 @@
* input_ext-dec.c: services to the decoders
*****************************************************************************
* Copyright (C) 1998-2001 VideoLAN
* $Id: input_ext-dec.c,v 1.37 2002/10/24 09:37:47 gbazin Exp $
* $Id: input_ext-dec.c,v 1.38 2002/10/24 10:33:09 fenrir Exp $
*
* Authors: Christophe Massiot <massiot@via.ecp.fr>
*
......@@ -158,6 +158,14 @@ static inline pes_packet_t * _NextPES( decoder_fifo_t * p_fifo )
{
pes_packet_t * p_next;
if( p_fifo->p_first == NULL )
{
if( GetPES( p_fifo ) == NULL )
{
return( NULL );
}
}
vlc_mutex_lock( &p_fifo->data_lock );
/* Free the previous PES packet. */
......
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