[vlc-commits] [Git][videolan/vlc][master] 18 commits: demux: avi: account header outside of sample size
Steve Lhomme (@robUx4)
gitlab at videolan.org
Tue Nov 1 10:23:15 UTC 2022
Steve Lhomme pushed to branch master at VideoLAN / VLC
Commits:
c8fe3d81 by Francois Cartegnie at 2022-11-01T10:10:28+00:00
demux: avi: account header outside of sample size
- - - - -
c6cc1df8 by Francois Cartegnie at 2022-11-01T10:10:28+00:00
demux: avi: move around code to ease understanding
- - - - -
b354b052 by Francois Cartegnie at 2022-11-01T10:10:28+00:00
demux: avi: remove unneeded temp var/refetch
- - - - -
9836217e by Francois Cartegnie at 2022-11-01T10:10:28+00:00
demux: avi: add comments
- - - - -
4502f33c by Francois Cartegnie at 2022-11-01T10:10:28+00:00
demux: avi: set frame flags on video_es only
- - - - -
58aba619 by Francois Cartegnie at 2022-11-01T10:10:28+00:00
demux: avi: simplify audio seek computation
- - - - -
4ea55641 by Francois Cartegnie at 2022-11-01T10:10:28+00:00
demux: avi: replace useless define
- - - - -
cfc23381 by Francois Cartegnie at 2022-11-01T10:10:28+00:00
demux: avi: replace redundant track lookups
- - - - -
2bb10868 by Francois Cartegnie at 2022-11-01T10:10:28+00:00
demux: avi: add proper check for index alloc
- - - - -
4ed9fa53 by Francois Cartegnie at 2022-11-01T10:10:28+00:00
demux: avi: interleave 0 samplesize PCM
Avoids sending [a single] montrosample[s]
refs #27393
- - - - -
817e0d30 by Francois Cartegnie at 2022-11-01T10:10:28+00:00
demux: avi: return insert position on indexAppend
- - - - -
b108e622 by Francois Cartegnie at 2022-11-01T10:10:28+00:00
demux: avi: fix bogus indexless sample reads
was always using the previous chunk size
refs #27425
- - - - -
bb629537 by Francois Cartegnie at 2022-11-01T10:10:28+00:00
demux: avi: change index non fatal messages to warning
- - - - -
13e48e51 by Francois Cartegnie at 2022-11-01T10:10:28+00:00
demux: avi: add QNap fourcc defines
- - - - -
6853c770 by Francois Cartegnie at 2022-11-01T10:10:28+00:00
demux: avi: fix peek beyond QNap header
- - - - -
34710736 by Francois Cartegnie at 2022-11-01T10:10:28+00:00
demux: avi: extract meta from QNap header
- - - - -
9bb482ba by Francois Cartegnie at 2022-11-01T10:10:28+00:00
demux: avi: fix unmatched video codec
Parsing bitmapinfoheader resets to MS fourcc.
Demuxer's codec conditionals cannot match.
- - - - -
0acdec00 by Francois Cartegnie at 2022-11-01T10:10:28+00:00
demux: libavi: use only typedef'ed anon structs
- - - - -
4 changed files:
- modules/demux/avi/avi.c
- modules/demux/avi/bitmapinfoheader.h
- modules/demux/avi/libavi.c
- modules/demux/avi/libavi.h
Changes:
=====================================
modules/demux/avi/avi.c
=====================================
@@ -35,6 +35,7 @@
#include <vlc_plugin.h>
#include <vlc_demux.h>
#include <vlc_input.h>
+#include <vlc_aout.h>
#include <vlc_dialog.h>
@@ -135,7 +136,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
{
@@ -147,6 +148,7 @@ typedef struct
unsigned int i_samplesize;
struct bitmapinfoheader_properties bihprops;
+ bool is_qnap;
es_format_t fmt;
es_out_id_t *p_es;
@@ -191,6 +193,7 @@ typedef struct
/* meta */
vlc_meta_t *meta;
+ unsigned int updates;
unsigned int i_attachment;
input_attachment_t **attachment;
@@ -204,14 +207,12 @@ 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 * );
+static int AVI_GetKeyFlag ( const avi_track_t *, const uint8_t * );
static int AVI_PacketGetHeader( demux_t *, avi_packet_t *p_pk );
static int AVI_PacketNext ( demux_t * );
@@ -243,20 +244,21 @@ static int AVI_TrackStopFinishedStreams( demux_t *);
- to complete....
*/
-#define QNAP_HEADER_SIZE 56
-static bool IsQNAPCodec(vlc_fourcc_t codec)
+#define QNAP_VIDEO_HEADER_SIZE 56
+/* https://github.com/qnap-dev/qnap-qiot-sdks/blob/master/doc/QVRPro/live_stream_parser.cpp#L90 */
+static bool IsQNAPCodec(uint32_t biCompression)
{
- switch (codec)
- {
- case VLC_FOURCC('w', '2', '6', '4'):
- case VLC_FOURCC('q', '2', '6', '4'):
- case VLC_FOURCC('Q', '2', '6', '4'):
- case VLC_FOURCC('w', 'M', 'P', '4'):
- case VLC_FOURCC('q', 'M', 'P', '4'):
- case VLC_FOURCC('Q', 'M', 'P', '4'):
- case VLC_FOURCC('w', 'I', 'V', 'G'):
- case VLC_FOURCC('q', 'I', 'V', 'G'):
- case VLC_FOURCC('Q', 'I', 'V', 'G'):
+ switch (biCompression)
+ {
+ case QNAP_FCC_w264:
+ case QNAP_FCC_q264:
+ case QNAP_FCC_Q264:
+ case QNAP_FCC_wMP4:
+ case QNAP_FCC_qMP4:
+ case QNAP_FCC_QMP4:
+ case QNAP_FCC_wIVG:
+ case QNAP_FCC_qIVG:
+ case QNAP_FCC_QIVG:
return true;
default:
return false;
@@ -503,14 +505,27 @@ static int Open( vlc_object_t * p_this )
tk->fmt.i_codec = AVI_FourccGetCodec( AUDIO_ES, p_auds->p_wf->wFormatTag );
tk->i_blocksize = p_auds->p_wf->nBlockAlign;
- if( tk->i_blocksize == 0 )
+
+ /* Fix blocksize == 0 and force interleaving PCM chunks samplesize == 0 */
+ if( tk->i_samplesize == 0 || tk->i_blocksize == 0 )
{
- if( p_auds->p_wf->wFormatTag == 1 )
- tk->i_blocksize = p_auds->p_wf->nChannels * (p_auds->p_wf->wBitsPerSample/8);
- else
+ vlc_fourcc_t i_codec = vlc_fourcc_GetCodecAudio( tk->fmt.i_codec,
+ p_auds->p_wf->wBitsPerSample );
+ unsigned bps = aout_BitsPerSample( i_codec );
+ if( bps > 0 ) /* PCM audio */
+ {
+ if( tk->i_blocksize == 0 )
+ tk->i_blocksize = bps * p_auds->p_wf->nChannels / 8;
+ if( tk->i_samplesize == 0 )
+ tk->i_samplesize = tk->i_blocksize;
+ tk->fmt.b_packetized = true;
+ }
+ else if( tk->i_blocksize == 0 )
+ {
tk->i_blocksize = 1;
+ }
}
- else if( tk->i_samplesize != 0 && tk->i_samplesize != tk->i_blocksize )
+ else if( tk->i_samplesize != tk->i_blocksize )
{
msg_Warn( p_demux, "track[%u] samplesize=%u and blocksize=%u are not equal."
"Using blocksize as a workaround.",
@@ -599,8 +614,7 @@ static int Open( vlc_object_t * p_this )
break;
}
- es_format_Init( &tk->fmt, VIDEO_ES,
- AVI_FourccGetCodec( VIDEO_ES, p_vids->p_bih->biCompression ) );
+ es_format_Init( &tk->fmt, VIDEO_ES, 0 );
if( ParseBitmapInfoHeader( p_vids->p_bih, p_vids->i_chunk_size, &tk->fmt,
&tk->bihprops ) != VLC_SUCCESS )
@@ -617,8 +631,11 @@ static int Open( vlc_object_t * p_this )
tk->fmt.i_original_fourcc = VLC_FOURCC( 'X', 'V', 'I', 'D' );
}
- if( IsQNAPCodec( tk->fmt.i_codec ) )
+ if( IsQNAPCodec( p_vids->p_bih->biCompression ) )
+ {
+ tk->is_qnap = true;
tk->fmt.b_packetized = false;
+ }
tk->i_samplesize = 0;
tk->fmt.video.i_frame_rate = tk->i_rate;
@@ -832,26 +849,33 @@ 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_size )
{
- 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->bihprops.i_stride > INT32_MAX - 3 )
+ /* read size padded on word boundary */
+ i_size = __EVEN(i_size);
+
+ 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( tk->bihprops.i_stride > 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->bihprops.i_stride + 3) & ~3;
if ( !tk->bihprops.i_stride || !i_stride_bytes )
@@ -914,6 +938,8 @@ static block_t * ReadFrame( demux_t *p_demux, const avi_track_t *tk,
*****************************************************************************/
static void AVI_SendFrame( demux_t *p_demux, avi_track_t *tk, block_t *p_frame )
{
+ demux_sys_t *p_sys = p_demux->p_sys;
+
if( tk->fmt.i_cat != VIDEO_ES )
p_frame->i_dts = p_frame->i_pts;
else
@@ -925,17 +951,32 @@ static void AVI_SendFrame( demux_t *p_demux, avi_track_t *tk, block_t *p_frame )
if( tk->i_dv_audio_rate )
AVI_DvHandleAudio( p_demux, tk, p_frame );
- /* Strip QNAP header */
- if( IsQNAPCodec( tk->fmt.i_codec ) )
+ /* Strip 3rd party header */
+ if( tk->is_qnap )
{
- if( p_frame->i_buffer <= QNAP_HEADER_SIZE )
+ if( p_frame->i_buffer >= QNAP_VIDEO_HEADER_SIZE )
{
- block_Release( p_frame );
- return;
+ const uint8_t *p = p_frame->p_buffer;
+ /* Check header is really there */
+ vlc_fourcc_t fcc = VLC_FOURCC(p[0],p[1],p[2],p[3]);
+ /* Parse QNAP header */
+ if( IsQNAPCodec(fcc) && p_sys->meta )
+ {
+ const char *psz_title = vlc_meta_Get( p_sys->meta, vlc_meta_Title );
+ char *psz_osd = (char *) &p_frame->p_buffer[24];
+ if( *psz_osd != 0 )
+ {
+ psz_osd[23] = 0;
+ if( !psz_title || strncmp( psz_osd, psz_title, 24 ) )
+ {
+ vlc_meta_Set( p_sys->meta, vlc_meta_Title, psz_osd );
+ p_sys->updates |= INPUT_UPDATE_META;
+ }
+ }
+ }
+ p_frame->i_buffer -= QNAP_VIDEO_HEADER_SIZE;
+ p_frame->p_buffer += QNAP_VIDEO_HEADER_SIZE;
}
-
- p_frame->i_buffer -= QNAP_HEADER_SIZE;
- p_frame->p_buffer += QNAP_HEADER_SIZE;
}
if( tk->i_next_block_flags )
@@ -1073,7 +1114,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++ )
@@ -1165,15 +1205,18 @@ static int Demux_Seekable( demux_t *p_demux )
/* add this chunk to the index */
avi_entry_t index;
index.i_id = avi_pk.i_fourcc;
- index.i_flags = AVI_GetKeyFlag(tk->fmt.i_codec, avi_pk.i_peek);
+ index.i_flags = AVI_GetKeyFlag(tk, avi_pk.i_peek);
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
@@ -1198,11 +1241,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 )
@@ -1211,26 +1259,23 @@ static int Demux_Seekable( demux_t *p_demux )
}
else
{
+ /* refill current read increment */
i_toread = AVI_PTSToByte( tk, VLC_TICK_FROM_MS(20) );
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;
@@ -1243,18 +1288,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 >=
@@ -1264,18 +1305,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 =
@@ -1286,7 +1327,7 @@ static int Demux_Seekable( demux_t *p_demux )
}
}
- else
+ else /* all chunks read for this track */
{
toread[i_track].i_posf = -1;
}
@@ -1402,7 +1443,7 @@ static int Demux_UnSeekable( demux_t *p_demux )
AVI_GetPTS( p_stream_master ) )< VLC_TICK_FROM_SEC(2) )
{
/* 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;
@@ -1478,13 +1519,12 @@ static int Seek( demux_t *p_demux, vlc_tick_t i_date, double f_ratio, bool b_acc
if( p_sys->i_length == 0 )
{
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 %2.2f%%"
+ msg_Warn( p_demux, "seeking without index at %2.2f%%"
" only works for interleaved files", f_ratio * 100 );
goto failandresetpos;
}
@@ -1507,7 +1547,6 @@ static int Seek( demux_t *p_demux, vlc_tick_t i_date, double f_ratio, bool b_acc
continue;
p_stream = p_track;
- i_stream = i;
if( !p_track->b_eof )
break;
}
@@ -1518,7 +1557,7 @@ static int Seek( demux_t *p_demux, vlc_tick_t i_date, double f_ratio, bool b_acc
}
/* 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;
@@ -1529,7 +1568,7 @@ static int Seek( demux_t *p_demux, vlc_tick_t i_date, double f_ratio, bool b_acc
{
/* 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;
@@ -1710,6 +1749,14 @@ static int Control( demux_t *p_demux, int i_query, va_list args )
return VLC_EGENERIC;
}
+ case DEMUX_TEST_AND_CLEAR_FLAGS:
+ {
+ unsigned *restrict flags = va_arg( args, unsigned * );
+ *flags &= p_sys->updates;
+ p_sys->updates &= ~*flags;
+ return VLC_SUCCESS;
+ }
+
case DEMUX_CAN_PAUSE:
case DEMUX_SET_PAUSE_STATE:
case DEMUX_CAN_CONTROL_PACE:
@@ -1807,7 +1854,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;
@@ -1855,13 +1902,13 @@ static int AVI_StreamChunkFind( demux_t *p_demux, unsigned int i_stream )
/* add this chunk to the index */
avi_entry_t index;
index.i_id = avi_pk.i_fourcc;
- index.i_flags = AVI_GetKeyFlag(tk_pk->fmt.i_codec, avi_pk.i_peek);
+ index.i_flags = AVI_GetKeyFlag(tk_pk, avi_pk.i_peek);
index.i_pos = avi_pk.i_pos;
index.i_length = avi_pk.i_size;
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;
}
@@ -1875,12 +1922,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;
@@ -1890,7 +1934,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;
}
@@ -1903,12 +1947,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 ) )
@@ -1951,7 +1992,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;
}
@@ -1971,35 +2012,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++;
- }
}
}
@@ -2009,18 +2043,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;
}
@@ -2029,13 +2060,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;
}
@@ -2046,23 +2074,27 @@ 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
}
/****************************************************************************
* Return true if it's a key frame
****************************************************************************/
-static int AVI_GetKeyFlag( vlc_fourcc_t i_fourcc, uint8_t *p_byte )
+static int AVI_GetKeyFlag( const avi_track_t *tk, const uint8_t *p_byte )
{
- switch( i_fourcc )
+ if( tk->is_qnap )
+ {
+ const uint8_t *p = p_byte;
+ if( IsQNAPCodec(VLC_FOURCC(p[0],p[1],p[2],p[3])) )
+ return p[4] & 0x01 ? AVIIF_KEYFRAME : 0;
+ }
+
+ switch( tk->fmt.i_codec )
{
case VLC_CODEC_DIV1:
/* we have:
@@ -2273,21 +2305,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 )
@@ -2302,6 +2345,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,
@@ -2483,7 +2527,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 );
@@ -2522,7 +2565,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
}
}
@@ -2576,7 +2618,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;
}
@@ -2657,7 +2699,7 @@ static void AVI_IndexCreate( demux_t *p_demux )
avi_entry_t index;
index.i_id = pk.i_fourcc;
- index.i_flags = AVI_GetKeyFlag(tk->fmt.i_codec, pk.i_peek);
+ index.i_flags = AVI_GetKeyFlag(tk, pk.i_peek);
index.i_pos = pk.i_pos;
index.i_length = pk.i_size;
index.i_lengthtotal = pk.i_size;
=====================================
modules/demux/avi/bitmapinfoheader.h
=====================================
@@ -188,7 +188,7 @@ static inline int ParseBitmapInfoHeader( VLC_BITMAPINFOHEADER *p_bih, size_t i_b
}
else /* Compressed codecs */
{
- fmt->i_codec = p_bih->biCompression;
+ fmt->i_codec = vlc_fourcc_GetCodec( VIDEO_ES, p_bih->biCompression );
/* Copy extradata if any */
if( i_bihextra > 0 )
=====================================
modules/demux/avi/libavi.c
=====================================
@@ -195,7 +195,7 @@ static int AVI_ChunkRead_list( stream_t *s, avi_chunk_t *p_container )
#endif
msg_Dbg( s, "<list \'%4.4s\'>", (char*)&p_container->list.i_type );
- union avi_chunk_u **pp_append = &p_container->common.p_first;
+ avi_chunk_t **pp_append = &p_container->common.p_first;
for( ; ; )
{
p_chk = calloc( 1, sizeof( avi_chunk_t ) );
@@ -259,7 +259,7 @@ int AVI_ChunkFetchIndexes( stream_t *s, avi_chunk_t *p_riff )
if ( !b_seekable || vlc_stream_Seek( s, i_indexpos ) )
return VLC_EGENERIC;
- union avi_chunk_u **pp_append = &p_riff->common.p_first;
+ avi_chunk_t **pp_append = &p_riff->common.p_first;
for( ; ; )
{
p_chk = calloc( 1, sizeof( avi_chunk_t ) );
@@ -1128,7 +1128,7 @@ int AVI_ChunkReadRoot( stream_t *s, avi_chunk_t *p_root )
p_list->i_type = VLC_FOURCC( 'r', 'o', 'o', 't' );
- union avi_chunk_u **pp_append = &p_root->common.p_first;
+ avi_chunk_t **pp_append = &p_root->common.p_first;
for( ; ; )
{
p_chk = calloc( 1, sizeof( avi_chunk_t ) );
=====================================
modules/demux/avi/libavi.h
=====================================
@@ -37,17 +37,19 @@
/* the keyframe flag isn't a true flag */
/* but have to be verified */
+typedef union avi_chunk_u avi_chunk_t;
+
#define AVI_CHUNK_COMMON \
vlc_fourcc_t i_chunk_fourcc; \
uint64_t i_chunk_size; \
uint64_t i_chunk_pos; \
- union avi_chunk_u *p_next; \
- union avi_chunk_u *p_father; \
- union avi_chunk_u *p_first;
+ avi_chunk_t *p_next; \
+ avi_chunk_t *p_father; \
+ avi_chunk_t *p_first;
#define AVI_CHUNK( p_chk ) (avi_chunk_t*)(p_chk)
-typedef struct idx1_entry_s
+typedef struct
{
vlc_fourcc_t i_fourcc;
uint32_t i_flags;
@@ -56,18 +58,18 @@ typedef struct idx1_entry_s
} idx1_entry_t;
-typedef struct avi_chunk_common_s
+typedef struct
{
AVI_CHUNK_COMMON
} avi_chunk_common_t;
-typedef struct avi_chunk_list_s
+typedef struct
{
AVI_CHUNK_COMMON
vlc_fourcc_t i_type;
} avi_chunk_list_t;
-typedef struct avi_chunk_idx1_s
+typedef struct
{
AVI_CHUNK_COMMON
unsigned int i_entry_count;
@@ -76,7 +78,7 @@ typedef struct avi_chunk_idx1_s
} avi_chunk_idx1_t;
-typedef struct avi_chunk_avih_s
+typedef struct
{
AVI_CHUNK_COMMON
uint32_t i_microsecperframe;
@@ -96,7 +98,7 @@ typedef struct avi_chunk_avih_s
uint32_t i_length;
} avi_chunk_avih_t;
-typedef struct avi_chunk_strh_s
+typedef struct
{
AVI_CHUNK_COMMON
vlc_fourcc_t i_type;
@@ -113,21 +115,21 @@ typedef struct avi_chunk_strh_s
uint32_t i_samplesize;
} avi_chunk_strh_t;
-typedef struct avi_chunk_strf_auds_s
+typedef struct
{
AVI_CHUNK_COMMON
int i_cat;
WAVEFORMATEX *p_wf;
} avi_chunk_strf_auds_t;
-typedef struct avi_chunk_strf_vids_s
+typedef struct
{
AVI_CHUNK_COMMON
int i_cat;
VLC_BITMAPINFOHEADER *p_bih;
} avi_chunk_strf_vids_t;
-typedef union avi_chunk_strf_u
+typedef union
{
avi_chunk_strf_auds_t auds;
avi_chunk_strf_vids_t vids;
@@ -138,13 +140,13 @@ typedef union avi_chunk_strf_u
} common;
} avi_chunk_strf_t;
-typedef struct avi_chunk_strd_s
+typedef struct
{
AVI_CHUNK_COMMON
uint8_t *p_data;
} avi_chunk_strd_t;
-typedef struct avi_chunk_vprp_s
+typedef struct
{
AVI_CHUNK_COMMON
uint32_t i_video_format_token;
@@ -170,7 +172,7 @@ typedef struct avi_chunk_vprp_s
} avi_chunk_vprp_t;
-typedef struct avi_chunk_dmlh_s
+typedef struct
{
AVI_CHUNK_COMMON
uint32_t dwTotalFrames;
@@ -204,7 +206,7 @@ typedef struct
uint32_t i_duration;
} indx_super_entry_t;
-typedef struct avi_chunk_indx_s
+typedef struct
{
AVI_CHUNK_COMMON
int16_t i_longsperentry;
@@ -223,14 +225,14 @@ typedef struct avi_chunk_indx_s
} idx;
} avi_chunk_indx_t;
-typedef struct avi_chunk_STRING_s
+typedef struct
{
AVI_CHUNK_COMMON
char *p_type;
char *p_str;
} avi_chunk_STRING_t;
-typedef union avi_chunk_u
+union avi_chunk_u
{
avi_chunk_common_t common;
avi_chunk_list_t list;
@@ -242,7 +244,7 @@ typedef union avi_chunk_u
avi_chunk_vprp_t vprp;
avi_chunk_indx_t indx;
avi_chunk_STRING_t strz;
-} avi_chunk_t;
+};
/****************************************************************************
* Stream(input) access functions
@@ -368,3 +370,14 @@ int AVI_ChunkFetchIndexes( stream_t *, avi_chunk_t *p_riff );
#define FOURCC_dvsl VLC_FOURCC('d','v','s','l')
#define FOURCC_dv25 VLC_FOURCC('d','v','2','5')
#define FOURCC_dv50 VLC_FOURCC('d','v','5','0')
+
+/* QNap */
+#define QNAP_FCC_w264 VLC_FOURCC('w','2','6','4')
+#define QNAP_FCC_q264 VLC_FOURCC('q','2','6','4')
+#define QNAP_FCC_Q264 VLC_FOURCC('Q','2','6','4')
+#define QNAP_FCC_wMP4 VLC_FOURCC('w','M','P','4')
+#define QNAP_FCC_qMP4 VLC_FOURCC('q','M','P','4')
+#define QNAP_FCC_QMP4 VLC_FOURCC('Q','M','P','4')
+#define QNAP_FCC_wIVG VLC_FOURCC('w','I','V','G')
+#define QNAP_FCC_qIVG VLC_FOURCC('q','I','V','G')
+#define QNAP_FCC_QIVG VLC_FOURCC('Q','I','V','G')
View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/81d75d3010a3a051c4dba2d42a3f4d3dc065b404...0acdec00f7c7f1b77776cd931356b2fec5d6a340
--
View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/81d75d3010a3a051c4dba2d42a3f4d3dc065b404...0acdec00f7c7f1b77776cd931356b2fec5d6a340
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