[vlc-commits] [Git][videolan/vlc][master] 3 commits: codec: opus: header fix needs valid defaults

François Cartegnie (@fcartegnie) gitlab at videolan.org
Thu Jun 2 14:12:30 UTC 2022



François Cartegnie pushed to branch master at VideoLAN / VLC


Commits:
0d0df433 by Francois Cartegnie at 2022-06-02T13:57:05+00:00
codec: opus: header fix needs valid defaults

- - - - -
c9cd7454 by Francois Cartegnie at 2022-06-02T13:57:05+00:00
codec: opus: rewrite extradata handling

- - - - -
1e9613f8 by Francois Cartegnie at 2022-06-02T13:57:05+00:00
access: rtp: add opus

- - - - -


3 changed files:

- modules/access/rtp/Makefile.am
- + modules/access/rtp/opus.c
- modules/codec/opus.c


Changes:

=====================================
modules/access/rtp/Makefile.am
=====================================
@@ -38,6 +38,7 @@ rtpparse_LTLIBRARIES = \
 	librtp_pcm_plugin.la \
 	librtp_raw_plugin.la \
 	librtp_h264_plugin.la \
+	librtp_opus_plugin.la \
 	librtp_xiph_plugin.la
 
 librtp_ac3_plugin_la_SOURCES = access/rtp/ac3.c
@@ -50,4 +51,6 @@ librtp_raw_plugin_la_SOURCES = access/rtp/raw.c
 
 librtp_h264_plugin_la_SOURCES = access/rtp/h264.c
 
+librtp_opus_plugin_la_SOURCES = access/rtp/opus.c
+
 librtp_xiph_plugin_la_SOURCES = access/rtp/xiph.c


=====================================
modules/access/rtp/opus.c
=====================================
@@ -0,0 +1,106 @@
+/**
+ * @file opus.c
+ * @brief Real-Time Protocol Opus payload format parser
+ */
+/*****************************************************************************
+ * Copyright © 2022 VideoLabs, Videolan and VLC Authors
+ *
+ * This library 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 library 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ ****************************************************************************/
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+
+#include <vlc_common.h>
+#include <vlc_block.h>
+#include <vlc_es.h>
+#include <vlc_plugin.h>
+#include <vlc_strings.h>
+
+#include "rtp.h"
+
+static void *rtp_opus_init(struct vlc_rtp_pt *pt)
+{
+    VLC_UNUSED(pt);
+
+    es_format_t fmt;
+    es_format_Init(&fmt, AUDIO_ES, VLC_CODEC_OPUS);
+    static const uint8_t header[] = { 'O', 'p', 'u', 's', 'H', 'e', 'a', 'd',
+                                       0x01, 0x02, /* version / 2 channels */
+                                       0x00, 0x00, /* preskip */
+                                       0x80, 0xbb, 0x00, 0x00, /* rate 48000 */
+                                       0x00, 0x00, 0x00 }; /* gain / mapping */
+    fmt.p_extra = malloc(sizeof(header));
+    if(!fmt.p_extra)
+        return NULL;
+    fmt.i_extra = sizeof(header);
+    memcpy(fmt.p_extra, header, sizeof(header));
+
+    struct vlc_rtp_es *es = vlc_rtp_pt_request_es(pt, &fmt);
+    es_format_Clean(&fmt);
+
+    return es;
+}
+
+static void rtp_opus_destroy(struct vlc_rtp_pt *pt, void *data)
+{
+    VLC_UNUSED(pt);
+    struct vlc_rtp_es *es = data;
+    vlc_rtp_es_destroy(es);
+}
+
+static void rtp_opus_decode(struct vlc_rtp_pt *pt, void *data, block_t *block,
+                           const struct vlc_rtp_pktinfo *restrict info)
+{
+    VLC_UNUSED(pt); VLC_UNUSED(info);
+    struct vlc_rtp_es *es = data;
+
+    if (block->i_buffer == 0)
+    {
+        block_Release(block);
+        return;
+    }
+
+    vlc_rtp_es_send(es, block);
+}
+
+static const struct vlc_rtp_pt_operations rtp_opus_ops = {
+    NULL, rtp_opus_init, rtp_opus_destroy, rtp_opus_decode,
+};
+
+static int rtp_opus_open(vlc_object_t *obj, struct vlc_rtp_pt *pt,
+                        const struct vlc_sdp_pt *desc)
+{
+    VLC_UNUSED(obj);
+
+    if (vlc_ascii_strcasecmp(desc->name, "OPUS") ||
+        desc->clock_rate != 48000 ||
+        desc->channel_count != 2)
+        return VLC_ENOTSUP;
+
+    pt->ops = &rtp_opus_ops;
+
+    return VLC_SUCCESS;
+}
+
+vlc_module_begin()
+    set_shortname(N_("RTP Opus"))
+    set_description(N_("RTP Opus audio payload parser"))
+    set_subcategory(SUBCAT_INPUT_DEMUX)
+    set_rtp_parser_callback(rtp_opus_open)
+    add_shortcut("audio/opus")
+vlc_module_end()


