Commit 2616f427 authored by François Cartegnie's avatar François Cartegnie 🤞

packetizer: mpeg4audio: implement draining and handle discontinuities

parent ef6dd48f
......@@ -978,25 +978,33 @@ static block_t *PacketizeStreamBlock(decoder_t *p_dec, block_t **pp_block)
block_t *p_out_buffer;
uint8_t *p_buf;
if (!pp_block || !*pp_block)
return NULL;
block_t *p_block = pp_block ? *pp_block : NULL;
if ((*pp_block)->i_flags & (BLOCK_FLAG_DISCONTINUITY|BLOCK_FLAG_CORRUPTED)) {
FlushStreamBlock(p_dec);
if ((*pp_block)->i_flags & BLOCK_FLAG_CORRUPTED) {
block_Release(*pp_block);
if(p_block)
{
if (p_block->i_flags & (BLOCK_FLAG_DISCONTINUITY|BLOCK_FLAG_CORRUPTED)) {
/* First always drain complete blocks before discontinuity */
block_t *p_drain = PacketizeStreamBlock(p_dec, NULL);
if(p_drain)
return p_drain;
FlushStreamBlock(p_dec);
if (p_block->i_flags & BLOCK_FLAG_CORRUPTED) {
block_Release(p_block);
return NULL;
}
}
if (!date_Get(&p_sys->end_date) && p_block->i_pts <= VLC_TS_INVALID) {
/* We've just started the stream, wait for the first PTS. */
block_Release(p_block);
return NULL;
}
}
if (!date_Get(&p_sys->end_date) && (*pp_block)->i_pts <= VLC_TS_INVALID) {
/* We've just started the stream, wait for the first PTS. */
block_Release(*pp_block);
return NULL;
block_BytestreamPush(&p_sys->bytestream, p_block);
}
block_BytestreamPush(&p_sys->bytestream, *pp_block);
for (;;) switch(p_sys->i_state) {
case STATE_NOSYNC:
while (block_PeekBytes(&p_sys->bytestream, p_header, 2) == VLC_SUCCESS) {
......@@ -1031,7 +1039,7 @@ static block_t *PacketizeStreamBlock(decoder_t *p_dec, block_t **pp_block)
if (p_sys->i_pts > VLC_TS_INVALID &&
p_sys->i_pts != date_Get(&p_sys->end_date))
{
if(date_Get(&p_sys->end_date) != 0)
if(date_Get(&p_sys->end_date) != VLC_TS_INVALID)
p_sys->b_discontuinity = true;
date_Set(&p_sys->end_date, p_sys->i_pts);
}
......@@ -1072,8 +1080,6 @@ static block_t *PacketizeStreamBlock(decoder_t *p_dec, block_t **pp_block)
p_sys->i_state = STATE_NEXT_SYNC;
case STATE_NEXT_SYNC:
/* TODO: If p_block == NULL, flush the buffer without checking the
* next sync word */
if (p_sys->bytestream.p_block == NULL) {
p_sys->i_state = STATE_NOSYNC;
block_BytestreamFlush(&p_sys->bytestream);
......@@ -1083,7 +1089,14 @@ static block_t *PacketizeStreamBlock(decoder_t *p_dec, block_t **pp_block)
/* Check if next expected frame contains the sync word */
if (block_PeekOffsetBytes(&p_sys->bytestream, p_sys->i_frame_size
+ p_sys->i_header_size, p_header, 2) != VLC_SUCCESS)
{
if(p_block == NULL) /* drain */
{
p_sys->i_state = STATE_SEND_DATA;
break;
}
return NULL; /* Need more data */
}
assert((p_sys->i_type == TYPE_ADTS) || (p_sys->i_type == TYPE_LOAS));
if (((p_sys->i_type == TYPE_ADTS) &&
......@@ -1143,7 +1156,8 @@ static block_t *PacketizeStreamBlock(decoder_t *p_dec, block_t **pp_block)
p_sys->i_pts = p_sys->bytestream.p_block->i_pts = VLC_TS_INVALID;
/* So p_block doesn't get re-added several times */
*pp_block = block_BytestreamPop(&p_sys->bytestream);
if( pp_block )
*pp_block = block_BytestreamPop(&p_sys->bytestream);
p_sys->i_state = STATE_NOSYNC;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment