[vlc-devel] commit: RTP: partial Vorbis payload format support: defragmentation ( Rémi Denis-Courmont )

git version control git at videolan.org
Sun Jun 8 17:39:22 CEST 2008


vlc | branch: master | Rémi Denis-Courmont <rdenis at simphalempin.com> | Sun Jun  8 18:40:09 2008 +0300| [eff0b66b3f4486d7f62b6bd4749145967baa7b49]

RTP: partial Vorbis payload format support: defragmentation

> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=eff0b66b3f4486d7f62b6bd4749145967baa7b49
---

 modules/demux/rtp.c |  132 +++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 132 insertions(+), 0 deletions(-)

diff --git a/modules/demux/rtp.c b/modules/demux/rtp.c
index 8f917ef..fb512ad 100644
--- a/modules/demux/rtp.c
+++ b/modules/demux/rtp.c
@@ -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;
         }




More information about the vlc-devel mailing list