Commit 79da0194 authored by Laurent Aimar's avatar Laurent Aimar

* ffmpeg: sync with latest ffmpeg cvs. As it need too much

#if LIBAVCODEC_BUILD , I've enable direct rendering only with latest
ffmpeg cvs (anyway dr isn't cleanly ported to the latest version).
parent 1b7ce269
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* video.c: video decoder using ffmpeg library * video.c: video decoder using ffmpeg library
***************************************************************************** *****************************************************************************
* Copyright (C) 1999-2001 VideoLAN * Copyright (C) 1999-2001 VideoLAN
* $Id: video.c,v 1.8 2002/11/28 17:35:00 sam Exp $ * $Id: video.c,v 1.9 2002/12/06 11:53:45 fenrir Exp $
* *
* Authors: Laurent Aimar <fenrir@via.ecp.fr> * Authors: Laurent Aimar <fenrir@via.ecp.fr>
* Gildas Bazin <gbazin@netcourrier.com> * Gildas Bazin <gbazin@netcourrier.com>
...@@ -49,53 +49,44 @@ ...@@ -49,53 +49,44 @@
/***************************************************************************** /*****************************************************************************
* Local prototypes * Local prototypes
*****************************************************************************/ *****************************************************************************/
#if LIBAVCODEC_BUILD >= 4641
static void ffmpeg_CopyPicture( picture_t *, AVVideoFrame *, vdec_thread_t * );
#else
static void ffmpeg_CopyPicture( picture_t *, AVPicture *, vdec_thread_t * ); static void ffmpeg_CopyPicture( picture_t *, AVPicture *, vdec_thread_t * );
#endif
static void ffmpeg_PostProcPicture( vdec_thread_t *, picture_t * ); static void ffmpeg_PostProcPicture( vdec_thread_t *, picture_t * );
static int ffmpeg_GetFrameBuf( struct AVCodecContext *, int, int, int );
/* FIXME FIXME some of them are wrong */ #if LIBAVCODEC_BUILD >= 4641
static int i_ffmpeg_PixFmtToChroma[] = static int ffmpeg_GetFrameBuf( struct AVCodecContext *, AVVideoFrame *);
{ static void ffmpeg_ReleaseFrameBuf( struct AVCodecContext *, AVVideoFrame *);
/* PIX_FMT_ANY = -1, PIX_FMT_YUV420P, #endif
PIX_FMT_YUV422, PIX_FMT_RGB24,
PIX_FMT_BGR24, PIX_FMT_YUV422P,
PIX_FMT_YUV444P, PIX_FMT_YUV410P
*/
0, VLC_FOURCC('I','4','2','0'),
VLC_FOURCC('I','4','2','0'), VLC_FOURCC('R','V','2','4'),
0, VLC_FOURCC('I','4','2','2'),
VLC_FOURCC('I','4','4','4'), 0
};
/***************************************************************************** /*****************************************************************************
* Local Functions * Local Functions
*****************************************************************************/ *****************************************************************************/
static inline u32 ffmpeg_PixFmtToChroma( int i_ffmpegchroma ) static inline uint32_t ffmpeg_PixFmtToChroma( int i_ff_chroma )
{ {
if( ++i_ffmpegchroma > 7 ) /* FIXME FIXME some of them are wrong */
{ switch( i_ff_chroma )
return( 0 ); {
} case PIX_FMT_YUV420P:
else case PIX_FMT_YUV422:
{ return( VLC_FOURCC('I','4','2','0') );
return( i_ffmpeg_PixFmtToChroma[i_ffmpegchroma] ); case PIX_FMT_RGB24:
} return( VLC_FOURCC('R','V','2','4') );
}
case PIX_FMT_YUV422P:
static inline int ffmpeg_FfAspect( int i_width, int i_height, int i_ffaspect ) return( VLC_FOURCC('I','4','2','2') );
{ case PIX_FMT_YUV444P:
switch( i_ffaspect ) return( VLC_FOURCC('I','4','4','4') );
{ #if LIBAVCODEC_BUILD >= 4615
case( FF_ASPECT_4_3_625 ): case PIX_FMT_YUV410P:
case( FF_ASPECT_4_3_525 ): #endif
return( VOUT_ASPECT_FACTOR * 4 / 3); case PIX_FMT_BGR24:
case( FF_ASPECT_16_9_625 ):
case( FF_ASPECT_16_9_525 ):
return( VOUT_ASPECT_FACTOR * 16 / 9 );
case( FF_ASPECT_SQUARE ):
default: default:
return( VOUT_ASPECT_FACTOR * i_width / i_height ); return( 0 );
} }
} }
...@@ -122,15 +113,12 @@ static vout_thread_t *ffmpeg_CreateVout( vdec_thread_t *p_vdec, ...@@ -122,15 +113,12 @@ static vout_thread_t *ffmpeg_CreateVout( vdec_thread_t *p_vdec,
/* It's mainly for I410 -> I420 conversion that I've made, /* It's mainly for I410 -> I420 conversion that I've made,
it's buggy and very slow */ it's buggy and very slow */
} }
#if LIBAVCODEC_BUILD >= 4640 #if LIBAVCODEC_BUILD >= 4640
i_aspect = (int) ( VOUT_ASPECT_FACTOR * p_vdec->p_context->aspect_ratio ); if( ( i_aspect = (int) ( VOUT_ASPECT_FACTOR *
p_vdec->p_context->aspect_ratio ) ) == 0 )
if( i_aspect == 0 )
{ {
i_aspect = VOUT_ASPECT_FACTOR * i_width / i_height; i_aspect = VOUT_ASPECT_FACTOR * i_width / i_height;
} }
#else #else
switch( p_vdec->p_context->aspect_ratio_info ) switch( p_vdec->p_context->aspect_ratio_info )
{ {
...@@ -141,13 +129,14 @@ static vout_thread_t *ffmpeg_CreateVout( vdec_thread_t *p_vdec, ...@@ -141,13 +129,14 @@ static vout_thread_t *ffmpeg_CreateVout( vdec_thread_t *p_vdec,
case( FF_ASPECT_16_9_625 ): case( FF_ASPECT_16_9_625 ):
case( FF_ASPECT_16_9_525 ): case( FF_ASPECT_16_9_525 ):
i_aspect = VOUT_ASPECT_FACTOR * 16 / 9 ; i_aspect = VOUT_ASPECT_FACTOR * 16 / 9 ;
break; break;
case( FF_ASPECT_SQUARE ): case( FF_ASPECT_SQUARE ):
default: default:
i_aspect = VOUT_ASPECT_FACTOR * i_width / i_height; i_aspect = VOUT_ASPECT_FACTOR * i_width / i_height;
break; break;
} }
#endif #endif
/* Spawn a video output if there is none. First we look for our children, /* Spawn a video output if there is none. First we look for our children,
* then we look for any other vout that might be available. */ * then we look for any other vout that might be available. */
p_vout = vout_Request( p_vdec->p_fifo, NULL, p_vout = vout_Request( p_vdec->p_fifo, NULL,
...@@ -161,9 +150,15 @@ static vout_thread_t *ffmpeg_CreateVout( vdec_thread_t *p_vdec, ...@@ -161,9 +150,15 @@ static vout_thread_t *ffmpeg_CreateVout( vdec_thread_t *p_vdec,
or said to me how write a better thing or said to me how write a better thing
FIXME FIXME FIXME FIXME FIXME FIXME
*/ */
#if LIBAVCODEC_BUILD >= 4641
static void ffmpeg_ConvertPictureI410toI420( picture_t *p_pic,
AVVideoFrame *p_ff_pic,
vdec_thread_t *p_vdec )
#else
static void ffmpeg_ConvertPictureI410toI420( picture_t *p_pic, static void ffmpeg_ConvertPictureI410toI420( picture_t *p_pic,
AVPicture *p_avpicture, AVPicture *p_ff_pic,
vdec_thread_t *p_vdec ) vdec_thread_t *p_vdec )
#endif
{ {
u8 *p_src, *p_dst; u8 *p_src, *p_dst;
u8 *p_plane[3]; u8 *p_plane[3];
...@@ -177,24 +172,24 @@ static void ffmpeg_ConvertPictureI410toI420( picture_t *p_pic, ...@@ -177,24 +172,24 @@ static void ffmpeg_ConvertPictureI410toI420( picture_t *p_pic,
i_width = p_vdec->p_context->width; i_width = p_vdec->p_context->width;
p_dst = p_pic->p[0].p_pixels; p_dst = p_pic->p[0].p_pixels;
p_src = p_avpicture->data[0]; p_src = p_ff_pic->data[0];
/* copy first plane */ /* copy first plane */
for( i_y = 0; i_y < i_height; i_y++ ) for( i_y = 0; i_y < i_height; i_y++ )
{ {
p_vdec->p_fifo->p_vlc->pf_memcpy( p_dst, p_src, i_width); p_vdec->p_fifo->p_vlc->pf_memcpy( p_dst, p_src, i_width);
p_dst += p_pic->p[0].i_pitch; p_dst += p_pic->p[0].i_pitch;
p_src += p_avpicture->linesize[0]; p_src += p_ff_pic->linesize[0];
} }
/* process each plane in a temporary buffer */ /* process each plane in a temporary buffer */
for( i_plane = 1; i_plane < 3; i_plane++ ) for( i_plane = 1; i_plane < 3; i_plane++ )
{ {
i_stride = p_avpicture->linesize[i_plane]; i_stride = p_ff_pic->linesize[i_plane];
i_lines = i_height / 4; i_lines = i_height / 4;
p_dst = p_plane[i_plane] = malloc( i_lines * i_stride * 2 * 2 ); p_dst = p_plane[i_plane] = malloc( i_lines * i_stride * 2 * 2 );
p_src = p_avpicture->data[i_plane]; p_src = p_ff_pic->data[i_plane];
/* for each source line */ /* for each source line */
for( i_y = 0; i_y < i_lines; i_y++ ) for( i_y = 0; i_y < i_lines; i_y++ )
...@@ -215,7 +210,7 @@ static void ffmpeg_ConvertPictureI410toI420( picture_t *p_pic, ...@@ -215,7 +210,7 @@ static void ffmpeg_ConvertPictureI410toI420( picture_t *p_pic,
for( i_plane = 1; i_plane < 3; i_plane++ ) for( i_plane = 1; i_plane < 3; i_plane++ )
{ {
i_stride = p_avpicture->linesize[i_plane]; i_stride = p_ff_pic->linesize[i_plane];
i_lines = i_height / 4; i_lines = i_height / 4;
p_dst = p_plane[i_plane] + 2*i_stride; p_dst = p_plane[i_plane] + 2*i_stride;
...@@ -277,6 +272,11 @@ static void ffmpeg_ConvertPictureI410toI420( picture_t *p_pic, ...@@ -277,6 +272,11 @@ static void ffmpeg_ConvertPictureI410toI420( picture_t *p_pic,
int E_( InitThread_Video )( vdec_thread_t *p_vdec ) int E_( InitThread_Video )( vdec_thread_t *p_vdec )
{ {
int i_tmp; int i_tmp;
#if LIBAVCODEC_BUILD >= 4641
p_vdec->p_ff_pic = avcodec_alloc_picture();
#else
p_vdec->p_ff_pic = &p_vdec->ff_pic;
#endif
if( p_vdec->p_fifo->p_demux_data ) if( p_vdec->p_fifo->p_demux_data )
{ {
...@@ -311,19 +311,20 @@ int E_( InitThread_Video )( vdec_thread_t *p_vdec ) ...@@ -311,19 +311,20 @@ int E_( InitThread_Video )( vdec_thread_t *p_vdec )
p_vdec->b_hurry_up = config_GetInt(p_vdec->p_fifo, "ffmpeg-hurry-up"); p_vdec->b_hurry_up = config_GetInt(p_vdec->p_fifo, "ffmpeg-hurry-up");
p_vdec->p_lastpic = NULL;
p_vdec->p_secondlastpic = NULL;
p_vdec->b_direct_rendering = 0; p_vdec->b_direct_rendering = 0;
#if LIBAVCODEC_BUILD > 4615
if( (p_vdec->p_codec->capabilities & CODEC_CAP_DR1) #if LIBAVCODEC_BUILD >= 4641
&& (p_vdec->p_context->pix_fmt != PIX_FMT_YUV410P) && if( config_GetInt( p_vdec->p_fifo, "ffmpeg-dr" ) &&
config_GetInt( p_vdec->p_fifo, "ffmpeg-dr" ) ) p_vdec->p_codec->capabilities & CODEC_CAP_DR1 &&
p_vdec->p_context->pix_fmt != PIX_FMT_YUV410P ) /* <- FIXME */
{ {
msg_Dbg( p_vdec->p_fifo, "using direct rendering" ); msg_Dbg( p_vdec->p_fifo, "using direct rendering" );
p_vdec->b_direct_rendering = 1; p_vdec->b_direct_rendering = 1;
p_vdec->p_context->flags|= CODEC_FLAG_EMU_EDGE | CODEC_FLAG_DR1; p_vdec->p_context->flags|= CODEC_FLAG_EMU_EDGE;
p_vdec->p_context->get_buffer_callback = ffmpeg_GetFrameBuf; p_vdec->p_context->get_buffer = ffmpeg_GetFrameBuf;
p_vdec->p_context->release_buffer = ffmpeg_ReleaseFrameBuf;
p_vdec->p_context->opaque = p_vdec; p_vdec->p_context->opaque = p_vdec;
} }
#endif #endif
...@@ -354,13 +355,12 @@ int E_( InitThread_Video )( vdec_thread_t *p_vdec ) ...@@ -354,13 +355,12 @@ int E_( InitThread_Video )( vdec_thread_t *p_vdec )
if( p_vdec->p_format && if( p_vdec->p_format &&
p_vdec->p_format->biSize > sizeof(BITMAPINFOHEADER) ) p_vdec->p_format->biSize > sizeof(BITMAPINFOHEADER) )
{ {
AVPicture avpicture;
int b_gotpicture; int b_gotpicture;
switch( p_vdec->i_codec_id ) switch( p_vdec->i_codec_id )
{ {
case( CODEC_ID_MPEG4 ): case( CODEC_ID_MPEG4 ):
avcodec_decode_video( p_vdec->p_context, &avpicture, avcodec_decode_video( p_vdec->p_context, p_vdec->p_ff_pic,
&b_gotpicture, &b_gotpicture,
(void *)&p_vdec->p_format[1], (void *)&p_vdec->p_format[1],
p_vdec->p_format->biSize p_vdec->p_format->biSize
...@@ -450,11 +450,6 @@ int E_( InitThread_Video )( vdec_thread_t *p_vdec ) ...@@ -450,11 +450,6 @@ int E_( InitThread_Video )( vdec_thread_t *p_vdec )
config_GetInt( p_vdec->p_fifo, "ffmpeg-pp-q" ), config_GetInt( p_vdec->p_fifo, "ffmpeg-pp-q" ),
config_GetInt( p_vdec->p_fifo, "ffmpeg-pp-auto" ) 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 #else
p_vdec->i_pp_mode = 0; p_vdec->i_pp_mode = 0;
...@@ -488,7 +483,6 @@ void E_( DecodeThread_Video )( vdec_thread_t *p_vdec ) ...@@ -488,7 +483,6 @@ void E_( DecodeThread_Video )( vdec_thread_t *p_vdec )
int i_used; int i_used;
int b_drawpicture; int b_drawpicture;
int b_gotpicture; int b_gotpicture;
AVPicture avpicture; /* ffmpeg picture */
picture_t *p_pic; /* videolan picture */ picture_t *p_pic; /* videolan picture */
mtime_t i_pts; mtime_t i_pts;
...@@ -496,7 +490,6 @@ void E_( DecodeThread_Video )( vdec_thread_t *p_vdec ) ...@@ -496,7 +490,6 @@ void E_( DecodeThread_Video )( vdec_thread_t *p_vdec )
/* A good idea could be to decode all I pictures and see for the other */ /* A good idea could be to decode all I pictures and see for the other */
if( ( p_vdec->b_hurry_up )&& ( p_vdec->i_frame_late > 4 ) ) if( ( p_vdec->b_hurry_up )&& ( p_vdec->i_frame_late > 4 ) )
{ {
#if LIBAVCODEC_BUILD > 4603
b_drawpicture = 0; b_drawpicture = 0;
if( p_vdec->i_frame_late < 8 ) if( p_vdec->i_frame_late < 8 )
{ {
...@@ -510,27 +503,11 @@ void E_( DecodeThread_Video )( vdec_thread_t *p_vdec ) ...@@ -510,27 +503,11 @@ void E_( DecodeThread_Video )( vdec_thread_t *p_vdec )
input_ExtractPES( p_vdec->p_fifo, NULL ); input_ExtractPES( p_vdec->p_fifo, NULL );
return; return;
} }
#else
if( p_vdec->i_frame_late < 8 )
{
b_drawpicture = 0; /* not really good but .. UPGRADE FFMPEG !! */
}
else
{
/* too much late picture, won't decode
but break picture until a new I, and for mpeg4 ...*/
p_vdec->i_frame_late--; /* needed else it will never be decrease */
input_ExtractPES( p_vdec->p_fifo, NULL );
return;
}
#endif
} }
else else
{ {
b_drawpicture = 1; b_drawpicture = 1;
#if LIBAVCODEC_BUILD > 4603
p_vdec->p_context->hurry_up = 0; p_vdec->p_context->hurry_up = 0;
#endif
} }
do do
...@@ -600,7 +577,7 @@ void E_( DecodeThread_Video )( vdec_thread_t *p_vdec ) ...@@ -600,7 +577,7 @@ void E_( DecodeThread_Video )( vdec_thread_t *p_vdec )
usenextdata: usenextdata:
i_used = avcodec_decode_video( p_vdec->p_context, i_used = avcodec_decode_video( p_vdec->p_context,
&avpicture, p_vdec->p_ff_pic,
&b_gotpicture, &b_gotpicture,
p_vdec->p_buffer, p_vdec->p_buffer,
i_frame_size ); i_frame_size );
...@@ -654,7 +631,7 @@ usenextdata: ...@@ -654,7 +631,7 @@ usenextdata:
p_vdec->i_frame_late = 0; p_vdec->i_frame_late = 0;
} }
if( !b_gotpicture || avpicture.linesize[0] == 0 || !b_drawpicture ) if( !b_gotpicture || p_vdec->p_ff_pic->linesize[0] == 0 || !b_drawpicture )
{ {
return; return;
} }
...@@ -679,20 +656,24 @@ usenextdata: ...@@ -679,20 +656,24 @@ usenextdata:
msleep( VOUT_OUTMEM_SLEEP ); msleep( VOUT_OUTMEM_SLEEP );
} }
/* fill p_picture_t from avpicture, do I410->I420 if needed */ /* fill p_picture_t from AVVideoFrame, do I410->I420 if needed */
ffmpeg_CopyPicture( p_pic, &avpicture, p_vdec ); ffmpeg_CopyPicture( p_pic, p_vdec->p_ff_pic, p_vdec );
} }
else else
{ {
#if LIBAVCODEC_BUILD > 4615 #if LIBAVCODEC_BUILD >= 4641
p_pic = (picture_t *)p_vdec->p_context->dr_opaque_frame; p_pic = (picture_t *)p_vdec->p_ff_pic->opaque;
#else
p_pic = NULL; /* f**ck gcc warning */
#endif #endif
} }
/* Do post-processing if requested */ /* Do post-processing if requested */
ffmpeg_PostProcPicture( p_vdec, p_pic ); /* XXX: with dr it is not a good thing if the picture will be used as
reference... */
ffmpeg_PostProcPicture( p_vdec, p_pic );
/* Send decoded frame to vout */ /* fix date calculation */
if( p_vdec->pts > 0 ) if( p_vdec->pts > 0 )
{ {
i_pts = p_vdec->pts; i_pts = p_vdec->pts;
...@@ -714,11 +695,12 @@ usenextdata: ...@@ -714,11 +695,12 @@ usenextdata:
p_pic, p_pic,
i_pts ); i_pts );
/* Send decoded frame to vout */
vout_DisplayPicture( p_vdec->p_vout, p_pic ); vout_DisplayPicture( p_vdec->p_vout, p_pic );
if( i_frame_size > 0 ) if( i_frame_size > 0 )
{ {
goto usenextdata; goto usenextdata; /* try to use all data */
} }
} }
...@@ -730,10 +712,6 @@ usenextdata: ...@@ -730,10 +712,6 @@ usenextdata:
*****************************************************************************/ *****************************************************************************/
void E_( EndThread_Video )( vdec_thread_t *p_vdec ) void E_( EndThread_Video )( vdec_thread_t *p_vdec )
{ {
if( p_vdec->p_secondlastpic )
vout_UnlinkPicture( p_vdec->p_vout, p_vdec->p_secondlastpic );
if( p_vdec->p_lastpic )
vout_UnlinkPicture( p_vdec->p_vout, p_vdec->p_lastpic );
if( p_vdec->p_pp ) if( p_vdec->p_pp )
{ {
...@@ -743,6 +721,13 @@ void E_( EndThread_Video )( vdec_thread_t *p_vdec ) ...@@ -743,6 +721,13 @@ void E_( EndThread_Video )( vdec_thread_t *p_vdec )
p_vdec->p_pp = NULL; p_vdec->p_pp = NULL;
} }
#if LIBAVCODEC_BUILD >= 4641
if( p_vdec->p_ff_pic )
{
free( p_vdec->p_ff_pic );
}
#endif
/* We are about to die. Reattach video output to p_vlc. */ /* We are about to die. Reattach video output to p_vlc. */
vout_Request( p_vdec->p_fifo, p_vdec->p_vout, 0, 0, 0, 0 ); vout_Request( p_vdec->p_fifo, p_vdec->p_vout, 0, 0, 0, 0 );
} }
...@@ -751,8 +736,15 @@ void E_( EndThread_Video )( vdec_thread_t *p_vdec ) ...@@ -751,8 +736,15 @@ void E_( EndThread_Video )( vdec_thread_t *p_vdec )
* ffmpeg_CopyPicture: copy a picture from ffmpeg internal buffers to a * ffmpeg_CopyPicture: copy a picture from ffmpeg internal buffers to a
* picture_t structure (when not in direct rendering mode). * picture_t structure (when not in direct rendering mode).
*****************************************************************************/ *****************************************************************************/
static void ffmpeg_CopyPicture( picture_t *p_pic, AVPicture *p_avpicture, #if LIBAVCODEC_BUILD >= 4641
static void ffmpeg_CopyPicture( picture_t *p_pic,
AVVideoFrame *p_ff_pic,
vdec_thread_t *p_vdec )
#else
static void ffmpeg_CopyPicture( picture_t *p_pic,
AVPicture *p_ff_pic,
vdec_thread_t *p_vdec ) vdec_thread_t *p_vdec )
#endif
{ {
int i_plane; int i_plane;
int i_size; int i_size;
...@@ -767,9 +759,9 @@ static void ffmpeg_CopyPicture( picture_t *p_pic, AVPicture *p_avpicture, ...@@ -767,9 +759,9 @@ static void ffmpeg_CopyPicture( picture_t *p_pic, AVPicture *p_avpicture,
{ {
for( i_plane = 0; i_plane < p_pic->i_planes; i_plane++ ) for( i_plane = 0; i_plane < p_pic->i_planes; i_plane++ )
{ {
p_src = p_avpicture->data[i_plane]; p_src = p_ff_pic->data[i_plane];
p_dst = p_pic->p[i_plane].p_pixels; p_dst = p_pic->p[i_plane].p_pixels;
i_src_stride = p_avpicture->linesize[i_plane]; i_src_stride = p_ff_pic->linesize[i_plane];
i_dst_stride = p_pic->p[i_plane].i_pitch; i_dst_stride = p_pic->p[i_plane].i_pitch;
i_size = __MIN( i_src_stride, i_dst_stride ); i_size = __MIN( i_src_stride, i_dst_stride );
...@@ -788,7 +780,7 @@ static void ffmpeg_CopyPicture( picture_t *p_pic, AVPicture *p_avpicture, ...@@ -788,7 +780,7 @@ static void ffmpeg_CopyPicture( picture_t *p_pic, AVPicture *p_avpicture,
{ {
#if LIBAVCODEC_BUILD >= 4615 #if LIBAVCODEC_BUILD >= 4615
case( PIX_FMT_YUV410P ): case( PIX_FMT_YUV410P ):
ffmpeg_ConvertPictureI410toI420( p_pic, p_avpicture, p_vdec ); ffmpeg_ConvertPictureI410toI420( p_pic, p_ff_pic, p_vdec );
break; break;
#endif #endif
default: default:
...@@ -803,35 +795,40 @@ static void ffmpeg_CopyPicture( picture_t *p_pic, AVPicture *p_avpicture, ...@@ -803,35 +795,40 @@ static void ffmpeg_CopyPicture( picture_t *p_pic, AVPicture *p_avpicture,
*****************************************************************************/ *****************************************************************************/
static void ffmpeg_PostProcPicture( vdec_thread_t *p_vdec, picture_t *p_pic ) static void ffmpeg_PostProcPicture( vdec_thread_t *p_vdec, picture_t *p_pic )
{ {
#if LIBAVCODEC_BUILD > 4313
if( ( p_vdec->i_pp_mode )&& if( ( p_vdec->i_pp_mode )&&
( ( p_vdec->p_vout->render.i_chroma == ( ( p_vdec->p_vout->render.i_chroma ==
VLC_FOURCC( 'I','4','2','0' ) )|| VLC_FOURCC( 'I','4','2','0' ) )||
( p_vdec->p_vout->render.i_chroma == ( p_vdec->p_vout->render.i_chroma ==
VLC_FOURCC( 'Y','V','1','2' ) ) ) ) VLC_FOURCC( 'Y','V','1','2' ) ) ) )
{ {
/* Make postproc */ #if LIBAVCODEC_BUILD >= 4641
/* Make postproc */
p_vdec->p_pp->pf_postprocess( p_pic,
p_vdec->p_ff_pic->qscale_table,
p_vdec->p_ff_pic->qstride,
p_vdec->i_pp_mode );
#elif LIBAVCODEC_BUILD >= 4633
p_vdec->p_pp->pf_postprocess( p_pic, p_vdec->p_pp->pf_postprocess( p_pic,
p_vdec->p_context->display_qscale_table, p_vdec->p_context->display_qscale_table,
// p_vdec->p_context->current_qscale_table,
p_vdec->p_context->qstride, p_vdec->p_context->qstride,
p_vdec->i_pp_mode ); p_vdec->i_pp_mode );
}
#endif #endif
}
} }
#if LIBAVCODEC_BUILD >= 4641
/***************************************************************************** /*****************************************************************************
* ffmpeg_GetFrameBuf: callback used by ffmpeg to get a frame buffer. * ffmpeg_GetFrameBuf: callback used by ffmpeg to get a frame buffer.
* (used for direct rendering) * (used for direct rendering)
*****************************************************************************/ *****************************************************************************/
static int ffmpeg_GetFrameBuf( struct AVCodecContext *avctx, int width,
int height, int pict_type ) static int ffmpeg_GetFrameBuf( struct AVCodecContext *p_context,
AVVideoFrame *p_ff_pic )
{ {
#if LIBAVCODEC_BUILD > 4615 vdec_thread_t *p_vdec = (vdec_thread_t *)p_context->opaque;
vdec_thread_t *p_vdec = (vdec_thread_t *)avctx->opaque;
picture_t *p_pic; picture_t *p_pic;
/* Check our vout */ /* Check and (re)create if needed our vout */
p_vdec->p_vout = ffmpeg_CreateVout( p_vdec, p_vdec->p_context ); p_vdec->p_vout = ffmpeg_CreateVout( p_vdec, p_vdec->p_context );
if( !p_vdec->p_vout ) if( !p_vdec->p_vout )
{ {
...@@ -839,6 +836,7 @@ static int ffmpeg_GetFrameBuf( struct AVCodecContext *avctx, int width, ...@@ -839,6 +836,7 @@ static int ffmpeg_GetFrameBuf( struct AVCodecContext *avctx, int width,
p_vdec->p_fifo->b_error = 1; /* abort */ p_vdec->p_fifo->b_error = 1; /* abort */
return -1; return -1;
} }
p_vdec->p_vout->render.b_allow_modify_pics = 0;
/* Get a new picture */ /* Get a new picture */
while( !(p_pic = vout_CreatePicture( p_vdec->p_vout, 0, 0, 0 ) ) ) while( !(p_pic = vout_CreatePicture( p_vdec->p_vout, 0, 0, 0 ) ) )
...@@ -849,32 +847,47 @@ static int ffmpeg_GetFrameBuf( struct AVCodecContext *avctx, int width, ...@@ -849,32 +847,47 @@ static int ffmpeg_GetFrameBuf( struct AVCodecContext *avctx, int width,
} }
msleep( VOUT_OUTMEM_SLEEP ); msleep( VOUT_OUTMEM_SLEEP );
} }
p_vdec->p_context->draw_horiz_band= NULL;
p_ff_pic->opaque = (void*)p_pic;
p_ff_pic->data[0] = p_pic->p[0].p_pixels;
p_ff_pic->data[1] = p_pic->p[1].p_pixels;
p_ff_pic->data[2] = p_pic->p[2].p_pixels;
p_ff_pic->data[3] = NULL; /* alpha channel but I'm not sure */
p_ff_pic->linesize[0] = p_pic->p[0].i_pitch;
p_ff_pic->linesize[1] = p_pic->p[1].i_pitch;
p_ff_pic->linesize[2] = p_pic->p[2].i_pitch;
p_ff_pic->linesize[3] = 0;
if( p_ff_pic->reference != 0 )
{
vout_LinkPicture( p_vdec->p_vout, p_pic );
}
/* FIXME what is that, should give good value */
p_ff_pic->age = 256*256*256*64; // FIXME FIXME from ffmpeg
/* FIXME: We keep the last picture linked until the current one is decoded, return( 0 );
* this trick won't work with streams with B frames though. */ }
vout_LinkPicture( p_vdec->p_vout, p_pic );
if( p_vdec->p_secondlastpic ) static void ffmpeg_ReleaseFrameBuf( struct AVCodecContext *p_context,
vout_UnlinkPicture( p_vdec->p_vout, p_vdec->p_secondlastpic ); AVVideoFrame *p_ff_pic )
p_vdec->p_secondlastpic = p_vdec->p_lastpic; {
p_vdec->p_lastpic = p_pic; vdec_thread_t *p_vdec = (vdec_thread_t *)p_context->opaque;
picture_t *p_pic;
avctx->draw_horiz_band= NULL; //msg_Dbg( p_vdec->p_fifo, "ffmpeg_ReleaseFrameBuf" );
avctx->dr_buffer[0]= p_pic->p[0].p_pixels; p_pic = (picture_t*)p_ff_pic->opaque;
avctx->dr_buffer[1]= p_pic->p[1].p_pixels;
avctx->dr_buffer[2]= p_pic->p[2].p_pixels;
avctx->dr_stride = p_pic->p[0].i_pitch; p_ff_pic->data[0] = NULL;
avctx->dr_uvstride = p_pic->p[1].i_pitch; p_ff_pic->data[1] = NULL;
p_ff_pic->data[2] = NULL;
p_ff_pic->data[3] = NULL;
avctx->dr_opaque_frame = p_pic; vout_UnlinkPicture( p_vdec->p_vout, p_pic );
}
/* This variable is used to determine if a macro-block to be written
* can be skipped. The idea behind this is that if a macro-block hasn't
* changed and all the frame-buffers already have the value of this
* macro-block, then we don't need to write it again. */
avctx->dr_ip_buffer_count = p_vdec->p_vout->render.i_pictures;
p_vdec->p_vout->render.b_allow_modify_pics = 0;
return 0;
#endif #endif
}
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* video.h: video decoder using ffmpeg library * video.h: video decoder using ffmpeg library
***************************************************************************** *****************************************************************************
* Copyright (C) 1999-2001 VideoLAN * Copyright (C) 1999-2001 VideoLAN
* $Id: video.h,v 1.4 2002/11/27 12:41:45 fenrir Exp $ * $Id: video.h,v 1.5 2002/12/06 11:53:45 fenrir Exp $
* *
* Authors: Laurent Aimar <fenrir@via.ecp.fr> * Authors: Laurent Aimar <fenrir@via.ecp.fr>
* *
...@@ -24,7 +24,11 @@ ...@@ -24,7 +24,11 @@
typedef struct vdec_thread_s typedef struct vdec_thread_s
{ {
DECODER_THREAD_COMMON DECODER_THREAD_COMMON
#if LIBAVCODEC_BUILD >= 4641
AVVideoFrame *p_ff_pic;
#else
AVPicture ff_pic, *p_ff_pic;
#endif
BITMAPINFOHEADER *p_format; BITMAPINFOHEADER *p_format;
vout_thread_t *p_vout; vout_thread_t *p_vout;
...@@ -43,8 +47,6 @@ typedef struct vdec_thread_s ...@@ -43,8 +47,6 @@ typedef struct vdec_thread_s
/* for direct rendering */ /* for direct rendering */
int b_direct_rendering; int b_direct_rendering;
picture_t *p_lastpic;
picture_t *p_secondlastpic;
} vdec_thread_t; } vdec_thread_t;
......
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