[vlc-devel] [PATCH v2] demux: avformat: handle AV_PKT_DATA_NEW_EXTRADATA
Zhao Zhili
quinkblack at foxmail.com
Mon Jan 4 10:39:00 UTC 2021
This is a best-effort solution. Seek may not work as expected.
---
v2:
1. check on p_track->p_es before es_format_Copy
2. check ES_OUT_SET_ES_FMT return value
3. ignore new extradata which is the same as previous version
modules/demux/avformat/demux.c | 38 +++++++++++++++++++++++++++++++++-
1 file changed, 37 insertions(+), 1 deletion(-)
diff --git a/modules/demux/avformat/demux.c b/modules/demux/avformat/demux.c
index 4a765b7352..b0d231d160 100644
--- a/modules/demux/avformat/demux.c
+++ b/modules/demux/avformat/demux.c
@@ -55,6 +55,7 @@ struct avformat_track_s
{
es_out_id_t *p_es;
vlc_tick_t i_pcr;
+ es_format_t es_format;
};
/*****************************************************************************
@@ -711,6 +712,8 @@ int avformat_OpenDemux( vlc_object_t *p_this )
es_fmt.i_id = i;
p_track->p_es = es_out_Add( p_demux->out, &es_fmt );
+ if( p_track->p_es != NULL )
+ es_format_Copy( &p_track->es_format, &es_fmt );
if( p_track->p_es && (s->disposition & AV_DISPOSITION_DEFAULT) )
es_out_Control( p_demux->out, ES_OUT_SET_ES_DEFAULT, p_track->p_es );
@@ -766,7 +769,12 @@ void avformat_CloseDemux( vlc_object_t *p_this )
demux_t *p_demux = (demux_t*)p_this;
demux_sys_t *p_sys = p_demux->p_sys;
- free( p_sys->tracks );
+ if( p_sys->tracks != NULL )
+ {
+ for( unsigned i = 0; i < p_sys->i_tracks; i++ )
+ es_format_Clean( &p_sys->tracks[i].es_format );
+ free( p_sys->tracks );
+ }
if( p_sys->ic )
{
@@ -821,6 +829,34 @@ static int Demux( demux_t *p_demux )
av_packet_unref( &pkt );
return 1;
}
+
+ // handle extra data change, this can happen for FLV
+ int side_data_size;
+ uint8_t *side_data = av_packet_get_side_data( &pkt, AV_PKT_DATA_NEW_EXTRADATA, &side_data_size );
+ if( side_data != NULL && side_data_size > 0 ) {
+ // ignore new extradata which is the same as previous version
+ if( side_data_size != p_track->es_format.i_extra ||
+ memcmp( side_data, p_track->es_format.p_extra, side_data_size ) != 0 )
+ {
+ msg_Warn( p_demux, "New extra data found, seek may not work as expected" );
+ void *p_extra = realloc( p_track->es_format.p_extra, side_data_size );
+ if( p_extra == NULL )
+ {
+ av_packet_unref( &pkt );
+ return 0;
+ }
+ p_track->es_format.p_extra = p_extra;
+ memcpy( p_track->es_format.p_extra, side_data, side_data_size );
+ p_track->es_format.i_extra = side_data_size;
+ if( es_out_Control( p_demux->out, ES_OUT_SET_ES_FMT,
+ p_track->p_es, &p_track->es_format ) != VLC_SUCCESS )
+ {
+ av_packet_unref( &pkt );
+ return 0;
+ }
+ }
+ }
+
if( p_stream->codecpar->codec_id == AV_CODEC_ID_SSA )
{
p_frame = BuildSsaFrame( &pkt, p_sys->i_ssa_order++ );
--
2.25.1
More information about the vlc-devel
mailing list