]> git.sesse.net Git - vlc/blobdiff - modules/stream_out/rtpfmt.c
transcode: set pts on module open
[vlc] / modules / stream_out / rtpfmt.c
index 7b71588545b3bafd0e558e4455fd887ce3ae843e..f3518322833952f7c168902c6f4d96a6d67f357d 100644 (file)
@@ -1,25 +1,25 @@
 /*****************************************************************************
  * rtpfmt.c: RTP payload formats
  *****************************************************************************
- * Copyright (C) 2003-2004 the VideoLAN team
+ * Copyright (C) 2003-2004 VLC authors and VideoLAN
  * Copyright © 2007 Rémi Denis-Courmont
  * $Id$
  *
  * Authors: Laurent Aimar <fenrir@via.ecp.fr>
  *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or
  * (at your option) any later version.
  *
  * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
  *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
  *****************************************************************************/
 
 #ifdef HAVE_CONFIG_H
@@ -53,6 +53,7 @@ static int rtp_packetize_g726_24 (sout_stream_id_t *, block_t *);
 static int rtp_packetize_g726_32 (sout_stream_id_t *, block_t *);
 static int rtp_packetize_g726_40 (sout_stream_id_t *, block_t *);
 static int rtp_packetize_xiph (sout_stream_id_t *, block_t *);
+static int rtp_packetize_vp8 (sout_stream_id_t *, block_t *);
 
 #define XIPH_IDENT (0)
 
@@ -65,23 +66,16 @@ static int rtp_xiph_pack_headers(size_t room, void *p_extra, size_t i_extra,
     unsigned packet_size[XIPH_MAX_HEADER_COUNT];
     void *packet[XIPH_MAX_HEADER_COUNT];
     unsigned packet_count;
-    int val = xiph_SplitHeaders(packet_size, packet, &packet_count,
-                                i_extra, p_extra);
-    if (val != VLC_SUCCESS)
-        return val;
+    if (xiph_SplitHeaders(packet_size, packet, &packet_count,
+                                i_extra, p_extra))
+        return VLC_EGENERIC;;
     if (packet_count < 3)
-    {
-        val = VLC_EGENERIC;
-        goto free;
-    }
+        return VLC_EGENERIC;;
 
     if (theora_pixel_fmt != NULL)
     {
         if (packet_size[0] < 42)
-        {
-            val = VLC_EGENERIC;
-            goto free;
-        }
+            return VLC_EGENERIC;
         *theora_pixel_fmt = (((uint8_t *)packet[0])[41] >> 3) & 0x03;
     }
 
@@ -100,10 +94,7 @@ static int rtp_xiph_pack_headers(size_t room, void *p_extra, size_t i_extra,
                 + packet_size[0] + packet_size[1] + packet_size[2];
     *p_buffer = malloc(*i_buffer);
     if (*p_buffer == NULL)
-    {
-        val = VLC_ENOMEM;
-        goto free;
-    }
+        return VLC_ENOMEM;
 
     uint8_t *p = *p_buffer + room;
     /* Number of headers */
@@ -126,12 +117,7 @@ static int rtp_xiph_pack_headers(size_t room, void *p_extra, size_t i_extra,
         p += packet_size[i];
     }
 
-    val = VLC_SUCCESS;
-free:
-    for (unsigned i = 0; i < packet_count; i++)
-        free(packet[i]);
-
-    return val;
+    return VLC_SUCCESS;
 }
 
 static char *rtp_xiph_b64_oob_config(void *p_extra, size_t i_extra,
@@ -511,6 +497,30 @@ int rtp_get_fmt( vlc_object_t *obj, es_format_t *p_fmt, const char *mux,
             rtp_fmt->clock_rate = 1000;
             rtp_fmt->pf_packetize = rtp_packetize_t140;
             break;
+        case VLC_CODEC_GSM:
+            rtp_fmt->payload_type = 3;
+            rtp_fmt->ptname = "GSM";
+            rtp_fmt->pf_packetize = rtp_packetize_split;
+            break;
+        case VLC_CODEC_OPUS:
+            if (p_fmt->audio.i_channels > 2)
+            {
+                msg_Err( obj, "Multistream opus not supported in RTP"
+                         " (having %d channels input)",
+                         p_fmt->audio.i_channels );
+                return VLC_EGENERIC;
+            }
+            rtp_fmt->ptname = "opus";
+            rtp_fmt->pf_packetize = rtp_packetize_split;
+            rtp_fmt->clock_rate = 48000;
+            rtp_fmt->channels = 2;
+            if (p_fmt->audio.i_channels == 2)
+                rtp_fmt->fmtp = strdup( "sprop-stereo=1" );
+            break;
+        case VLC_CODEC_VP8:
+            rtp_fmt->ptname = "VP8";
+            rtp_fmt->pf_packetize = rtp_packetize_vp8;
+            break;
 
         default:
             msg_Err( obj, "cannot add this stream (unsupported "
@@ -1370,3 +1380,49 @@ static int rtp_packetize_g726_40( sout_stream_id_t *id, block_t *in )
 {
     return rtp_packetize_g726( id, in, 8 );
 }
+
+#define RTP_VP8_HEADER_SIZE 1
+#define RTP_VP8_PAYLOAD_START (12 + RTP_VP8_HEADER_SIZE)
+
+static int rtp_packetize_vp8( sout_stream_id_t *id, block_t *in )
+{
+    int     i_max   = rtp_mtu (id) - RTP_VP8_HEADER_SIZE;
+    int     i_count = ( in->i_buffer + i_max - 1 ) / i_max;
+
+    uint8_t *p_data = in->p_buffer;
+    int     i_data  = in->i_buffer;
+
+    if ( i_max <= 0 )
+        return VLC_EGENERIC;
+
+    for( int i = 0; i < i_count; i++ )
+    {
+        int i_payload = __MIN( i_max, i_data );
+        block_t *out = block_Alloc( RTP_VP8_PAYLOAD_START + i_payload );
+        if ( out == NULL )
+            return VLC_ENOMEM;
+
+        /* VP8 payload header */
+        /* All frames are marked as reference ones */
+        if (i == 0)
+            out->p_buffer[12] = 0x10; // partition start
+        else
+            out->p_buffer[12] = 0;
+
+        /* rtp common header */
+        rtp_packetize_common( id, out, (i == i_count - 1),
+                      (in->i_pts > VLC_TS_INVALID ? in->i_pts : in->i_dts) );
+        memcpy( &out->p_buffer[RTP_VP8_PAYLOAD_START], p_data, i_payload );
+
+        out->i_buffer = RTP_VP8_PAYLOAD_START + i_payload;
+        out->i_dts    = in->i_dts + i * in->i_length / i_count;
+        out->i_length = in->i_length / i_count;
+
+        rtp_packetize_send( id, out );
+
+        p_data += i_payload;
+        i_data -= i_payload;
+    }
+
+    return VLC_SUCCESS;
+}