mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-30 04:00:37 +00:00
ext/amrnb/amrnbparse.*: Fix the duration query. Fixes #536226.
Original commit message from CVS: Patch by: Benoit Fouet <benoit dot fouet at purplelabs dot com> * ext/amrnb/amrnbparse.c: (gst_amrnbparse_query), (gst_amrnbparse_chain), (gst_amrnbparse_loop), (gst_amrnbparse_state_change): * ext/amrnb/amrnbparse.h: Fix the duration query. Fixes #536226. Also set caps on the pads and buffers more correctly.
This commit is contained in:
parent
600ab94cc2
commit
f0d2495012
4 changed files with 53 additions and 27 deletions
11
ChangeLog
11
ChangeLog
|
@ -1,3 +1,14 @@
|
|||
2008-09-26 Wim Taymans <wim.taymans@collabora.co.uk>
|
||||
|
||||
Patch by: Benoit Fouet <benoit dot fouet at purplelabs dot com>
|
||||
|
||||
* ext/amrnb/amrnbparse.c: (gst_amrnbparse_query),
|
||||
(gst_amrnbparse_chain), (gst_amrnbparse_loop),
|
||||
(gst_amrnbparse_state_change):
|
||||
* ext/amrnb/amrnbparse.h:
|
||||
Fix the duration query. Fixes #536226.
|
||||
Also set caps on the pads and buffers more correctly.
|
||||
|
||||
2008-09-02 Tim-Philipp Müller <tim.muller at collabora co uk>
|
||||
|
||||
* po/LINGUAS:
|
||||
|
|
2
common
2
common
|
@ -1 +1 @@
|
|||
Subproject commit 8d494854a6018336a80ece82ceb3df0033e2da9c
|
||||
Subproject commit 1ff63d8f92c36bf207434436f4ce75f2a4ea11a4
|
|
@ -216,22 +216,23 @@ gst_amrnbparse_query (GstPad * pad, GstQuery * query)
|
|||
return FALSE;
|
||||
|
||||
tot = -1;
|
||||
res = FALSE;
|
||||
|
||||
peer = gst_pad_get_peer (amrnbparse->sinkpad);
|
||||
if (peer) {
|
||||
GstFormat pformat;
|
||||
gint64 pcur, ptot;
|
||||
gint64 ptot;
|
||||
|
||||
pformat = GST_FORMAT_BYTES;
|
||||
res = gst_pad_query_position (peer, &pformat, &pcur);
|
||||
res &= gst_pad_query_duration (peer, &pformat, &ptot);
|
||||
gst_object_unref (GST_OBJECT (peer));
|
||||
if (res) {
|
||||
tot = amrnbparse->ts * ((gdouble) ptot / pcur);
|
||||
res = gst_pad_query_duration (peer, &pformat, &ptot);
|
||||
if (res && amrnbparse->block) {
|
||||
tot =
|
||||
gst_util_uint64_scale_int (ptot, 20 * GST_MSECOND,
|
||||
amrnbparse->block);
|
||||
}
|
||||
gst_object_unref (GST_OBJECT (peer));
|
||||
}
|
||||
gst_query_set_duration (query, GST_FORMAT_TIME, tot);
|
||||
res = TRUE;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
|
@ -290,7 +291,7 @@ gst_amrnbparse_chain (GstPad * pad, GstBuffer * buffer)
|
|||
{
|
||||
GstAmrnbParse *amrnbparse;
|
||||
GstFlowReturn res;
|
||||
gint block, mode;
|
||||
gint mode;
|
||||
const guint8 *data;
|
||||
GstBuffer *out;
|
||||
GstClockTime timestamp;
|
||||
|
@ -311,6 +312,7 @@ gst_amrnbparse_chain (GstPad * pad, GstBuffer * buffer)
|
|||
/* init */
|
||||
if (amrnbparse->need_header) {
|
||||
GstEvent *segev;
|
||||
GstCaps *caps;
|
||||
|
||||
if (gst_adapter_available (amrnbparse->adapter) < 6)
|
||||
goto done;
|
||||
|
@ -323,6 +325,11 @@ gst_amrnbparse_chain (GstPad * pad, GstBuffer * buffer)
|
|||
|
||||
amrnbparse->need_header = FALSE;
|
||||
|
||||
caps = gst_caps_new_simple ("audio/AMR",
|
||||
"rate", G_TYPE_INT, 8000, "channels", G_TYPE_INT, 1, NULL);
|
||||
gst_pad_set_caps (amrnbparse->srcpad, caps);
|
||||
gst_caps_unref (caps);
|
||||
|
||||
GST_DEBUG_OBJECT (amrnbparse, "Sending first segment");
|
||||
segev = gst_event_new_new_segment_full (FALSE, 1.0, 1.0,
|
||||
GST_FORMAT_TIME, 0, -1, 0);
|
||||
|
@ -337,15 +344,15 @@ gst_amrnbparse_chain (GstPad * pad, GstBuffer * buffer)
|
|||
|
||||
/* get size */
|
||||
mode = (data[0] >> 3) & 0x0F;
|
||||
block = block_size[mode] + 1; /* add one for the mode */
|
||||
amrnbparse->block = block_size[mode] + 1; /* add one for the mode */
|
||||
|
||||
if (gst_adapter_available (amrnbparse->adapter) < block)
|
||||
if (gst_adapter_available (amrnbparse->adapter) < amrnbparse->block)
|
||||
break;
|
||||
|
||||
out = gst_buffer_new_and_alloc (block);
|
||||
out = gst_buffer_new_and_alloc (amrnbparse->block);
|
||||
|
||||
data = gst_adapter_peek (amrnbparse->adapter, block);
|
||||
memcpy (GST_BUFFER_DATA (out), data, block);
|
||||
data = gst_adapter_peek (amrnbparse->adapter, amrnbparse->block);
|
||||
memcpy (GST_BUFFER_DATA (out), data, amrnbparse->block);
|
||||
|
||||
/* timestamp, all constants that won't overflow */
|
||||
GST_BUFFER_DURATION (out) = GST_SECOND * 160 / 8000;
|
||||
|
@ -353,13 +360,13 @@ gst_amrnbparse_chain (GstPad * pad, GstBuffer * buffer)
|
|||
if (GST_CLOCK_TIME_IS_VALID (amrnbparse->ts))
|
||||
amrnbparse->ts += GST_BUFFER_DURATION (out);
|
||||
|
||||
gst_buffer_set_caps (out,
|
||||
(GstCaps *) gst_pad_get_pad_template_caps (amrnbparse->srcpad));
|
||||
gst_buffer_set_caps (out, GST_PAD_CAPS (amrnbparse->srcpad));
|
||||
|
||||
GST_DEBUG_OBJECT (amrnbparse, "Pushing %d bytes of data", block);
|
||||
GST_DEBUG_OBJECT (amrnbparse, "Pushing %d bytes of data",
|
||||
amrnbparse->block);
|
||||
res = gst_pad_push (amrnbparse->srcpad, out);
|
||||
|
||||
gst_adapter_flush (amrnbparse->adapter, block);
|
||||
gst_adapter_flush (amrnbparse->adapter, amrnbparse->block);
|
||||
}
|
||||
done:
|
||||
|
||||
|
@ -412,19 +419,26 @@ gst_amrnbparse_loop (GstPad * pad)
|
|||
GstBuffer *buffer;
|
||||
guint8 *data;
|
||||
gint size;
|
||||
gint block, mode;
|
||||
gint mode;
|
||||
GstFlowReturn ret;
|
||||
|
||||
amrnbparse = GST_AMRNBPARSE (GST_PAD_PARENT (pad));
|
||||
|
||||
/* init */
|
||||
if (G_UNLIKELY (amrnbparse->need_header)) {
|
||||
GstCaps *caps;
|
||||
|
||||
if (!gst_amrnbparse_pull_header (amrnbparse)) {
|
||||
GST_ELEMENT_ERROR (amrnbparse, STREAM, WRONG_TYPE, (NULL), (NULL));
|
||||
GST_LOG_OBJECT (amrnbparse, "could not read header");
|
||||
goto need_pause;
|
||||
}
|
||||
|
||||
caps = gst_caps_new_simple ("audio/AMR",
|
||||
"rate", G_TYPE_INT, 8000, "channels", G_TYPE_INT, 1, NULL);
|
||||
gst_pad_set_caps (amrnbparse->srcpad, caps);
|
||||
gst_caps_unref (caps);
|
||||
|
||||
GST_DEBUG_OBJECT (amrnbparse, "Sending newsegment event");
|
||||
gst_pad_push_event (amrnbparse->srcpad,
|
||||
gst_event_new_new_segment_full (FALSE, 1.0, 1.0,
|
||||
|
@ -452,36 +466,35 @@ gst_amrnbparse_loop (GstPad * pad)
|
|||
|
||||
/* get size */
|
||||
mode = (data[0] >> 3) & 0x0F;
|
||||
block = block_size[mode] + 1; /* add one for the mode */
|
||||
amrnbparse->block = block_size[mode] + 1; /* add one for the mode */
|
||||
|
||||
gst_buffer_unref (buffer);
|
||||
|
||||
ret =
|
||||
gst_pad_pull_range (amrnbparse->sinkpad, amrnbparse->offset, block,
|
||||
&buffer);
|
||||
gst_pad_pull_range (amrnbparse->sinkpad, amrnbparse->offset,
|
||||
amrnbparse->block, &buffer);
|
||||
|
||||
if (ret == GST_FLOW_UNEXPECTED)
|
||||
goto eos;
|
||||
else if (ret != GST_FLOW_OK)
|
||||
goto need_pause;
|
||||
|
||||
if (GST_BUFFER_SIZE (buffer) < block) {
|
||||
if (GST_BUFFER_SIZE (buffer) < amrnbparse->block) {
|
||||
gst_buffer_unref (buffer);
|
||||
goto eos;
|
||||
}
|
||||
|
||||
amrnbparse->offset += block;
|
||||
amrnbparse->offset += amrnbparse->block;
|
||||
|
||||
/* output */
|
||||
buffer = gst_buffer_make_metadata_writable (buffer);
|
||||
GST_BUFFER_DURATION (buffer) = GST_SECOND * 160 / 8000;
|
||||
GST_BUFFER_TIMESTAMP (buffer) = amrnbparse->ts;
|
||||
|
||||
gst_buffer_set_caps (buffer,
|
||||
(GstCaps *) gst_pad_get_pad_template_caps (amrnbparse->srcpad));
|
||||
gst_buffer_set_caps (buffer, GST_PAD_CAPS (amrnbparse->srcpad));
|
||||
|
||||
GST_DEBUG_OBJECT (amrnbparse, "Pushing %2d bytes, ts=%" GST_TIME_FORMAT,
|
||||
block, GST_TIME_ARGS (amrnbparse->ts));
|
||||
amrnbparse->block, GST_TIME_ARGS (amrnbparse->ts));
|
||||
|
||||
ret = gst_pad_push (amrnbparse->srcpad, buffer);
|
||||
|
||||
|
@ -576,6 +589,7 @@ gst_amrnbparse_state_change (GstElement * element, GstStateChange transition)
|
|||
case GST_STATE_CHANGE_READY_TO_PAUSED:
|
||||
amrnbparse->need_header = TRUE;
|
||||
amrnbparse->ts = -1;
|
||||
amrnbparse->block = 0;
|
||||
gst_segment_init (&amrnbparse->segment, GST_FORMAT_TIME);
|
||||
break;
|
||||
default:
|
||||
|
|
|
@ -50,6 +50,7 @@ struct _GstAmrnbParse {
|
|||
gboolean seekable;
|
||||
gboolean need_header;
|
||||
gint64 offset;
|
||||
gint block;
|
||||
|
||||
guint64 ts;
|
||||
|
||||
|
|
Loading…
Reference in a new issue