mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-23 10:11:08 +00:00
tsmux: Add support for Opus
https://bugzilla.gnome.org/show_bug.cgi?id=757049
This commit is contained in:
parent
1e785a3778
commit
e75a9edff1
6 changed files with 338 additions and 2 deletions
|
@ -5,7 +5,8 @@ SUBDIRS = tsmux
|
|||
libgstmpegtsmux_la_SOURCES = \
|
||||
mpegtsmux.c \
|
||||
mpegtsmux_aac.c \
|
||||
mpegtsmux_ttxt.c
|
||||
mpegtsmux_ttxt.c \
|
||||
mpegtsmux_opus.c
|
||||
|
||||
libgstmpegtsmux_la_CFLAGS = $(GST_PLUGINS_BAD_CFLAGS) $(GST_PLUGINS_BASE_CFLAGS) \
|
||||
$(GST_BASE_CFLAGS) $(GST_CFLAGS)
|
||||
|
@ -18,4 +19,5 @@ libgstmpegtsmux_la_LIBTOOLFLAGS = $(GST_PLUGIN_LIBTOOLFLAGS)
|
|||
noinst_HEADERS = \
|
||||
mpegtsmux.h \
|
||||
mpegtsmux_aac.h \
|
||||
mpegtsmux_ttxt.h
|
||||
mpegtsmux_ttxt.h \
|
||||
mpegtsmux_opus.h
|
||||
|
|
|
@ -96,6 +96,7 @@
|
|||
|
||||
#include "mpegtsmux_aac.h"
|
||||
#include "mpegtsmux_ttxt.h"
|
||||
#include "mpegtsmux_opus.h"
|
||||
|
||||
GST_DEBUG_CATEGORY (mpegtsmux_debug);
|
||||
#define GST_CAT_DEFAULT mpegtsmux_debug
|
||||
|
@ -142,6 +143,7 @@ static GstStaticPadTemplate mpegtsmux_sink_factory =
|
|||
"mute = (boolean) { FALSE, TRUE }; "
|
||||
"audio/x-ac3, framed = (boolean) TRUE;"
|
||||
"audio/x-dts, framed = (boolean) TRUE;"
|
||||
"audio/x-opus;"
|
||||
"subpicture/x-dvb; application/x-teletext; meta/x-klv, parsed=true"));
|
||||
|
||||
static GstStaticPadTemplate mpegtsmux_src_factory =
|
||||
|
@ -580,6 +582,7 @@ mpegtsmux_create_stream (MpegTsMux * mux, MpegTsPadData * ts_data)
|
|||
const gchar *mt;
|
||||
const GValue *value = NULL;
|
||||
GstBuffer *codec_data = NULL;
|
||||
guint8 opus_channel_config_code = 0;
|
||||
|
||||
pad = ts_data->collect.pad;
|
||||
caps = gst_pad_get_current_caps (pad);
|
||||
|
@ -667,6 +670,93 @@ mpegtsmux_create_stream (MpegTsMux * mux, MpegTsPadData * ts_data)
|
|||
st = TSMUX_ST_PS_TELETEXT;
|
||||
/* needs a particularly sized layout */
|
||||
ts_data->prepare_func = mpegtsmux_prepare_teletext;
|
||||
} else if (strcmp (mt, "audio/x-opus") == 0) {
|
||||
GstBuffer *streamheader = NULL;
|
||||
const GValue *v;
|
||||
GstMapInfo map;
|
||||
|
||||
v = gst_structure_get_value (s, "streamheader");
|
||||
if (v && G_VALUE_HOLDS (v, GST_TYPE_ARRAY)
|
||||
&& gst_value_array_get_size (v) >= 1) {
|
||||
const GValue *h = gst_value_array_get_value (v, 0);
|
||||
|
||||
streamheader = gst_value_get_buffer (h);
|
||||
}
|
||||
|
||||
/* FIXME: We need to either map all values for the OpusHead header
|
||||
* to caps, or always require/generate an OpusHead streamheader for the
|
||||
* caps. E.g. in rtpopusdepay */
|
||||
if (!streamheader || gst_buffer_get_size (streamheader) < 22) {
|
||||
gint channels;
|
||||
|
||||
if (gst_structure_get_int (s, "channels", &channels) && channels <= 2) {
|
||||
opus_channel_config_code = channels;
|
||||
} else {
|
||||
GST_FIXME_OBJECT (pad,
|
||||
"Multichannel Opus without streamheader not handled");
|
||||
goto not_negotiated;
|
||||
}
|
||||
}
|
||||
|
||||
gst_buffer_map (streamheader, &map, GST_MAP_READ);
|
||||
if (map.data[9] == 2 && map.data[18] == 255 && map.data[19] == 1
|
||||
&& map.data[20] == 1) {
|
||||
/* Dual mono */
|
||||
opus_channel_config_code = 0;
|
||||
} else if (map.data[9] >= 1 && map.data[9] <= 2 && map.data[18] == 0) {
|
||||
/* RTP mapping */
|
||||
opus_channel_config_code = map.data[9];
|
||||
} else if (map.data[9] >= 2 && map.data[9] <= 8 && map.data[18] == 1
|
||||
&& map.size >= 21 + map.data[9]) {
|
||||
static const guint8 coupled_stream_counts[9] = {
|
||||
1, 0, 1, 1, 2, 2, 2, 3, 3
|
||||
};
|
||||
static const guint8 channel_map_a[8][8] = {
|
||||
{0},
|
||||
{0, 1},
|
||||
{0, 2, 1},
|
||||
{0, 1, 2, 3},
|
||||
{0, 4, 1, 2, 3},
|
||||
{0, 4, 1, 2, 3, 5},
|
||||
{0, 4, 1, 2, 3, 5, 6},
|
||||
{0, 6, 1, 2, 3, 4, 5, 7},
|
||||
};
|
||||
static const guint8 channel_map_b[8][8] = {
|
||||
{0},
|
||||
{0, 1},
|
||||
{0, 1, 2},
|
||||
{0, 1, 2, 3},
|
||||
{0, 1, 2, 3, 4},
|
||||
{0, 1, 2, 3, 4, 5},
|
||||
{0, 1, 2, 3, 4, 5, 6},
|
||||
{0, 1, 2, 3, 4, 5, 6, 7},
|
||||
};
|
||||
|
||||
/* Vorbis mapping */
|
||||
if (map.data[19] == map.data[9] - coupled_stream_counts[map.data[9]] &&
|
||||
map.data[20] == coupled_stream_counts[map.data[9]] &&
|
||||
memcmp (&map.data[21], channel_map_a[map.data[9] - 1],
|
||||
map.data[9]) == 0) {
|
||||
opus_channel_config_code = map.data[9];
|
||||
} else if (map.data[19] == map.data[9] &&
|
||||
map.data[20] == 0 &&
|
||||
memcmp (&map.data[21], channel_map_b[map.data[9] - 1],
|
||||
map.data[9]) == 0) {
|
||||
opus_channel_config_code = map.data[9] | 0x80;
|
||||
} else {
|
||||
gst_buffer_unmap (streamheader, &map);
|
||||
GST_FIXME_OBJECT (pad, "Opus channel mapping not handled");
|
||||
goto not_negotiated;
|
||||
}
|
||||
} else {
|
||||
gst_buffer_unmap (streamheader, &map);
|
||||
GST_FIXME_OBJECT (pad, "Opus channel mapping not handled");
|
||||
goto not_negotiated;
|
||||
}
|
||||
gst_buffer_unmap (streamheader, &map);
|
||||
|
||||
st = TSMUX_ST_PS_OPUS;
|
||||
ts_data->prepare_func = mpegtsmux_prepare_opus;
|
||||
} else if (strcmp (mt, "meta/x-klv") == 0) {
|
||||
st = TSMUX_ST_PS_KLV;
|
||||
}
|
||||
|
@ -683,6 +773,8 @@ mpegtsmux_create_stream (MpegTsMux * mux, MpegTsPadData * ts_data)
|
|||
gst_structure_get_int (s, "channels", &ts_data->stream->audio_channels);
|
||||
gst_structure_get_int (s, "bitrate", &ts_data->stream->audio_bitrate);
|
||||
|
||||
ts_data->stream->opus_channel_config_code = opus_channel_config_code;
|
||||
|
||||
tsmux_stream_set_buffer_release_func (ts_data->stream, release_buffer_cb);
|
||||
tsmux_program_add_stream (ts_data->prog, ts_data->stream);
|
||||
|
||||
|
|
128
gst/mpegtsmux/mpegtsmux_opus.c
Normal file
128
gst/mpegtsmux/mpegtsmux_opus.c
Normal file
|
@ -0,0 +1,128 @@
|
|||
/*
|
||||
* Copyright 2006, 2007, 2008 Fluendo S.A.
|
||||
* Authors: Jan Schmidt <jan@fluendo.com>
|
||||
* Kapil Agrawal <kapil@fluendo.com>
|
||||
* Julien Moutte <julien@fluendo.com>
|
||||
*
|
||||
* This library is licensed under 4 different licenses and you
|
||||
* can choose to use it under the terms of any one of them. The
|
||||
* four licenses are the MPL 1.1, the LGPL, the GPL and the MIT
|
||||
* license.
|
||||
*
|
||||
* MPL:
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License
|
||||
* Version 1.1 (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/.
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS"
|
||||
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing rights and limitations
|
||||
* under the License.
|
||||
*
|
||||
* LGPL:
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 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
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library 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.
|
||||
*
|
||||
* GPL:
|
||||
*
|
||||
* 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
|
||||
* (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.
|
||||
*
|
||||
* 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 St, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* MIT:
|
||||
*
|
||||
* Unless otherwise indicated, Source Code is licensed under MIT license.
|
||||
* See further explanation attached in License Statement (distributed in the file
|
||||
* LICENSE).
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
* of the Software, and to permit persons to whom the Software is furnished to do
|
||||
* so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "mpegtsmux_opus.h"
|
||||
#include <string.h>
|
||||
|
||||
#define GST_CAT_DEFAULT mpegtsmux_debug
|
||||
|
||||
GstBuffer *
|
||||
mpegtsmux_prepare_opus (GstBuffer * buf, MpegTsPadData * pad_data,
|
||||
MpegTsMux * mux)
|
||||
{
|
||||
gssize insize = gst_buffer_get_size (buf);
|
||||
gsize outsize;
|
||||
GstBuffer *outbuf;
|
||||
GstMapInfo map;
|
||||
guint n;
|
||||
|
||||
/* TODO: Write start/end trim */
|
||||
outsize = 2 + insize / 255 + 1;
|
||||
|
||||
outbuf = gst_buffer_new_and_alloc (outsize);
|
||||
gst_buffer_copy_into (outbuf, buf,
|
||||
GST_BUFFER_COPY_METADATA | GST_BUFFER_COPY_TIMESTAMPS, 0, 0);
|
||||
gst_buffer_map (outbuf, &map, GST_MAP_WRITE);
|
||||
map.data[0] = 0x7f;
|
||||
map.data[1] = 0xe0;
|
||||
n = 2;
|
||||
do {
|
||||
g_assert (n < outsize);
|
||||
/* FIXME: this should be using insize for writing here but ffmpeg and the
|
||||
* only available sample stream from obe.tv are not including the control
|
||||
* header size in au_size
|
||||
*/
|
||||
map.data[n] = MIN (insize, 255);
|
||||
insize -= 255;
|
||||
n++;
|
||||
} while (insize >= 0);
|
||||
|
||||
gst_buffer_unmap (outbuf, &map);
|
||||
|
||||
outbuf = gst_buffer_append (outbuf, gst_buffer_ref (buf));
|
||||
|
||||
return outbuf;
|
||||
}
|
91
gst/mpegtsmux/mpegtsmux_opus.h
Normal file
91
gst/mpegtsmux/mpegtsmux_opus.h
Normal file
|
@ -0,0 +1,91 @@
|
|||
/*
|
||||
* Copyright 2006, 2007, 2008 Fluendo S.A.
|
||||
* Authors: Jan Schmidt <jan@fluendo.com>
|
||||
* Kapil Agrawal <kapil@fluendo.com>
|
||||
* Julien Moutte <julien@fluendo.com>
|
||||
*
|
||||
* This library is licensed under 4 different licenses and you
|
||||
* can choose to use it under the terms of any one of them. The
|
||||
* four licenses are the MPL 1.1, the LGPL, the GPL and the MIT
|
||||
* license.
|
||||
*
|
||||
* MPL:
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License
|
||||
* Version 1.1 (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/.
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS"
|
||||
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing rights and limitations
|
||||
* under the License.
|
||||
*
|
||||
* LGPL:
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 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
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library 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.
|
||||
*
|
||||
* GPL:
|
||||
*
|
||||
* 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
|
||||
* (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.
|
||||
*
|
||||
* 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 St, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* MIT:
|
||||
*
|
||||
* Unless otherwise indicated, Source Code is licensed under MIT license.
|
||||
* See further explanation attached in License Statement (distributed in the file
|
||||
* LICENSE).
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
* of the Software, and to permit persons to whom the Software is furnished to do
|
||||
* so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __MPEGTSMUX_OPUS_H__
|
||||
#define __MPEGTSMUX_OPUS_H__
|
||||
|
||||
#include "mpegtsmux.h"
|
||||
|
||||
GstBuffer * mpegtsmux_prepare_opus (GstBuffer * buf, MpegTsPadData * data,
|
||||
MpegTsMux * mux);
|
||||
|
||||
#endif /* __MPEGTSMUX_OPUS_H__ */
|
|
@ -200,6 +200,13 @@ tsmux_stream_new (guint16 pid, TsMuxStreamType stream_type)
|
|||
TSMUX_PACKET_FLAG_PES_FULL_HEADER |
|
||||
TSMUX_PACKET_FLAG_PES_DATA_ALIGNMENT;
|
||||
break;
|
||||
case TSMUX_ST_PS_OPUS:
|
||||
/* FIXME: assign sequential extended IDs? */
|
||||
stream->id = 0xBD;
|
||||
stream->stream_type = TSMUX_ST_PRIVATE_DATA;
|
||||
stream->is_opus = TRUE;
|
||||
stream->pi.flags |= TSMUX_PACKET_FLAG_PES_FULL_HEADER;
|
||||
break;
|
||||
default:
|
||||
g_critical ("Stream type 0x%0x not yet implemented", stream_type);
|
||||
break;
|
||||
|
@ -910,6 +917,17 @@ tsmux_stream_get_es_descrs (TsMuxStream * stream,
|
|||
g_ptr_array_add (pmt_stream->descriptors, descriptor);
|
||||
break;
|
||||
}
|
||||
if (stream->is_opus) {
|
||||
descriptor = gst_mpegts_descriptor_from_registration ("Opus", NULL, 0);
|
||||
g_ptr_array_add (pmt_stream->descriptors, descriptor);
|
||||
|
||||
descriptor =
|
||||
gst_mpegts_descriptor_from_custom_with_extension
|
||||
(GST_MTS_DESC_DVB_EXTENSION, 0x80,
|
||||
&stream->opus_channel_config_code, 1);
|
||||
|
||||
g_ptr_array_add (pmt_stream->descriptors, descriptor);
|
||||
}
|
||||
if (stream->is_meta) {
|
||||
descriptor = gst_mpegts_descriptor_from_registration ("KLVA", NULL, 0);
|
||||
GST_ERROR ("adding KLVA registration descriptor!");
|
||||
|
|
|
@ -141,6 +141,7 @@ enum TsMuxStreamType {
|
|||
TSMUX_ST_PS_DVB_SUBPICTURE = 0x8c,
|
||||
TSMUX_ST_PS_TELETEXT = 0x8d,
|
||||
TSMUX_ST_PS_KLV = 0x8e, /* only used internally */
|
||||
TSMUX_ST_PS_OPUS = 0x8f, /* only used internally */
|
||||
TSMUX_ST_PS_DVD_SUBPICTURE = 0xff,
|
||||
|
||||
/* Non-standard definitions */
|
||||
|
@ -209,6 +210,10 @@ struct TsMuxStream {
|
|||
gchar language[4];
|
||||
|
||||
gboolean is_meta;
|
||||
|
||||
/* Opus */
|
||||
gboolean is_opus;
|
||||
guint8 opus_channel_config_code;
|
||||
};
|
||||
|
||||
/* stream management */
|
||||
|
|
Loading…
Reference in a new issue