mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-10-07 03:02:17 +00:00
oggdemux: use bitrate to estimate length in pushmode
Parse the bitrate from the various streams. Use the bitrate and the upstream length in bytes to estimate the total stream duration in push mode.
This commit is contained in:
parent
63931dc80b
commit
f9ca4f6097
4 changed files with 44 additions and 3 deletions
|
@ -230,7 +230,7 @@ gst_ogg_pad_src_query (GstPad * pad, GstQuery * query)
|
||||||
case GST_QUERY_DURATION:
|
case GST_QUERY_DURATION:
|
||||||
{
|
{
|
||||||
GstFormat format;
|
GstFormat format;
|
||||||
gint64 total_time;
|
gint64 total_time = -1;
|
||||||
|
|
||||||
gst_query_parse_duration (query, &format, NULL);
|
gst_query_parse_duration (query, &format, NULL);
|
||||||
/* can only get position in time */
|
/* 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 */
|
/* we must return the total length */
|
||||||
total_time = ogg->total_time;
|
total_time = ogg->total_time;
|
||||||
} else {
|
} else {
|
||||||
/* in push mode we can answer the query and we must return -1 */
|
gint bitrate = ogg->bitrate;
|
||||||
total_time = -1;
|
|
||||||
|
/* 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);
|
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 */
|
/* FIXME, should not be called with NULL */
|
||||||
if (chain != NULL) {
|
if (chain != NULL) {
|
||||||
|
gint bitrate;
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (ogg, "activating chain %p", chain);
|
GST_DEBUG_OBJECT (ogg, "activating chain %p", chain);
|
||||||
|
|
||||||
|
bitrate = 0;
|
||||||
|
|
||||||
/* first add the pads */
|
/* first add the pads */
|
||||||
for (i = 0; i < chain->streams->len; i++) {
|
for (i = 0; i < chain->streams->len; i++) {
|
||||||
GstOggPad *pad;
|
GstOggPad *pad;
|
||||||
|
@ -1633,6 +1658,8 @@ gst_ogg_demux_activate_chain (GstOggDemux * ogg, GstOggChain * chain,
|
||||||
|
|
||||||
pad = g_array_index (chain->streams, GstOggPad *, i);
|
pad = g_array_index (chain->streams, GstOggPad *, i);
|
||||||
|
|
||||||
|
bitrate += pad->map.bitrate;
|
||||||
|
|
||||||
if (pad->map.is_skeleton || pad->added || GST_PAD_CAPS (pad) == NULL)
|
if (pad->map.is_skeleton || pad->added || GST_PAD_CAPS (pad) == NULL)
|
||||||
continue;
|
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));
|
gst_element_add_pad (GST_ELEMENT (ogg), GST_PAD_CAST (pad));
|
||||||
}
|
}
|
||||||
|
ogg->bitrate = bitrate;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* after adding the new pads, remove the old pads */
|
/* 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:
|
case GST_STATE_CHANGE_READY_TO_PAUSED:
|
||||||
ogg_sync_reset (&ogg->sync);
|
ogg_sync_reset (&ogg->sync);
|
||||||
ogg->running = FALSE;
|
ogg->running = FALSE;
|
||||||
|
ogg->bitrate = 0;
|
||||||
ogg->segment_running = FALSE;
|
ogg->segment_running = FALSE;
|
||||||
gst_segment_init (&ogg->segment, GST_FORMAT_TIME);
|
gst_segment_init (&ogg->segment, GST_FORMAT_TIME);
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -145,6 +145,7 @@ struct _GstOggDemux
|
||||||
GMutex *chain_lock; /* we need the lock to protect the chains */
|
GMutex *chain_lock; /* we need the lock to protect the chains */
|
||||||
GArray *chains; /* list of chains we know */
|
GArray *chains; /* list of chains we know */
|
||||||
GstClockTime total_time;
|
GstClockTime total_time;
|
||||||
|
gint bitrate; /* bitrate of the current chain */
|
||||||
|
|
||||||
GstOggChain *current_chain;
|
GstOggChain *current_chain;
|
||||||
GstOggChain *building_chain;
|
GstOggChain *building_chain;
|
||||||
|
|
|
@ -304,6 +304,9 @@ setup_theora_mapper (GstOggStream * pad, ogg_packet * packet)
|
||||||
pad->n_header_packets = 3;
|
pad->n_header_packets = 3;
|
||||||
pad->frame_size = 1;
|
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) {
|
if (pad->granulerate_n == 0 || pad->granulerate_d == 0) {
|
||||||
GST_WARNING ("frame rate %d/%d", pad->granulerate_n, pad->granulerate_d);
|
GST_WARNING ("frame rate %d/%d", pad->granulerate_n, pad->granulerate_d);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
@ -478,6 +481,10 @@ setup_vorbis_mapper (GstOggStream * pad, ogg_packet * packet)
|
||||||
pad->last_size = 0;
|
pad->last_size = 0;
|
||||||
GST_LOG ("sample rate: %d", pad->granulerate_n);
|
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;
|
pad->n_header_packets = 3;
|
||||||
|
|
||||||
if (pad->granulerate_n == 0)
|
if (pad->granulerate_n == 0)
|
||||||
|
@ -546,8 +553,11 @@ setup_speex_mapper (GstOggStream * pad, ogg_packet * packet)
|
||||||
|
|
||||||
data += 4 + 4 + 4;
|
data += 4 + 4 + 4;
|
||||||
chans = GST_READ_UINT32_LE (data);
|
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 ("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->n_header_packets = GST_READ_UINT32_LE (packet->packet + 68) + 2;
|
||||||
pad->frame_size = GST_READ_UINT32_LE (packet->packet + 64) *
|
pad->frame_size = GST_READ_UINT32_LE (packet->packet + 64) *
|
||||||
|
|
|
@ -54,6 +54,7 @@ struct _GstOggStream
|
||||||
gint n_header_packets_seen;
|
gint n_header_packets_seen;
|
||||||
gint64 accumulated_granule;
|
gint64 accumulated_granule;
|
||||||
gint frame_size;
|
gint frame_size;
|
||||||
|
gint bitrate;
|
||||||
|
|
||||||
GstCaps *caps;
|
GstCaps *caps;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue