mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-06-05 06:58:56 +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>
|
2006-05-26 Jan Schmidt <thaytan@mad.scientist.com>
|
||||||
|
|
||||||
* sys/ximage/ximagesink.c: (gst_ximagesink_ximage_new),
|
* sys/ximage/ximagesink.c: (gst_ximagesink_ximage_new),
|
||||||
|
|
|
@ -334,14 +334,19 @@ vorbis_dec_src_query (GstPad * pad, GstQuery * query)
|
||||||
}
|
}
|
||||||
case GST_QUERY_DURATION:
|
case GST_QUERY_DURATION:
|
||||||
{
|
{
|
||||||
/* query peer for total length */
|
GstPad *peer;
|
||||||
if (!gst_pad_is_linked (dec->sinkpad)) {
|
|
||||||
|
if (!(peer = gst_pad_get_peer (dec->sinkpad))) {
|
||||||
GST_WARNING_OBJECT (dec, "sink pad %" GST_PTR_FORMAT " is not linked",
|
GST_WARNING_OBJECT (dec, "sink pad %" GST_PTR_FORMAT " is not linked",
|
||||||
dec->sinkpad);
|
dec->sinkpad);
|
||||||
goto error;
|
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;
|
goto error;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case GST_QUERY_CONVERT:
|
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));
|
dec = GST_VORBIS_DEC (gst_pad_get_parent (pad));
|
||||||
|
|
||||||
switch (GST_EVENT_TYPE (event)) {
|
switch (GST_EVENT_TYPE (event)) {
|
||||||
case GST_EVENT_SEEK:{
|
case GST_EVENT_SEEK:
|
||||||
|
{
|
||||||
GstFormat format, tformat;
|
GstFormat format, tformat;
|
||||||
gdouble rate;
|
gdouble rate;
|
||||||
GstEvent *real_seek;
|
GstEvent *real_seek;
|
||||||
|
@ -512,6 +518,12 @@ vorbis_dec_sink_event (GstPad * pad, GstEvent * event)
|
||||||
if (rate <= 0.0)
|
if (rate <= 0.0)
|
||||||
goto newseg_wrong_rate;
|
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 */
|
/* now configure the values */
|
||||||
gst_segment_set_newsegment_full (&dec->segment, update,
|
gst_segment_set_newsegment_full (&dec->segment, update,
|
||||||
rate, arate, format, start, stop, time);
|
rate, arate, format, start, stop, time);
|
||||||
|
@ -752,6 +764,61 @@ copy_samples (float *out, float **in, guint samples, gint channels)
|
||||||
#endif
|
#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
|
static GstFlowReturn
|
||||||
vorbis_dec_push (GstVorbisDec * dec, GstBuffer * buf)
|
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)) {
|
for (walk = dec->queued; walk; walk = g_list_next (walk)) {
|
||||||
GstBuffer *buffer = GST_BUFFER (walk->data);
|
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) {
|
if (dec->discont) {
|
||||||
GST_BUFFER_FLAG_SET (buffer, GST_BUFFER_FLAG_DISCONT);
|
GST_BUFFER_FLAG_SET (buffer, GST_BUFFER_FLAG_DISCONT);
|
||||||
dec->discont = FALSE;
|
dec->discont = FALSE;
|
||||||
|
@ -797,6 +869,11 @@ vorbis_dec_push (GstVorbisDec * dec, GstBuffer * buf)
|
||||||
g_list_free (dec->queued);
|
g_list_free (dec->queued);
|
||||||
dec->queued = NULL;
|
dec->queued = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* clip */
|
||||||
|
if (vorbis_do_clip (dec, buf))
|
||||||
|
return GST_FLOW_OK;
|
||||||
|
|
||||||
if (dec->discont) {
|
if (dec->discont) {
|
||||||
GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_DISCONT);
|
GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_DISCONT);
|
||||||
dec->discont = FALSE;
|
dec->discont = FALSE;
|
||||||
|
@ -819,7 +896,20 @@ vorbis_handle_data_packet (GstVorbisDec * vd, ogg_packet * packet)
|
||||||
if (!vd->initialized)
|
if (!vd->initialized)
|
||||||
goto not_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 */
|
/* 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)))
|
if (G_UNLIKELY (vorbis_synthesis (&vd->vb, packet)))
|
||||||
goto could_not_read;
|
goto could_not_read;
|
||||||
|
|
||||||
|
@ -923,6 +1013,8 @@ vorbis_dec_chain (GstPad * pad, GstBuffer * buffer)
|
||||||
GstVorbisDec *vd;
|
GstVorbisDec *vd;
|
||||||
ogg_packet packet;
|
ogg_packet packet;
|
||||||
GstFlowReturn result = GST_FLOW_OK;
|
GstFlowReturn result = GST_FLOW_OK;
|
||||||
|
GstClockTime timestamp;
|
||||||
|
guint64 offset_end;
|
||||||
|
|
||||||
vd = GST_VORBIS_DEC (gst_pad_get_parent (pad));
|
vd = GST_VORBIS_DEC (gst_pad_get_parent (pad));
|
||||||
|
|
||||||
|
@ -938,14 +1030,16 @@ vorbis_dec_chain (GstPad * pad, GstBuffer * buffer)
|
||||||
vd->discont = TRUE;
|
vd->discont = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
timestamp = GST_BUFFER_TIMESTAMP (buffer);
|
||||||
|
offset_end = GST_BUFFER_OFFSET_END (buffer);
|
||||||
|
|
||||||
/* only ogg has granulepos, demuxers of other container formats
|
/* only ogg has granulepos, demuxers of other container formats
|
||||||
* might provide us with timestamps instead (e.g. matroskademux) */
|
* might provide us with timestamps instead (e.g. matroskademux) */
|
||||||
if (GST_BUFFER_OFFSET_END (buffer) == GST_BUFFER_OFFSET_NONE &&
|
if (offset_end == GST_BUFFER_OFFSET_NONE && timestamp != GST_CLOCK_TIME_NONE) {
|
||||||
GST_BUFFER_TIMESTAMP (buffer) != GST_CLOCK_TIME_NONE) {
|
|
||||||
/* we might get multiple consecutive buffers with the same timestamp */
|
/* we might get multiple consecutive buffers with the same timestamp */
|
||||||
if (GST_BUFFER_TIMESTAMP (buffer) != vd->prev_timestamp) {
|
if (timestamp != vd->prev_timestamp) {
|
||||||
vd->cur_timestamp = GST_BUFFER_TIMESTAMP (buffer);
|
vd->cur_timestamp = timestamp;
|
||||||
vd->prev_timestamp = GST_BUFFER_TIMESTAMP (buffer);
|
vd->prev_timestamp = timestamp;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
vd->cur_timestamp = GST_CLOCK_TIME_NONE;
|
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 */
|
/* make ogg_packet out of the buffer */
|
||||||
packet.packet = GST_BUFFER_DATA (buffer);
|
packet.packet = GST_BUFFER_DATA (buffer);
|
||||||
packet.bytes = GST_BUFFER_SIZE (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 */
|
packet.packetno = 0; /* we don't care */
|
||||||
/*
|
/*
|
||||||
* FIXME. Is there anyway to know that this is the last packet and
|
* 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);
|
result = vorbis_handle_data_packet (vd, &packet);
|
||||||
}
|
}
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (vd, "offset end: %" G_GINT64_FORMAT,
|
GST_DEBUG_OBJECT (vd, "offset end: %" G_GUINT64_FORMAT, offset_end);
|
||||||
(gint64) GST_BUFFER_OFFSET_END (buffer));
|
|
||||||
|
|
||||||
done:
|
done:
|
||||||
gst_buffer_unref (buffer);
|
gst_buffer_unref (buffer);
|
||||||
|
@ -1007,7 +1100,6 @@ vorbis_dec_change_state (GstElement * element, GstStateChange transition)
|
||||||
GstVorbisDec *vd = GST_VORBIS_DEC (element);
|
GstVorbisDec *vd = GST_VORBIS_DEC (element);
|
||||||
GstStateChangeReturn res;
|
GstStateChangeReturn res;
|
||||||
|
|
||||||
|
|
||||||
switch (transition) {
|
switch (transition) {
|
||||||
case GST_STATE_CHANGE_NULL_TO_READY:
|
case GST_STATE_CHANGE_NULL_TO_READY:
|
||||||
break;
|
break;
|
||||||
|
|
Loading…
Reference in a new issue