X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=src%2Finput%2Fes_out.c;h=b2326435e9923971fbc862425f8078a860a0347c;hb=cc116115681a9c484ee23592ef16d724f843ae70;hp=97e6b65524d6159a804896d6f0c5e200089d9087;hpb=d6a019d094973e71a45ab60d5a937961352e8536;p=vlc diff --git a/src/input/es_out.c b/src/input/es_out.c index 97e6b65524..b2326435e9 100644 --- a/src/input/es_out.c +++ b/src/input/es_out.c @@ -461,7 +461,7 @@ static int EsOutSetRecord( es_out_t *out, bool b_record ) if( !psz_sout && psz_path ) { - char *psz_file = input_CreateFilename( VLC_OBJECT(p_input), psz_path, INPUT_RECORD_PREFIX, NULL ); + char *psz_file = input_CreateFilename( p_input, psz_path, INPUT_RECORD_PREFIX, NULL ); if( psz_file ) { if( asprintf( &psz_sout, "#record{dst-prefix='%s'}", psz_file ) < 0 ) @@ -491,7 +491,7 @@ static int EsOutSetRecord( es_out_t *out, bool b_record ) p_es->p_dec_record = input_DecoderNew( p_input, &p_es->fmt, p_es->p_pgrm->p_clock, p_sys->p_sout_record ); if( p_es->p_dec_record && p_sys->b_buffering ) - input_DecoderStartBuffering( p_es->p_dec_record ); + input_DecoderStartWait( p_es->p_dec_record ); } } else @@ -573,13 +573,16 @@ static void EsOutChangePosition( es_out_t *out ) { es_out_id_t *p_es = p_sys->es[i]; - if( !p_es->p_dec ) - continue; - - input_DecoderStartBuffering( p_es->p_dec ); - - if( p_es->p_dec_record ) - input_DecoderStartBuffering( p_es->p_dec_record ); + if( p_es->p_dec != NULL ) + { + input_DecoderFlush( p_es->p_dec ); + if( !p_sys->b_buffering ) + { + input_DecoderStartWait( p_es->p_dec ); + if( p_es->p_dec_record != NULL ) + input_DecoderStartWait( p_es->p_dec_record ); + } + } } for( int i = 0; i < p_sys->i_pgrm; i++ ) @@ -597,17 +600,14 @@ static void EsOutChangePosition( es_out_t *out ) static void EsOutDecodersStopBuffering( es_out_t *out, bool b_forced ) { es_out_sys_t *p_sys = out->p_sys; - int i_ret; mtime_t i_stream_start; mtime_t i_system_start; mtime_t i_stream_duration; mtime_t i_system_duration; - i_ret = input_clock_GetState( p_sys->p_pgrm->p_clock, + if (input_clock_GetState( p_sys->p_pgrm->p_clock, &i_stream_start, &i_system_start, - &i_stream_duration, &i_system_duration ); - assert( !i_ret || b_forced ); - if( i_ret ) + &i_stream_duration, &i_system_duration )) return; mtime_t i_preroll_duration = 0; @@ -620,7 +620,11 @@ static void EsOutDecodersStopBuffering( es_out_t *out, bool b_forced ) if( i_stream_duration <= i_buffering_duration && !b_forced ) { - const double f_level = __MAX( (double)i_stream_duration / i_buffering_duration, 0 ); + double f_level; + if (i_buffering_duration == 0) + f_level = 0; + else + f_level = __MAX( (double)i_stream_duration / i_buffering_duration, 0 ); input_SendEventCache( p_sys->p_input, f_level ); msg_Dbg( p_sys->p_input, "Buffering %d%%", (int)(100 * f_level) ); @@ -646,12 +650,12 @@ static void EsOutDecodersStopBuffering( es_out_t *out, bool b_forced ) if( !p_es->p_dec || p_es->fmt.i_cat == SPU_ES ) continue; - input_DecoderWaitBuffering( p_es->p_dec ); + input_DecoderWait( p_es->p_dec ); if( p_es->p_dec_record ) - input_DecoderWaitBuffering( p_es->p_dec_record ); + input_DecoderWait( p_es->p_dec_record ); } - msg_Dbg( p_sys->p_input, "Decoder buffering done in %d ms", + msg_Dbg( p_sys->p_input, "Decoder wait done in %d ms", (int)(mdate() - i_decoder_buffering_start)/1000 ); /* Here is a good place to destroy unused vout with every demuxer */ @@ -671,9 +675,9 @@ static void EsOutDecodersStopBuffering( es_out_t *out, bool b_forced ) if( !p_es->p_dec ) continue; - input_DecoderStopBuffering( p_es->p_dec ); + input_DecoderStopWait( p_es->p_dec ); if( p_es->p_dec_record ) - input_DecoderStopBuffering( p_es->p_dec_record ); + input_DecoderStopWait( p_es->p_dec_record ); } } static void EsOutDecodersChangePause( es_out_t *out, bool b_paused, mtime_t i_date ) @@ -823,21 +827,19 @@ static void EsOutFrameNext( es_out_t *out ) static mtime_t EsOutGetBuffering( es_out_t *out ) { es_out_sys_t *p_sys = out->p_sys; + mtime_t i_stream_duration, i_system_start; if( !p_sys->p_pgrm ) return 0; + else + { + mtime_t i_stream_start, i_system_duration; - int i_ret; - mtime_t i_stream_start; - mtime_t i_system_start; - mtime_t i_stream_duration; - mtime_t i_system_duration; - i_ret = input_clock_GetState( p_sys->p_pgrm->p_clock, + if( input_clock_GetState( p_sys->p_pgrm->p_clock, &i_stream_start, &i_system_start, - &i_stream_duration, &i_system_duration ); - - if( i_ret ) - return 0; + &i_stream_duration, &i_system_duration ) ) + return 0; + } mtime_t i_delay; @@ -848,6 +850,7 @@ static mtime_t EsOutGetBuffering( es_out_t *out ) else { mtime_t i_system_duration; + if( p_sys->b_paused ) { i_system_duration = p_sys->i_pause_date - i_system_start; @@ -1012,7 +1015,7 @@ static void EsOutProgramSelect( es_out_t *out, es_out_pgrm_t *p_pgrm ) } /* Update now playing */ - input_item_SetNowPlaying( p_input->p->p_item, p_pgrm->psz_now_playing ); + input_item_SetESNowPlaying( p_input->p->p_item, p_pgrm->psz_now_playing ); input_item_SetPublisher( p_input->p->p_item, p_pgrm->psz_publisher ); input_SendEventMeta( p_input ); @@ -1154,7 +1157,7 @@ static void EsOutProgramMeta( es_out_t *out, int i_group, const vlc_meta_t *p_me /* Check against empty meta data (empty for what we handle) */ if( !vlc_meta_Get( p_meta, vlc_meta_Title) && - !vlc_meta_Get( p_meta, vlc_meta_NowPlaying) && + !vlc_meta_Get( p_meta, vlc_meta_ESNowPlaying) && !vlc_meta_Get( p_meta, vlc_meta_Publisher) && vlc_meta_GetExtraCount( p_meta ) <= 0 ) { @@ -1293,20 +1296,20 @@ static void EsOutProgramEpg( es_out_t *out, int i_group, const vlc_epg_t *p_epg if( p_pgrm == p_sys->p_pgrm ) { - input_item_SetNowPlaying( p_input->p->p_item, p_pgrm->psz_now_playing ); + input_item_SetESNowPlaying( p_input->p->p_item, p_pgrm->psz_now_playing ); input_SendEventMeta( p_input ); } if( p_pgrm->psz_now_playing ) { input_Control( p_input, INPUT_ADD_INFO, psz_cat, - vlc_meta_TypeToLocalizedString(vlc_meta_NowPlaying), + vlc_meta_TypeToLocalizedString(vlc_meta_ESNowPlaying), "%s", p_pgrm->psz_now_playing ); } else { input_Control( p_input, INPUT_DEL_INFO, psz_cat, - vlc_meta_TypeToLocalizedString(vlc_meta_NowPlaying) ); + vlc_meta_TypeToLocalizedString(vlc_meta_ESNowPlaying) ); } free( psz_cat ); @@ -1344,48 +1347,34 @@ static void EsOutMeta( es_out_t *p_out, const vlc_meta_t *p_meta ) { es_out_sys_t *p_sys = p_out->p_sys; input_thread_t *p_input = p_sys->p_input; - input_item_t *p_item = input_GetItem( p_input ); - char *psz_title = NULL; - char *psz_arturl = input_item_GetArtURL( p_item ); - - vlc_mutex_lock( &p_item->lock ); + if( vlc_meta_Get( p_meta, vlc_meta_Title ) != NULL ) + input_item_SetName( p_item, vlc_meta_Get( p_meta, vlc_meta_Title ) ); - if( vlc_meta_Get( p_meta, vlc_meta_Title ) && !p_item->b_fixed_name ) - psz_title = strdup( vlc_meta_Get( p_meta, vlc_meta_Title ) ); + char *psz_arturl = NULL; + if( vlc_meta_Get( p_item->p_meta, vlc_meta_ArtworkURL ) != NULL ) + psz_arturl = input_item_GetArtURL( p_item ); /* save value */ + vlc_mutex_lock( &p_item->lock ); vlc_meta_Merge( p_item->p_meta, p_meta ); - - if( !psz_arturl || *psz_arturl == '\0' ) - { - const char *psz_tmp = vlc_meta_Get( p_item->p_meta, vlc_meta_ArtworkURL ); - if( psz_tmp ) - psz_arturl = strdup( psz_tmp ); - } vlc_mutex_unlock( &p_item->lock ); - if( psz_arturl && *psz_arturl ) - { + if( psz_arturl != NULL ) /* restore/favor previously set item art URL */ input_item_SetArtURL( p_item, psz_arturl ); + else + psz_arturl = input_item_GetArtURL( p_item ); - if( !strncmp( psz_arturl, "attachment://", strlen("attachment") ) ) - { - /* Don't look for art cover if sout - * XXX It can change when sout has meta data support */ - if( p_input->p->p_sout && !p_input->b_preparsing ) - input_item_SetArtURL( p_item, "" ); - else - input_ExtractAttachmentAndCacheArt( p_input ); - } + if( psz_arturl != NULL && !strncmp( psz_arturl, "attachment://", 13 ) ) + { /* Clear art cover if streaming out. + * FIXME: Why? Remove this when sout gets meta data support. */ + if( p_input->p->p_sout && !p_input->b_preparsing ) + input_item_SetArtURL( p_item, NULL ); + else + input_ExtractAttachmentAndCacheArt( p_input, psz_arturl + 13 ); } free( psz_arturl ); - if( psz_title ) - { - input_item_SetName( p_item, psz_title ); - free( psz_title ); - } input_item_SetPreparsed( p_item, true ); input_SendEventMeta( p_input ); @@ -1558,13 +1547,13 @@ static void EsCreateDecoder( es_out_t *out, es_out_id_t *p_es ) if( p_es->p_dec ) { if( p_sys->b_buffering ) - input_DecoderStartBuffering( p_es->p_dec ); + input_DecoderStartWait( p_es->p_dec ); if( !p_es->p_master && p_sys->p_sout_record ) { p_es->p_dec_record = input_DecoderNew( p_input, &p_es->fmt, p_es->p_pgrm->p_clock, p_sys->p_sout_record ); if( p_es->p_dec_record && p_sys->b_buffering ) - input_DecoderStartBuffering( p_es->p_dec_record ); + input_DecoderStartWait( p_es->p_dec_record ); } } @@ -1829,6 +1818,16 @@ static void EsOutSelect( es_out_t *out, es_out_id_t *es, bool b_force ) i_wanted = es->i_channel; } } + else if ( es->fmt.i_codec == EsOutFourccClosedCaptions[0] || + es->fmt.i_codec == EsOutFourccClosedCaptions[1] || + es->fmt.i_codec == EsOutFourccClosedCaptions[2] || + es->fmt.i_codec == EsOutFourccClosedCaptions[3]) + { + /* We don't want to enable on initial create since p_master + isn't set yet (otherwise we will think it's a standard + ES_SUB stream and cause a resource leak) */ + return; + } else { /* If there is no user preference, select the default subtitle @@ -1839,6 +1838,9 @@ static void EsOutSelect( es_out_t *out, es_out_id_t *es, bool b_force ) ( p_sys->p_es_sub && p_sys->p_es_sub->fmt.i_priority < es->fmt.i_priority ) ) i_wanted = es->i_channel; + else if( p_sys->p_es_sub && + p_sys->p_es_sub->fmt.i_priority >= es->fmt.i_priority ) + i_wanted = p_sys->p_es_sub->i_channel; } if( p_sys->i_sub_last >= 0 ) @@ -2010,6 +2012,10 @@ static int EsOutSend( es_out_t *out, es_out_id_t *es, block_t *p_block ) /* */ es->pb_cc_present[i] = true; + + /* Enable if user specified on command line */ + if (p_sys->i_sub_last == i) + EsOutSelect(out, es->pp_cc_es[i], true); } vlc_mutex_unlock( &p_sys->lock ); @@ -2031,7 +2037,7 @@ static void EsOutDel( es_out_t *out, es_out_id_t *es ) /* We don't try to reselect */ if( es->p_dec ) { - while( vlc_object_alive(p_sys->p_input) && !p_sys->b_buffering && es->p_dec ) + while( vlc_object_alive(p_sys->p_input) && !p_sys->b_buffering ) { if( input_DecoderIsEmpty( es->p_dec ) && ( !es->p_dec_record || input_DecoderIsEmpty( es->p_dec_record ) )) @@ -2309,6 +2315,9 @@ static int EsOutControlLocked( es_out_t *out, int i_query, va_list args ) EsOutIsExtraBufferingAllowed( out ), i_pcr, mdate() ); + if( !p_sys->p_pgrm ) + return VLC_SUCCESS; + if( p_sys->b_buffering ) { /* Check buffering state on master clock update */ @@ -2476,7 +2485,7 @@ static int EsOutControlLocked( es_out_t *out, int i_query, va_list args ) { const int i_id = (int)va_arg( args, int ); es_out_id_t *p_es = EsOutGetFromID( out, i_id ); - int i_new_query; + int i_new_query = 0; switch( i_query ) { @@ -2484,7 +2493,7 @@ static int EsOutControlLocked( es_out_t *out, int i_query, va_list args ) case ES_OUT_RESTART_ES_BY_ID: i_new_query = ES_OUT_RESTART_ES; break; case ES_OUT_SET_ES_DEFAULT_BY_ID: i_new_query = ES_OUT_SET_ES_DEFAULT; break; default: - assert(0); + vlc_assert_unreachable(); } /* TODO if the lock is made non recursive it should be changed */ int i_ret = es_out_Control( out, i_new_query, p_es );