Merge branch 'master' into 0.11

Conflicts:
	ext/ogg/gstoggmux.c
This commit is contained in:
Wim Taymans 2011-11-23 10:50:53 +01:00
commit 7b45a7367b
5 changed files with 130 additions and 4 deletions

View file

@ -891,9 +891,12 @@ gst_ogg_pad_submit_packet (GstOggPad * pad, ogg_packet * packet)
pad->start_time = gst_ogg_stream_granule_to_time (&pad->map,
start_granule);
GST_DEBUG_OBJECT (ogg,
"start time %" GST_TIME_FORMAT " (%" GST_TIME_FORMAT ") for %s",
"start time %" GST_TIME_FORMAT " (%" GST_TIME_FORMAT ") for %s "
"from granpos %" G_GINT64_FORMAT " (granule %" G_GINT64_FORMAT ", "
"accumulated granule %" G_GINT64_FORMAT,
GST_TIME_ARGS (pad->start_time), GST_TIME_ARGS (pad->start_time),
gst_ogg_stream_get_media_type (&pad->map));
gst_ogg_stream_get_media_type (&pad->map), packet->granulepos,
granule, pad->map.accumulated_granule);
} else {
packet->granulepos = gst_ogg_stream_granule_to_granulepos (&pad->map,
pad->map.accumulated_granule, pad->keyframe_granule);

View file

@ -115,7 +115,7 @@ static GstStaticPadTemplate audio_sink_factory =
GST_PAD_REQUEST,
GST_STATIC_CAPS
("audio/x-vorbis; audio/x-flac; audio/x-speex; audio/x-celt; "
"application/x-ogm-audio; ")
"application/x-ogm-audio; audio/x-opus")
);
static GstStaticPadTemplate subtitle_sink_factory =

View file

@ -127,6 +127,10 @@ gst_ogg_stream_granule_to_time (GstOggStream * pad, gint64 granule)
if (granule == 0 || pad->granulerate_n == 0 || pad->granulerate_d == 0)
return 0;
granule += pad->granule_offset;
if (granule < 0)
return 0;
return gst_util_uint64_scale (granule, GST_SECOND * pad->granulerate_d,
pad->granulerate_n);
}
@ -1820,6 +1824,103 @@ 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;
/* pre-skip is in samples at 48000 Hz, which matches granule one for one */
pad->granule_offset = -GST_READ_UINT16_LE (packet->packet + 10);
GST_INFO ("Opus has a pre-skip of %" G_GINT64_FORMAT " samples",
-pad->granule_offset);
pad->caps = gst_caps_new_simple ("audio/x-opus", NULL);
return TRUE;
}
static gboolean
is_header_opus (GstOggStream * pad, ogg_packet * packet)
{
return packet->bytes >= 8 && !memcmp (packet->packet, "Opus", 4);
}
static gint64
packet_duration_opus (GstOggStream * pad, ogg_packet * packet)
{
static const guint64 durations[32] = {
480, 960, 1920, 2880, /* Silk NB */
480, 960, 1920, 2880, /* Silk MB */
480, 960, 1920, 2880, /* Silk WB */
480, 960, /* Hybrid SWB */
480, 960, /* Hybrid FB */
120, 240, 480, 960, /* CELT NB */
120, 240, 480, 960, /* CELT NB */
120, 240, 480, 960, /* CELT NB */
120, 240, 480, 960, /* CELT NB */
};
gint64 duration;
gint64 frame_duration;
gint nframes;
guint8 toc;
if (packet->bytes < 1)
return 0;
/* headers */
if (is_header_opus (pad, packet))
return 0;
toc = packet->packet[0];
frame_duration = durations[toc >> 3];
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 > 5760) {
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 / 48.f, nframes, duration / 48.f);
return duration;
}
static void
extract_tags_opus (GstOggStream * pad, ogg_packet * packet)
{
if (packet->bytes >= 8 && memcmp (packet->packet, "OpusTags", 8) == 0) {
tag_list_from_vorbiscomment_packet (packet,
(const guint8 *) "OpusTags", 8, &pad->taglist);
}
}
/* *INDENT-OFF* */
/* indent hates our freedoms */
@ -1991,6 +2092,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_opus,
packet_duration_opus,
NULL,
extract_tags_opus
},
{
"\001audio\0\0\0", 9, 53,
"application/x-ogm-audio",

View file

@ -60,6 +60,7 @@ struct _GstOggStream
gboolean have_fisbone;
gint granulerate_n;
gint granulerate_d;
gint64 granule_offset;
guint32 preroll;
guint granuleshift;
gint n_header_packets;

View file

@ -446,12 +446,20 @@ gst_play_sink_convert_bin_remove_elements (GstPlaySinkConvertBin * self)
}
static void
gst_play_sink_convert_bin_finalize (GObject * object)
gst_play_sink_convert_bin_dispose (GObject * object)
{
GstPlaySinkConvertBin *self = GST_PLAY_SINK_CONVERT_BIN_CAST (object);
gst_play_sink_convert_bin_remove_elements (self);
G_OBJECT_CLASS (parent_class)->dispose (object);
}
static void
gst_play_sink_convert_bin_finalize (GObject * object)
{
GstPlaySinkConvertBin *self = GST_PLAY_SINK_CONVERT_BIN_CAST (object);
gst_object_unref (self->sink_proxypad);
g_mutex_free (self->lock);
@ -548,6 +556,7 @@ gst_play_sink_convert_bin_class_init (GstPlaySinkConvertBinClass * klass)
gobject_class = (GObjectClass *) klass;
gstelement_class = (GstElementClass *) klass;
gobject_class->dispose = gst_play_sink_convert_bin_dispose;
gobject_class->finalize = gst_play_sink_convert_bin_finalize;
gst_element_class_add_pad_template (gstelement_class,