Commit 0925ed0b authored by Laurent Aimar's avatar Laurent Aimar

* src/video_output/video_output.c : do not use FIND_ANYWHERE to catch

 the playlist.  but use FIND_PARENT. vlc_object_find  with FIND_ANYWHERE
 use p_obj->p_vlc as a starting point  and that doesn't work as playlist
 is  detach from  vlc before  vout is  destroyed by  the decoders  (when
 shutting down)  Perhaps vlc_object_find  should be  fixing to  find the
 root object, but I'm not sure.

 * src/input/*  : move  subtitle handling  from avi  to input.  Now subs
 should works with all file types _BUT_ won't be in synch if the demuxer
 doesn't implement a _precise_ DEMUX_GET_TIME.  So only .avi, .mp4 will
 be ok. Others could works if perfectly cbr.
  Now  Subtitle  track is  only  selected  when specified  by  sub-file
 option.(auto-dectected file is always added but not selected by default)
  Btw, the code could support multiple  subs files, but I don't know how
 to pass multiple filenames, any ideas ?


 * demux/mpeg/mpga.c : play with es_out_t. I'm investigating for now so
 don't use that elsewhere.
parent a903f128
......@@ -4,7 +4,7 @@
* control the pace of reading.
*****************************************************************************
* Copyright (C) 1999, 2000 VideoLAN
* $Id: input_ext-intf.h,v 1.95 2003/09/12 18:34:44 fenrir Exp $
* $Id: input_ext-intf.h,v 1.96 2003/09/13 17:42:15 fenrir Exp $
*
* Authors: Christophe Massiot <massiot@via.ecp.fr>
*
......@@ -346,6 +346,9 @@ struct input_thread_t
char * psz_name;
count_t c_loops;
/* private, do not touch it */
input_thread_sys_t *p_sys;
};
/* Input methods */
......
......@@ -2,7 +2,7 @@
* ninput.h
*****************************************************************************
* Copyright (C) 1999-2001 VideoLAN
* $Id: ninput.h,v 1.10 2003/09/12 18:34:44 fenrir Exp $
* $Id: ninput.h,v 1.11 2003/09/13 17:42:15 fenrir Exp $
*
* Authors: Laurent Aimar <fenrir@via.ecp.fr>
*
......@@ -36,9 +36,9 @@ typedef struct
int i_cat;
vlc_fourcc_t i_codec;
int i_group; /* eg -1. if >= 0 then a "group" (program) is
created for each value */
int i_group; /* -1 : standalone
>= 0 then a "group" (program) is created
for each value */
int i_priority; /* -2 : mean not selectable by the users
-1 : mean not selected by default even
when no other stream
......@@ -78,7 +78,7 @@ static inline void es_format_Init( es_format_t *fmt,
{
fmt->i_cat = i_cat;
fmt->i_codec = i_codec;
fmt->i_group = -1;
fmt->i_group = 0;
fmt->i_priority = 0;
fmt->psz_language = NULL;
fmt->psz_description = NULL;
......@@ -213,7 +213,9 @@ enum demux_query_e
DEMUX_GET_TIME, /* arg1= int64_t * res= */
DEMUX_SET_TIME, /* arg1= int64_t res=can fail */
DEMUX_GET_LENGTH /* arg1= int64_t * res=can fail */
DEMUX_GET_LENGTH, /* arg1= int64_t * res=can fail */
DEMUX_GET_FPS /* arg1= float * res=can fail */
};
......
......@@ -3,7 +3,7 @@
* Collection of useful common types and macros definitions
*****************************************************************************
* Copyright (C) 1998, 1999, 2000 VideoLAN
* $Id: vlc_common.h,v 1.77 2003/09/12 18:34:44 fenrir Exp $
* $Id: vlc_common.h,v 1.78 2003/09/13 17:42:15 fenrir Exp $
*
* Authors: Samuel Hocevar <sam@via.ecp.fr>
* Vincent Seguin <seguin@via.ecp.fr>
......@@ -211,6 +211,7 @@ typedef struct intf_channel_t intf_channel_t;
/* Input */
typedef struct input_thread_t input_thread_t;
typedef struct input_thread_sys_t input_thread_sys_t;
typedef struct input_channel_t input_channel_t;
typedef struct input_area_t input_area_t;
typedef struct input_buffers_t input_buffers_t;
......
......@@ -2,7 +2,7 @@
* avi.c : AVI file Stream input module for vlc
*****************************************************************************
* Copyright (C) 2001 VideoLAN
* $Id: avi.c,v 1.61 2003/09/12 16:26:40 fenrir Exp $
* $Id: avi.c,v 1.62 2003/09/13 17:42:15 fenrir Exp $
* Authors: Laurent Aimar <fenrir@via.ecp.fr>
*
* This program is free software; you can redistribute it and/or modify
......@@ -29,8 +29,6 @@
#include <vlc/input.h>
#include "codecs.h"
#include "../util/sub.h"
#include "libavi.h"
#include "avi.h"
......@@ -123,7 +121,6 @@ static int Open( vlc_object_t * p_this )
demux_sys_t *p_avi;
es_descriptor_t *p_es = NULL; /* avoid warning */
unsigned int i;
mtime_t i_microsecperframe = 0; // for some subtitle format
vlc_bool_t b_stream_audio, b_stream_video;
uint8_t *p_peek;
......@@ -377,12 +374,6 @@ static int Open( vlc_object_t * p_this )
input_AddInfo( p_cat, _("Bits Per Pixel"), "%d",
p_avi_strf_vids->p_bih->biBitCount );
}
if( i_microsecperframe == 0 )
{
i_microsecperframe = (mtime_t)1000000 *
(mtime_t)p_info->i_scale /
(mtime_t)p_info->i_rate;
}
break;
default:
msg_Warn( p_input, "stream[%d] unknown type", i );
......@@ -424,11 +415,6 @@ static int Open( vlc_object_t * p_this )
#undef p_info
}
if( ( p_avi->p_sub = subtitle_New( p_input, NULL, i_microsecperframe ) ) )
{
subtitle_Select( p_avi->p_sub );
}
if( config_GetInt( p_input, "avi-index" ) )
{
if( p_avi->b_seekable )
......@@ -572,10 +558,6 @@ static void Close ( vlc_object_t * p_this )
}
}
FREE( p_avi->pp_info );
if( p_avi->p_sub )
{
subtitle_Close( p_avi->p_sub );
}
AVI_ChunkFreeRoot( p_input->s, &p_avi->ck_root );
free( p_avi );
......@@ -658,11 +640,6 @@ static int Demux_Seekable( input_thread_t *p_input )
p_avi->i_time += 25*1000; /* read 25ms */
if( p_avi->p_sub )
{
subtitle_Demux( p_avi->p_sub, p_avi->i_time );
}
/* Check if we need to send the audio data to decoder */
b_play_audio = !p_input->stream.control.b_mute;
......@@ -1227,6 +1204,7 @@ static int Seek( input_thread_t *p_input, mtime_t i_date, int i_percent )
static int Control( input_thread_t *p_input, int i_query, va_list args )
{
demux_sys_t *p_sys = p_input->p_demux_data;
int i;
double f, *pf;
int64_t i64, *pi64;
......@@ -1276,10 +1254,6 @@ static int Control( input_thread_t *p_input, int i_query, va_list args )
f = (double)va_arg( args, double );
i64 = (mtime_t)(1000000.0 * p_sys->i_length * f );
i_ret = Seek( p_input, i64, (int)(f * 100) );
if( p_sys->p_sub )
{
subtitle_Seek( p_sys->p_sub, p_sys->i_time );
}
return i_ret;
}
else
......@@ -1301,6 +1275,21 @@ static int Control( input_thread_t *p_input, int i_query, va_list args )
*pi64 = p_sys->i_length * (mtime_t)1000000;
return VLC_SUCCESS;
case DEMUX_GET_FPS:
pf = (double*)va_arg( args, double * );
*pf = 0.0;
for( i = 0; i < (int)p_sys->i_streams; i++ )
{
#define tk p_sys->pp_info[i]
if( tk->i_cat == VIDEO_ES && tk->i_scale > 0)
{
*pf = (float)tk->i_rate / (float)tk->i_scale;
break;
}
#undef tk
}
return VLC_SUCCESS;
default:
return demux_vaControlDefault( p_input, i_query, args );
}
......
......@@ -2,7 +2,7 @@
* avi.h : AVI file Stream input module for vlc
*****************************************************************************
* Copyright (C) 2001 VideoLAN
* $Id: avi.h,v 1.14 2003/09/12 16:26:40 fenrir Exp $
* $Id: avi.h,v 1.15 2003/09/13 17:42:15 fenrir Exp $
* Authors: Laurent Aimar <fenrir@via.ecp.fr>
*
* This program is free software; you can redistribute it and/or modify
......@@ -85,7 +85,5 @@ struct demux_sys_t
/* number of streams and information */
unsigned int i_streams;
avi_stream_t **pp_info;
subtitle_demux_t *p_sub;
};
......@@ -2,7 +2,7 @@
* mp4.c : MP4 file input module for vlc
*****************************************************************************
* Copyright (C) 2001 VideoLAN
* $Id: mp4.c,v 1.37 2003/09/12 16:26:40 fenrir Exp $
* $Id: mp4.c,v 1.38 2003/09/13 17:42:16 fenrir Exp $
* Authors: Laurent Aimar <fenrir@via.ecp.fr>
*
* This program is free software; you can redistribute it and/or modify
......@@ -618,7 +618,9 @@ static int Control ( input_thread_t *p_input, int i_query, va_list args )
(mtime_t)p_sys->i_duration /
(mtime_t)p_sys->i_timescale;
return VLC_SUCCESS;
case DEMUX_GET_FPS:
msg_Warn( p_input, "DEMUX_GET_FPS unimplemented !!" );
return VLC_EGENERIC;
default:
msg_Err( p_input, "control query unimplemented !!!" );
return demux_vaControlDefault( p_input, i_query, args );
......
......@@ -2,7 +2,7 @@
* mpga.c : MPEG-I/II Audio input module for vlc
*****************************************************************************
* Copyright (C) 2001 VideoLAN
* $Id: mpga.c,v 1.5 2003/09/12 16:26:40 fenrir Exp $
* $Id: mpga.c,v 1.6 2003/09/13 17:42:16 fenrir Exp $
*
* Authors: Laurent Aimar <fenrir@via.ecp.fr>
*
......@@ -57,7 +57,9 @@ struct demux_sys_t
mtime_t i_time;
int i_bitrate_avg; /* extracted from Xing header */
es_descriptor_t *p_es;
es_out_id_t *p_es;
//es_descriptor_t *p_es;
};
static int HeaderCheck( uint32_t h )
......@@ -173,6 +175,8 @@ static int Open( vlc_object_t * p_this )
module_t *p_id3;
es_format_t fmt;
if( p_input->psz_demux &&
( !strncmp( p_input->psz_demux, "mpga", 4 ) ||
......@@ -334,28 +338,11 @@ static int Open( vlc_object_t * p_this )
msg_Err( p_input, "cannot init stream" );
goto error;
}
if( input_AddProgram( p_input, 0, 0) == NULL )
{
vlc_mutex_unlock( &p_input->stream.stream_lock );
msg_Err( p_input, "cannot add program" );
goto error;
}
p_input->stream.pp_programs[0]->b_is_ok = 0;
p_input->stream.p_selected_program = p_input->stream.pp_programs[0];
p_input->stream.i_mux_rate = p_sys->i_bitrate_avg / 8 / 50;
p_sys->p_es = input_AddES( p_input,
p_input->stream.p_selected_program,
1 , AUDIO_ES, NULL, 0 );
p_sys->p_es->i_stream_id = 1;
p_sys->p_es->i_fourcc = VLC_FOURCC( 'm', 'p', 'g', 'a' );
input_SelectES( p_input, p_sys->p_es );
p_input->stream.p_selected_program->b_is_ok = 1;
vlc_mutex_unlock( &p_input->stream.stream_lock );
es_format_Init( &fmt, AUDIO_ES, VLC_FOURCC( 'm', 'p', 'g', 'a' ) );
p_sys->p_es = es_out_Add( p_input->p_es_out, &fmt );
return VLC_SUCCESS;
error:
......@@ -431,14 +418,8 @@ static int Demux( input_thread_t * p_input )
p_input->stream.p_selected_program,
p_sys->i_time * 9 / 100 );
if( !p_sys->p_es->p_decoder_fifo )
{
msg_Err( p_input, "no audio decoder" );
input_DeletePES( p_input->p_method_data, p_pes );
return( -1 );
}
es_out_Send( p_input->p_es_out, p_sys->p_es, p_pes );
input_DecodePES( p_sys->p_es->p_decoder_fifo, p_pes );
p_sys->i_time += (mtime_t)1000000 *
(mtime_t)mpga_frame_samples( header ) /
(mtime_t)MPGA_SAMPLE_RATE( header );
......
......@@ -2,7 +2,7 @@
* demux.c
*****************************************************************************
* Copyright (C) 1999-2003 VideoLAN
* $Id: demux.c,v 1.2 2003/09/07 22:51:11 fenrir Exp $
* $Id: demux.c,v 1.3 2003/09/13 17:42:16 fenrir Exp $
*
* Authors: Laurent Aimar <fenrir@via.ecp.fr>
*
......@@ -133,6 +133,9 @@ int demux_vaControlDefault( input_thread_t *p_input, int i_query, va_list args
i_ret = VLC_EGENERIC;
}
break;
case DEMUX_GET_FPS:
i_ret = VLC_EGENERIC;
break;
default:
msg_Err( p_input, "unknown query in demux_vaControlDefault !!!" );
......
......@@ -4,7 +4,7 @@
* decoders.
*****************************************************************************
* Copyright (C) 1998-2002 VideoLAN
* $Id: input.c,v 1.239 2003/09/12 18:34:45 fenrir Exp $
* $Id: input.c,v 1.240 2003/09/13 17:42:16 fenrir Exp $
*
* Authors: Christophe Massiot <massiot@via.ecp.fr>
*
......@@ -41,10 +41,19 @@
#include "stream_output.h"
#include "vlc_interface.h"
#include "codecs.h"
#include "modules/demux/util/sub.h"
/*****************************************************************************
* Local prototypes
*****************************************************************************/
struct input_thread_sys_t
{
/* subtitles */
int i_sub;
subtitle_demux_t **sub;
};
static int RunThread ( input_thread_t *p_input );
static int InitThread ( input_thread_t *p_input );
static void ErrorThread ( input_thread_t *p_input );
......@@ -145,6 +154,7 @@ input_thread_t *__input_CreateThread( vlc_object_t *p_parent,
/* Initialize thread properties */
p_input->b_eof = 0;
p_input->p_sys = NULL;
/* Set target */
p_input->psz_source = strdup( p_item->psz_uri );
......@@ -367,6 +377,7 @@ static int RunThread( input_thread_t *p_input )
if( p_input->stream.p_selected_area->i_size > 0 )
{
unsigned int i;
mtime_t i_time;
double f = (double)p_input->stream.p_selected_area->i_seek /
(double)p_input->stream.p_selected_area->i_size;
......@@ -385,6 +396,22 @@ static int RunThread( input_thread_t *p_input )
/* Reinitialize synchro. */
p_pgrm->i_synchro_state = SYNCHRO_REINIT;
}
if( !demux_Control( p_input, DEMUX_GET_TIME, &i_time ) )
{
int i;
vlc_value_t val;
/* Help in bar display */
val.i_time = i_time;
var_Change( p_input, "time", VLC_VAR_SETVALUE, &val, NULL );
/* Seek subs */
for( i = 0; i < p_input->p_sys->i_sub; i++ )
{
subtitle_Seek( p_input->p_sys->sub[i], i_time );
}
}
}
p_input->stream.p_selected_area->i_seek = NO_SEEK;
}
......@@ -434,24 +461,35 @@ static int RunThread( input_thread_t *p_input )
if( !p_input->b_error && !p_input->b_eof && i_update_next < mdate() )
{
double d;
int i;
mtime_t i_time;
mtime_t i_length;
double d_pos;
/* update input status variables */
if( !demux_Control( p_input, DEMUX_GET_POSITION, &d ) )
if( !demux_Control( p_input, DEMUX_GET_POSITION, &d_pos ) )
{
val.f_float = (float)d;
val.f_float = (float)d_pos;
var_Change( p_input, "position", VLC_VAR_SETVALUE, &val, NULL );
}
if( !demux_Control( p_input, DEMUX_GET_TIME, &val.i_time ) )
if( !demux_Control( p_input, DEMUX_GET_TIME, &i_time ) )
{
val.i_time = i_time;
var_Change( p_input, "time", VLC_VAR_SETVALUE, &val, NULL );
}
if( !demux_Control( p_input, DEMUX_GET_LENGTH, &val.i_time ) )
if( !demux_Control( p_input, DEMUX_GET_LENGTH, &i_length ) )
{
val.i_time = i_length;
var_Change( p_input, "length", VLC_VAR_SETVALUE, &val, NULL );
}
i_update_next = mdate() + 200000LL;
/* update subs */
for( i = 0; i < p_input->p_sys->i_sub; i++ )
{
subtitle_Demux( p_input->p_sys->sub[i], i_time );
}
i_update_next = mdate() + 150000LL;
}
}
......@@ -470,9 +508,12 @@ static int RunThread( input_thread_t *p_input )
*****************************************************************************/
static int InitThread( input_thread_t * p_input )
{
float f_fps;
/* Parse source string. Syntax : [[<access>][/<demux>]:][<source>] */
char * psz_parser = p_input->psz_dupsource = strdup(p_input->psz_source);
vlc_value_t val;
subtitle_demux_t *p_sub;
int64_t i_microsecondperframe;
/* Skip the plug-in names */
while( *psz_parser && *psz_parser != ':' )
......@@ -663,6 +704,34 @@ static int InitThread( input_thread_t * p_input )
return VLC_EGENERIC;
}
/* Init input_thread_sys_t */
p_input->p_sys = malloc( sizeof( input_thread_sys_t ) );
p_input->p_sys->i_sub = 0;
p_input->p_sys->sub = NULL;
/* get fps */
if( demux_Control( p_input, DEMUX_GET_FPS, &f_fps ) || f_fps < 0.1 )
{
i_microsecondperframe = 0;
}
else
{
i_microsecondperframe = (int64_t)( (double)1000000.0 / (double)f_fps );
}
/* Now add subtitles (for now only one) */
if( ( p_sub = subtitle_New( p_input, NULL, i_microsecondperframe ) ) )
{
TAB_APPEND( p_input->p_sys->i_sub, p_input->p_sys->sub, p_sub );
/* see if it should be selected */
var_Get( p_sub, "sub-file", &val );
if( val.psz_string && *val.psz_string )
{
subtitle_Select( p_sub );
}
}
return VLC_SUCCESS;
}
......@@ -685,6 +754,7 @@ static void ErrorThread( input_thread_t *p_input )
*****************************************************************************/
static void EndThread( input_thread_t * p_input )
{
int i;
#ifdef HAVE_SYS_TIMES_H
/* Display statistics */
struct tms cpu_usage;
......@@ -704,7 +774,8 @@ static void EndThread( input_thread_t * p_input )
/* Close optional stream output instance */
if ( p_input->stream.p_sout != NULL )
{
vlc_object_t *p_pl = vlc_object_find( p_input, VLC_OBJECT_PLAYLIST, FIND_ANYWHERE );
vlc_object_t *p_pl =
vlc_object_find( p_input, VLC_OBJECT_PLAYLIST, FIND_ANYWHERE );
vlc_value_t keep;
if( var_Get( p_input, "sout-keep", &keep ) >= 0 && keep.b_bool && p_pl )
......@@ -725,6 +796,19 @@ static void EndThread( input_thread_t * p_input )
}
}
/* Destroy subtitles demuxers */
for( i = 0; i < p_input->p_sys->i_sub; i++ )
{
subtitle_Close( p_input->p_sys->sub[i] );
}
if( p_input->p_sys->i_sub > 0 )
{
free( p_input->p_sys->sub );
}
/* Free input_thread_sys_t */
free( p_input->p_sys );
/* Free demultiplexer's data */
module_Unneed( p_input, p_input->p_demux );
......@@ -855,6 +939,9 @@ struct es_out_sys_t
int i_id;
es_out_id_t **id;
vlc_bool_t i_audio;
vlc_bool_t i_video;
};
struct es_out_id_t
{
......@@ -879,32 +966,218 @@ static es_out_t *EsOutCreate( input_thread_t *p_input )
out->p_sys->p_input = p_input;
out->p_sys->i_id = 0;
out->p_sys->id = NULL;
out->p_sys->i_audio = -1;
out->p_sys->i_video = -1;
return out;
}
static void EsOutRelease( es_out_t *out )
{
free( out->p_sys );
es_out_sys_t *p_sys = out->p_sys;
int i;
for( i = 0; i < p_sys->i_id; i++ )
{
free( p_sys->id[i] );
}
if( p_sys->id )
{
free( p_sys->id );
}
free( p_sys );
free( out );
}
static es_out_id_t *EsOutAdd( es_out_t *out, es_format_t *fmt )
{
es_out_id_t *id = malloc( sizeof( es_out_id_t ) );
es_out_sys_t *p_sys = out->p_sys;
input_thread_t *p_input = p_sys->p_input;
es_out_id_t *id = malloc( sizeof( es_out_id_t ) );
pgrm_descriptor_t *p_prgm = NULL;
vlc_mutex_lock( &p_input->stream.stream_lock );
if( fmt->i_group >= 0 )
{
/* search program */
p_prgm = input_FindProgram( p_input, fmt->i_group );
if( p_prgm == NULL )
{
/* create it */
p_prgm = input_AddProgram( p_input, fmt->i_group, 0 );
/* Select the first by default */
if( p_input->stream.p_selected_program == NULL )
{
p_input->stream.p_selected_program = p_prgm;
}
}
}
id->p_es = input_AddES( p_input,
p_prgm,
1 + out->p_sys->i_id,
fmt->i_cat,
fmt->psz_description, 0 );
id->p_es->i_stream_id = 1 + out->p_sys->i_id;
id->p_es->i_fourcc = fmt->i_codec;
switch( fmt->i_cat )
{
case AUDIO_ES:
{
WAVEFORMATEX *p_wf = malloc( sizeof( WAVEFORMATEX ) + fmt->i_extra);
p_wf->wFormatTag = WAVE_FORMAT_UNKNOWN;
p_wf->nChannels = fmt->audio.i_channels;
p_wf->nSamplesPerSec = fmt->audio.i_samplerate;
p_wf->nAvgBytesPerSec = fmt->audio.i_bitrate / 8;
p_wf->nBlockAlign = fmt->audio.i_blockalign;
p_wf->wBitsPerSample = fmt->audio.i_bitspersample;
p_wf->cbSize = fmt->i_extra;
if( fmt->i_extra > 0 )
{
if( fmt->i_extra_type != ES_EXTRA_TYPE_WAVEFORMATEX )
{
msg_Warn( p_input, "extra type != WAVEFORMATEX for audio" );
}
memcpy( &p_wf[1], fmt->p_extra, fmt->i_extra );
}
id->p_es->p_waveformatex = p_wf;
break;
}
case VIDEO_ES:
{
BITMAPINFOHEADER *p_bih = malloc( sizeof( BITMAPINFOHEADER ) +
fmt->i_extra );
p_bih->biSize = sizeof(BITMAPINFOHEADER) + fmt->i_extra;
p_bih->biWidth = fmt->video.i_width;
p_bih->biHeight = fmt->video.i_height;
p_bih->biPlanes = 1;
p_bih->biBitCount = 24;
p_bih->biCompression = fmt->i_codec;
p_bih->biSizeImage = fmt->video.i_width * fmt->video.i_height;
p_bih->biXPelsPerMeter = 0;
p_bih->biYPelsPerMeter = 0;
p_bih->biClrUsed = 0;
p_bih->biClrImportant = 0;
if( fmt->i_extra > 0 )
{
if( fmt->i_extra_type != ES_EXTRA_TYPE_BITMAPINFOHEADER )
{
msg_Warn( p_input,
"extra type != BITMAPINFOHEADER for video" );
}
memcpy( &p_bih[1], fmt->p_extra, fmt->i_extra );
}
id->p_es->p_bitmapinfoheader = p_bih;
break;
}
default:
break;
}
if( fmt->i_cat == AUDIO_ES && fmt->i_priority > out->p_sys->i_audio )
{
if( out->p_sys->i_audio >= 0 )
{
msg_Err( p_input, "FIXME unselect es in es_out_Add" );
}
input_SelectES( p_input, id->p_es );
if( id->p_es->p_decoder_fifo )
{
out->p_sys->i_audio = fmt->i_priority;
}
}
else if( fmt->i_cat == VIDEO_ES && fmt->i_priority > out->p_sys->i_video )
{
if( out->p_sys->i_video >= 0 )
{
msg_Err( p_input, "FIXME unselect es in es_out_Add" );
}
input_SelectES( p_input, id->p_es );
if( id->p_es->p_decoder_fifo )
{
out->p_sys->i_video = fmt->i_priority;
}</