Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • videolan/vlc
  • chouquette/vlc
  • bakiewicz.marek122/vlc
  • devnexen/vlc
  • rohanrajpal/vlc
  • blurrrb/vlc
  • gsoc/gsoc2019/darkapex/vlc
  • b1ue/vlc
  • fkuehne/vlc
  • magsoft/vlc
  • chub/vlc
  • cramiro9/vlc
  • robUx4/vlc
  • rom1v/vlc
  • akshayaky/vlc
  • tmk907/vlc
  • akymaster/vlc
  • govind.sharma/vlc
  • psilokos/vlc
  • xjbeta/vlc
  • jahan/vlc
  • 1480c1/vlc
  • amanchande/vlc
  • aaqib/vlc
  • rist/vlc
  • apol/vlc
  • mindfreeze/vlc
  • alexandre-janniaux/vlc
  • sandsmark/vlc
  • jagannatharjun/vlc
  • gsoc/gsoc2020/matiaslgonzalez/vlc
  • gsoc/gsoc2020/jagannatharjun/vlc
  • mstorsjo/vlc
  • gsoc/gsoc2020/vedenta/vlc
  • gsoc/gsoc2020/arnav-ishaan/vlc
  • gsoc/gsoc2020/andreduong/vlc
  • fuzun/vlc
  • gsoc/gsoc2020/vatsin/vlc
  • gsoc/gsoc2020/sagid/vlc
  • yaron/vlc
  • Phoenix/vlc
  • Garf/vlc
  • ePiratWorkarounds/vlc
  • tguillem/vlc
  • jnqnfe/vlc
  • mdc/vlc
  • Vedaa/vlc
  • rasa/vlc
  • quink/vlc
  • yealo/vlc
  • aleksey_ak/vlc
  • ePirat/vlc
  • ilya.yanok/vlc
  • asenat/vlc
  • m/vlc
  • bunjee/vlc
  • BLumia/vlc
  • sagudev/vlc
  • hamedmonji30/vlc
  • nullgemm/vlc
  • DivyamAhuja/vlc
  • thesamesam/vlc
  • dag7/vlc
  • snehil101/vlc
  • haasn/vlc
  • jbk/vlc
  • ValZapod/vlc
  • mfkl/vlc
  • WangChuan/vlc
  • core1024/vlc
  • GhostVaibhav/vlc
  • dfuhrmann/vlc
  • davide.prade/vlc
  • tmatth/vlc
  • Courmisch/vlc
  • zouya/vlc
  • hpi/vlc
  • EwoutH/vlc
  • aleung27/vlc
  • hengwu0/vlc
  • saladin/vlc
  • ashuio/vlc
  • richselwood/vlc
  • verma16Ayush/vlc
  • chemicalflash/vlc
  • PoignardAzur/vlc
  • huangjieNT/vlc
  • Blake-Haydon/vlc
  • AnuthaDev/vlc
  • gsoc/gsoc2021/mpd/vlc
  • nicolas_lequec/vlc
  • sambassaly/vlc
  • thresh/vlc
  • bonniegong/vlc
  • myaashish/vlc
  • stavros.vagionitis/vlc
  • ileoo/vlc
  • louis-santucci/vlc
  • cchristiansen/vlc
  • sabyasachi07/vlc
  • AbduAmeen/vlc
  • ashishb0410/vlc
  • urbanhusky/vlc
  • davidepietrasanta/vlc
  • riksleutelstad/vlc
  • jeremyVignelles/vlc
  • komh/vlc
  • iamjithinjohn/vlc
  • JohannesKauffmann/vlc2
  • kunglao/vlc
  • natzberg/vlc
  • jill/vlc
  • cwendling/vlc
  • adufou/vlc
  • ErwanAirone/vlc
  • HasinduDilshan10/vlc
  • vagrantc/vlc
  • rafiv/macos-bigsur-icon
  • Aymeriic/vlc
  • saranshg20/vlc
  • metzlove24/vlc
  • linkfanel/vlc
  • Ds886/vlc
  • metehan-arslan/vlc
  • Skantes/vlc
  • kgsandundananjaya96/vlc
  • mitchcapper/vlc
  • advaitgupta/vlc
  • StefanBruens/vlc
  • ratajs/vlc
  • T.M.F.B.3761/vlc
  • m222059/vlc
  • casemerrick/vlc
  • joshuaword2alt/vlc
  • sjwaddy/vlc
  • dima/vlc
  • Ybalrid/vlc
  • umxprime/vlc
  • eschmidt/vlc
  • vannieuwenhuysenmichelle/vlc
  • badcf00d/vlc
  • wesinator/vlc
  • louis/vlc
  • xqq/vlc
  • EmperorYP7/vlc
  • NicoLiam/vlc
  • loveleen/vlc
  • rofferom/vlc
  • rbultje/vlc
  • TheUnamed/vlc
  • pratiksharma341/vlc
  • Saurab17/vlc
  • purist.coder/vlc
  • Shuicheng/vlc
  • mdrrubel292/vlc
  • silverbleu00/vlc
  • metif12/vlc
  • asher-m/vlc
  • jeffk/vlc
  • Brandonbr1/vlc
  • beautyyuyanli/vlc
  • rego21/vlc
  • muyangren907/vlc
  • collectionbylawrencejason/vlc
  • evelez/vlc
  • GSMgeeth/vlc
  • Oneric/vlc
  • TJ5/vlc
  • XuanTung95/vlc
  • darrenjenny21/vlc
  • Trenly/vlc
  • RockyTDR/vlc
  • mjakubowski/vlc
  • caprica/vlc
  • ForteFrankie/vlc
  • seannamiller19/vlc
  • junlon2006/vlc
  • kiwiren6666/vlc
  • iuseiphonexs/vlc
  • fenngtun/vlc
  • Rajdutt999/vlc
  • typx/vlc
  • leon.vitanos/vlc
  • robertogarci0938/vlc
  • gsoc/gsoc2022/luc65r/vlc-mpd
  • skeller/vlc
  • MCJack123/vlc
  • luc65r/vlc-mpd
  • popov895/vlc
  • claucambra/vlc
  • brad/vlc
  • matthewmurua88/vlc
  • Tomas8874/vlc
  • philenotfound/vlc
  • makita-do3/vlc
  • LZXCorp/vlc
  • mar0x/vlc
  • senojetkennedy0102/vlc
  • shaneb243/vlc
  • ahmadbader/vlc
  • rajduttcse26/vlc-audio-filters
  • Juniorzito8415/vlc
  • achernyakov/vlc
  • lucasjetgroup/vlc
  • pupdoggy666/vlc
  • gmde9363/vlc
  • alexnwayne/vlc
  • bahareebrahimi781/vlc
  • hamad633666/vlc
  • umghof3112/vlc
  • joe0199771874/vlc
  • Octocats66666666/vlc
  • jjm_223/vlc
  • btech10110.19/vlc
  • sunnykfc028/vlc-audio-filters
  • loic/vlc
  • nguyenminhducmx1/vlc
  • JanekKrueger/vlc
  • bstubbington2/vlc
  • rcombs/vlc
  • Ordissimo/vlc
  • king7532/vlc
  • noobsauce101/vlc
  • schong0525/vlc
  • myQwil/vlc
  • apisbg91/vlc
  • geeboy0101017/vlc
  • kim.faughey/vlc
  • nurupo/vlc
  • yyusea/vlc
  • 0711235879.khco/vlc
  • ialo/vlc
  • iloveyeye2/vlc
  • gdtdftdqtd/vlc
  • leandroconsiglio/vlc
  • AndyHTML2012/vlc
  • ncz/vlc
  • lucenticus/vlc
  • knr1931/vlc
  • kjoonlee/vlc
  • chandrakant100/vlc-qt
  • johge42/vlc
  • polter/vlc
  • hexchain/vlc
  • Tushwrld/vlc
  • mztea928/vlc
  • jbelloncastro/vlc
  • alvinhochun/vlc
  • ghostpiratecrow/vlc
  • ujjwaltwitx/vlc
  • alexsonarin06/vlc
  • adrianbon76/vlc
  • altsod/vlc
  • damien.lucas44/vlc
  • dmytrivtaisa/vlc
  • utk202/vlc
  • aaxhrj/vlc
  • thomas.hermes/vlc
  • structurenewworldorder/vlc
  • slomo/vlc
  • wantlamy/vlc
  • musc.o3cminc/vlc
  • thebarshablog/vlc
  • kerrick/vlc
  • kratos142518/vlc
  • leogps/vlc
  • vacantron/vlc
  • luna_koly/vlc
  • Ratio2/vlc
  • anuoshemohammad/vlc
  • apsun/vlc
  • aaa1115910/vlc
  • alimotmoyo/vlc
  • Ambossmann/vlc
  • Sam-LearnsToCode/vlc
  • Chilledheart/vlc
  • Labnann/vlc
  • ktcoooot1/vlc
  • mohit-marathe/vlc
  • johnddx/vlc
  • manstabuk/vlc
  • Omar-ahmed314/vlc
  • vineethkm/vlc
  • 9Enemi86/vlc
  • radoslav.m.panteleev/vlc
  • ashishami2002/vlc
  • Corbax/vlc
  • firnasahmed/vlc
  • pelayarmalam4/vlc
  • c0ff330k/vlc
  • shikhindahikar/vlc
  • l342723951/vlc
  • christianschwandner/vlc
  • douniwan5788/vlc
  • 7damian7/vlc
  • ferdnyc/vlc
  • f.ales1/vlc
  • pandagby/vlc
  • BaaBaa/vlc
  • jewe37/vlc
  • w00drow/vlc
  • russelltg/vlc
  • ironicallygod/vlc
  • soumyaDghosh/vlc
  • linzihao1999/vlc
  • deyayush6/vlc
  • mibi88/vlc
  • newabdallah10/vlc
  • jhorbincolombia/vlc
  • rimvihaqueshupto/vlc
  • andrewkhon98/vlc
  • fab78/vlc
  • lapaz17/vlc
  • amanna13/vlc
  • mdakram28/vlc
  • 07jw1980/vlc
  • sohamgupta/vlc
  • Eson-Jia1/vlc
  • Sumou/vlc
  • vikram-kangotra/vlc
  • chalice191/vlc
  • olivercalder/vlc
  • aaasg4001/vlc
  • zipdox/vlc
  • kwizart/vlc
  • Dragon-S/vlc
  • jdemeule/vlc
  • gabriel_lt/vlc
  • locutusofborg/vlc
  • sammirata/vlc-librist
  • another/vlc
  • Benjamin_Loison/vlc
  • ahmedmoselhi/vlc
  • petergaal/vlc
  • huynhsontung/vlc
  • dariusmihut/vlc
  • tvermaashutosh/vlc
  • buti/vlc
  • Niram7777/vlc
  • rohan-here/vlc
  • balaji-sivasakthi/vlc
  • rlindner81/vlc
  • Kakadus/vlc
  • djain/vlc
  • ABBurmeister/vlc
  • craighuggins/vlc
  • orbea/vlc
  • maxos/vlc
  • aakarshmj/vlc
  • kblaschke/vlc
  • ankitm/vlc
  • advait-0/vlc
  • mohak2003/vlc
  • yselkowitz/vlc
  • AZM999/vlc-azm
  • andrey.turkin/vlc
  • Disha-Baghel/vlc
  • nowrep/vlc
  • Apeng/vlc
  • Choucroute_melba/vlc
  • autra/vlc
  • eclipseo/vlc
  • fhuber/vlc
  • olafhering/vlc
  • sdasda7777/vlc
  • 1div0/vlc
  • skosnits/vlc-extended-playlist-support
  • dnicolson/vlc
  • Timshel/vlc
  • octopols/vlc
  • MangalK/vlc
  • nima64/vlc
  • misawai/vlc
  • Alexander-Wilms/vlc
  • Maxime2/vlc-fork-for-visualizer
  • ww/vlc
  • jeske/vlc
  • sgross-emlix/vlc
  • morenonatural/vlc
  • freakingLovesVLC/vlc
  • borisgolovnev/vlc
  • mpromonet/vlc
  • diogo.simao-marques/vlc
  • masstock/vlc
  • pratikpatel8982/vlc
  • hugok79/vlc
  • longervision/vlc
  • abhiudaysurya/vlc
  • rishabhgarg/vlc
  • tumic/vlc
  • cart/vlc
  • shubham442/vlc
  • Aditya692005/vlc
  • sammirata/vlc4
  • syrykh/vlc
  • Vvorcun/macos-new-icon
  • AyaanshC/vlc
  • nasso/vlc
  • Quark/vlc
  • sebastinas/vlc
  • rhstone/vlc
  • talregev/vlc
  • Managor/vlc
