[vlc-devel] [RFC 2/3] rtp: support setting frequency from decoded packets

Pierre Ynard linkfanel at yahoo.fr
Thu Nov 18 05:58:42 CET 2010


This is used by vorbis. This is ugly so I'm not to sure about the API.


diff --git a/modules/access/rtp/rtp.c b/modules/access/rtp/rtp.c
index 3cf48eb..6030624 100644
--- a/modules/access/rtp/rtp.c
+++ b/modules/access/rtp/rtp.c
@@ -419,7 +419,7 @@ static int Control (demux_t *demux, int i_query, va_list args)
 }
 
 /* Send a packet to decoder */
-static void codec_decode (demux_t *demux, void *data, block_t *block)
+static uint32_t codec_decode (demux_t *demux, void *data, block_t *block)
 {
     if (data)
     {
@@ -429,6 +429,7 @@ static void codec_decode (demux_t *demux, void *data, block_t *block)
     }
     else
         block_Release (block);
+    return 0;
 }
 
 static void *stream_init (demux_t *demux, const char *name)
@@ -444,13 +445,14 @@ static void stream_destroy (demux_t *demux, void *data)
 }
 
 /* Send a packet to a chained demuxer */
-static void stream_decode (demux_t *demux, void *data, block_t *block)
+static uint32_t stream_decode (demux_t *demux, void *data, block_t *block)
 {
     if (data)
         stream_DemuxSend ((stream_t *)data, block);
     else
         block_Release (block);
     (void)demux;
+    return 0;
 }
 
 static void *demux_init (demux_t *demux)
@@ -550,18 +552,19 @@ static void *mpa_init (demux_t *demux)
     return codec_init (demux, &fmt);
 }
 
-static void mpa_decode (demux_t *demux, void *data, block_t *block)
+static uint32_t mpa_decode (demux_t *demux, void *data, block_t *block)
 {
     if (block->i_buffer < 4)
     {
         block_Release (block);
-        return;
+        return 0;
     }
 
     block->i_buffer -= 4; /* 32-bits RTP/MPA header */
     block->p_buffer += 4;
 
     codec_decode (demux, data, block);
+    return 0;
 }
 
 
@@ -577,12 +580,12 @@ static void *mpv_init (demux_t *demux)
     return codec_init (demux, &fmt);
 }
 
-static void mpv_decode (demux_t *demux, void *data, block_t *block)
+static uint32_t mpv_decode (demux_t *demux, void *data, block_t *block)
 {
     if (block->i_buffer < 4)
     {
         block_Release (block);
-        return;
+        return 0;
     }
 
     block->i_buffer -= 4; /* 32-bits RTP/MPV header */
@@ -595,6 +598,7 @@ static void mpv_decode (demux_t *demux, void *data, block_t *block)
     }
 #endif
     codec_decode (demux, data, block);
+    return 0;
 }
 
 
diff --git a/modules/access/rtp/rtp.h b/modules/access/rtp/rtp.h
index c90b010..04598af 100644
--- a/modules/access/rtp/rtp.h
+++ b/modules/access/rtp/rtp.h
@@ -28,7 +28,7 @@ struct rtp_pt_t
 {
     void   *(*init) (demux_t *);
     void    (*destroy) (demux_t *, void *);
-    void    (*decode) (demux_t *, void *, block_t *);
+    uint32_t (*decode) (demux_t *, void *, block_t *);
     uint32_t  frequency; /* RTP clock rate (Hz) */
     uint8_t   number;
 };
diff --git a/modules/access/rtp/session.c b/modules/access/rtp/session.c
index 7fb52dc..eeea361 100644
--- a/modules/access/rtp/session.c
+++ b/modules/access/rtp/session.c
@@ -96,10 +96,11 @@ static void no_destroy (demux_t *demux, void *opaque)
     (void)demux; (void)opaque;
 }
 
-static void no_decode (demux_t *demux, void *opaque, block_t *block)
+static uint32_t no_decode (demux_t *demux, void *opaque, block_t *block)
 {
     (void)demux; (void)opaque;
     block_Release (block);
+    return 0;
 }
 
 /**
@@ -128,7 +129,6 @@ int rtp_add_type (demux_t *demux, rtp_session_t *ses, const rtp_pt_t *pt)
     msg_Dbg (demux, "added payload type %"PRIu8" (f = %"PRIu32" Hz)",
              ppt->number, ppt->frequency);
 
-    assert (ppt->frequency > 0); /* SIGFPE! */
     (void)demux;
     return 0;
 }
@@ -210,7 +210,7 @@ static inline uint32_t rtp_timestamp (const block_t *block)
     return GetDWBE (block->p_buffer + 4);
 }
 
