mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-01-24 08:08:22 +00:00
isomp4: add support for Opus in mp4mpux
Add support for muxing MP4 files containing Opus. Based on the spec detailed here: https://www.opus-codec.org/docs/opus_in_isobmff.html https://bugzilla.gnome.org/show_bug.cgi?id=742643
This commit is contained in:
parent
cc119e6eb9
commit
5ed8cba024
5 changed files with 97 additions and 1 deletions
|
@ -4727,6 +4727,44 @@ build_ac3_extension (guint8 fscod, guint8 bsid, guint8 bsmod, guint8 acmod,
|
|||
atom_data_free);
|
||||
}
|
||||
|
||||
AtomInfo *
|
||||
build_opus_extension (guint32 rate, guint8 channels, guint8 mapping_family,
|
||||
guint8 stream_count, guint8 coupled_count, guint8 channel_mapping[256],
|
||||
guint16 pre_skip, guint16 output_gain)
|
||||
{
|
||||
AtomData *atom_data;
|
||||
guint8 *data_block;
|
||||
GstByteWriter bw;
|
||||
gboolean hdl = TRUE;
|
||||
guint data_block_len;
|
||||
|
||||
gst_byte_writer_init (&bw);
|
||||
hdl &= gst_byte_writer_put_uint8 (&bw, 0x00); /* version number */
|
||||
hdl &= gst_byte_writer_put_uint8 (&bw, channels);
|
||||
hdl &= gst_byte_writer_put_uint16_le (&bw, pre_skip);
|
||||
hdl &= gst_byte_writer_put_uint32_le (&bw, rate);
|
||||
hdl &= gst_byte_writer_put_uint16_le (&bw, output_gain);
|
||||
hdl &= gst_byte_writer_put_uint8 (&bw, mapping_family);
|
||||
if (mapping_family > 0) {
|
||||
hdl &= gst_byte_writer_put_uint8 (&bw, stream_count);
|
||||
hdl &= gst_byte_writer_put_uint8 (&bw, coupled_count);
|
||||
hdl &= gst_byte_writer_put_data (&bw, channel_mapping, channels);
|
||||
}
|
||||
|
||||
if (!hdl) {
|
||||
GST_WARNING ("Error creating header");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
data_block_len = gst_byte_writer_get_size (&bw);
|
||||
data_block = gst_byte_writer_reset_and_get_data (&bw);
|
||||
atom_data = atom_data_new_from_data (FOURCC_dops, data_block, data_block_len);
|
||||
g_free (data_block);
|
||||
|
||||
return build_atom_info_wrapper ((Atom *) atom_data, atom_data_copy_data,
|
||||
atom_data_free);
|
||||
}
|
||||
|
||||
AtomInfo *
|
||||
build_uuid_xmp_atom (GstBuffer * xmp_data)
|
||||
{
|
||||
|
|
|
@ -964,6 +964,11 @@ AtomInfo * build_fiel_extension (gint fields);
|
|||
AtomInfo * build_ac3_extension (guint8 fscod, guint8 bsid,
|
||||
guint8 bsmod, guint8 acmod,
|
||||
guint8 lfe_on, guint8 bitrate_code);
|
||||
AtomInfo * build_opus_extension (guint32 rate, guint8 channels, guint8 mapping_family,
|
||||
guint8 stream_count, guint8 coupled_count,
|
||||
guint8 channel_mapping[256], guint16 pre_skip,
|
||||
guint16 output_gain);
|
||||
|
||||
AtomInfo * build_amr_extension (void);
|
||||
AtomInfo * build_h263_extension (void);
|
||||
AtomInfo * build_gama_atom (gdouble gamma);
|
||||
|
|
|
@ -163,6 +163,8 @@ G_BEGIN_DECLS
|
|||
#define FOURCC_mp4s GST_MAKE_FOURCC('m','p','4','s')
|
||||
#define FOURCC_mp4v GST_MAKE_FOURCC('m','p','4','v')
|
||||
#define FOURCC_name GST_MAKE_FOURCC('n','a','m','e')
|
||||
#define FOURCC_opus GST_MAKE_FOURCC('O','p','u','s')
|
||||
#define FOURCC_dops GST_MAKE_FOURCC('d','O','p','s')
|
||||
#define FOURCC_pasp GST_MAKE_FOURCC('p','a','s','p')
|
||||
#define FOURCC_pcst GST_MAKE_FOURCC('p','c','s','t')
|
||||
#define FOURCC_pgap GST_MAKE_FOURCC('p','g','a','p')
|
||||
|
|
|
@ -122,6 +122,7 @@
|
|||
#include <gst/audio/audio.h>
|
||||
#include <gst/video/video.h>
|
||||
#include <gst/tag/tag.h>
|
||||
#include <gst/pbutils/pbutils.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
#ifdef G_OS_WIN32
|
||||
|
@ -3665,6 +3666,49 @@ gst_qt_mux_audio_sink_set_caps (GstQTPad * qtpad, GstCaps * caps)
|
|||
* the stream itself. Abuse the prepare_buf_func so we parse a frame
|
||||
* and get the needed data */
|
||||
qtpad->prepare_buf_func = gst_qt_mux_prepare_parse_ac3_frame;
|
||||
} else if (strcmp (mimetype, "audio/x-opus") == 0) {
|
||||
/* Based on the specification defined in:
|
||||
* https://www.opus-codec.org/docs/opus_in_isobmff.html */
|
||||
guint8 channels, mapping_family, stream_count, coupled_count;
|
||||
guint16 pre_skip;
|
||||
gint16 output_gain;
|
||||
guint32 rate;
|
||||
guint8 channel_mapping[256];
|
||||
const GValue *streamheader;
|
||||
const GValue *first_element;
|
||||
GstBuffer *header;
|
||||
|
||||
entry.fourcc = FOURCC_opus;
|
||||
entry.sample_size = 16;
|
||||
|
||||
streamheader = gst_structure_get_value (structure, "streamheader");
|
||||
if (streamheader && GST_VALUE_HOLDS_ARRAY (streamheader) &&
|
||||
gst_value_array_get_size (streamheader) != 0) {
|
||||
first_element = gst_value_array_get_value (streamheader, 0);
|
||||
header = gst_value_get_buffer (first_element);
|
||||
if (!gst_codec_utils_opus_parse_header (header, &rate, &channels,
|
||||
&mapping_family, &stream_count, &coupled_count, channel_mapping,
|
||||
&pre_skip, &output_gain)) {
|
||||
GST_ERROR_OBJECT (qtmux, "Incomplete OpusHead");
|
||||
goto refuse_caps;
|
||||
}
|
||||
} else {
|
||||
GST_WARNING_OBJECT (qtmux,
|
||||
"no streamheader field in caps %" GST_PTR_FORMAT, caps);
|
||||
|
||||
if (!gst_codec_utils_opus_parse_caps (caps, &rate, &channels,
|
||||
&mapping_family, &stream_count, &coupled_count,
|
||||
channel_mapping)) {
|
||||
GST_ERROR_OBJECT (qtmux, "Incomplete Opus caps");
|
||||
goto refuse_caps;
|
||||
}
|
||||
pre_skip = 0;
|
||||
output_gain = 0;
|
||||
}
|
||||
|
||||
entry.channels = channels;
|
||||
ext_atom = build_opus_extension (rate, channels, mapping_family,
|
||||
stream_count, coupled_count, channel_mapping, pre_skip, output_gain);
|
||||
}
|
||||
|
||||
if (!entry.fourcc)
|
||||
|
|
|
@ -132,6 +132,12 @@
|
|||
"audio/x-alac, " \
|
||||
COMMON_AUDIO_CAPS(2, MAX)
|
||||
|
||||
#define OPUS_CAPS \
|
||||
"audio/x-opus, " \
|
||||
"channel-mapping-family = (int) [0, 255], " \
|
||||
COMMON_AUDIO_CAPS(8, MAX)
|
||||
|
||||
|
||||
#define TEXT_UTF8 \
|
||||
"text/x-raw, " \
|
||||
"format=(string)utf8"
|
||||
|
@ -184,7 +190,8 @@ GstQTMuxFormatProp gst_qt_mux_format_list[] = {
|
|||
GST_STATIC_CAPS ("video/quicktime, variant = (string) iso"),
|
||||
GST_STATIC_CAPS (MPEG4V_CAPS "; " H264_CAPS ";"
|
||||
"video/x-mp4-part," COMMON_VIDEO_CAPS),
|
||||
GST_STATIC_CAPS (MP3_CAPS "; " AAC_CAPS " ; " AC3_CAPS " ; " ALAC_CAPS),
|
||||
GST_STATIC_CAPS (MP3_CAPS "; "
|
||||
AAC_CAPS " ; " AC3_CAPS " ; " ALAC_CAPS " ; " OPUS_CAPS),
|
||||
GST_STATIC_CAPS (TEXT_UTF8)}
|
||||
,
|
||||
/* Microsoft Smooth Streaming fmp4/isml */
|
||||
|
|
Loading…
Reference in a new issue