[vlc-commits] [Git][videolan/vlc][master] 7 commits: packetizer: flac: don't send invalid frame on drain
Jean-Baptiste Kempf (@jbk)
gitlab at videolan.org
Wed Jul 20 07:34:49 UTC 2022
Jean-Baptiste Kempf pushed to branch master at VideoLAN / VLC
Commits:
599757d9 by Francois Cartegnie at 2022-07-20T07:16:28+00:00
packetizer: flac: don't send invalid frame on drain
- - - - -
d2312650 by Francois Cartegnie at 2022-07-20T07:16:28+00:00
packetizer: flac: fix potential endless loop on drain
- - - - -
6aeaeb61 by Francois Cartegnie at 2022-07-20T07:16:28+00:00
packetizer: flac: add comments
- - - - -
1cd8422a by Francois Cartegnie at 2022-07-20T07:16:28+00:00
packetizer: flac: fix fixed blocksize streams last pts
- - - - -
54ffcdec by Francois Cartegnie at 2022-07-20T07:16:28+00:00
packetizer: flac: remove useless frame_size
- - - - -
1c03970b by Francois Cartegnie at 2022-07-20T07:16:28+00:00
packetizer: flac: move frame check outside reader
- - - - -
1db4d294 by Francois Cartegnie at 2022-07-20T07:16:28+00:00
packetizer: flac: do not check min frame size for fixed block
cannot pass on truncated end
- - - - -
2 changed files:
- modules/packetizer/flac.c
- modules/packetizer/flac.h
Changes:
=====================================
modules/packetizer/flac.c
=====================================
@@ -75,7 +75,6 @@ typedef struct
date_t pts;
struct flac_header_info headerinfo;
- size_t i_frame_size;
size_t i_last_frame_size;
uint16_t crc;
size_t i_buf;
@@ -347,6 +346,7 @@ static block_t *Packetize(decoder_t *p_dec, block_t **pp_block)
p_sys->i_state = STATE_SYNC;
}
+ /* First Sync is now on bytestream head, offset == 0 */
block_SkipBytes(&p_sys->bytestream, p_sys->i_offset);
block_BytestreamFlush(&p_sys->bytestream);
p_sys->i_offset = 0;
@@ -368,10 +368,12 @@ static block_t *Packetize(decoder_t *p_dec, block_t **pp_block)
return NULL; /* Need more data */
/* Check if frame is valid and get frame info */
- int i_ret = FLAC_ParseSyncInfo(p_header, FLAC_HEADER_SIZE_MAX,
- p_sys->b_stream_info ? &p_sys->stream_info : NULL,
- flac_crc8, &p_sys->headerinfo);
- if (!i_ret) {
+ const struct flac_stream_info *streaminfo =
+ p_sys->b_stream_info ? &p_sys->stream_info : NULL;
+ struct flac_header_info headerinfo;
+ int i_ret = FLAC_ParseSyncInfo(p_header, FLAC_HEADER_SIZE_MAX, streaminfo,
+ flac_crc8, &headerinfo);
+ if (!i_ret || !FLAC_CheckFrameInfo(streaminfo, &headerinfo)) {
msg_Dbg(p_dec, "emulated sync word");
block_SkipByte(&p_sys->bytestream);
p_sys->i_offset = 0;
@@ -379,9 +381,9 @@ static block_t *Packetize(decoder_t *p_dec, block_t **pp_block)
break;
}
+ p_sys->headerinfo = headerinfo;
p_sys->i_state = STATE_NEXT_SYNC;
- p_sys->i_offset = 1;
- p_sys->i_frame_size = 0;
+ p_sys->i_offset = FLAC_FRAME_SIZE_MIN;
p_sys->crc = 0;
/* We have to read until next frame sync code to compute current frame size
@@ -393,14 +395,19 @@ static block_t *Packetize(decoder_t *p_dec, block_t **pp_block)
case STATE_NEXT_SYNC:
{
+ /* First Sync is on bytestream head, offset will be the position
+ * of the next sync code candidate */
if(block_FindStartcodeFromOffset(&p_sys->bytestream, &p_sys->i_offset,
NULL, 2,
FLACStartcodeHelper,
FLACStartcodeMatcher) != VLC_SUCCESS)
{
- if( pp_block == NULL ) /* EOF/Drain */
+ size_t i_remain = block_BytestreamRemaining( &p_sys->bytestream );
+ if( pp_block == NULL && i_remain > FLAC_FRAME_SIZE_MIN ) /* EOF/Drain */
{
- p_sys->i_offset = block_BytestreamRemaining( &p_sys->bytestream );
+ /* There is no other synccode in the bytestream,
+ * we assume the end of our flac frame is end of bytestream */
+ p_sys->i_offset = i_remain;
p_sys->i_state = STATE_GET_DATA;
continue;
}
@@ -413,12 +420,14 @@ static block_t *Packetize(decoder_t *p_dec, block_t **pp_block)
nextheader, FLAC_HEADER_SIZE_MAX))
return NULL; /* Need more data */
+ const struct flac_stream_info *streaminfo =
+ p_sys->b_stream_info ? &p_sys->stream_info : NULL;
struct flac_header_info dummy;
/* Check if frame is valid and get frame info */
- if(FLAC_ParseSyncInfo(nextheader, FLAC_HEADER_SIZE_MAX,
- p_sys->b_stream_info ? &p_sys->stream_info : NULL,
- NULL, &dummy) == 0)
+ if(!FLAC_ParseSyncInfo(nextheader, FLAC_HEADER_SIZE_MAX, streaminfo, NULL, &dummy)||
+ !FLAC_CheckFrameInfo(streaminfo, &dummy))
{
+ /* Keep trying to find next sync point in bytestream */
p_sys->i_offset++;
continue;
}
@@ -428,9 +437,11 @@ static block_t *Packetize(decoder_t *p_dec, block_t **pp_block)
}
case STATE_GET_DATA:
- if( p_sys->i_offset < FLAC_FRAME_SIZE_MIN ||
- ( p_sys->b_stream_info &&
- p_sys->stream_info.min_framesize > p_sys->i_offset ) )
+ /* i_offset is the next sync point candidate
+ * our frame_size is the offset from the first sync */
+ if( pp_block != NULL &&
+ p_sys->b_stream_info &&
+ p_sys->stream_info.min_framesize > p_sys->i_offset )
{
p_sys->i_offset += 1;
p_sys->i_state = STATE_NEXT_SYNC;
@@ -441,9 +452,11 @@ static block_t *Packetize(decoder_t *p_dec, block_t **pp_block)
p_sys->stream_info.max_framesize < p_sys->i_offset )
{
/* Something went wrong, truncate stream head and restart */
+ msg_Warn(p_dec, "discarding bytes as we're over framesize %u, %zu",
+ p_sys->stream_info.max_framesize,
+ p_sys->i_offset);
block_SkipBytes( &p_sys->bytestream, FLAC_HEADER_SIZE_MAX + 2 );
block_BytestreamFlush( &p_sys->bytestream );
- p_sys->i_frame_size = 0;
p_sys->crc = 0;
p_sys->i_offset = 0;
p_sys->i_state = STATE_NOSYNC;
@@ -467,17 +480,13 @@ static block_t *Packetize(decoder_t *p_dec, block_t **pp_block)
return NULL;
}
- /* Copy from previous sync point (frame_size) up to to current (offset) */
- block_PeekOffsetBytes( &p_sys->bytestream, p_sys->i_frame_size,
- &p_sys->p_buf[p_sys->i_frame_size],
- p_sys->i_offset - p_sys->i_frame_size );
+ /* Copy from previous sync point up to to current (offset) */
+ block_PeekOffsetBytes( &p_sys->bytestream, 0, p_sys->p_buf, p_sys->i_offset );
/* update crc to include this data chunk */
- for( size_t i = p_sys->i_frame_size; i < p_sys->i_offset - 2; i++ )
+ for( size_t i = 0; i < p_sys->i_offset - 2; i++ )
p_sys->crc = flac_crc16( p_sys->crc, p_sys->p_buf[i] );
- p_sys->i_frame_size = p_sys->i_offset;
-
uint16_t stream_crc = GetWBE(&p_sys->p_buf[p_sys->i_offset - 2]);
if( stream_crc != p_sys->crc )
{
@@ -492,10 +501,13 @@ static block_t *Packetize(decoder_t *p_dec, block_t **pp_block)
p_sys->i_state = STATE_SEND_DATA;
+ /* frame size between the two sync codes is now known */
+ p_sys->i_last_frame_size = p_sys->i_offset;
+ p_sys->i_buf = p_sys->i_offset;
+
/* clean */
block_SkipBytes( &p_sys->bytestream, p_sys->i_offset );
block_BytestreamFlush( &p_sys->bytestream );
- p_sys->i_last_frame_size = p_sys->i_frame_size;
p_sys->i_offset = 0;
p_sys->crc = 0;
@@ -521,7 +533,7 @@ static block_t *Packetize(decoder_t *p_dec, block_t **pp_block)
}
- out = block_heap_Alloc( p_sys->p_buf, p_sys->i_frame_size );
+ out = block_heap_Alloc( p_sys->p_buf, p_sys->i_buf );
if( out )
{
out->i_dts = out->i_pts = date_Get( &p_sys->pts );
@@ -539,7 +551,6 @@ static block_t *Packetize(decoder_t *p_dec, block_t **pp_block)
p_sys->i_buf = 0;
p_sys->p_buf = NULL;
- p_sys->i_frame_size = 0;
p_sys->i_offset = 0;
p_sys->i_state = STATE_NOSYNC;
@@ -571,7 +582,6 @@ static int Open(vlc_object_t *p_this)
p_sys->i_offset = 0;
p_sys->b_stream_info = false;
p_sys->i_last_frame_size = FLAC_FRAME_SIZE_MIN;
- p_sys->i_frame_size = 0;
p_sys->headerinfo.i_pts = VLC_TICK_INVALID;
p_sys->i_buf = 0;
p_sys->p_buf = NULL;
=====================================
modules/packetizer/flac.h
=====================================
@@ -115,6 +115,24 @@ static inline int64_t read_utf8(const uint8_t *p_buf, unsigned i_buf, int *pi_re
return i_result;
}
+static inline int FLAC_CheckFrameInfo(const struct flac_stream_info *stream_info,
+ const struct flac_header_info *h)
+{
+ /* Sanity check using stream info header when possible */
+ if (stream_info)
+ {
+ if ((stream_info->min_blocksize != stream_info->max_blocksize &&
+ h->i_frame_length < stream_info->min_blocksize) ||
+ h->i_frame_length > stream_info->max_blocksize)
+ return 0;
+ if (h->i_bits_per_sample != stream_info->bits_per_sample)
+ return 0;
+ if (h->i_rate != stream_info->sample_rate)
+ return 0;
+ }
+ return 1;
+}
+
/*****************************************************************************
* FLAC_ParseSyncInfo: parse FLAC sync info
* - stream_info can be NULL
@@ -268,20 +286,12 @@ static inline int FLAC_ParseSyncInfo(const uint8_t *p_buf, unsigned i_buf,
pf_crc8(p_buf, i_header) != p_buf[i_header])
return 0;
- /* Sanity check using stream info header when possible */
- if (stream_info) {
- if (blocksize < stream_info->min_blocksize ||
- blocksize > stream_info->max_blocksize)
- return 0;
- if ((unsigned)bits_per_sample != stream_info->bits_per_sample)
- return 0;
- if (samplerate != stream_info->sample_rate)
- return 0;
- }
-
/* Compute from frame absolute time */
if ( (p_buf[1] & 0x01) == 0 ) /* Fixed blocksize stream / Frames */
- h->i_pts = VLC_TICK_0 + vlc_tick_from_samples(blocksize * i_fsnumber, samplerate);
+ {
+ const unsigned fixedblocksize = stream_info ? stream_info->min_blocksize : blocksize;
+ h->i_pts = VLC_TICK_0 + vlc_tick_from_samples(fixedblocksize * i_fsnumber, samplerate);
+ }
else /* Variable blocksize stream / Samples */
h->i_pts = VLC_TICK_0 + vlc_tick_from_samples(i_fsnumber, samplerate);
View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/8e2c76e5f523106375ca8612ade8a51bb7a6c926...1db4d294ca8185e5a9e25d823c40677831d9f538
--
View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/8e2c76e5f523106375ca8612ade8a51bb7a6c926...1db4d294ca8185e5a9e25d823c40677831d9f538
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