-static const struct rtp_pt_t *
+static struct rtp_pt_t *
 rtp_find_ptype (const rtp_session_t *session, rtp_source_t *source,
                 const block_t *block, void **pt_data)
 {
@@ -306,7 +306,7 @@ rtp_queue (demux_t *demux, rtp_session_t *session, block_t *block)
     {
         const rtp_pt_t *pt = rtp_find_ptype (session, src, block, NULL);
 
-        if (pt != NULL)
+        if (pt != NULL && pt->frequency > 0)
         {
             /* Recompute jitter estimate.
              * That is computed from the RTP timestamps and the system clock.
@@ -432,7 +432,7 @@ bool rtp_dequeue (demux_t *demux, const rtp_session_t *session,
              */
             mtime_t deadline;
             const rtp_pt_t *pt = rtp_find_ptype (session, src, block, NULL);
-            if (pt)
+            if (pt != NULL && pt->frequency > 0)
                 deadline = CLOCK_FREQ * 3 * src->jitter / pt->frequency;
             else
                 deadline = 0; /* no jitter estimate with no frequency :( */
@@ -491,7 +491,7 @@ rtp_decode (demux_t *demux, const rtp_session_t *session, rtp_source_t *src)
 
     /* Match the payload type */
     void *pt_data;
-    const rtp_pt_t *pt = rtp_find_ptype (session, src, block, &pt_data);
+    rtp_pt_t *pt = rtp_find_ptype (session, src, block, &pt_data);
     if (pt == NULL)
     {
         msg_Dbg (demux, "unknown payload (%"PRIu8")",
@@ -503,12 +503,15 @@ rtp_decode (demux_t *demux, const rtp_session_t *session, rtp_source_t *src)
      * DTS is unknown. Also, while the clock frequency depends on the payload
      * format, a single source MUST only use payloads of a chosen frequency.
      * Otherwise it would be impossible to compute consistent timestamps. */
-    const uint32_t timestamp = rtp_timestamp (block);
-    block->i_pts = src->ref_ntp
-       + CLOCK_FREQ * (int32_t)(timestamp - src->ref_rtp) / pt->frequency;
-    /* TODO: proper inter-medias/sessions sync (using RTCP-SR) */
-    src->ref_ntp = block->i_pts;
-    src->ref_rtp = timestamp;
+    if (pt->frequency > 0)
+    {
+        const uint32_t timestamp = rtp_timestamp (block);
+        block->i_pts = src->ref_ntp
+           + CLOCK_FREQ * (int32_t)(timestamp - src->ref_rtp) / pt->frequency;
+        /* TODO: proper inter-medias/sessions sync (using RTCP-SR) */
+        src->ref_ntp = block->i_pts;
+        src->ref_rtp = timestamp;
+    }
 
     /* CSRC count */
     size_t skip = 12u + (block->p_buffer[0] & 0x0F) * 4;
@@ -529,7 +532,9 @@ rtp_decode (demux_t *demux, const rtp_session_t *session, rtp_source_t *src)
     block->p_buffer += skip;
     block->i_buffer -= skip;
 
-    pt->decode (demux, pt_data, block);
+    uint32_t frequency = pt->decode (demux, pt_data, block);
+    if (pt->frequency == 0 && frequency > 0)
+        pt->frequency = frequency;
     return;
 
 drop:
diff --git a/modules/access/rtp/xiph.c b/modules/access/rtp/xiph.c
index 03ef83a..7a27e79 100644
--- a/modules/access/rtp/xiph.c
+++ b/modules/access/rtp/xiph.c
@@ -137,8 +137,9 @@ static ssize_t vorbis_header (void **pextra, const uint8_t *buf, size_t len)
 }
 
 
-static void vorbis_decode (demux_t *demux, void *data, block_t *block)
+static uint32_t vorbis_decode (demux_t *demux, void *data, block_t *block)
 {
+    uint32_t frequency = 0;
     rtp_vorbis_t *self = data;
 
     if (!data || block->i_buffer < 4)
@@ -197,14 +198,14 @@ static void vorbis_decode (demux_t *demux, void *data, block_t *block)
             if (!self->block)
             {
                 block_Release (block);
-                return;
+                return 0;
             }
             memcpy (self->block->p_buffer + len, block->p_buffer + 2,
                     fraglen);
             block_Release (block);
         }
         if (fragtype < 3)
-            return; /* Non-last fragment */
+            return 0; /* Non-last fragment */
 
         /* Last fragment reached, process it */
         block = self->block;
@@ -259,6 +260,8 @@ static void vorbis_decode (demux_t *demux, void *data, block_t *block)
                          "(%06"PRIx32")", ident);
                 self->ident = ident;
                 self->id = codec_init (demux, &fmt);
+
+                frequency = fmt.audio.i_rate;
                 break;
             }
         }
@@ -270,4 +273,5 @@ static void vorbis_decode (demux_t *demux, void *data, block_t *block)
 
 drop:
     block_Release (block);
+    return frequency;
 }


-- 
Pierre Ynard
"Une âme dans un corps, c'est comme un dessin sur une feuille de papier."



More information about the vlc-devel mailing list