403 results
Show changes
Commits on Source (7)
......@@ -3291,10 +3291,7 @@ static int MP4_ReadBox_stdp( stream_t *p_stream, MP4_Box_t *p_box )
static void MP4_FreeBox_elst( MP4_Box_t *p_box )
{
free( p_box->data.p_elst->i_segment_duration );
free( p_box->data.p_elst->i_media_time );
free( p_box->data.p_elst->i_media_rate_integer );
free( p_box->data.p_elst->i_media_rate_fraction );
free( p_box->data.p_elst->entries );
}
static int MP4_ReadBox_elst( stream_t *p_stream, MP4_Box_t *p_box )
......@@ -3302,39 +3299,36 @@ static int MP4_ReadBox_elst( stream_t *p_stream, MP4_Box_t *p_box )
uint32_t count;
MP4_READBOX_ENTER( MP4_Box_data_elst_t, MP4_FreeBox_elst );
MP4_Box_data_elst_t *p_elst = p_box->data.p_elst;
MP4_GETVERSIONFLAGS( p_box->data.p_elst );
MP4_GET4BYTES( count );
uint8_t i_version;
uint32_t dummy;
MP4_GET1BYTE( i_version );
MP4_GET3BYTES( dummy ); VLC_UNUSED(dummy);
if( i_version > 1 )
MP4_READBOX_EXIT( 0 );
MP4_GET4BYTES( count );
if( count == 0 )
MP4_READBOX_EXIT( 1 );
uint32_t i_entries_max = i_read / ((p_box->data.p_elst->i_version == 1) ? 20 : 12);
uint32_t i_entries_max = i_read / ((i_version == 1) ? 20 : 12);
if( count > i_entries_max )
count = i_entries_max;
p_box->data.p_elst->i_segment_duration = vlc_alloc( count,
sizeof(uint64_t) );
p_box->data.p_elst->i_media_time = vlc_alloc( count, sizeof(int64_t) );
p_box->data.p_elst->i_media_rate_integer = vlc_alloc( count,
sizeof(uint16_t) );
p_box->data.p_elst->i_media_rate_fraction = vlc_alloc( count,
sizeof(uint16_t) );
if( p_box->data.p_elst->i_segment_duration == NULL
|| p_box->data.p_elst->i_media_time == NULL
|| p_box->data.p_elst->i_media_rate_integer == NULL
|| p_box->data.p_elst->i_media_rate_fraction == NULL )
{
p_elst->entries = vlc_alloc( count, sizeof(*p_elst->entries) );
if( !p_elst->entries )
MP4_READBOX_EXIT( 0 );
}
p_box->data.p_elst->i_entry_count = count;
p_elst->i_entry_count = count;
for( uint32_t i = 0; i < count; i++ )
{
uint64_t segment_duration;
int64_t media_time;
if( p_box->data.p_elst->i_version == 1 )
if( i_version == 1 )
{
union { int64_t s; uint64_t u; } u;
......@@ -3351,15 +3345,15 @@ static int MP4_ReadBox_elst( stream_t *p_stream, MP4_Box_t *p_box )
media_time = u.s;
}
p_box->data.p_elst->i_segment_duration[i] = segment_duration;
p_box->data.p_elst->i_media_time[i] = media_time;
MP4_GET2BYTES( p_box->data.p_elst->i_media_rate_integer[i] );
MP4_GET2BYTES( p_box->data.p_elst->i_media_rate_fraction[i] );
p_elst->entries[i].i_segment_duration = segment_duration;
p_elst->entries[i].i_media_time = media_time;
MP4_GET2BYTES( p_elst->entries[i].i_media_rate_integer );
MP4_GET2BYTES( p_elst->entries[i].i_media_rate_fraction );
}
#ifdef MP4_VERBOSE
msg_Dbg( p_stream, "read box: \"elst\" entry-count %" PRIu32,
p_box->data.p_elst->i_entry_count );
p_elst->i_entry_count );
#endif
MP4_READBOX_EXIT( 1 );
}
......
......@@ -984,18 +984,19 @@ typedef struct MP4_Box_data_stdp_s
} MP4_Box_data_stdp_t;
typedef struct MP4_Box_data_elst_s
typedef struct
{
uint8_t i_version;
uint32_t i_flags;
uint64_t i_segment_duration; /* movie timescale */
int64_t i_media_time; /* media(track) timescale */
uint16_t i_media_rate_integer;
uint16_t i_media_rate_fraction;
} MP4_Box_data_elst_entry_t;
typedef struct MP4_Box_data_elst_s
{
uint32_t i_entry_count;
uint64_t *i_segment_duration; /* movie timescale */
int64_t *i_media_time; /* media(track) timescale */
uint16_t *i_media_rate_integer;
uint16_t *i_media_rate_fraction;
MP4_Box_data_elst_entry_t *entries;
} MP4_Box_data_elst_t;
......
......@@ -499,6 +499,52 @@ static const mp4_chunk_t * MP4_TrackChunkForSample( const mp4_track_t *p_track,
return NULL;
}
static stime_t MP4_MapTrackTimeIntoTimeline( const mp4_track_t *p_track,
uint32_t i_movie_timescale,
stime_t i_time )
{
if( !p_track->p_elst || p_track->BOXDATA(p_elst)->i_entry_count == 0 )
return i_time;
const MP4_Box_data_elst_entry_t *edit =
&p_track->BOXDATA(p_elst)->entries[p_track->i_elst];
/* convert to offset in our current edit */
if( edit->i_media_time > 0 && p_track->i_start_dts >= edit->i_media_time )
i_time -= edit->i_media_time;
/* convert media timeline to track timescale */
stime_t i_media_elst_start = MP4_rescale( p_track->i_elst_time,
i_movie_timescale,
p_track->i_timescale );
/* add to timeline start in current edit */
i_time += i_media_elst_start;
return i_time;
}
static stime_t MP4_MapMediaTimelineToTrackTime( const mp4_track_t *p_track,
uint32_t i_movie_timescale,
stime_t i_time )
{
if( !p_track->p_elst || p_track->BOXDATA(p_elst)->i_entry_count == 0 )
return i_time;
const MP4_Box_data_elst_t *elst = p_track->BOXDATA(p_elst);
/* convert media timeline to track timescale */
stime_t i_media_elst_start = MP4_rescale( p_track->i_elst_time,
i_movie_timescale,
p_track->i_timescale );
/* convert to timeline offset in current edit */
i_time -= i_media_elst_start;
/* add edit start in track samples time to get track sample time */
if( elst->entries[p_track->i_elst].i_media_time > 0 )
i_time += elst->entries[p_track->i_elst].i_media_time;
return i_time;
}
static stime_t MP4_ChunkGetSampleDTS( const mp4_chunk_t *p_chunk,
uint32_t i_sample )
{
......@@ -548,25 +594,9 @@ static vlc_tick_t MP4_TrackGetDTSPTS( demux_t *p_demux, const mp4_track_t *p_tra
uint32_t delta = p_track->i_next_delta;
/* now handle elst */
if( p_track->p_elst && p_track->BOXDATA(p_elst)->i_entry_count )
{
const MP4_Box_data_elst_t *elst = p_track->BOXDATA(p_elst);
/* convert to offset */
if( elst->i_media_time[p_track->i_elst] > 0 &&
( elst->i_media_rate_integer[p_track->i_elst] > 0 ||
elst->i_media_rate_fraction[p_track->i_elst] > 0 ) )
{
if( p_track->i_start_dts >= elst->i_media_time[p_track->i_elst] )
{
sdts -= elst->i_media_time[p_track->i_elst];
}
}
}
sdts = MP4_MapTrackTimeIntoTimeline( p_track, p_sys->i_timescale, sdts );
vlc_tick_t i_dts = MP4_rescale_mtime( sdts, p_track->i_timescale);
/* add i_elst_time */
i_dts += MP4_rescale_mtime( p_track->i_elst_time, p_sys->i_timescale );
if( pi_nzpts )
{
......@@ -1813,8 +1843,8 @@ static int Seek( demux_t *p_demux, vlc_tick_t i_date, bool b_accurate )
}
}
msg_Dbg( p_demux, "seeking with %"PRId64 "ms %s", MS_FROM_VLC_TICK(i_date - i_start),
!b_accurate ? "alignment" : "preroll (use input-fast-seek to avoid)" );
msg_Dbg( p_demux, "seeking with %"PRId64 "ms %s to %ld", MS_FROM_VLC_TICK(i_date - i_start),
!b_accurate ? "alignment" : "preroll (use input-fast-seek to avoid)", i_date );
for( i_track = 0; i_track < p_sys->i_tracks; i_track++ )
{
......@@ -3315,9 +3345,6 @@ static int TrackTimeToSampleChunk( demux_t *p_demux, mp4_track_t *p_track,
MP4_TrackSetELST( p_demux, p_track, start );
if( p_track->p_elst && p_track->BOXDATA(p_elst)->i_entry_count > 0 )
{
MP4_Box_data_elst_t *elst = p_track->BOXDATA(p_elst);
int64_t i_mvt= MP4_rescale_qtime( start, p_sys->i_timescale );
/* now calculate i_start for this elst */
/* offset */
if( start < MP4_rescale_mtime( p_track->i_elst_time, p_sys->i_timescale ) )
......@@ -3328,18 +3355,13 @@ static int TrackTimeToSampleChunk( demux_t *p_demux, mp4_track_t *p_track,
return VLC_SUCCESS;
}
/* to track time scale */
i_start = MP4_rescale_qtime( start, p_track->i_timescale );
/* add elst offset */
if( ( elst->i_media_rate_integer[p_track->i_elst] > 0 ||
elst->i_media_rate_fraction[p_track->i_elst] > 0 ) &&
elst->i_media_time[p_track->i_elst] > 0 )
{
i_start += elst->i_media_time[p_track->i_elst];
}
i_start = MP4_rescale_qtime( start, p_track->i_timescale );
/* map through elst offset */
i_start = MP4_MapMediaTimelineToTrackTime( p_track, p_sys->i_timescale, i_start );
msg_Dbg( p_demux, "elst (%d) gives %"PRId64"ms (movie)-> %"PRId64
"ms (track)", p_track->i_elst,
MP4_rescale( i_mvt, p_sys->i_timescale, 1000 ),
MS_FROM_VLC_TICK(start),
MP4_rescale( i_start, p_track->i_timescale, 1000 ) );
}
else
......@@ -3411,12 +3433,14 @@ static bool FormatIsCompatible( const es_format_t *p_fmt1, const es_format_t *p_
return es_format_IsSimilar( p_fmt1, p_fmt2 );
}
static int TrackUpdateFormat( demux_t *p_demux, mp4_track_t *p_track, uint32_t i_chunk )
static int TrackUpdateFormat( demux_t *p_demux, mp4_track_t *p_track,
uint32_t i_previous_chunk )
{
uint32_t i_chunk = p_track->i_chunk;
/* now see if actual es is ok */
if( p_track->i_chunk >= p_track->i_chunk_count ||
(p_track->chunk[p_track->i_chunk].i_sample_description_index !=
p_track->chunk[i_chunk].i_sample_description_index ) )
if( i_previous_chunk != i_chunk &&
p_track->chunk[i_previous_chunk].i_sample_description_index !=
p_track->chunk[i_chunk].i_sample_description_index )
{
msg_Warn( p_demux, "recreate ES for track[Id 0x%x]",
p_track->i_track_ID );
......@@ -3478,7 +3502,7 @@ static int TrackUpdateFormat( demux_t *p_demux, mp4_track_t *p_track, uint32_t i
static int TrackGotoChunkSample( demux_t *p_demux, mp4_track_t *p_track,
uint32_t i_chunk, uint32_t i_sample )
{
if( TrackUpdateFormat( p_demux, p_track, i_chunk ) != VLC_SUCCESS )
if( TrackUpdateFormat( p_demux, p_track, p_track->i_chunk ) != VLC_SUCCESS )
return VLC_EGENERIC;
p_track->i_chunk = i_chunk;
......@@ -3525,6 +3549,8 @@ static void TrackUpdateSampleAndTimes( mp4_track_t *p_track )
{
const mp4_chunk_t *p_chunk = &p_track->chunk[p_track->i_chunk];
uint32_t i_chunk_sample = p_track->i_sample - p_chunk->i_sample_first;
if( i_chunk_sample > p_chunk->i_sample_count && p_chunk->i_sample_count )
i_chunk_sample = p_chunk->i_sample_count - 1;
p_track->i_next_dts = MP4_ChunkGetSampleDTS( p_chunk, i_chunk_sample );
stime_t i_next_delta;
if( !MP4_ChunkGetSampleCTSDelta( p_chunk, i_chunk_sample, &i_next_delta ) )
......@@ -3668,14 +3694,15 @@ static void MP4_TrackSetup( demux_t *p_demux, mp4_track_t *p_track,
msg_Warn( p_demux, "elst box found" );
for( i = 0; i < elst->i_entry_count; i++ )
{
const MP4_Box_data_elst_entry_t *edit = &elst->entries[i];
msg_Dbg( p_demux, " - [%d] duration=%"PRId64"ms media time=%"PRId64
"ms) rate=%d.%d", i,
MP4_rescale( elst->i_segment_duration[i], p_sys->i_timescale, 1000 ),
elst->i_media_time[i] >= 0 ?
MP4_rescale( elst->i_media_time[i], p_track->i_timescale, 1000 ) :
MP4_rescale( edit->i_segment_duration, p_sys->i_timescale, 1000 ),
edit->i_media_time >= 0 ?
MP4_rescale( edit->i_media_time, p_track->i_timescale, 1000 ) :
INT64_C(-1),
elst->i_media_rate_integer[i],
elst->i_media_rate_fraction[i] );
edit->i_media_rate_integer,
edit->i_media_rate_fraction );
}
if( var_InheritBool( p_demux, CFG_PREFIX"editlist" ) )
......@@ -3776,12 +3803,12 @@ static void MP4_TrackSetup( demux_t *p_demux, mp4_track_t *p_track,
#define MAX_SELECTABLE (INT_MAX - ES_PRIORITY_SELECTABLE_MIN)
for ( uint32_t i=0; i<p_track->BOXDATA(p_elst)->i_entry_count; i++ )
{
if ( p_track->BOXDATA(p_elst)->i_media_time[i] >= 0 &&
p_track->BOXDATA(p_elst)->i_segment_duration[i] )
const MP4_Box_data_elst_entry_t *edit = &p_track->BOXDATA(p_elst)->entries[i];
if ( edit->i_media_time >= 0 && edit->i_segment_duration )
{
/* We do selection by inverting start time into priority.
The track with earliest edit will have the highest prio */
const int i_time = __MIN( MAX_SELECTABLE, p_track->BOXDATA(p_elst)->i_media_time[i] );
const int i_time = __MIN( MAX_SELECTABLE, edit->i_media_time );
p_track->fmt.i_priority = ES_PRIORITY_SELECTABLE_MIN + MAX_SELECTABLE - i_time;
break;
}
......@@ -4195,52 +4222,99 @@ static uint64_t MP4_TrackGetPos( mp4_track_t *p_track )
return i_pos;
}
static int MP4_TrackNextSample( demux_t *p_demux, mp4_track_t *p_track, uint32_t i_samples )
static int MP4_TrackSetNextELST( mp4_track_t *tk )
{
if ( UINT32_MAX - p_track->i_sample < i_samples )
{
p_track->i_sample = UINT32_MAX;
if( !tk->p_elst ||
tk->i_elst == UINT32_MAX - 1 ||
tk->i_elst + 1 >= tk->BOXDATA(p_elst)->i_entry_count )
return VLC_EGENERIC;
tk->i_elst_time += tk->BOXDATA(p_elst)->entries[tk->i_elst++].i_segment_duration;
return VLC_SUCCESS;
}
static int MP4_TrackUpdateELST( mp4_track_t *tk, uint32_t i_movie_timescale,
stime_t i_track_time, uint32_t i_track_sample )
{
if( !tk->p_elst || tk->BOXDATA(p_elst)->i_entry_count == 0 )
return VLC_SUCCESS;
if( i_track_sample >= tk->i_sample_count )
return MP4_TrackSetNextELST( tk );
vlc_tick_t i_time = MP4_rescale_mtime( i_track_time, tk->i_timescale );
for(;;)
{
const MP4_Box_data_elst_entry_t *edit = &tk->BOXDATA(p_elst)->entries[tk->i_elst];
vlc_tick_t i_end = MP4_rescale_mtime( edit->i_media_time, tk->i_timescale ) +
MP4_rescale_mtime( edit->i_segment_duration, i_movie_timescale );
if ( i_time < i_end || MP4_TrackSetNextELST( tk ) )
break;
}
p_track->i_sample += i_samples;
return VLC_SUCCESS;
}
if( p_track->i_sample >= p_track->i_sample_count )
return VLC_EGENERIC;
static int MP4_TrackNextSample( demux_t *p_demux, mp4_track_t *p_track, uint32_t i_samples )
{
demux_sys_t *p_sys = p_demux->p_sys;
/* Have we changed chunk ? */
if( p_track->i_sample >=
p_track->chunk[p_track->i_chunk].i_sample_first +
p_track->chunk[p_track->i_chunk].i_sample_count )
if ( UINT32_MAX - p_track->i_sample < i_samples )
i_samples = UINT32_MAX - p_track->i_sample; /* Ensure we won't overflow next add */
p_track->i_sample += i_samples;
const uint32_t i_previous_chunk = p_track->i_chunk;
if( p_track->i_sample < p_track->i_sample_count )
{
if( TrackGotoChunkSample( p_demux, p_track, p_track->i_chunk + 1,
p_track->i_sample ) )
/* Have we changed chunk ? */
while( p_track->i_sample >=
p_track->chunk[p_track->i_chunk].i_sample_first +
p_track->chunk[p_track->i_chunk].i_sample_count &&
p_track->i_chunk < p_track->i_chunk_count - 1 )
{
msg_Warn( p_demux, "track[0x%x] will be disabled "
"(cannot restart decoder)", p_track->i_track_ID );
MP4_TrackSelect( p_demux, p_track, false );
return VLC_EGENERIC;
p_track->i_chunk++;
}
}
if( p_track->p_elst ) /* Update */
{
uint32_t i_prev_elst = p_track->i_elst;
TrackUpdateSampleAndTimes( p_track );
MP4_TrackUpdateELST( p_track, p_sys->i_timescale, p_track->i_next_dts, p_track->i_sample);
if( p_track->i_elst != i_prev_elst )
{
msg_Dbg( p_demux, "changed elst %u -> %u", i_prev_elst, p_track->i_elst);
/* *** find good chunk *** */
uint32_t i_sample, i_chunk;
stime_t i_start = p_track->BOXDATA(p_elst)->entries[p_track->i_elst].i_media_time;
if( STTSToSampleChunk( p_track, i_start, &i_chunk, &i_sample ) != VLC_SUCCESS )
{
msg_Warn( p_demux, "track[Id 0x%x] will be disabled "
"(seeking too far) chunk=%"PRIu32" sample=%"PRIu32,
p_track->i_track_ID, i_chunk, i_sample );
return VLC_EGENERIC;
}
p_track->i_chunk = i_chunk;
p_track->i_sample = i_sample;
}
}
TrackUpdateSampleAndTimes( p_track );
/* Have we changed elst */
if( p_track->p_elst && p_track->BOXDATA(p_elst)->i_entry_count > 0 )
if( TrackUpdateFormat( p_demux, p_track, i_previous_chunk ) != VLC_SUCCESS )
{
demux_sys_t *p_sys = p_demux->p_sys;
MP4_Box_data_elst_t *elst = p_track->BOXDATA(p_elst);
uint64_t i_mvt = MP4_rescale_qtime( MP4_TrackGetDTSPTS( p_demux, p_track, NULL ),
p_sys->i_timescale );
if( p_track->i_elst < elst->i_entry_count &&
i_mvt >= p_track->i_elst_time +
elst->i_segment_duration[p_track->i_elst] )
{
MP4_TrackSetELST( p_demux, p_track,
MP4_TrackGetDTSPTS( p_demux, p_track, NULL ) );
}
msg_Warn( p_demux, "track[0x%x] will be disabled "
"(cannot restart decoder)", p_track->i_track_ID );
MP4_TrackSelect( p_demux, p_track, false );
return VLC_EGENERIC;
}
if( !p_track->b_selected || p_track->i_sample >= p_track->i_sample_count )
return VLC_EGENERIC;
return VLC_SUCCESS;
}
......@@ -4260,10 +4334,11 @@ static void MP4_TrackSetELST( demux_t *p_demux, mp4_track_t *tk,
for( tk->i_elst = 0; tk->i_elst < elst->i_entry_count; tk->i_elst++ )
{
uint64_t i_dur = elst->i_segment_duration[tk->i_elst];
uint64_t i_dur = elst->entries[tk->i_elst].i_segment_duration;
if( tk->i_elst_time <= i_mvt
&& i_mvt < (int64_t)(tk->i_elst_time + i_dur) )
if( elst->entries[tk->i_elst].i_media_time >=0 &&
tk->i_elst_time <= i_mvt &&
i_mvt < (int64_t)(tk->i_elst_time + i_dur) )
{
break;
}
......@@ -4274,20 +4349,14 @@ static void MP4_TrackSetELST( demux_t *p_demux, mp4_track_t *tk,
{
/* msg_Dbg( p_demux, "invalid number of entry in elst" ); */
tk->i_elst = elst->i_entry_count - 1;
tk->i_elst_time -= elst->i_segment_duration[tk->i_elst];
}
if( elst->i_media_time[tk->i_elst] < 0 )
{
/* track offset */
tk->i_elst_time += elst->i_segment_duration[tk->i_elst];
tk->i_elst_time -= elst->entries[tk->i_elst].i_segment_duration;
}
if( i_elst_last != tk->i_elst )
{
msg_Warn( p_demux, "elst old=%d new=%"PRIu32, i_elst_last, tk->i_elst );
if( i_elst_last < elst->i_entry_count &&
elst->i_media_time[i_elst_last] >= 0 )
elst->entries[i_elst_last].i_media_time >= 0 )
tk->i_next_block_flags |= BLOCK_FLAG_DISCONTINUITY;
}
}
......
......@@ -2707,7 +2707,7 @@ static int InputSourceInit( input_source_t *in, input_thread_t *p_input,
if( in->p_demux == NULL )
{
if( !b_in_can_fail && !input_Stopped( p_input ) )
vlc_dialog_display_error( p_input, _("Your input can't be opened"),
vlc_dialog_display_error( p_input, _("Your media can't be opened"),
_("VLC is unable to open the MRL '%s'."
" Check the log for details."), psz_mrl );
if( in->p_slave_es_out )
......