/* Video output callbacks
* XXX use decoder_NewPicture/decoder_DeletePicture
* and decoder_LinkPicture/decoder_UnlinkPicture */
+ int (*pf_vout_format_update)( decoder_t * );
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 * );
*/
+/**
+ * This function notifies the video output pipeline of a new video output
+ * format (fmt_out.video). If there is currently no video output or if the
+ * video output format has changed, a new audio video will be set up.
+ * @return 0 if the video output is working, -1 if not. */
+static inline int decoder_UpdateVideoFormat( decoder_t *dec )
+{
+ if( dec->pf_vout_format_update != NULL )
+ return dec->pf_vout_format_update( dec );
+ else
+ return -1;
+}
+
/**
* This function will return a new picture usable by a decoder as an output
* buffer. You have to release it using decoder_DeletePicture or by returning
inline static void video_del_buffer_decoder( decoder_t *, picture_t * );
inline static void video_del_buffer_filter( filter_t *, picture_t * );
+inline static int video_update_format_decoder( decoder_t *p_dec );
inline static picture_t *video_new_buffer_decoder( decoder_t * );
inline static picture_t *video_new_buffer_filter( filter_t * );
-static picture_t *video_new_buffer( vlc_object_t *, decoder_owner_sys_t *,
- es_format_t * );
+static int video_update_format( vlc_object_t *, decoder_owner_sys_t *,
+ es_format_t * );
static void video_link_picture_decoder( decoder_t *, picture_t * );
static void video_unlink_picture_decoder( decoder_t *, picture_t * );
p_sys->p_decoder->fmt_out.i_extra = 0;
p_sys->p_decoder->fmt_out.p_extra = 0;
p_sys->p_decoder->pf_decode_video = 0;
+ p_sys->p_decoder->pf_vout_format_update = video_update_format_decoder;
p_sys->p_decoder->pf_vout_buffer_new = video_new_buffer_decoder;
p_sys->p_decoder->pf_vout_buffer_del = video_del_buffer_decoder;
p_sys->p_decoder->pf_picture_link = video_link_picture_decoder;
return VLC_SUCCESS;
}
+inline static int video_update_format_decoder( decoder_t *p_dec )
+{
+ return video_update_format( VLC_OBJECT( p_dec ),
+ (decoder_owner_sys_t *)p_dec->p_owner,
+ &p_dec->fmt_out );
+}
+
inline static picture_t *video_new_buffer_decoder( decoder_t *p_dec )
{
- return video_new_buffer( VLC_OBJECT( p_dec ),
- (decoder_owner_sys_t *)p_dec->p_owner,
- &p_dec->fmt_out );
+ return picture_NewFromFormat( &p_dec->fmt_out.video );
}
inline static picture_t *video_new_buffer_filter( filter_t *p_filter )
{
- return video_new_buffer( VLC_OBJECT( p_filter ),
+ if( video_update_format( VLC_OBJECT( p_filter ),
(decoder_owner_sys_t *)p_filter->owner.sys,
- &p_filter->fmt_out );
+ &p_filter->fmt_out ) ) {
+ msg_Warn( p_filter, "can't get output picture" );
+ return NULL;
+ }
+ return picture_NewFromFormat( &p_filter->fmt_out.video );
}
-static picture_t *video_new_buffer( vlc_object_t *p_this,
+static int video_update_format( vlc_object_t *p_this,
decoder_owner_sys_t *p_sys,
es_format_t *fmt_out )
{
/* */
fmt_out->video.i_chroma = fmt_out->i_codec;
-
- return picture_NewFromFormat( &fmt_out->video );
+ return 0;
}
inline static void video_del_buffer_decoder( decoder_t *p_this,
picture_Release( p_pic );
}
-static picture_t *video_new_buffer_decoder( decoder_t *p_dec )
+static int video_update_format_decoder( decoder_t *p_dec )
{
p_dec->fmt_out.video.i_chroma = p_dec->fmt_out.i_codec;
+ return 0;
+}
+
+static picture_t *video_new_buffer_decoder( decoder_t *p_dec )
+{
return picture_NewFromFormat( &p_dec->fmt_out.video );
}
id->p_decoder->pf_decode_video = NULL;
id->p_decoder->pf_get_cc = NULL;
id->p_decoder->pf_get_cc = 0;
+ id->p_decoder->pf_vout_format_update = video_update_format_decoder;
id->p_decoder->pf_vout_buffer_new = video_new_buffer_decoder;
id->p_decoder->pf_vout_buffer_del = video_del_buffer_decoder;
id->p_decoder->pf_picture_link = video_link_picture_decoder;
static void DecoderUnsupportedCodec( decoder_t *, vlc_fourcc_t );
/* Buffers allocation callbacks for the decoders */
+static int vout_update_format( decoder_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 * );
*****************************************************************************/
picture_t *decoder_NewPicture( decoder_t *p_decoder )
{
+ if( decoder_UpdateVideoFormat( p_decoder ) )
+ return NULL;
+
picture_t *p_picture = p_decoder->pf_vout_buffer_new( p_decoder );
if( !p_picture )
msg_Warn( p_decoder, "can't get output picture" );
/* Set buffers allocation callbacks for the decoders */
p_dec->pf_aout_format_update = aout_update_format;
+ p_dec->pf_vout_format_update = vout_update_format;
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;
return 0;
}
-static picture_t *vout_new_buffer( decoder_t *p_dec )
+static int vout_update_format( decoder_t *p_dec )
{
decoder_owner_sys_t *p_owner = p_dec->p_owner;
!p_dec->fmt_out.video.i_height )
{
/* Can't create a new vout without display size */
- return NULL;
+ return -1;
}
video_format_t fmt = p_dec->fmt_out.video;
{
msg_Err( p_dec, "failed to create video output" );
p_dec->b_error = true;
- return NULL;
+ return -1;
}
}
+ return 0;
+}
+
+static picture_t *vout_new_buffer( decoder_t *p_dec )
+{
+ decoder_owner_sys_t *p_owner = p_dec->p_owner;
- /* Get a new picture
- */
for( ;; )
{
if( DecoderIsExitRequested( p_dec ) || p_dec->b_error )
return 0;
}
+static int video_update_format( decoder_t *p_dec )
+{
+ p_dec->fmt_out.video.i_chroma = p_dec->fmt_out.i_codec;
+ return 0;
+}
static picture_t *video_new_buffer( decoder_t *p_dec )
{
- p_dec->fmt_out.video.i_chroma = p_dec->fmt_out.i_codec;
return picture_NewFromFormat( &p_dec->fmt_out.video );
}
p_dec->fmt_in.video = *fmt;
p_dec->b_pace_control = true;
+ p_dec->pf_vout_format_update = video_update_format;
p_dec->pf_vout_buffer_new = video_new_buffer;
p_dec->pf_vout_buffer_del = video_del_buffer;
p_dec->pf_picture_link = video_link_picture;