[vlc-commits] es_out: store ES's in a list
Rémi Denis-Courmont
git at videolan.org
Wed Jun 13 20:49:26 CEST 2018
vlc | branch: master | Rémi Denis-Courmont <remi at remlab.net> | Wed Jun 13 21:45:59 2018 +0300| [b09ab2cf7cf762cd20436be73b74495407de2450] | committer: Rémi Denis-Courmont
es_out: store ES's in a list
> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=b09ab2cf7cf762cd20436be73b74495407de2450
---
src/input/es_out.c | 251 ++++++++++++++++++++++++-----------------------------
1 file changed, 115 insertions(+), 136 deletions(-)
diff --git a/src/input/es_out.c b/src/input/es_out.c
index 2671cea705..38283e0df0 100644
--- a/src/input/es_out.c
+++ b/src/input/es_out.c
@@ -107,6 +107,8 @@ struct es_out_id_t
/* ID for the meta data */
int i_meta_id;
+
+ struct vlc_list node;
};
typedef struct
@@ -136,8 +138,7 @@ typedef struct
/* all es */
int i_id;
- int i_es;
- es_out_id_t **es;
+ struct vlc_list es;
/* mode gestion */
bool b_active;
@@ -301,8 +302,7 @@ es_out_t *input_EsOutNew( input_thread_t *p_input, int i_rate )
p_sys->i_mode = ES_OUT_MODE_NONE;
vlc_list_init(&p_sys->programs);
-
- TAB_INIT( p_sys->i_es, p_sys->es );
+ vlc_list_init(&p_sys->es);
/* */
EsOutPropsInit( &p_sys->video, true, p_input, ES_OUT_ES_POLICY_SIMULTANEOUS,
@@ -332,7 +332,7 @@ static void EsOutDelete( es_out_t *out )
{
es_out_sys_t *p_sys = container_of(out, es_out_sys_t, out);
- assert(p_sys->i_es == 0);
+ assert(vlc_list_is_empty(&p_sys->es));
assert(vlc_list_is_empty(&p_sys->programs));
assert(p_sys->p_pgrm == NULL);
EsOutPropsCleanup( &p_sys->audio );
@@ -346,22 +346,22 @@ static void EsOutDelete( es_out_t *out )
static void EsOutTerminate( es_out_t *out )
{
es_out_sys_t *p_sys = container_of(out, es_out_sys_t, out);
+ es_out_id_t *es;
if( p_sys->p_sout_record )
EsOutSetRecord( out, false );
- for( int i = 0; i < p_sys->i_es; i++ )
+ vlc_list_foreach(es, &p_sys->es, node)
{
- if( p_sys->es[i]->p_dec )
- input_DecoderDelete( p_sys->es[i]->p_dec );
-
- free( p_sys->es[i]->psz_language );
- free( p_sys->es[i]->psz_language_code );
- es_format_Clean( &p_sys->es[i]->fmt );
+ if (es->p_dec != NULL)
+ input_DecoderDelete(es->p_dec);
- free( p_sys->es[i] );
+ free(es->psz_language);
+ free(es->psz_language_code);
+ es_format_Clean(&es->fmt);
+ vlc_list_remove(&es->node);
+ free(es);
}
- TAB_CLEAN( p_sys->i_es, p_sys->es );
/* FIXME duplicate work EsOutProgramDel (but we cannot use it) add a EsOutProgramClean ? */
es_out_pgrm_t *p_pgrm;
@@ -407,6 +407,7 @@ static es_out_id_t es_cat[DATA_ES];
static es_out_id_t *EsOutGetFromID( es_out_t *out, int i_id )
{
es_out_sys_t *p_sys = container_of(out, es_out_sys_t, out);
+ es_out_id_t *es;
if( i_id < 0 )
{
@@ -414,17 +415,16 @@ static es_out_id_t *EsOutGetFromID( es_out_t *out, int i_id )
return es_cat - i_id;
}
- for( int i = 0; i < p_sys->i_es; i++ )
- {
- if( p_sys->es[i]->i_id == i_id )
- return p_sys->es[i];
- }
+ vlc_list_foreach(es, &p_sys->es, node)
+ if (es->i_id == i_id)
+ return es;
return NULL;
}
static bool EsOutDecodersIsEmpty( es_out_t *out )
{
es_out_sys_t *p_sys = container_of(out, es_out_sys_t, out);
+ es_out_id_t *es;
if( p_sys->b_buffering && p_sys->p_pgrm )
{
@@ -433,10 +433,8 @@ static bool EsOutDecodersIsEmpty( es_out_t *out )
return true;
}
- for( int i = 0; i < p_sys->i_es; i++ )
+ vlc_list_foreach(es, &p_sys->es, node)
{
- es_out_id_t *es = p_sys->es[i];
-
if( es->p_dec && !input_DecoderIsEmpty( es->p_dec ) )
return false;
if( es->p_dec_record && !input_DecoderIsEmpty( es->p_dec_record ) )
@@ -448,20 +446,22 @@ static bool EsOutDecodersIsEmpty( es_out_t *out )
static void EsOutSetDelay( es_out_t *out, int i_cat, mtime_t i_delay )
{
es_out_sys_t *p_sys = container_of(out, es_out_sys_t, out);
+ es_out_id_t *es;
if( i_cat == AUDIO_ES )
p_sys->i_audio_delay = i_delay;
else if( i_cat == SPU_ES )
p_sys->i_spu_delay = i_delay;
- for( int i = 0; i < p_sys->i_es; i++ )
- EsOutDecoderChangeDelay( out, p_sys->es[i] );
+ vlc_list_foreach(es, &p_sys->es, node)
+ EsOutDecoderChangeDelay(out, es);
}
static int EsOutSetRecord( es_out_t *out, bool b_record )
{
es_out_sys_t *p_sys = container_of(out, es_out_sys_t, out);
input_thread_t *p_input = p_sys->p_input;
+ es_out_id_t *p_es;
assert( ( b_record && !p_sys->p_sout_record ) || ( !b_record && p_sys->p_sout_record ) );
@@ -508,10 +508,8 @@ static int EsOutSetRecord( es_out_t *out, bool b_record )
if( !p_sys->p_sout_record )
return VLC_EGENERIC;
- for( int i = 0; i < p_sys->i_es; i++ )
+ vlc_list_foreach(p_es, &p_sys->es, node)
{
- es_out_id_t *p_es = p_sys->es[i];
-
if( !p_es->p_dec || p_es->p_master )
continue;
@@ -522,10 +520,8 @@ static int EsOutSetRecord( es_out_t *out, bool b_record )
}
else
{
- for( int i = 0; i < p_sys->i_es; i++ )
+ vlc_list_foreach(p_es, &p_sys->es, node)
{
- es_out_id_t *p_es = p_sys->es[i];
-
if( !p_es->p_dec_record )
continue;
@@ -585,29 +581,24 @@ static void EsOutChangeRate( es_out_t *out, int i_rate )
{
es_out_sys_t *p_sys = container_of(out, es_out_sys_t, out);
float rate = (float)i_rate / (float)INPUT_RATE_DEFAULT;
+ es_out_id_t *es;
p_sys->i_rate = i_rate;
EsOutProgramsChangeRate( out );
- for( int i = 0; i < p_sys->i_es; i++ )
- {
- es_out_id_t *es = p_sys->es[i];
-
+ vlc_list_foreach(es, &p_sys->es, node)
if( es->p_dec != NULL )
input_DecoderChangeRate( es->p_dec, rate );
- }
}
static void EsOutChangePosition( es_out_t *out )
{
es_out_sys_t *p_sys = container_of(out, es_out_sys_t, out);
+ es_out_id_t *p_es;
input_SendEventCache( p_sys->p_input, 0.0 );
- for( int i = 0; i < p_sys->i_es; i++ )
- {
- es_out_id_t *p_es = p_sys->es[i];
-
+ vlc_list_foreach(p_es, &p_sys->es, node)
if( p_es->p_dec != NULL )
{
input_DecoderFlush( p_es->p_dec );
@@ -618,7 +609,6 @@ static void EsOutChangePosition( es_out_t *out )
input_DecoderStartWait( p_es->p_dec_record );
}
}
- }
es_out_pgrm_t *pgrm;
vlc_list_foreach(pgrm, &p_sys->programs, node)
@@ -637,6 +627,7 @@ static void EsOutChangePosition( es_out_t *out )
static void EsOutDecodersStopBuffering( es_out_t *out, bool b_forced )
{
es_out_sys_t *p_sys = container_of(out, es_out_sys_t, out);
+ es_out_id_t *p_es;
mtime_t i_stream_start;
mtime_t i_system_start;
@@ -688,10 +679,8 @@ static void EsOutDecodersStopBuffering( es_out_t *out, bool b_forced )
}
const mtime_t i_decoder_buffering_start = mdate();
- for( int i = 0; i < p_sys->i_es; i++ )
+ vlc_list_foreach(p_es, &p_sys->es, node)
{
- es_out_id_t *p_es = p_sys->es[i];
-
if( !p_es->p_dec || p_es->fmt.i_cat == SPU_ES )
continue;
input_DecoderWait( p_es->p_dec );
@@ -712,10 +701,8 @@ static void EsOutDecodersStopBuffering( es_out_t *out, bool b_forced )
input_clock_ChangeSystemOrigin( p_sys->p_pgrm->p_input_clock, true,
i_current_date + i_wakeup_delay - i_buffering_duration );
- for( int i = 0; i < p_sys->i_es; i++ )
+ vlc_list_foreach(p_es, &p_sys->es, node)
{
- es_out_id_t *p_es = p_sys->es[i];
-
if( !p_es->p_dec )
continue;
@@ -727,30 +714,26 @@ static void EsOutDecodersStopBuffering( es_out_t *out, bool b_forced )
static void EsOutDecodersChangePause( es_out_t *out, bool b_paused, mtime_t i_date )
{
es_out_sys_t *p_sys = container_of(out, es_out_sys_t, out);
+ es_out_id_t *es;
/* Pause decoders first */
- for( int i = 0; i < p_sys->i_es; i++ )
- {
- es_out_id_t *es = p_sys->es[i];
-
+ vlc_list_foreach(es, &p_sys->es, node)
if( es->p_dec )
{
input_DecoderChangePause( es->p_dec, b_paused, i_date );
if( es->p_dec_record )
input_DecoderChangePause( es->p_dec_record, b_paused, i_date );
}
- }
}
static bool EsOutIsExtraBufferingAllowed( es_out_t *out )
{
es_out_sys_t *p_sys = container_of(out, es_out_sys_t, out);
+ es_out_id_t *p_es;
size_t i_size = 0;
- for( int i = 0; i < p_sys->i_es; i++ )
+ vlc_list_foreach(p_es, &p_sys->es, node)
{
- es_out_id_t *p_es = p_sys->es[i];
-
if( p_es->p_dec )
i_size += input_DecoderGetFifoSize( p_es->p_dec );
if( p_es->p_dec_record )
@@ -805,7 +788,7 @@ static void EsOutProgramsChangeRate( es_out_t *out )
static void EsOutFrameNext( es_out_t *out )
{
es_out_sys_t *p_sys = container_of(out, es_out_sys_t, out);
- es_out_id_t *p_es_video = NULL;
+ es_out_id_t *p_es_video = NULL, *p_es;
if( p_sys->b_buffering )
{
@@ -815,16 +798,12 @@ static void EsOutFrameNext( es_out_t *out )
assert( p_sys->b_paused );
- for( int i = 0; i < p_sys->i_es; i++ )
- {
- es_out_id_t *p_es = p_sys->es[i];
-
+ vlc_list_foreach(p_es, &p_sys->es, node)
if( p_es->fmt.i_cat == VIDEO_ES && p_es->p_dec )
{
p_es_video = p_es;
break;
}
- }
if( !p_es_video )
{
@@ -1014,7 +993,7 @@ static void EsOutProgramSelect( es_out_t *out, es_out_pgrm_t *p_pgrm )
{
es_out_sys_t *p_sys = container_of(out, es_out_sys_t, out);
input_thread_t *p_input = p_sys->p_input;
- int i;
+ es_out_id_t *es;
if( p_sys->p_pgrm == p_pgrm )
return; /* Nothing to do */
@@ -1022,14 +1001,13 @@ static void EsOutProgramSelect( es_out_t *out, es_out_pgrm_t *p_pgrm )
if( p_sys->p_pgrm )
{
es_out_pgrm_t *old = p_sys->p_pgrm;
+
msg_Dbg( p_input, "unselecting program id=%d", old->i_id );
- for( i = 0; i < p_sys->i_es; i++ )
- {
- if( p_sys->es[i]->p_pgrm == old && EsIsSelected( p_sys->es[i] ) &&
- p_sys->i_mode != ES_OUT_MODE_ALL )
- EsUnselect( out, p_sys->es[i], true );
- }
+ vlc_list_foreach(es, &p_sys->es, node)
+ if (es->p_pgrm == old && EsIsSelected(es)
+ && p_sys->i_mode != ES_OUT_MODE_ALL)
+ EsUnselect(out, es, true);
p_sys->audio.p_main_es = NULL;
p_sys->video.p_main_es = NULL;
@@ -1057,15 +1035,15 @@ static void EsOutProgramSelect( es_out_t *out, es_out_pgrm_t *p_pgrm )
/* TODO event */
var_SetInteger( p_input, "teletext-es", -1 );
- for( i = 0; i < p_sys->i_es; i++ )
+ vlc_list_foreach(es, &p_sys->es, node)
{
- if( p_sys->es[i]->p_pgrm == p_sys->p_pgrm )
+ if (es->p_pgrm == p_sys->p_pgrm)
{
- EsOutESVarUpdate( out, p_sys->es[i], false );
- EsOutUpdateInfo( out, p_sys->es[i], &p_sys->es[i]->fmt, NULL );
+ EsOutESVarUpdate(out, es, false);
+ EsOutUpdateInfo(out, es, &es->fmt, NULL);
}
- EsOutSelect( out, p_sys->es[i], false );
+ EsOutSelect(out, es, false);
}
/* Ensure the correct running EPG table is selected */
@@ -1458,16 +1436,16 @@ static void EsOutProgramUpdateScrambled( es_out_t *p_out, es_out_pgrm_t *p_pgrm
{
es_out_sys_t *p_sys = container_of(p_out, es_out_sys_t, out);
input_thread_t *p_input = p_sys->p_input;
+ es_out_id_t *es;
bool b_scrambled = false;
- for( int i = 0; i < p_sys->i_es; i++ )
- {
- if( p_sys->es[i]->p_pgrm == p_pgrm && p_sys->es[i]->b_scrambled )
+ vlc_list_foreach(es, &p_sys->es, node)
+ if (es->p_pgrm == p_pgrm && es->b_scrambled)
{
b_scrambled = true;
break;
}
- }
+
if( !p_pgrm->b_scrambled == !b_scrambled )
return;
@@ -1644,7 +1622,7 @@ static es_out_id_t *EsOutAddSlave( es_out_t *out, const es_format_t *fmt, es_out
es->cc.i_bitmap = 0;
es->p_master = p_master;
- TAB_APPEND( p_sys->i_es, p_sys->es, es );
+ vlc_list_append(&es->node, &p_sys->es);
if( es->p_pgrm == p_sys->p_pgrm )
EsOutESVarUpdate( out, es, false );
@@ -2159,7 +2137,6 @@ static void EsOutDel( es_out_t *out, es_out_id_t *es )
{
es_out_sys_t *p_sys = container_of(out, es_out_sys_t, out);
bool b_reselect = false;
- int i;
vlc_mutex_lock( &p_sys->lock );
@@ -2188,7 +2165,7 @@ static void EsOutDel( es_out_t *out, es_out_id_t *es )
EsDeleteInfo( out, es );
- TAB_REMOVE( p_sys->i_es, p_sys->es, es );
+ vlc_list_remove(&es->node);
/* Update program */
es->p_pgrm->i_es--;
@@ -2212,20 +2189,21 @@ static void EsOutDel( es_out_t *out, es_out_id_t *es )
/* Re-select another track when needed */
if( b_reselect )
{
- for( i = 0; i < p_sys->i_es; i++ )
- {
- if( es->fmt.i_cat == p_sys->es[i]->fmt.i_cat )
+ es_out_id_t *other;
+
+ vlc_list_foreach(other, &p_sys->es, node)
+ if( es->fmt.i_cat == other->fmt.i_cat )
{
- if( EsIsSelected(p_sys->es[i]) )
+ if (EsIsSelected(other))
{
- input_SendEventEsSelect( p_sys->p_input, es->fmt.i_cat, p_sys->es[i]->i_id );
+ input_SendEventEsSelect(p_sys->p_input, es->fmt.i_cat,
+ other->i_id);
if( p_esprops->p_main_es == NULL )
- p_esprops->p_main_es = p_sys->es[i];
+ p_esprops->p_main_es = es;
}
else
- EsOutSelect( out, p_sys->es[i], false );
+ EsOutSelect(out, other, false);
}
- }
}
free( es->psz_language );
@@ -2303,33 +2281,34 @@ static int EsOutControlLocked( es_out_t *out, int i_query, va_list args )
i_mode == ES_OUT_MODE_AUTO || i_mode == ES_OUT_MODE_PARTIAL ||
i_mode == ES_OUT_MODE_END );
- if( i_mode != ES_OUT_MODE_NONE && !p_sys->b_active && p_sys->i_es > 0 )
+ if (i_mode != ES_OUT_MODE_NONE && !p_sys->b_active)
{
/* XXX Terminate vout if there are tracks but no video one.
* This one is not mandatory but is he earliest place where it
* can be done */
- int i;
- for( i = 0; i < p_sys->i_es; i++ )
- {
- es_out_id_t *p_es = p_sys->es[i];
+ es_out_id_t *p_es;
+ bool found = false;
+
+ vlc_list_foreach(p_es, &p_sys->es, node)
if( p_es->fmt.i_cat == VIDEO_ES )
+ {
+ found = true;
break;
- }
- if( i >= p_sys->i_es )
+ }
+
+ if (!found)
input_resource_TerminateVout( input_priv(p_sys->p_input)->p_resource );
}
p_sys->b_active = i_mode != ES_OUT_MODE_NONE;
p_sys->i_mode = i_mode;
/* Reapply policy mode */
- for( int i = 0; i < p_sys->i_es; i++ )
- {
- if( EsIsSelected( p_sys->es[i] ) )
- EsUnselect( out, p_sys->es[i],
- p_sys->es[i]->p_pgrm == p_sys->p_pgrm );
- }
- for( int i = 0; i < p_sys->i_es; i++ )
- EsOutSelect( out, p_sys->es[i], false );
+ es_out_id_t *es;
+ vlc_list_foreach(es, &p_sys->es, node)
+ if (EsIsSelected(es))
+ EsUnselect(out, es, es->p_pgrm == p_sys->p_pgrm);
+ vlc_list_foreach(es, &p_sys->es, node)
+ EsOutSelect(out, es, false);
if( i_mode == ES_OUT_MODE_END )
EsOutTerminate( out );
return VLC_SUCCESS;
@@ -2339,7 +2318,7 @@ static int EsOutControlLocked( es_out_t *out, int i_query, va_list args )
case ES_OUT_RESTART_ES:
{
#define IGNORE_ES DATA_ES
- es_out_id_t *es = va_arg( args, es_out_id_t * );
+ es_out_id_t *es = va_arg( args, es_out_id_t * ), *other;
enum es_format_category_e i_cat;
if( es == NULL )
@@ -2353,66 +2332,67 @@ static int EsOutControlLocked( es_out_t *out, int i_query, va_list args )
else
i_cat = IGNORE_ES;
- for( int i = 0; i < p_sys->i_es; i++ )
- {
+ vlc_list_foreach(other, &p_sys->es, node)
if( i_cat == IGNORE_ES )
{
- if( es == p_sys->es[i] )
+ if (es == other)
{
- if( i_query == ES_OUT_RESTART_ES && p_sys->es[i]->p_dec )
+ if (i_query == ES_OUT_RESTART_ES && es->p_dec != NULL)
{
- EsDestroyDecoder( out, p_sys->es[i] );
- EsCreateDecoder( out, p_sys->es[i] );
+ EsDestroyDecoder(out, es);
+ EsCreateDecoder(out, es);
}
else if( i_query == ES_OUT_SET_ES )
{
- EsOutSelect( out, es, true );
+ EsOutSelect(out, es, true);
}
break;
}
}
- else
+ else if (i_cat == UNKNOWN_ES || other->fmt.i_cat == i_cat)
{
- if( i_cat == UNKNOWN_ES || p_sys->es[i]->fmt.i_cat == i_cat )
+ if (EsIsSelected(other))
{
- if( EsIsSelected( p_sys->es[i] ) )
+ if (i_query == ES_OUT_RESTART_ES)
{
- if( i_query == ES_OUT_RESTART_ES )
+ if (other->p_dec != NULL)
{
- if( p_sys->es[i]->p_dec )
- {
- EsDestroyDecoder( out, p_sys->es[i] );
- EsCreateDecoder( out, p_sys->es[i] );
- }
- }
- else
- {
- EsUnselect( out, p_sys->es[i],
- p_sys->es[i]->p_pgrm == p_sys->p_pgrm );
+ EsDestroyDecoder(out, other);
+ EsCreateDecoder(out, other);
}
}
+ else
+ EsUnselect(out, other, other->p_pgrm == p_sys->p_pgrm);
}
}
- }
+
return VLC_SUCCESS;
}
case ES_OUT_STOP_ALL_ES:
{
- int *selected_es = vlc_alloc(p_sys->i_es + 1, sizeof(int));
+ es_out_id_t *es;
+ int count = 0;
+
+ vlc_list_foreach(es, &p_sys->es, node)
+ count++;
+
+ int *selected_es = vlc_alloc(count + 1, sizeof(int));
if (!selected_es)
return VLC_ENOMEM;
- selected_es[0] = p_sys->i_es;
- for( int i = 0; i < p_sys->i_es; i++ )
+
+ *va_arg(args, void **) = selected_es;
+ *selected_es = count;
+
+ vlc_list_foreach(es, &p_sys->es, node)
{
- if( EsIsSelected( p_sys->es[i] ) )
+ if (EsIsSelected(es))
{
- EsDestroyDecoder( out, p_sys->es[i] );
- selected_es[i + 1] = p_sys->es[i]->i_id;
+ EsDestroyDecoder(out, es);
+ *++selected_es = es->i_id;
}
else
- selected_es[i + 1] = -1;
+ *++selected_es = -1;
}
- *va_arg( args, void **) = selected_es;
return VLC_SUCCESS;
}
case ES_OUT_START_ALL_ES:
@@ -2868,11 +2848,10 @@ static int EsOutControlLocked( es_out_t *out, int i_query, va_list args )
}
case ES_OUT_SET_EOS:
{
- for (int i = 0; i < p_sys->i_es; i++) {
- es_out_id_t *id = p_sys->es[i];
+ es_out_id_t *id;
+ vlc_list_foreach(id, &p_sys->es, node)
if (id->p_dec != NULL)
input_DecoderDrain(id->p_dec);
- }
return VLC_SUCCESS;
}
More information about the vlc-commits
mailing list