mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-02-03 13:02:29 +00:00
ext/vorbis/vorbisdec.c: Small cleanups.
Original commit message from CVS: * ext/vorbis/vorbisdec.c: (vorbis_dec_src_query), (vorbis_dec_src_event), (vorbis_dec_sink_event), (vorbis_do_clip), (vorbis_dec_push), (vorbis_handle_data_packet), (vorbis_dec_chain), (vorbis_dec_change_state): Small cleanups. Add some FIXMEs Clip output samples to segment boundaries.
This commit is contained in:
parent
63bd38cd2b
commit
696dd6e320
2 changed files with 115 additions and 13 deletions
10
ChangeLog
10
ChangeLog
|
@ -1,3 +1,13 @@
|
|||
2006-05-26 Wim Taymans <wim@fluendo.com>
|
||||
|
||||
* ext/vorbis/vorbisdec.c: (vorbis_dec_src_query),
|
||||
(vorbis_dec_src_event), (vorbis_dec_sink_event), (vorbis_do_clip),
|
||||
(vorbis_dec_push), (vorbis_handle_data_packet), (vorbis_dec_chain),
|
||||
(vorbis_dec_change_state):
|
||||
Small cleanups.
|
||||
Add some FIXMEs
|
||||
Clip output samples to segment boundaries.
|
||||
|
||||
2006-05-26 Jan Schmidt <thaytan@mad.scientist.com>
|
||||
|
||||
* sys/ximage/ximagesink.c: (gst_ximagesink_ximage_new),
|
||||
|
|
|
@ -334,14 +334,19 @@ vorbis_dec_src_query (GstPad * pad, GstQuery * query)
|
|||
}
|
||||
case GST_QUERY_DURATION:
|
||||
{
|
||||
/* query peer for total length */
|
||||
if (!gst_pad_is_linked (dec->sinkpad)) {
|
||||
GstPad *peer;
|
||||
|
||||
if (!(peer = gst_pad_get_peer (dec->sinkpad))) {
|
||||
GST_WARNING_OBJECT (dec, "sink pad %" GST_PTR_FORMAT " is not linked",
|
||||
dec->sinkpad);
|
||||
goto error;
|
||||
}
|
||||
if (!(res = gst_pad_query (GST_PAD_PEER (dec->sinkpad), query)))
|
||||
|
||||
res = gst_pad_query (peer, query);
|
||||
gst_object_unref (peer);
|
||||
if (!res)
|
||||
goto error;
|
||||
|
||||
break;
|
||||
}
|
||||
case GST_QUERY_CONVERT:
|
||||
|
@ -421,7 +426,8 @@ vorbis_dec_src_event (GstPad * pad, GstEvent * event)
|
|||
dec = GST_VORBIS_DEC (gst_pad_get_parent (pad));
|
||||
|
||||
switch (GST_EVENT_TYPE (event)) {
|
||||
case GST_EVENT_SEEK:{
|
||||
case GST_EVENT_SEEK:
|
||||
{
|
||||
GstFormat format, tformat;
|
||||
gdouble rate;
|
||||
GstEvent *real_seek;
|
||||
|
@ -512,6 +518,12 @@ vorbis_dec_sink_event (GstPad * pad, GstEvent * event)
|
|||
if (rate <= 0.0)
|
||||
goto newseg_wrong_rate;
|
||||
|
||||
GST_DEBUG_OBJECT (dec,
|
||||
"newsegment: update %d, rate %g, arate %g, start %" GST_TIME_FORMAT
|
||||
", stop %" GST_TIME_FORMAT ", time %" GST_TIME_FORMAT,
|
||||
update, rate, arate, GST_TIME_ARGS (start), GST_TIME_ARGS (stop),
|
||||
GST_TIME_ARGS (time));
|
||||
|
||||
/* now configure the values */
|
||||
gst_segment_set_newsegment_full (&dec->segment, update,
|
||||
rate, arate, format, start, stop, time);
|
||||
|
@ -752,6 +764,61 @@ copy_samples (float *out, float **in, guint samples, gint channels)
|
|||
#endif
|
||||
}
|
||||
|
||||
/* clip output samples to the segment boundaries
|
||||
*/
|
||||
static gboolean
|
||||
vorbis_do_clip (GstVorbisDec * dec, GstBuffer * buf)
|
||||
{
|
||||
gint64 start, stop, cstart, cstop, diff;
|
||||
guint size;
|
||||
|
||||
start = GST_BUFFER_TIMESTAMP (buf);
|
||||
stop = start + GST_BUFFER_DURATION (buf);
|
||||
|
||||
size = GST_BUFFER_SIZE (buf);
|
||||
|
||||
if (!gst_segment_clip (&dec->segment, GST_FORMAT_TIME,
|
||||
start, stop, &cstart, &cstop))
|
||||
goto clipped;
|
||||
|
||||
/* see if some clipping happened */
|
||||
diff = cstart - start;
|
||||
if (diff > 0) {
|
||||
GST_BUFFER_TIMESTAMP (buf) = cstart;
|
||||
GST_BUFFER_DURATION (buf) -= diff;
|
||||
|
||||
/* bring clipped time to samples */
|
||||
diff = gst_util_uint64_scale_int (diff, dec->vi.rate, GST_SECOND);
|
||||
/* samples to bytes */
|
||||
diff *= (sizeof (float) * dec->vi.channels);
|
||||
GST_DEBUG_OBJECT (dec, "clipping start to %" GST_TIME_FORMAT " %"
|
||||
G_GUINT64_FORMAT " bytes", GST_TIME_ARGS (cstart), diff);
|
||||
GST_BUFFER_DATA (buf) += diff;
|
||||
GST_BUFFER_SIZE (buf) -= diff;
|
||||
}
|
||||
diff = stop - cstop;
|
||||
if (diff > 0) {
|
||||
GST_BUFFER_DURATION (buf) -= diff;
|
||||
|
||||
/* bring clipped time to samples and then to bytes */
|
||||
diff = gst_util_uint64_scale_int (diff, dec->vi.rate, GST_SECOND);
|
||||
diff *= (sizeof (float) * dec->vi.channels);
|
||||
GST_DEBUG_OBJECT (dec, "clipping stop to %" GST_TIME_FORMAT " %"
|
||||
G_GUINT64_FORMAT " bytes", GST_TIME_ARGS (cstop), diff);
|
||||
GST_BUFFER_SIZE (buf) -= diff;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
|
||||
/* dropped buffer */
|
||||
clipped:
|
||||
{
|
||||
GST_DEBUG_OBJECT (dec, "clipped buffer");
|
||||
gst_buffer_unref (buf);
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
static GstFlowReturn
|
||||
vorbis_dec_push (GstVorbisDec * dec, GstBuffer * buf)
|
||||
{
|
||||
|
@ -787,6 +854,11 @@ vorbis_dec_push (GstVorbisDec * dec, GstBuffer * buf)
|
|||
for (walk = dec->queued; walk; walk = g_list_next (walk)) {
|
||||
GstBuffer *buffer = GST_BUFFER (walk->data);
|
||||
|
||||
/* clips or returns FALSE with buffer unreffed when completely
|
||||
* clipped */
|
||||
if (vorbis_do_clip (dec, buffer))
|
||||
continue;
|
||||
|
||||
if (dec->discont) {
|
||||
GST_BUFFER_FLAG_SET (buffer, GST_BUFFER_FLAG_DISCONT);
|
||||
dec->discont = FALSE;
|
||||
|
@ -797,6 +869,11 @@ vorbis_dec_push (GstVorbisDec * dec, GstBuffer * buf)
|
|||
g_list_free (dec->queued);
|
||||
dec->queued = NULL;
|
||||
}
|
||||
|
||||
/* clip */
|
||||
if (vorbis_do_clip (dec, buf))
|
||||
return GST_FLOW_OK;
|
||||
|
||||
if (dec->discont) {
|
||||
GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_DISCONT);
|
||||
dec->discont = FALSE;
|
||||
|
@ -819,7 +896,20 @@ vorbis_handle_data_packet (GstVorbisDec * vd, ogg_packet * packet)
|
|||
if (!vd->initialized)
|
||||
goto not_initialized;
|
||||
|
||||
/* FIXME, we should queue undecoded packets here until we get
|
||||
* a timestamp, then we reverse timestamp the queued packets and
|
||||
* clip them, then we decode only the ones we want and don't
|
||||
* keep decoded data in memory.
|
||||
* Ideally, of course, the demuxer gives us a valid timestamp on
|
||||
* the first packet.
|
||||
*/
|
||||
|
||||
/* normal data packet */
|
||||
/* FIXME, we can skip decoding if the packet is outside of the
|
||||
* segment, this is however not very trivial as we need a previous
|
||||
* packet to decode the current one so we must be carefull not to
|
||||
* throw away too much. For now we decode everything and clip right
|
||||
* before pushing data. */
|
||||
if (G_UNLIKELY (vorbis_synthesis (&vd->vb, packet)))
|
||||
goto could_not_read;
|
||||
|
||||
|
@ -923,6 +1013,8 @@ vorbis_dec_chain (GstPad * pad, GstBuffer * buffer)
|
|||
GstVorbisDec *vd;
|
||||
ogg_packet packet;
|
||||
GstFlowReturn result = GST_FLOW_OK;
|
||||
GstClockTime timestamp;
|
||||
guint64 offset_end;
|
||||
|
||||
vd = GST_VORBIS_DEC (gst_pad_get_parent (pad));
|
||||
|
||||
|
@ -938,14 +1030,16 @@ vorbis_dec_chain (GstPad * pad, GstBuffer * buffer)
|
|||
vd->discont = TRUE;
|
||||
}
|
||||
|
||||
timestamp = GST_BUFFER_TIMESTAMP (buffer);
|
||||
offset_end = GST_BUFFER_OFFSET_END (buffer);
|
||||
|
||||
/* only ogg has granulepos, demuxers of other container formats
|
||||
* might provide us with timestamps instead (e.g. matroskademux) */
|
||||
if (GST_BUFFER_OFFSET_END (buffer) == GST_BUFFER_OFFSET_NONE &&
|
||||
GST_BUFFER_TIMESTAMP (buffer) != GST_CLOCK_TIME_NONE) {
|
||||
if (offset_end == GST_BUFFER_OFFSET_NONE && timestamp != GST_CLOCK_TIME_NONE) {
|
||||
/* we might get multiple consecutive buffers with the same timestamp */
|
||||
if (GST_BUFFER_TIMESTAMP (buffer) != vd->prev_timestamp) {
|
||||
vd->cur_timestamp = GST_BUFFER_TIMESTAMP (buffer);
|
||||
vd->prev_timestamp = GST_BUFFER_TIMESTAMP (buffer);
|
||||
if (timestamp != vd->prev_timestamp) {
|
||||
vd->cur_timestamp = timestamp;
|
||||
vd->prev_timestamp = timestamp;
|
||||
}
|
||||
} else {
|
||||
vd->cur_timestamp = GST_CLOCK_TIME_NONE;
|
||||
|
@ -955,7 +1049,7 @@ vorbis_dec_chain (GstPad * pad, GstBuffer * buffer)
|
|||
/* make ogg_packet out of the buffer */
|
||||
packet.packet = GST_BUFFER_DATA (buffer);
|
||||
packet.bytes = GST_BUFFER_SIZE (buffer);
|
||||
packet.granulepos = GST_BUFFER_OFFSET_END (buffer);
|
||||
packet.granulepos = offset_end;
|
||||
packet.packetno = 0; /* we don't care */
|
||||
/*
|
||||
* FIXME. Is there anyway to know that this is the last packet and
|
||||
|
@ -982,8 +1076,7 @@ vorbis_dec_chain (GstPad * pad, GstBuffer * buffer)
|
|||
result = vorbis_handle_data_packet (vd, &packet);
|
||||
}
|
||||
|
||||
GST_DEBUG_OBJECT (vd, "offset end: %" G_GINT64_FORMAT,
|
||||
(gint64) GST_BUFFER_OFFSET_END (buffer));
|
||||
GST_DEBUG_OBJECT (vd, "offset end: %" G_GUINT64_FORMAT, offset_end);
|
||||
|
||||
done:
|
||||
gst_buffer_unref (buffer);
|
||||
|
@ -1007,7 +1100,6 @@ vorbis_dec_change_state (GstElement * element, GstStateChange transition)
|
|||
GstVorbisDec *vd = GST_VORBIS_DEC (element);
|
||||
GstStateChangeReturn res;
|
||||
|
||||
|
||||
switch (transition) {
|
||||
case GST_STATE_CHANGE_NULL_TO_READY:
|
||||
break;
|
||||
|
|
Loading…
Reference in a new issue