[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