=====================================
modules/codec/opus.c
=====================================
@@ -357,40 +357,50 @@ static int ProcessHeaders( decoder_t *p_dec )
     const uint8_t *p_extra = p_dec->fmt_in.p_extra;
     uint8_t *p_alloc = NULL;
 
+    /* Xiph headers as extradata */
+    if( i_extra > 21 && !memcmp( &p_extra[2], "OpusHead", 8 ) )
+    {
+        if( xiph_SplitHeaders( pi_size, pp_data, &i_count,
+                               i_extra, p_extra ) || i_count < 2 )
+        {
+            /* Borked Xiph headers */
+            free( p_alloc );
+            return VLC_EGENERIC;
+        }
+
+        oggpacket.bytes  = pi_size[0];
+        oggpacket.packet = (unsigned char *) pp_data[0];
+    }
     /* If we have no header (e.g. from RTP), make one. */
-    if( !i_extra ||
-        (i_extra > 10 && memcmp( &p_extra[2], "OpusHead", 8 )) ) /* Borked muxers */
+    else if( i_extra < 19 || memcmp( p_extra, "OpusHead", 8 ) )
     {
         OpusHeader header;
         opus_header_init(&header);
-        opus_prepare_header( p_dec->fmt_in.audio.i_channels,
-                             p_dec->fmt_in.audio.i_rate, &header );
+        opus_prepare_header( p_dec->fmt_in.audio.i_channels ? p_dec->fmt_in.audio.i_channels : 2,
+                             p_dec->fmt_in.audio.i_rate ? p_dec->fmt_in.audio.i_rate : 48000,
+                             &header );
         int ret = opus_write_header( &p_alloc, &i_extra, &header,
                                      opus_get_version_string() );
         opus_header_clean(&header);
-        if(ret != 0)
+        if(ret != 0 || i_extra < 21)
         {
             free( p_alloc );
             return VLC_ENOMEM;
         }
-        p_extra = p_alloc;
+        oggpacket.bytes  = p_alloc[1]; /* Xiph header is type8/size8 */
+        oggpacket.packet = (unsigned char *) p_alloc + 2; /* Point directly to opus header start */
     }
-
-    if( xiph_SplitHeaders( pi_size, pp_data, &i_count,
-                           i_extra, p_extra ) || i_count < 2 )
+    else /* raw header in extradata */
     {
-        free( p_alloc );
-        return VLC_EGENERIC;
+        oggpacket.bytes  = i_extra;
+        oggpacket.packet  = (unsigned char *) p_extra;
     }
 
+    /* Take care of the initial Opus header */
     oggpacket.granulepos = -1;
     oggpacket.e_o_s = 0;
     oggpacket.packetno = 0;
-
-    /* Take care of the initial Opus header */
     oggpacket.b_o_s = 1; /* yes this actually is a b_o_s packet :) */
-    oggpacket.bytes  = pi_size[0];
-    oggpacket.packet = (void *)pp_data[0];
     int ret = ProcessInitialHeader( p_dec, &oggpacket );
 
     if (ret != VLC_SUCCESS)



View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/0d201c35492e44cd162874cfcb5c10fb78f99f5c...1e9613f8eaf9cf17010d035d58e91eee6a3f771c

-- 
View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/0d201c35492e44cd162874cfcb5c10fb78f99f5c...1e9613f8eaf9cf17010d035d58e91eee6a3f771c
You're receiving this email because of your account on code.videolan.org.


VideoLAN code repository instance


More information about the vlc-commits mailing list