Commit eff0b66b authored by Rémi Denis-Courmont's avatar Rémi Denis-Courmont

RTP: partial Vorbis payload format support: defragmentation

parent 3e3e4050
......@@ -601,6 +601,130 @@ static void *ts_init (demux_t *demux)
* Hmm, none implemented yet.
*/
/* PT=dynamic
* vorbis: Xiph Vorbis audio (draft-ietf-avt-rtp-vorbis-09, RFC FIXME)
*/
typedef struct rtp_vorbis_t
{
es_out_id_t *id;
block_t *block;
} rtp_vorbis_t;
static void *vorbis_init (demux_t *demux)
{
es_format_t fmt;
rtp_vorbis_t *self = malloc (sizeof (*self));
if (self == NULL)
return NULL;
es_format_Init (&fmt, AUDIO_ES, VLC_FOURCC ('v', 'o', 'r', 'b'));
self->id = codec_init (demux, &fmt);
self->block = NULL;
return self;
}
static void vorbis_destroy (demux_t *demux, void *data)
{
rtp_vorbis_t *self = data;
if (!data)
return;
if (self->block)
{
self->block->i_flags |= BLOCK_FLAG_CORRUPTED;
codec_decode (demux, NULL, self->block);
}
codec_destroy (demux, self->id);
free (self);
}
static void vorbis_decode (demux_t *demux, void *data, block_t *block)
{
rtp_vorbis_t *self = data;
if (!data || block->i_buffer < 4)
goto drop;
/* 32-bits Vorbis RTP header */
uint32_t ident = GetDWBE (block->p_buffer);
block->i_buffer -= 4;
block->p_buffer += 4;
unsigned fragtype = (ident >> 6) & 3;
unsigned datatype = (ident >> 4) & 3;
unsigned pkts = (ident) & 15;
ident >>= 8;
/* Vorbis RTP defragmentation */
if ((fragtype != 0) && (pkts > 0))
goto drop;
if (self->block && (block->i_flags & BLOCK_FLAG_DISCONTINUITY))
{ /* Screwed! discontinuity within a fragmented packet */
msg_Warn (demux, "discontinuity in fragmented Vorbis packet");
self->block->i_flags |= BLOCK_FLAG_CORRUPTED;
codec_decode (demux, NULL, self->block);
self->block = NULL;
}
if (fragtype <= 1)
{
if (self->block) /* Buggy sender! */
{
block_Release (self->block);
self->block = NULL;
}
if (fragtype == 1)
{
self->block = block;
return;
}
}
else
{
if (!self->block) /* Buggy sender! */
goto drop;
size_t len = self->block->i_buffer;
self->block = block_Realloc (self->block, 0, len + block->i_buffer);
if (self->block)
memcpy (self->block->p_buffer + len, block->p_buffer,
block->i_buffer);
block_Release (block);
if (fragtype == 2 || !self->block)
return;
/* End of fragment reached */
block = self->block;
self->block = NULL;
}
switch (datatype)
{
case 0:
msg_Dbg (demux, "Payload: raw");
break;
case 1:
msg_Dbg (demux, "Payload: configuration");
break;
case 2:
msg_Dbg (demux, "Payload: comment");
break;
default:
block_Release (block);
return;
}
msg_Dbg (demux, "Packets number %u", pkts);
msg_Dbg (demux, "Configuration %"PRIu32, ident);
codec_decode (demux, NULL, block);
return;
drop:
block_Release (block);
}
/**
* Processing callback
*/
......@@ -692,6 +816,14 @@ static int Demux (demux_t *demux)
pt.frequency = 90000;
break;
case 96:
msg_Dbg (demux, "detected Vorbis");
pt.init = vorbis_init;
pt.destroy = vorbis_destroy;
pt.decode = vorbis_decode;
pt.frequency = 4281000;
break;
default:
goto drop;
}
......
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