summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ext/ogg/gstoggdemux.c35
-rw-r--r--ext/ogg/gstoggdemux.h1
-rw-r--r--ext/ogg/gstoggstream.c10
-rw-r--r--ext/ogg/gstoggstream.h1
4 files changed, 44 insertions, 3 deletions
diff --git a/ext/ogg/gstoggdemux.c b/ext/ogg/gstoggdemux.c
index a77d2c9e2..bf4072f24 100644
--- a/ext/ogg/gstoggdemux.c
+++ b/ext/ogg/gstoggdemux.c
@@ -230,7 +230,7 @@ gst_ogg_pad_src_query (GstPad * pad, GstQuery * query)
case GST_QUERY_DURATION:
{
GstFormat format;
- gint64 total_time;
+ gint64 total_time = -1;
gst_query_parse_duration (query, &format, NULL);
/* can only get position in time */
@@ -241,8 +241,29 @@ gst_ogg_pad_src_query (GstPad * pad, GstQuery * query)
/* we must return the total length */
total_time = ogg->total_time;
} else {
- /* in push mode we can answer the query and we must return -1 */
- total_time = -1;
+ gint bitrate = ogg->bitrate;
+
+ /* try with length and bitrate */
+ if (bitrate > 0) {
+ GstQuery *uquery;
+
+ /* ask upstream for total length in bytes */
+ uquery = gst_query_new_duration (GST_FORMAT_BYTES);
+ if (gst_pad_peer_query (ogg->sinkpad, uquery)) {
+ gint64 length;
+
+ gst_query_parse_duration (uquery, NULL, &length);
+
+ /* estimate using the bitrate */
+ total_time =
+ gst_util_uint64_scale (length, 8 * GST_SECOND, bitrate);
+
+ GST_LOG_OBJECT (ogg,
+ "length: %" G_GINT64_FORMAT ", bitrate %d, total_time %"
+ GST_TIME_FORMAT, length, bitrate, GST_TIME_ARGS (total_time));
+ }
+ gst_query_unref (uquery);
+ }
}
gst_query_set_duration (query, GST_FORMAT_TIME, total_time);
@@ -1624,8 +1645,12 @@ gst_ogg_demux_activate_chain (GstOggDemux * ogg, GstOggChain * chain,
/* FIXME, should not be called with NULL */
if (chain != NULL) {
+ gint bitrate;
+
GST_DEBUG_OBJECT (ogg, "activating chain %p", chain);
+ bitrate = 0;
+
/* first add the pads */
for (i = 0; i < chain->streams->len; i++) {
GstOggPad *pad;
@@ -1633,6 +1658,8 @@ gst_ogg_demux_activate_chain (GstOggDemux * ogg, GstOggChain * chain,
pad = g_array_index (chain->streams, GstOggPad *, i);
+ bitrate += pad->map.bitrate;
+
if (pad->map.is_skeleton || pad->added || GST_PAD_CAPS (pad) == NULL)
continue;
@@ -1656,6 +1683,7 @@ gst_ogg_demux_activate_chain (GstOggDemux * ogg, GstOggChain * chain,
gst_element_add_pad (GST_ELEMENT (ogg), GST_PAD_CAST (pad));
}
+ ogg->bitrate = bitrate;
}
/* after adding the new pads, remove the old pads */
@@ -3293,6 +3321,7 @@ gst_ogg_demux_change_state (GstElement * element, GstStateChange transition)
case GST_STATE_CHANGE_READY_TO_PAUSED:
ogg_sync_reset (&ogg->sync);
ogg->running = FALSE;
+ ogg->bitrate = 0;
ogg->segment_running = FALSE;
gst_segment_init (&ogg->segment, GST_FORMAT_TIME);
break;
diff --git a/ext/ogg/gstoggdemux.h b/ext/ogg/gstoggdemux.h
index 2cee7b6b8..97cbdd327 100644
--- a/ext/ogg/gstoggdemux.h
+++ b/ext/ogg/gstoggdemux.h
@@ -145,6 +145,7 @@ struct _GstOggDemux
GMutex *chain_lock; /* we need the lock to protect the chains */
GArray *chains; /* list of chains we know */
GstClockTime total_time;
+ gint bitrate; /* bitrate of the current chain */
GstOggChain *current_chain;
GstOggChain *building_chain;
diff --git a/ext/ogg/gstoggstream.c b/ext/ogg/gstoggstream.c
index 9c3392c2a..707fa03ea 100644
--- a/ext/ogg/gstoggstream.c
+++ b/ext/ogg/gstoggstream.c
@@ -304,6 +304,9 @@ setup_theora_mapper (GstOggStream * pad, ogg_packet * packet)
pad->n_header_packets = 3;
pad->frame_size = 1;
+ pad->bitrate = GST_READ_UINT24_BE (data + 37);
+ GST_LOG ("bit rate: %d", pad->bitrate);
+
if (pad->granulerate_n == 0 || pad->granulerate_d == 0) {
GST_WARNING ("frame rate %d/%d", pad->granulerate_n, pad->granulerate_d);
return FALSE;
@@ -478,6 +481,10 @@ setup_vorbis_mapper (GstOggStream * pad, ogg_packet * packet)
pad->last_size = 0;
GST_LOG ("sample rate: %d", pad->granulerate_n);
+ data += 8;
+ pad->bitrate = GST_READ_UINT32_LE (data);
+ GST_LOG ("bit rate: %d", pad->bitrate);
+
pad->n_header_packets = 3;
if (pad->granulerate_n == 0)
@@ -546,8 +553,11 @@ setup_speex_mapper (GstOggStream * pad, ogg_packet * packet)
data += 4 + 4 + 4;
chans = GST_READ_UINT32_LE (data);
+ data += 4;
+ pad->bitrate = GST_READ_UINT32_LE (data);
GST_LOG ("sample rate: %d, channels: %u", pad->granulerate_n, chans);
+ GST_LOG ("bit rate: %d", pad->bitrate);
pad->n_header_packets = GST_READ_UINT32_LE (packet->packet + 68) + 2;
pad->frame_size = GST_READ_UINT32_LE (packet->packet + 64) *
diff --git a/ext/ogg/gstoggstream.h b/ext/ogg/gstoggstream.h
index 78b55c06d..770fac752 100644
--- a/ext/ogg/gstoggstream.h
+++ b/ext/ogg/gstoggstream.h
@@ -54,6 +54,7 @@ struct _GstOggStream
gint n_header_packets_seen;
gint64 accumulated_granule;
gint frame_size;
+ gint bitrate;
GstCaps *caps;