[vlc-commits] [Git][videolan/vlc][3.0.x] 12 commits: demux: avi: set frame flags on video_es only
Jean-Baptiste Kempf (@jbk)
gitlab at videolan.org
Fri May 12 15:49:24 UTC 2023
Jean-Baptiste Kempf pushed to branch 3.0.x at VideoLAN / VLC
Commits:
fc7e4a2f by Francois Cartegnie at 2023-05-12T15:11:58+00:00
demux: avi: set frame flags on video_es only
(cherry picked from commit 4502f33c20e46f5f4837b47cd99e552d65f4b360)
- - - - -
dbcc0760 by Francois Cartegnie at 2023-05-12T15:11:58+00:00
demux: avi: account header outside of sample size
(cherry-picked from commit c8fe3d812c277821ade872e334e78acc19deaf03)
(cherry picked from commit 32705bd3675e8fb87eb3c5d827f91a5ae8d0bc3f)
- - - - -
8a561ea2 by Francois Cartegnie at 2023-05-12T15:11:58+00:00
demux: avi: move around code to ease understanding
(cherry picked from commit c6cc1df8e233818ca0ae1d423012f5099223ed3c)
- - - - -
91299bbc by Francois Cartegnie at 2023-05-12T15:11:58+00:00
demux: avi: remove unneeded temp var/refetch
(cherry picked from commit b354b0529a0c88f1cb48d21987801e537eafed38)
- - - - -
f1503017 by Francois Cartegnie at 2023-05-12T15:11:58+00:00
demux: avi: add comments
(cherry picked from commit 9836217e0ed6cb24a560c6dc42fda2b1af063085)
- - - - -
c8b6380b by Francois Cartegnie at 2023-05-12T15:11:58+00:00
demux: avi: simplify audio seek computation
(cherry picked from commit 58aba619c8a435c4a156404661b24a12d77d543c)
- - - - -
0a0ed889 by Francois Cartegnie at 2023-05-12T15:11:58+00:00
demux: avi: replace useless define
(cherry picked from commit 4ea55641013820e447c7a39eaf26c7ec0bdb3c73)
- - - - -
a8dc27d9 by Francois Cartegnie at 2023-05-12T15:11:58+00:00
demux: avi: replace redundant track lookups
(cherry picked from commit cfc233814e22e8c9e63ab983a0f1d2968cdd0bfb)
- - - - -
ccdc0322 by Francois Cartegnie at 2023-05-12T15:11:58+00:00
demux: avi: add proper check for index alloc
(cherry picked from commit 2bb108680bb633e9e695f93cd988be9fff0f44b6)
- - - - -
e2cc130f by Francois Cartegnie at 2023-05-12T15:11:58+00:00
demux: avi: return insert position on indexAppend
(cherry picked from commit 817e0d30c42c8ee3b245c7d9d5fd5cd7370989e8)
- - - - -
e61aa5e7 by Francois Cartegnie at 2023-05-12T15:11:58+00:00
demux: avi: fix bogus indexless sample reads
was always using the previous chunk size
refs #27425
(cherry picked from commit b108e622d9431bd9153658089adfa7cdcf5fb231)
- - - - -
f098271f by Francois Cartegnie at 2023-05-12T15:11:58+00:00
demux: avi: change index non fatal messages to warning
(cherry picked from commit bb629537b156c8ead0975c420fed1ccbcb55113a)
- - - - -
1 changed file:
- modules/demux/avi/avi.c
Changes:
=====================================
modules/demux/avi/avi.c
=====================================
@@ -137,7 +137,7 @@ typedef struct
} avi_index_t;
static void avi_index_Init( avi_index_t * );
static void avi_index_Clean( avi_index_t * );
-static void avi_index_Append( avi_index_t *, uint64_t *, avi_entry_t * );
+static int64_t avi_index_Append( avi_index_t *, uint64_t *, avi_entry_t * );
typedef struct
{
@@ -210,11 +210,9 @@ static vlc_tick_t AVI_GetDPTS ( avi_track_t *, int64_t i_count );
static vlc_tick_t AVI_GetPTS ( avi_track_t * );
-static int AVI_StreamChunkFind( demux_t *, unsigned int i_stream );
-static int AVI_StreamChunkSet ( demux_t *,
- unsigned int i_stream, unsigned int i_ck );
-static int AVI_StreamBytesSet ( demux_t *,
- unsigned int i_stream, uint64_t i_byte );
+static int AVI_StreamChunkFind( demux_t *, avi_track_t * );
+static int AVI_StreamChunkSet ( demux_t *, avi_track_t *, unsigned int i_ck );
+static int AVI_StreamBytesSet ( demux_t *, avi_track_t *, uint64_t i_byte );
vlc_fourcc_t AVI_FourccGetCodec( unsigned int i_cat, vlc_fourcc_t );
static int AVI_GetKeyFlag ( vlc_fourcc_t , uint8_t * );
@@ -988,26 +986,36 @@ error:
*****************************************************************************/
static block_t * ReadFrame( demux_t *p_demux, const avi_track_t *tk,
- const unsigned int i_header, const int i_size )
+ uint32_t i_header, uint32_t i_osize )
{
- block_t *p_frame = vlc_stream_Block( p_demux->s, __EVEN( i_size ) );
- if ( !p_frame ) return p_frame;
-
- if( i_size % 2 ) /* read was padded on word boundary */
+ /* skip header */
+ if( i_header )
{
- p_frame->i_buffer--;
+ assert(i_header % 8 == 0);
+ ssize_t i_skip = vlc_stream_Read( p_demux->s, NULL, i_header );
+ if( i_skip < 0 || (size_t) i_skip < i_header )
+ return NULL;
}
- if( i_header >= p_frame->i_buffer || tk->i_width_bytes > INT32_MAX - 3 )
+ /* read size padded on word boundary */
+ uint32_t i_size = __EVEN(i_osize);
+
+ if( i_size == 0 )
+ return block_Alloc(0); /* vlc_stream_Block can't read/alloc 0 sized */
+
+ block_t *p_frame = vlc_stream_Block( p_demux->s, i_size );
+ if ( !p_frame )
+ return p_frame;
+
+ if( i_osize == i_size - 1 )
+ p_frame->i_buffer--;
+
+ if( tk->i_width_bytes > INT32_MAX - 3 )
{
p_frame->i_buffer = 0;
return p_frame;
}
- /* skip header */
- p_frame->p_buffer += i_header;
- p_frame->i_buffer -= i_header;
-
const unsigned int i_stride_bytes = (tk->i_width_bytes + 3) & ~3;
if ( !tk->i_width_bytes || !i_stride_bytes )
@@ -1231,7 +1239,6 @@ static int Demux_Seekable( demux_t *p_demux )
block_t *p_frame;
int64_t i_pos;
unsigned int i;
- size_t i_size;
/* search for first chunk to be read */
for( i = 0, b_done = true, i_pos = -1; i < p_sys->i_track; i++ )
@@ -1333,11 +1340,14 @@ static int Demux_Seekable( demux_t *p_demux )
index.i_pos = avi_pk.i_pos;
index.i_length = avi_pk.i_size;
index.i_lengthtotal = index.i_length;
- avi_index_Append( &tk->idx, &p_sys->i_movi_lastchunk_pos, &index );
+ int64_t i_indexid = avi_index_Append( &tk->idx, &p_sys->i_movi_lastchunk_pos, &index );
/* do we will read this data ? */
- if( AVI_GetDPTS( tk, toread[i_track].i_toread ) > -p_sys->i_read_increment )
+ if( i_indexid >= 0 &&
+ AVI_GetDPTS( tk, toread[i_track].i_toread ) > -p_sys->i_read_increment )
{
+ tk->i_idxposc = (unsigned int) i_indexid;
+ tk->i_idxposb = 0;
break;
}
else
@@ -1361,11 +1371,16 @@ static int Demux_Seekable( demux_t *p_demux )
/* Set the track to use */
tk = p_sys->track[i_track];
+ size_t i_size;
+ unsigned i_ck_remaining_bytes = tk->idx.p_entry[tk->i_idxposc].i_length -
+ tk->i_idxposb;
+
/* read those data */
if( tk->i_samplesize )
{
int64_t i_toread;
+ /* remaining bytes to read inside the current read increment */
if( ( i_toread = toread[i_track].i_toread ) <= 0 )
{
if( tk->i_samplesize > 1 )
@@ -1374,26 +1389,23 @@ static int Demux_Seekable( demux_t *p_demux )
}
else
{
+ /* refill current read increment */
i_toread = AVI_PTSToByte( tk, 20 * 1000 );
i_toread = __MAX( i_toread, 100 );
}
}
- i_size = __MIN( tk->idx.p_entry[tk->i_idxposc].i_length -
- tk->i_idxposb,
- (size_t) i_toread );
+ i_size = __MIN( i_ck_remaining_bytes, (size_t) i_toread );
}
else
{
- i_size = tk->idx.p_entry[tk->i_idxposc].i_length;
+ assert(tk->i_idxposb == 0);
+ i_size = i_ck_remaining_bytes;
}
- if( tk->i_idxposb == 0 )
- {
- i_size += 8; /* need to read and skip header */
- }
+ /* need to read and skip tag/header */
+ const uint8_t i_header = ( tk->i_idxposb == 0 ) ? 8 : 0;
- if( ( p_frame = ReadFrame( p_demux, tk,
- ( tk->i_idxposb == 0 ) ? 8 : 0, i_size ) )==NULL )
+ if( ( p_frame = ReadFrame( p_demux, tk, i_header, i_size ) )==NULL )
{
msg_Warn( p_demux, "failed reading data" );
tk->b_eof = false;
@@ -1406,18 +1418,14 @@ static int Demux_Seekable( demux_t *p_demux )
{
p_frame->i_flags = BLOCK_FLAG_TYPE_I;
}
- else
+ else if( tk->fmt.i_cat == VIDEO_ES )
{
p_frame->i_flags = BLOCK_FLAG_TYPE_PB;
}
- /* read data */
+ /* advance chunk/byte pointers */
if( tk->i_samplesize )
{
- if( tk->i_idxposb == 0 )
- {
- i_size -= 8;
- }
toread[i_track].i_toread -= i_size;
tk->i_idxposb += i_size;
if( tk->i_idxposb >=
@@ -1427,18 +1435,18 @@ static int Demux_Seekable( demux_t *p_demux )
tk->i_idxposc++;
}
}
- else
+ else /* full chunk */
{
- int i_length = tk->idx.p_entry[tk->i_idxposc].i_length;
-
+ /* Goto to next chunk */
tk->i_idxposc++;
if( tk->fmt.i_cat == AUDIO_ES )
{
- tk->i_blockno += tk->i_blocksize > 0 ? ( i_length + tk->i_blocksize - 1 ) / tk->i_blocksize : 1;
+ tk->i_blockno += tk->i_blocksize > 0 ? ( i_size + tk->i_blocksize - 1 ) / tk->i_blocksize : 1;
}
toread[i_track].i_toread--;
}
+ /* check new chunk and set new read pos */
if( tk->i_idxposc < tk->idx.i_size)
{
toread[i_track].i_posf =
@@ -1449,7 +1457,7 @@ static int Demux_Seekable( demux_t *p_demux )
}
}
- else
+ else /* all chunks read for this track */
{
toread[i_track].i_posf = -1;
}
@@ -1566,7 +1574,7 @@ static int Demux_UnSeekable( demux_t *p_demux )
AVI_GetPTS( p_stream_master ) )< 2 * CLOCK_FREQ )
{
/* load it and send to decoder */
- block_t *p_frame = ReadFrame( p_demux, p_stream, 8, avi_pk.i_size + 8 ) ;
+ block_t *p_frame = ReadFrame( p_demux, p_stream, 8, avi_pk.i_size ) ;
if( p_frame == NULL )
{
return VLC_DEMUXER_EGENERIC;
@@ -1642,13 +1650,12 @@ static int Seek( demux_t *p_demux, vlc_tick_t i_date, int i_percent, bool b_accu
if( !p_sys->i_length )
{
avi_track_t *p_stream = NULL;
- unsigned i_stream = 0;
uint64_t i_pos;
if ( !p_sys->i_movi_lastchunk_pos && /* set when index is successfully loaded */
! ( p_sys->i_avih_flags & AVIF_ISINTERLEAVED ) )
{
- msg_Err( p_demux, "seeking without index at %d%%"
+ msg_Warn( p_demux, "seeking without index at %d%%"
" only works for interleaved files", i_percent );
goto failandresetpos;
}
@@ -1671,7 +1678,6 @@ static int Seek( demux_t *p_demux, vlc_tick_t i_date, int i_percent, bool b_accu
continue;
p_stream = p_track;
- i_stream = i;
if( !p_track->b_eof )
break;
}
@@ -1682,7 +1688,7 @@ static int Seek( demux_t *p_demux, vlc_tick_t i_date, int i_percent, bool b_accu
}
/* be sure that the index exist */
- if( AVI_StreamChunkSet( p_demux, i_stream, 0 ) )
+ if( AVI_StreamChunkSet( p_demux, p_stream, 0 ) )
{
msg_Warn( p_demux, "cannot seek" );
goto failandresetpos;
@@ -1693,7 +1699,7 @@ static int Seek( demux_t *p_demux, vlc_tick_t i_date, int i_percent, bool b_accu
{
/* search after i_idxposc */
if( AVI_StreamChunkSet( p_demux,
- i_stream, p_stream->i_idxposc + 1 ) )
+ p_stream, p_stream->i_idxposc + 1 ) )
{
msg_Warn( p_demux, "cannot seek" );
goto failandresetpos;
@@ -1965,7 +1971,7 @@ static vlc_tick_t AVI_GetPTS( avi_track_t *tk )
return AVI_GetDPTS( tk, tk->i_idxposc );
}
-static int AVI_StreamChunkFind( demux_t *p_demux, unsigned int i_stream )
+static int AVI_StreamChunkFind( demux_t *p_demux, avi_track_t *tk )
{
demux_sys_t *p_sys = p_demux->p_sys;
avi_packet_t avi_pk;
@@ -2025,7 +2031,7 @@ static int AVI_StreamChunkFind( demux_t *p_demux, unsigned int i_stream )
index.i_lengthtotal = index.i_length;
avi_index_Append( &tk_pk->idx, &p_sys->i_movi_lastchunk_pos, &index );
- if( avi_pk.i_stream == i_stream )
+ if( tk_pk == tk )
{
return VLC_SUCCESS;
}
@@ -2039,12 +2045,9 @@ static int AVI_StreamChunkFind( demux_t *p_demux, unsigned int i_stream )
}
/* be sure that i_ck will be a valid index entry */
-static int AVI_StreamChunkSet( demux_t *p_demux, unsigned int i_stream,
+static int AVI_StreamChunkSet( demux_t *p_demux, avi_track_t *p_stream,
unsigned int i_ck )
{
- demux_sys_t *p_sys = p_demux->p_sys;
- avi_track_t *p_stream = p_sys->track[i_stream];
-
p_stream->i_idxposc = i_ck;
p_stream->i_idxposb = 0;
@@ -2054,7 +2057,7 @@ static int AVI_StreamChunkSet( demux_t *p_demux, unsigned int i_stream,
do
{
p_stream->i_idxposc++;
- if( AVI_StreamChunkFind( p_demux, i_stream ) )
+ if( AVI_StreamChunkFind( p_demux, p_stream ) )
{
return VLC_EGENERIC;
}
@@ -2067,12 +2070,9 @@ static int AVI_StreamChunkSet( demux_t *p_demux, unsigned int i_stream,
/* XXX FIXME up to now, we assume that all chunk are one after one */
static int AVI_StreamBytesSet( demux_t *p_demux,
- unsigned int i_stream,
+ avi_track_t *p_stream,
uint64_t i_byte )
{
- demux_sys_t *p_sys = p_demux->p_sys;
- avi_track_t *p_stream = p_sys->track[i_stream];
-
if( ( p_stream->idx.i_size > 0 )
&&( i_byte < p_stream->idx.p_entry[p_stream->idx.i_size - 1].i_lengthtotal +
p_stream->idx.p_entry[p_stream->idx.i_size - 1].i_length ) )
@@ -2115,7 +2115,7 @@ static int AVI_StreamBytesSet( demux_t *p_demux,
do
{
p_stream->i_idxposc++;
- if( AVI_StreamChunkFind( p_demux, i_stream ) )
+ if( AVI_StreamChunkFind( p_demux, p_stream ) )
{
return VLC_EGENERIC;
}
@@ -2135,35 +2135,28 @@ static int AVI_TrackSeek( demux_t *p_demux,
{
demux_sys_t *p_sys = p_demux->p_sys;
avi_track_t *tk = p_sys->track[i_stream];
-
-#define p_stream p_sys->track[i_stream]
vlc_tick_t i_oldpts;
- i_oldpts = AVI_GetPTS( p_stream );
+ i_oldpts = AVI_GetPTS( tk );
- if( !p_stream->i_samplesize )
+ if( !tk->i_samplesize )
{
- if( AVI_StreamChunkSet( p_demux,
- i_stream,
- AVI_PTSToChunk( p_stream, i_date ) ) )
+ if( AVI_StreamChunkSet( p_demux, tk, AVI_PTSToChunk( tk, i_date ) ) )
{
return VLC_EGENERIC;
}
- if( p_stream->fmt.i_cat == AUDIO_ES )
+ if( tk->fmt.i_cat == AUDIO_ES )
{
- unsigned int i;
- tk->i_blockno = 0;
- for( i = 0; i < tk->i_idxposc; i++ )
+ if( tk->i_blocksize > 0 )
{
- if( tk->i_blocksize > 0 )
- {
+ tk->i_blockno = tk->i_idxposc;
+ }
+ else
+ {
+ tk->i_blockno = 0;
+ for( unsigned int i = 0; i < tk->i_idxposc; i++ )
tk->i_blockno += ( tk->idx.p_entry[i].i_length + tk->i_blocksize - 1 ) / tk->i_blocksize;
- }
- else
- {
- tk->i_blockno++;
- }
}
}
@@ -2173,18 +2166,15 @@ static int AVI_TrackSeek( demux_t *p_demux,
i_oldpts > i_date ? ">" : "<",
i_date );
- if( p_stream->fmt.i_cat == VIDEO_ES )
+ if( tk->fmt.i_cat == VIDEO_ES )
{
/* search key frame */
//if( i_date < i_oldpts || 1 )
{
- while( p_stream->i_idxposc > 0 &&
- !( p_stream->idx.p_entry[p_stream->i_idxposc].i_flags &
- AVIIF_KEYFRAME ) )
+ while( tk->i_idxposc > 0 &&
+ !( tk->idx.p_entry[tk->i_idxposc].i_flags & AVIIF_KEYFRAME ) )
{
- if( AVI_StreamChunkSet( p_demux,
- i_stream,
- p_stream->i_idxposc - 1 ) )
+ if( AVI_StreamChunkSet( p_demux, tk, tk->i_idxposc - 1 ) )
{
return VLC_EGENERIC;
}
@@ -2193,13 +2183,10 @@ static int AVI_TrackSeek( demux_t *p_demux,
#if 0
else
{
- while( p_stream->i_idxposc < p_stream->idx.i_size &&
- !( p_stream->idx.p_entry[p_stream->i_idxposc].i_flags &
- AVIIF_KEYFRAME ) )
+ while( tk->i_idxposc < tk->idx.i_size &&
+ !( tk->idx.p_entry[tk->i_idxposc].i_flags & AVIIF_KEYFRAME ) )
{
- if( AVI_StreamChunkSet( p_demux,
- i_stream,
- p_stream->i_idxposc + 1 ) )
+ if( AVI_StreamChunkSet( p_demux, tk, tk->i_idxposc + 1 ) )
{
return VLC_EGENERIC;
}
@@ -2210,15 +2197,12 @@ static int AVI_TrackSeek( demux_t *p_demux,
}
else
{
- if( AVI_StreamBytesSet( p_demux,
- i_stream,
- AVI_PTSToByte( p_stream, i_date ) ) )
+ if( AVI_StreamBytesSet( p_demux, tk, AVI_PTSToByte( tk, i_date ) ) )
{
return VLC_EGENERIC;
}
}
return VLC_SUCCESS;
-#undef p_stream
}
/****************************************************************************
@@ -2445,21 +2429,32 @@ static void avi_index_Clean( avi_index_t *p_index )
{
free( p_index->p_entry );
}
-static void avi_index_Append( avi_index_t *p_index, uint64_t *pi_last_pos,
- avi_entry_t *p_entry )
+#define MAX_INDEX_ENTRIES __MIN(SIZE_MAX/sizeof(avi_entry_t), UINT32_MAX)
+#define INDEX_EXTENT 16384
+static int64_t avi_index_Append( avi_index_t *p_index, uint64_t *pi_last_pos,
+ avi_entry_t *p_entry )
{
/* Update last chunk position */
if( *pi_last_pos < p_entry->i_pos )
*pi_last_pos = p_entry->i_pos;
+ if( p_index->i_size == MAX_INDEX_ENTRIES )
+ return -1;
+
/* add the entry */
if( p_index->i_size >= p_index->i_max )
{
- p_index->i_max += 16384;
+ if( MAX_INDEX_ENTRIES - INDEX_EXTENT > p_index->i_max )
+ p_index->i_max += INDEX_EXTENT;
+ else
+ p_index->i_max = MAX_INDEX_ENTRIES;
p_index->p_entry = realloc_or_free( p_index->p_entry,
- p_index->i_max * sizeof( *p_index->p_entry ) );
+ p_index->i_max * sizeof(avi_entry_t) );
if( !p_index->p_entry )
- return;
+ {
+ avi_index_Init( p_index );
+ return -1;
+ }
}
/* calculate cumulate length */
if( p_index->i_size > 0 )
@@ -2474,6 +2469,7 @@ static void avi_index_Append( avi_index_t *p_index, uint64_t *pi_last_pos,
}
p_index->p_entry[p_index->i_size++] = *p_entry;
+ return p_index->i_size - 1;
}
static int AVI_IndexFind_idx1( demux_t *p_demux,
@@ -2654,7 +2650,6 @@ static void AVI_IndexLoad_indx( demux_t *p_demux,
avi_chunk_list_t *p_strl;
avi_chunk_indx_t *p_indx;
-#define p_stream p_sys->track[i_stream]
p_strl = AVI_ChunkFind( p_hdrl, AVIFOURCC_strl, i_stream, true );
p_indx = AVI_ChunkFind( p_strl, AVIFOURCC_indx, 0, false );
@@ -2693,7 +2688,6 @@ static void AVI_IndexLoad_indx( demux_t *p_demux,
{
msg_Warn( p_demux, "unknown type index(0x%x)", p_indx->i_indextype );
}
-#undef p_stream
}
}
@@ -2745,7 +2739,7 @@ static void AVI_IndexLoad( demux_t *p_demux )
b_key = p_index->p_entry[j].i_flags & AVIIF_KEYFRAME;
if( !b_key )
{
- msg_Err( p_demux, "no key frame set for track %u", i );
+ msg_Warn( p_demux, "no key frame set for track %u", i );
for( unsigned j = 0; j < p_index->i_size; j++ )
p_index->p_entry[j].i_flags |= AVIIF_KEYFRAME;
}
View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/7533c9eee9f827ae2da8afb6249e07791d098102...f098271f03dfb54a6fd029efb87ed144eb74d7de
--
View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/7533c9eee9f827ae2da8afb6249e07791d098102...f098271f03dfb54a6fd029efb87ed144eb74d7de
You're receiving this email because of your account on code.videolan.org.
VideoLAN code repository instance
More information about the vlc-commits
mailing list