ogg: add opus support

This commit is contained in:
Vincent Penquerc'h 2011-11-19 16:06:09 +00:00
parent 80658564ae
commit 9d2a2750c2
2 changed files with 86 additions and 1 deletions

View file

@ -107,7 +107,7 @@ static GstStaticPadTemplate sink_factory = GST_STATIC_PAD_TEMPLATE ("sink_%d",
"audio/x-vorbis; audio/x-flac; audio/x-speex; audio/x-celt; "
"application/x-ogm-video; application/x-ogm-audio; video/x-dirac; "
"video/x-smoke; video/x-vp8; text/x-cmml, encoded = (boolean) TRUE; "
"subtitle/x-kate; application/x-kate")
"subtitle/x-kate; application/x-kate; audio/x-opus")
);
static void gst_ogg_mux_base_init (gpointer g_class);

View file

@ -1845,6 +1845,79 @@ extract_tags_kate (GstOggStream * pad, ogg_packet * packet)
}
}
/* opus */
static gboolean
setup_opus_mapper (GstOggStream * pad, ogg_packet * packet)
{
if (packet->bytes < 19)
return FALSE;
pad->granulerate_n = 48000;
pad->granulerate_d = 1;
pad->granuleshift = 0;
pad->n_header_packets = 2;
pad->caps = gst_caps_new_simple ("audio/x-opus", NULL);
return TRUE;
}
static gint64
packet_duration_opus (GstOggStream * pad, ogg_packet * packet)
{
static const guint64 durations[32] = {
10000, 20000, 40000, 60000, /* Silk NB */
10000, 20000, 40000, 60000, /* Silk MB */
10000, 20000, 40000, 60000, /* Silk WB */
10000, 20000, /* Hybrid SWB */
10000, 20000, /* Hybrid FB */
2500, 5000, 10000, 20000, /* CELT NB */
2500, 5000, 10000, 20000, /* CELT NB */
2500, 5000, 10000, 20000, /* CELT NB */
2500, 5000, 10000, 20000, /* CELT NB */
};
gint64 duration;
gint64 frame_duration;
gint nframes;
guint8 toc;
if (packet->bytes < 1)
return 0;
toc = packet->packet[0];
frame_duration = durations[toc >> 3] * 1000;
switch (toc & 3) {
case 0:
nframes = 1;
break;
case 1:
nframes = 2;
break;
case 2:
nframes = 2;
break;
case 3:
if (packet->bytes < 2) {
GST_WARNING ("Code 3 Opus packet has less than 2 bytes");
return 0;
}
nframes = packet->packet[1] & 63;
break;
}
duration = nframes * frame_duration;
if (duration > 120 * GST_MSECOND) {
GST_WARNING ("Opus packet duration > 120 ms, invalid");
return 0;
}
GST_LOG ("Opus packet: frame size %.1f ms, %d frames, duration %.1f ms",
frame_duration / 1000000.f, nframes, duration / 1000000.f);
return (duration + 24000) / 48000;
}
/* *INDENT-OFF* */
/* indent hates our freedoms */
@ -2016,6 +2089,18 @@ const GstOggMap mappers[] = {
granulepos_to_key_granule_vp8,
extract_tags_vp8
},
{
"OpusHead", 8, 0,
"audio/x-opus",
setup_opus_mapper,
granulepos_to_granule_default,
granule_to_granulepos_default,
NULL,
is_header_count,
packet_duration_opus,
NULL,
extract_tags_count
},
{
"\001audio\0\0\0", 9, 53,
"application/x-ogm-audio",