ext/ogg/gstoggdemux.c: Annodex support in ogg demuxer. Doesn't do very much without the other annodex patches (to come).
Original commit message from CVS: * ext/ogg/gstoggdemux.c: (gst_ogg_pad_parse_skeleton_fishead), (gst_ogg_pad_parse_skeleton_fisbone), (gst_ogg_pad_query_convert), (gst_ogg_demux_chain_peer), (gst_ogg_pad_submit_packet), (gst_ogg_demux_perform_seek), (gst_ogg_demux_read_chain), (gst_ogg_demux_read_end_chain), (gst_ogg_demux_collect_chain_info), (gst_ogg_demux_change_state), (gst_annodex_granule_to_time): Annodex support in ogg demuxer. Doesn't do very much without the other annodex patches (to come).
This commit is contained in:
parent
7647cafafc
commit
a61010004b
11
ChangeLog
11
ChangeLog
@ -1,3 +1,14 @@
|
|||||||
|
2006-02-04 Michael Smith <msmith@fluendo.com>
|
||||||
|
|
||||||
|
* ext/ogg/gstoggdemux.c: (gst_ogg_pad_parse_skeleton_fishead),
|
||||||
|
(gst_ogg_pad_parse_skeleton_fisbone), (gst_ogg_pad_query_convert),
|
||||||
|
(gst_ogg_demux_chain_peer), (gst_ogg_pad_submit_packet),
|
||||||
|
(gst_ogg_demux_perform_seek), (gst_ogg_demux_read_chain),
|
||||||
|
(gst_ogg_demux_read_end_chain), (gst_ogg_demux_collect_chain_info),
|
||||||
|
(gst_ogg_demux_change_state), (gst_annodex_granule_to_time):
|
||||||
|
Annodex support in ogg demuxer. Doesn't do very much without the
|
||||||
|
other annodex patches (to come).
|
||||||
|
|
||||||
2006-02-24 Tim-Philipp Müller <tim at centricular dot net>
|
2006-02-24 Tim-Philipp Müller <tim at centricular dot net>
|
||||||
|
|
||||||
* gst-libs/gst/riff/riff-media.c: (gst_riff_create_video_caps):
|
* gst-libs/gst/riff/riff-media.c: (gst_riff_create_video_caps):
|
||||||
|
@ -28,6 +28,8 @@
|
|||||||
#include <gst/gst-i18n-plugin.h>
|
#include <gst/gst-i18n-plugin.h>
|
||||||
|
|
||||||
#define CHUNKSIZE (8500) /* this is out of vorbisfile */
|
#define CHUNKSIZE (8500) /* this is out of vorbisfile */
|
||||||
|
#define SKELETON_FISHEAD_SIZE 64
|
||||||
|
#define SKELETON_FISBONE_MIN_SIZE 52
|
||||||
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
@ -111,6 +113,13 @@ struct _GstOggPad
|
|||||||
|
|
||||||
GList *headers;
|
GList *headers;
|
||||||
|
|
||||||
|
gboolean is_skeleton;
|
||||||
|
gboolean have_fisbone;
|
||||||
|
gint64 granulerate_n;
|
||||||
|
gint64 granulerate_d;
|
||||||
|
guint32 preroll;
|
||||||
|
guint granuleshift;
|
||||||
|
|
||||||
gint serialno;
|
gint serialno;
|
||||||
gint64 packetno;
|
gint64 packetno;
|
||||||
gint64 current_granule;
|
gint64 current_granule;
|
||||||
@ -165,6 +174,10 @@ struct _GstOggDemux
|
|||||||
gint64 current_granule;
|
gint64 current_granule;
|
||||||
GstClockTime current_time;
|
GstClockTime current_time;
|
||||||
|
|
||||||
|
/* annodex stuff */
|
||||||
|
gboolean have_fishead;
|
||||||
|
gint64 basetime;
|
||||||
|
|
||||||
/* ogg stuff */
|
/* ogg stuff */
|
||||||
ogg_sync_state sync;
|
ogg_sync_state sync;
|
||||||
};
|
};
|
||||||
@ -205,6 +218,15 @@ static gboolean gst_ogg_pad_src_query (GstPad * pad, GstQuery * query);
|
|||||||
static gboolean gst_ogg_pad_event (GstPad * pad, GstEvent * event);
|
static gboolean gst_ogg_pad_event (GstPad * pad, GstEvent * event);
|
||||||
static GstCaps *gst_ogg_pad_getcaps (GstPad * pad);
|
static GstCaps *gst_ogg_pad_getcaps (GstPad * pad);
|
||||||
static GstCaps *gst_ogg_type_find (ogg_packet * packet);
|
static GstCaps *gst_ogg_type_find (ogg_packet * packet);
|
||||||
|
static GstOggPad *gst_ogg_chain_get_stream (GstOggChain * chain,
|
||||||
|
glong serialno);
|
||||||
|
|
||||||
|
static gboolean gst_ogg_pad_query_convert (GstOggPad * pad,
|
||||||
|
GstFormat src_format, gint64 src_val,
|
||||||
|
GstFormat * dest_format, gint64 * dest_val);
|
||||||
|
static GstClockTime gst_annodex_granule_to_time (gint64 granulepos,
|
||||||
|
gint64 granulerate_n, gint64 granulerate_d, guint8 granuleshift);
|
||||||
|
|
||||||
|
|
||||||
static GstPadClass *ogg_pad_parent_class = NULL;
|
static GstPadClass *ogg_pad_parent_class = NULL;
|
||||||
|
|
||||||
@ -566,6 +588,142 @@ compare_ranks (GstPluginFeature * f1, GstPluginFeature * f2)
|
|||||||
gst_plugin_feature_get_name (f1));
|
gst_plugin_feature_get_name (f1));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* called when the skeleton fishead is found. Caller ensures the packet is
|
||||||
|
* precisely the correct size; we don't re-check this here. */
|
||||||
|
static void
|
||||||
|
gst_ogg_pad_parse_skeleton_fishead (GstOggPad * pad, ogg_packet * packet)
|
||||||
|
{
|
||||||
|
GstOggDemux *ogg = pad->ogg;
|
||||||
|
guint8 *data = packet->packet;
|
||||||
|
guint16 major, minor;
|
||||||
|
gint64 prestime_n, prestime_d;
|
||||||
|
gint64 basetime_n, basetime_d;
|
||||||
|
|
||||||
|
/* skip "fishead\0" */
|
||||||
|
data += 8;
|
||||||
|
major = GST_READ_UINT16_LE (data);
|
||||||
|
data += 2;
|
||||||
|
minor = GST_READ_UINT16_LE (data);
|
||||||
|
data += 2;
|
||||||
|
prestime_n = (gint64) GST_READ_UINT64_LE (data);
|
||||||
|
data += 8;
|
||||||
|
prestime_d = (gint64) GST_READ_UINT64_LE (data);
|
||||||
|
data += 8;
|
||||||
|
basetime_n = (gint64) GST_READ_UINT64_LE (data);
|
||||||
|
data += 8;
|
||||||
|
basetime_d = (gint64) GST_READ_UINT64_LE (data);
|
||||||
|
data += 8;
|
||||||
|
|
||||||
|
ogg->basetime = gst_util_uint64_scale (GST_SECOND, basetime_n, basetime_d);
|
||||||
|
ogg->have_fishead = TRUE;
|
||||||
|
pad->is_skeleton = TRUE;
|
||||||
|
pad->start_time = GST_CLOCK_TIME_NONE;
|
||||||
|
pad->first_granule = -1;
|
||||||
|
pad->first_time = GST_CLOCK_TIME_NONE;
|
||||||
|
GST_INFO_OBJECT (ogg, "skeleton fishead parsed (basetime: %"
|
||||||
|
GST_TIME_FORMAT ")", GST_TIME_ARGS (ogg->basetime));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* function called when a skeleton fisbone is found. Caller ensures that
|
||||||
|
* the packet length is sufficient */
|
||||||
|
static void
|
||||||
|
gst_ogg_pad_parse_skeleton_fisbone (GstOggPad * pad, ogg_packet * packet)
|
||||||
|
{
|
||||||
|
GstOggPad *fisbone_pad;
|
||||||
|
gint64 start_granule;
|
||||||
|
guint32 serialno;
|
||||||
|
guint8 *data = packet->packet;
|
||||||
|
|
||||||
|
/* skip "fisbone\0" */
|
||||||
|
data += 8;
|
||||||
|
/* skip headers offset */
|
||||||
|
data += 4;
|
||||||
|
serialno = GST_READ_UINT32_LE (data);
|
||||||
|
|
||||||
|
fisbone_pad = gst_ogg_chain_get_stream (pad->chain, serialno);
|
||||||
|
if (fisbone_pad) {
|
||||||
|
if (fisbone_pad->have_fisbone)
|
||||||
|
/* already parsed */
|
||||||
|
return;
|
||||||
|
|
||||||
|
fisbone_pad->have_fisbone = TRUE;
|
||||||
|
|
||||||
|
data += 4;
|
||||||
|
/* skip number of headers */
|
||||||
|
data += 4;
|
||||||
|
fisbone_pad->granulerate_n = GST_READ_UINT64_LE (data);
|
||||||
|
data += 8;
|
||||||
|
fisbone_pad->granulerate_d = GST_READ_UINT64_LE (data);
|
||||||
|
data += 8;
|
||||||
|
start_granule = GST_READ_UINT64_LE (data);
|
||||||
|
data += 8;
|
||||||
|
fisbone_pad->preroll = GST_READ_UINT32_LE (data);
|
||||||
|
data += 4;
|
||||||
|
fisbone_pad->granuleshift = GST_READ_UINT8 (data);
|
||||||
|
data += 1;
|
||||||
|
/* padding */
|
||||||
|
data += 3;
|
||||||
|
|
||||||
|
fisbone_pad->start_time = gst_annodex_granule_to_time (start_granule,
|
||||||
|
fisbone_pad->granulerate_n, fisbone_pad->granulerate_d,
|
||||||
|
fisbone_pad->granuleshift);
|
||||||
|
|
||||||
|
GST_INFO_OBJECT (pad->ogg, "skeleton fisbone parsed "
|
||||||
|
"(serialno: %" G_GUINT32_FORMAT " start time: %" GST_TIME_FORMAT
|
||||||
|
" granulerate_n: %" G_GINT64_FORMAT " granulerate_d: %" G_GINT64_FORMAT
|
||||||
|
" preroll: %" G_GUINT32_FORMAT " granuleshift: %d)",
|
||||||
|
serialno, GST_TIME_ARGS (fisbone_pad->start_time),
|
||||||
|
fisbone_pad->granulerate_n, fisbone_pad->granulerate_d,
|
||||||
|
fisbone_pad->preroll, fisbone_pad->granuleshift);
|
||||||
|
} else {
|
||||||
|
GST_WARNING_OBJECT (pad->ogg,
|
||||||
|
"found skeleton fisbone for an unknown stream %" G_GUINT32_FORMAT,
|
||||||
|
serialno);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* function called to convert a granulepos to a timestamp */
|
||||||
|
static gboolean
|
||||||
|
gst_ogg_pad_query_convert (GstOggPad * pad, GstFormat src_format,
|
||||||
|
gint64 src_val, GstFormat * dest_format, gint64 * dest_val)
|
||||||
|
{
|
||||||
|
gboolean res;
|
||||||
|
|
||||||
|
if (src_val == -1) {
|
||||||
|
*dest_val = -1;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!pad->have_fisbone && pad->elem_pad == NULL)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
switch (src_format) {
|
||||||
|
case GST_FORMAT_DEFAULT:
|
||||||
|
if (pad->have_fisbone && *dest_format == GST_FORMAT_TIME) {
|
||||||
|
*dest_val = gst_annodex_granule_to_time (src_val,
|
||||||
|
pad->granulerate_n, pad->granulerate_d, pad->granuleshift);
|
||||||
|
|
||||||
|
res = TRUE;
|
||||||
|
} else {
|
||||||
|
if (pad->elem_pad == NULL)
|
||||||
|
res = FALSE;
|
||||||
|
else
|
||||||
|
res = gst_pad_query_convert (pad->elem_pad, src_format, src_val,
|
||||||
|
dest_format, dest_val);
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
if (pad->elem_pad == NULL)
|
||||||
|
res = FALSE;
|
||||||
|
else
|
||||||
|
res = gst_pad_query_convert (pad->elem_pad, src_format, src_val,
|
||||||
|
dest_format, dest_val);
|
||||||
|
}
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
/* function called by the internal decoder elements when it outputs
|
/* function called by the internal decoder elements when it outputs
|
||||||
* a buffer. We use it to get the first timestamp of the stream
|
* a buffer. We use it to get the first timestamp of the stream
|
||||||
*/
|
*/
|
||||||
@ -760,23 +918,6 @@ gst_ogg_demux_queue_data (GstOggPad * pad, ogg_packet * packet)
|
|||||||
return GST_FLOW_OK;
|
return GST_FLOW_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
|
||||||
gst_ogg_pad_query_convert (GstOggPad * ogg_pad, GstFormat from_format,
|
|
||||||
gint64 from_value, GstFormat * to_format, gint64 * to_value)
|
|
||||||
{
|
|
||||||
if (from_value == -1) {
|
|
||||||
*to_value = -1;
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* If we don't know the stream type, we won't have an internal pad to ask */
|
|
||||||
if (!ogg_pad->elem_pad)
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
return gst_pad_query_convert (ogg_pad->elem_pad,
|
|
||||||
from_format, from_value, to_format, to_value);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* send packet to internal element */
|
/* send packet to internal element */
|
||||||
static GstFlowReturn
|
static GstFlowReturn
|
||||||
gst_ogg_demux_chain_peer (GstOggPad * pad, ogg_packet * packet)
|
gst_ogg_demux_chain_peer (GstOggPad * pad, ogg_packet * packet)
|
||||||
@ -807,13 +948,15 @@ gst_ogg_demux_chain_peer (GstOggPad * pad, ogg_packet * packet)
|
|||||||
|
|
||||||
ogg->current_granule = packet->granulepos;
|
ogg->current_granule = packet->granulepos;
|
||||||
format = GST_FORMAT_TIME;
|
format = GST_FORMAT_TIME;
|
||||||
if (!gst_ogg_pad_query_convert (pad,
|
if (!pad->is_skeleton) {
|
||||||
GST_FORMAT_DEFAULT, packet->granulepos, &format,
|
if (!gst_ogg_pad_query_convert (pad,
|
||||||
(gint64 *) & ogg->current_time)) {
|
GST_FORMAT_DEFAULT, packet->granulepos, &format,
|
||||||
GST_WARNING_OBJECT (ogg, "could not convert granulepos to time");
|
(gint64 *) & ogg->current_time)) {
|
||||||
} else {
|
GST_WARNING_OBJECT (ogg, "could not convert granulepos to time");
|
||||||
GST_DEBUG ("ogg current time %" GST_TIME_FORMAT,
|
} else {
|
||||||
GST_TIME_ARGS (ogg->current_time));
|
GST_DEBUG ("ogg current time %" GST_TIME_FORMAT,
|
||||||
|
GST_TIME_ARGS (ogg->current_time));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -840,12 +983,21 @@ gst_ogg_pad_submit_packet (GstOggPad * pad, ogg_packet * packet)
|
|||||||
|
|
||||||
GST_DEBUG_OBJECT (ogg, "%p submit packet serial %08lx", pad, pad->serialno);
|
GST_DEBUG_OBJECT (ogg, "%p submit packet serial %08lx", pad, pad->serialno);
|
||||||
|
|
||||||
/* first packet */
|
|
||||||
if (!pad->have_type) {
|
if (!pad->have_type) {
|
||||||
|
if (!ogg->have_fishead && packet->bytes == SKELETON_FISHEAD_SIZE &&
|
||||||
|
!memcmp (packet->packet, "fishead\0", 8)) {
|
||||||
|
gst_ogg_pad_parse_skeleton_fishead (pad, packet);
|
||||||
|
}
|
||||||
|
|
||||||
gst_ogg_pad_typefind (pad, packet);
|
gst_ogg_pad_typefind (pad, packet);
|
||||||
pad->have_type = TRUE;
|
pad->have_type = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ogg->have_fishead && packet->bytes >= SKELETON_FISBONE_MIN_SIZE &&
|
||||||
|
!memcmp (packet->packet, "fisbone\0", 8)) {
|
||||||
|
gst_ogg_pad_parse_skeleton_fisbone (pad, packet);
|
||||||
|
}
|
||||||
|
|
||||||
granule = packet->granulepos;
|
granule = packet->granulepos;
|
||||||
if (granule != -1) {
|
if (granule != -1) {
|
||||||
ogg->current_granule = granule;
|
ogg->current_granule = granule;
|
||||||
@ -856,8 +1008,8 @@ gst_ogg_pad_submit_packet (GstOggPad * pad, ogg_packet * packet)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* no start time known, stream to internal plugin to
|
/* no start time known, stream to internal plugin to
|
||||||
* get time */
|
* get time. always stream to the skeleton decoder */
|
||||||
if (pad->start_time == GST_CLOCK_TIME_NONE) {
|
if (pad->start_time == GST_CLOCK_TIME_NONE || pad->is_skeleton) {
|
||||||
ret = gst_ogg_demux_chain_elem_pad (pad, packet);
|
ret = gst_ogg_demux_chain_elem_pad (pad, packet);
|
||||||
}
|
}
|
||||||
/* we know the start_time of the pad data, see if we
|
/* we know the start_time of the pad data, see if we
|
||||||
@ -1102,10 +1254,10 @@ GST_STATIC_PAD_TEMPLATE ("src_%d",
|
|||||||
GST_STATIC_CAPS_ANY);
|
GST_STATIC_CAPS_ANY);
|
||||||
|
|
||||||
static GstStaticPadTemplate ogg_demux_sink_template_factory =
|
static GstStaticPadTemplate ogg_demux_sink_template_factory =
|
||||||
GST_STATIC_PAD_TEMPLATE ("sink",
|
GST_STATIC_PAD_TEMPLATE ("sink",
|
||||||
GST_PAD_SINK,
|
GST_PAD_SINK,
|
||||||
GST_PAD_ALWAYS,
|
GST_PAD_ALWAYS,
|
||||||
GST_STATIC_CAPS ("application/ogg")
|
GST_STATIC_CAPS ("application/ogg; application/x-annodex")
|
||||||
);
|
);
|
||||||
|
|
||||||
static void gst_ogg_demux_finalize (GObject * object);
|
static void gst_ogg_demux_finalize (GObject * object);
|
||||||
@ -1738,7 +1890,7 @@ gst_ogg_demux_perform_seek (GstOggDemux * ogg)
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
pad = gst_ogg_chain_get_stream (chain, ogg_page_serialno (&og));
|
pad = gst_ogg_chain_get_stream (chain, ogg_page_serialno (&og));
|
||||||
if (pad == NULL)
|
if (pad == NULL || pad->is_skeleton)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
format = GST_FORMAT_TIME;
|
format = GST_FORMAT_TIME;
|
||||||
@ -1748,6 +1900,9 @@ gst_ogg_demux_perform_seek (GstOggDemux * ogg)
|
|||||||
GST_WARNING_OBJECT (ogg, "could not convert granulepos to time");
|
GST_WARNING_OBJECT (ogg, "could not convert granulepos to time");
|
||||||
granuletime = target;
|
granuletime = target;
|
||||||
} else {
|
} else {
|
||||||
|
if (granuletime < pad->first_time)
|
||||||
|
continue;
|
||||||
|
|
||||||
granuletime -= pad->first_time;
|
granuletime -= pad->first_time;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1999,7 +2154,7 @@ gst_ogg_demux_read_chain (GstOggDemux * ogg)
|
|||||||
if (pad->serialno == serial) {
|
if (pad->serialno == serial) {
|
||||||
known_serial = TRUE;
|
known_serial = TRUE;
|
||||||
|
|
||||||
if (pad->start_time == -1 && ogg_page_eos (&op)) {
|
if (!pad->is_skeleton && pad->start_time == -1 && ogg_page_eos (&op)) {
|
||||||
/* got EOS on a pad before we could find its start_time.
|
/* got EOS on a pad before we could find its start_time.
|
||||||
* We have no chance of finding a start_time for every pad so
|
* We have no chance of finding a start_time for every pad so
|
||||||
* stop searching for the other start_time(s).
|
* stop searching for the other start_time(s).
|
||||||
@ -2034,6 +2189,9 @@ gst_ogg_demux_read_chain (GstOggDemux * ogg)
|
|||||||
GstOggPad *pad = g_array_index (chain->streams, GstOggPad *, i);
|
GstOggPad *pad = g_array_index (chain->streams, GstOggPad *, i);
|
||||||
GstFormat target;
|
GstFormat target;
|
||||||
|
|
||||||
|
if (pad->is_skeleton)
|
||||||
|
continue;
|
||||||
|
|
||||||
target = GST_FORMAT_TIME;
|
target = GST_FORMAT_TIME;
|
||||||
if (!gst_ogg_pad_query_convert (pad,
|
if (!gst_ogg_pad_query_convert (pad,
|
||||||
GST_FORMAT_DEFAULT, pad->first_granule, &target,
|
GST_FORMAT_DEFAULT, pad->first_granule, &target,
|
||||||
@ -2082,6 +2240,9 @@ gst_ogg_demux_read_end_chain (GstOggDemux * ogg, GstOggChain * chain)
|
|||||||
for (i = 0; i < chain->streams->len; i++) {
|
for (i = 0; i < chain->streams->len; i++) {
|
||||||
GstOggPad *pad = g_array_index (chain->streams, GstOggPad *, i);
|
GstOggPad *pad = g_array_index (chain->streams, GstOggPad *, i);
|
||||||
|
|
||||||
|
if (pad->is_skeleton)
|
||||||
|
continue;
|
||||||
|
|
||||||
if (pad->serialno == ogg_page_serialno (&og)) {
|
if (pad->serialno == ogg_page_serialno (&og)) {
|
||||||
gint64 granulepos = ogg_page_granulepos (&og);
|
gint64 granulepos = ogg_page_granulepos (&og);
|
||||||
|
|
||||||
@ -2166,6 +2327,9 @@ gst_ogg_demux_collect_chain_info (GstOggDemux * ogg, GstOggChain * chain)
|
|||||||
for (i = 0; i < chain->streams->len; i++) {
|
for (i = 0; i < chain->streams->len; i++) {
|
||||||
GstOggPad *pad = g_array_index (chain->streams, GstOggPad *, i);
|
GstOggPad *pad = g_array_index (chain->streams, GstOggPad *, i);
|
||||||
|
|
||||||
|
if (pad->is_skeleton)
|
||||||
|
continue;
|
||||||
|
|
||||||
/* can do this if the pad start time is not defined */
|
/* can do this if the pad start time is not defined */
|
||||||
if (pad->start_time == GST_CLOCK_TIME_NONE)
|
if (pad->start_time == GST_CLOCK_TIME_NONE)
|
||||||
goto no_start_time;
|
goto no_start_time;
|
||||||
@ -2595,6 +2759,8 @@ gst_ogg_demux_change_state (GstElement * element, GstStateChange transition)
|
|||||||
ogg->segment_start = GST_CLOCK_TIME_NONE;
|
ogg->segment_start = GST_CLOCK_TIME_NONE;
|
||||||
ogg->segment_stop = GST_CLOCK_TIME_NONE;
|
ogg->segment_stop = GST_CLOCK_TIME_NONE;
|
||||||
ogg->total_time = GST_CLOCK_TIME_NONE;
|
ogg->total_time = GST_CLOCK_TIME_NONE;
|
||||||
|
ogg->basetime = 0;
|
||||||
|
ogg->have_fishead = FALSE;
|
||||||
ogg->running = FALSE;
|
ogg->running = FALSE;
|
||||||
ogg_sync_init (&ogg->sync);
|
ogg_sync_init (&ogg->sync);
|
||||||
break;
|
break;
|
||||||
@ -2618,6 +2784,7 @@ gst_ogg_demux_change_state (GstElement * element, GstStateChange transition)
|
|||||||
gst_ogg_demux_clear_chains (ogg);
|
gst_ogg_demux_clear_chains (ogg);
|
||||||
GST_OBJECT_LOCK (ogg);
|
GST_OBJECT_LOCK (ogg);
|
||||||
ogg->running = FALSE;
|
ogg->running = FALSE;
|
||||||
|
ogg->have_fishead = FALSE;
|
||||||
ogg->segment_rate = 1.0;
|
ogg->segment_rate = 1.0;
|
||||||
ogg->segment_flags = GST_SEEK_FLAG_NONE;
|
ogg->segment_flags = GST_SEEK_FLAG_NONE;
|
||||||
ogg->segment_start = GST_CLOCK_TIME_NONE;
|
ogg->segment_start = GST_CLOCK_TIME_NONE;
|
||||||
@ -2633,6 +2800,30 @@ gst_ogg_demux_change_state (GstElement * element, GstStateChange transition)
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static GstClockTime
|
||||||
|
gst_annodex_granule_to_time (gint64 granulepos, gint64 granulerate_n,
|
||||||
|
gint64 granulerate_d, guint8 granuleshift)
|
||||||
|
{
|
||||||
|
gint64 keyindex, keyoffset;
|
||||||
|
gint64 granulerate;
|
||||||
|
GstClockTime res;
|
||||||
|
|
||||||
|
if (granulepos == 0 || granulerate_n == 0 || granulerate_d == 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (granuleshift != 0) {
|
||||||
|
keyindex = granulepos >> granuleshift;
|
||||||
|
keyoffset = granulepos - (keyindex << granuleshift);
|
||||||
|
granulepos = keyindex + keyoffset;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* GST_SECOND / (granulerate_n / granulerate_d) */
|
||||||
|
granulerate = gst_util_uint64_scale (GST_SECOND,
|
||||||
|
granulerate_d, granulerate_n);
|
||||||
|
res = gst_util_uint64_scale (granulepos, granulerate, 1);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
/*** typefinding **************************************************************/
|
/*** typefinding **************************************************************/
|
||||||
/* ogg supports its own typefinding because the ogg spec defines that the first
|
/* ogg supports its own typefinding because the ogg spec defines that the first
|
||||||
* packet of an ogg stream must identify the stream. Therefore ogg can use a
|
* packet of an ogg stream must identify the stream. Therefore ogg can use a
|
||||||
|
Loading…
x
Reference in New Issue
Block a user