From: Gildas Bazin Date: Mon, 24 Nov 2003 23:22:01 +0000 (+0000) Subject: * src/input/input_dec.c, include/vlc_codec.h: added 2 callbacks in the decoder_t... X-Git-Tag: 0.7.0~360 X-Git-Url: https://git.sesse.net/?a=commitdiff_plain;h=89fd537f7dbd6775d9fd3b6295e4a3bf1a61bbf7;p=vlc * src/input/input_dec.c, include/vlc_codec.h: added 2 callbacks in the decoder_t structure for pictures linking/unlinking. * modules/codec/libmpeg2.c: restored pictures linking/unlinking code. * modules/codec/ffmpeg/video.c: idem and reenabled direct rendering even when the hurry-up mode is activated as it doesn't seem to create a problem anymore with recent ffmpeg. --- diff --git a/include/vlc_codec.h b/include/vlc_codec.h index 0907186385..452cabc269 100644 --- a/include/vlc_codec.h +++ b/include/vlc_codec.h @@ -2,7 +2,7 @@ * vlc_codec.h: codec related structures ***************************************************************************** * Copyright (C) 1999-2003 VideoLAN - * $Id: vlc_codec.h,v 1.5 2003/11/24 00:39:00 fenrir Exp $ + * $Id: vlc_codec.h,v 1.6 2003/11/24 23:22:01 gbazin Exp $ * * Authors: Gildas Bazin * @@ -70,6 +70,8 @@ struct decoder_t /* Video output callbacks */ picture_t * ( * pf_vout_buffer_new) ( decoder_t * ); void ( * pf_vout_buffer_del) ( decoder_t *, picture_t * ); + void ( * pf_picture_link) ( decoder_t *, picture_t * ); + void ( * pf_picture_unlink) ( decoder_t *, picture_t * ); /* Private structure for the owner of the decoder */ diff --git a/modules/codec/ffmpeg/video.c b/modules/codec/ffmpeg/video.c index ab7744ee77..2baf7d9db5 100644 --- a/modules/codec/ffmpeg/video.c +++ b/modules/codec/ffmpeg/video.c @@ -2,7 +2,7 @@ * video.c: video decoder using the ffmpeg library ***************************************************************************** * Copyright (C) 1999-2001 VideoLAN - * $Id: video.c,v 1.52 2003/11/24 00:39:01 fenrir Exp $ + * $Id: video.c,v 1.53 2003/11/24 23:22:01 gbazin Exp $ * * Authors: Laurent Aimar * Gildas Bazin @@ -265,7 +265,7 @@ int E_(InitVideoDec)( decoder_t *p_dec, AVCodecContext *p_context, #endif /* ffmpeg doesn't properly release old pictures when frames are skipped */ - if( p_sys->b_hurry_up ) p_sys->b_direct_rendering = 0; + //if( p_sys->b_hurry_up ) p_sys->b_direct_rendering = 0; if( p_sys->b_direct_rendering ) { msg_Dbg( p_dec, "using direct rendering" ); @@ -686,7 +686,7 @@ static int ffmpeg_GetFrameBuf( struct AVCodecContext *p_context, if( p_ff_pic->reference != 0 ) { - //vout_LinkPicture( p_sys->p_vout, p_pic ); + p_dec->pf_picture_link( p_dec, p_pic ); } /* FIXME what is that, should give good value */ @@ -716,6 +716,6 @@ static void ffmpeg_ReleaseFrameBuf( struct AVCodecContext *p_context, if( p_ff_pic->reference != 0 ) { - //vout_UnlinkPicture( p_sys->p_vout, p_pic ); + p_dec->pf_picture_unlink( p_dec, p_pic ); } } diff --git a/modules/codec/libmpeg2.c b/modules/codec/libmpeg2.c index e827145668..2262cc17b4 100755 --- a/modules/codec/libmpeg2.c +++ b/modules/codec/libmpeg2.c @@ -2,7 +2,7 @@ * libmpeg2.c: mpeg2 video decoder module making use of libmpeg2. ***************************************************************************** * Copyright (C) 1999-2001 VideoLAN - * $Id: libmpeg2.c,v 1.34 2003/11/22 23:39:14 fenrir Exp $ + * $Id: libmpeg2.c,v 1.35 2003/11/24 23:22:01 gbazin Exp $ * * Authors: Gildas Bazin * Christophe Massiot @@ -287,7 +287,7 @@ static picture_t *DecodeBlock( decoder_t *p_dec, block_t **pp_block ) /* For some reason, libmpeg2 will put this pic twice in * discard_picture. This can be considered a bug in libmpeg2. */ - //vout_LinkPicture( p_sys->p_vout, p_pic ); + p_dec->pf_picture_link( p_dec, p_pic ); if( p_sys->p_synchro ) { @@ -376,6 +376,7 @@ static picture_t *DecodeBlock( decoder_t *p_dec, block_t **pp_block ) case STATE_END: case STATE_SLICE: + p_pic = NULL; if( p_sys->p_info->display_fbuf && p_sys->p_info->display_fbuf->id ) { @@ -396,17 +397,16 @@ static picture_t *DecodeBlock( decoder_t *p_dec, block_t **pp_block ) p_sys->p_picture_to_destroy = NULL; p_pic->date = 0; } - return p_pic; /* FIXME */ } if( p_sys->p_info->discard_fbuf && p_sys->p_info->discard_fbuf->id ) { - //p_pic = (picture_t *)p_sys->p_info->discard_fbuf->id; - //vout_UnlinkPicture( p_sys->p_vout, p_pic ); + p_dec->pf_picture_unlink( p_dec, + p_sys->p_info->discard_fbuf->id ); } - //return p_pic; /* FIXME */ + if( p_pic ) return p_pic; break; @@ -512,7 +512,7 @@ static picture_t *GetNewPicture( decoder_t *p_dec, uint8_t **pp_buf ) p_pic->i_nb_fields = p_sys->p_info->current_picture != NULL ? p_sys->p_info->current_picture->nb_fields : 2; - //vout_LinkPicture( p_sys->p_vout, p_pic ); + p_dec->pf_picture_link( p_dec, p_pic ); pp_buf[0] = p_pic->p[0].p_pixels; pp_buf[1] = p_pic->p[1].p_pixels; diff --git a/src/input/input_dec.c b/src/input/input_dec.c index 4af17995c7..2b10010eea 100644 --- a/src/input/input_dec.c +++ b/src/input/input_dec.c @@ -2,7 +2,7 @@ * input_dec.c: Functions for the management of decoders ***************************************************************************** * Copyright (C) 1999-2001 VideoLAN - * $Id: input_dec.c,v 1.78 2003/11/24 03:30:38 fenrir Exp $ + * $Id: input_dec.c,v 1.79 2003/11/24 23:22:01 gbazin Exp $ * * Authors: Christophe Massiot * Gildas Bazin @@ -51,6 +51,8 @@ static void aout_del_buffer( decoder_t *, aout_buffer_t * ); static picture_t *vout_new_buffer( decoder_t * ); static void vout_del_buffer( decoder_t *, picture_t * ); +static void vout_link_picture( decoder_t *, picture_t * ); +static void vout_unlink_picture( decoder_t *, picture_t * ); static es_format_t null_es_format = {0}; @@ -436,6 +438,8 @@ static decoder_t * CreateDecoder( input_thread_t * p_input, p_dec->pf_aout_buffer_del = aout_del_buffer; p_dec->pf_vout_buffer_new = vout_new_buffer; p_dec->pf_vout_buffer_del = vout_del_buffer; + p_dec->pf_picture_link = vout_link_picture; + p_dec->pf_picture_unlink = vout_unlink_picture; vlc_object_attach( p_dec, p_input ); @@ -589,19 +593,17 @@ static void DeleteDecoder( decoder_t * p_dec ) { int i_pic; +#define p_pic p_dec->p_owner->p_vout->render.pp_picture[i_pic] /* Hack to make sure all the the pictures are freed by the decoder */ for( i_pic = 0; i_pic < p_dec->p_owner->p_vout->render.i_pictures; i_pic++ ) { - if( p_dec->p_owner->p_vout->render.pp_picture[i_pic]->i_status == - RESERVED_PICTURE ) - vout_DestroyPicture( p_dec->p_owner->p_vout, - p_dec->p_owner->p_vout->render.pp_picture[i_pic] ); - if( p_dec->p_owner->p_vout->render.pp_picture[i_pic]->i_refcount - > 0 ) - vout_UnlinkPicture( p_dec->p_owner->p_vout, - p_dec->p_owner->p_vout->render.pp_picture[i_pic] ); + if( p_pic->i_status == RESERVED_PICTURE ) + vout_DestroyPicture( p_dec->p_owner->p_vout, p_pic ); + if( p_pic->i_refcount > 0 ) + vout_UnlinkPicture( p_dec->p_owner->p_vout, p_pic ); } +#undef p_pic /* We are about to die. Reattach video output to p_vlc. */ vout_Request( p_dec, p_dec->p_owner->p_vout, 0, 0, 0, 0 ); @@ -699,10 +701,39 @@ static picture_t *vout_new_buffer( decoder_t *p_dec ) /* Get a new picture */ while( !(p_pic = vout_CreatePicture( p_sys->p_vout, 0, 0, 0 ) ) ) { + int i_pic; + if( p_dec->b_die || p_dec->b_error ) { return NULL; } + +#define p_pic p_dec->p_owner->p_vout->render.pp_picture[i_pic] + /* Check the decoder doesn't leak pictures */ + for( i_pic = 0; i_pic < p_dec->p_owner->p_vout->render.i_pictures; + i_pic++ ) + { + if( p_pic->i_status != DISPLAYED_PICTURE && + p_pic->i_status != RESERVED_PICTURE ) break; + + if( !p_pic->i_refcount ) break; + } + if( i_pic == p_dec->p_owner->p_vout->render.i_pictures ) + { + msg_Err( p_dec, "decoder is leaking pictures, reseting the heap" ); + + /* Just free all the pictures */ + for( i_pic = 0; i_pic < p_dec->p_owner->p_vout->render.i_pictures; + i_pic++ ) + { + if( p_pic->i_status == RESERVED_PICTURE ) + vout_DestroyPicture( p_dec->p_owner->p_vout, p_pic ); + if( p_pic->i_refcount > 0 ) + vout_UnlinkPicture( p_dec->p_owner->p_vout, p_pic ); + } + } +#undef p_pic + msleep( VOUT_OUTMEM_SLEEP ); } @@ -713,3 +744,13 @@ static void vout_del_buffer( decoder_t *p_dec, picture_t *p_pic ) { vout_DestroyPicture( p_dec->p_owner->p_vout, p_pic ); } + +static void vout_link_picture( decoder_t *p_dec, picture_t *p_pic ) +{ + vout_LinkPicture( p_dec->p_owner->p_vout, p_pic ); +} + +static void vout_unlink_picture( decoder_t *p_dec, picture_t *p_pic ) +{ + vout_UnlinkPicture( p_dec->p_owner->p_vout, p_pic ); +}