mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-20 07:16:55 +00:00
ext/amrnb/amrnbparse.c: Fix pull mode operation some more: send newsegment event before sending data; handle EOS and ...
Original commit message from CVS: * ext/amrnb/amrnbparse.c: (gst_amrnbparse_get_type), (gst_amrnbparse_class_init), (gst_amrnbparse_init), (gst_amrnbparse_pull_header), (gst_amrnbparse_loop): Fix pull mode operation some more: send newsegment event before sending data; handle EOS and fatal flow returns a bit better; don't leak buffers in some cases. Misc. minor cleanups. Fixes #431707.
This commit is contained in:
parent
6197c64106
commit
8f73fe167e
2 changed files with 60 additions and 23 deletions
|
@ -1,3 +1,12 @@
|
||||||
|
2007-04-22 Tim-Philipp Müller <tim at centricular dot net>
|
||||||
|
|
||||||
|
* ext/amrnb/amrnbparse.c: (gst_amrnbparse_get_type),
|
||||||
|
(gst_amrnbparse_class_init), (gst_amrnbparse_init),
|
||||||
|
(gst_amrnbparse_pull_header), (gst_amrnbparse_loop):
|
||||||
|
Fix pull mode operation some more: send newsegment event before
|
||||||
|
sending data; handle EOS and fatal flow returns a bit better; don't
|
||||||
|
leak buffers in some cases. Misc. minor cleanups. Fixes #431707.
|
||||||
|
|
||||||
2007-04-20 Tim-Philipp Müller <tim at centricular dot net>
|
2007-04-20 Tim-Philipp Müller <tim at centricular dot net>
|
||||||
|
|
||||||
* gst/asfdemux/Makefile.am:
|
* gst/asfdemux/Makefile.am:
|
||||||
|
|
|
@ -83,6 +83,9 @@ gst_amrnbparse_get_type (void)
|
||||||
|
|
||||||
amrnbparse_type = g_type_register_static (GST_TYPE_ELEMENT,
|
amrnbparse_type = g_type_register_static (GST_TYPE_ELEMENT,
|
||||||
"GstAmrnbParse", &amrnbparse_info, 0);
|
"GstAmrnbParse", &amrnbparse_info, 0);
|
||||||
|
|
||||||
|
GST_DEBUG_CATEGORY_INIT (amrnbparse_debug,
|
||||||
|
"amrnbparse", 0, "AMR-NB stream parsing");
|
||||||
}
|
}
|
||||||
|
|
||||||
return amrnbparse_type;
|
return amrnbparse_type;
|
||||||
|
@ -115,9 +118,6 @@ gst_amrnbparse_class_init (GstAmrnbParseClass * klass)
|
||||||
parent_class = g_type_class_peek_parent (klass);
|
parent_class = g_type_class_peek_parent (klass);
|
||||||
|
|
||||||
element_class->change_state = gst_amrnbparse_state_change;
|
element_class->change_state = gst_amrnbparse_state_change;
|
||||||
|
|
||||||
GST_DEBUG_CATEGORY_INIT (amrnbparse_debug,
|
|
||||||
"amrnbparse", 0, "AMR-NB stream parsing");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -125,8 +125,7 @@ gst_amrnbparse_init (GstAmrnbParse * amrnbparse)
|
||||||
{
|
{
|
||||||
/* create the sink pad */
|
/* create the sink pad */
|
||||||
amrnbparse->sinkpad =
|
amrnbparse->sinkpad =
|
||||||
gst_pad_new_from_template (gst_static_pad_template_get (&sink_template),
|
gst_pad_new_from_static_template (&sink_template, "sink");
|
||||||
"sink");
|
|
||||||
gst_pad_set_chain_function (amrnbparse->sinkpad,
|
gst_pad_set_chain_function (amrnbparse->sinkpad,
|
||||||
GST_DEBUG_FUNCPTR (gst_amrnbparse_chain));
|
GST_DEBUG_FUNCPTR (gst_amrnbparse_chain));
|
||||||
gst_pad_set_event_function (amrnbparse->sinkpad,
|
gst_pad_set_event_function (amrnbparse->sinkpad,
|
||||||
|
@ -138,13 +137,12 @@ gst_amrnbparse_init (GstAmrnbParse * amrnbparse)
|
||||||
gst_element_add_pad (GST_ELEMENT (amrnbparse), amrnbparse->sinkpad);
|
gst_element_add_pad (GST_ELEMENT (amrnbparse), amrnbparse->sinkpad);
|
||||||
|
|
||||||
/* create the src pad */
|
/* create the src pad */
|
||||||
amrnbparse->srcpad =
|
amrnbparse->srcpad = gst_pad_new_from_static_template (&src_template, "src");
|
||||||
gst_pad_new_from_template (gst_static_pad_template_get (&src_template),
|
|
||||||
"src");
|
|
||||||
gst_pad_set_query_function (amrnbparse->srcpad,
|
gst_pad_set_query_function (amrnbparse->srcpad,
|
||||||
GST_DEBUG_FUNCPTR (gst_amrnbparse_query));
|
GST_DEBUG_FUNCPTR (gst_amrnbparse_query));
|
||||||
gst_pad_set_query_type_function (amrnbparse->srcpad,
|
gst_pad_set_query_type_function (amrnbparse->srcpad,
|
||||||
GST_DEBUG_FUNCPTR (gst_amrnbparse_querytypes));
|
GST_DEBUG_FUNCPTR (gst_amrnbparse_querytypes));
|
||||||
|
gst_pad_use_fixed_caps (amrnbparse->srcpad);
|
||||||
gst_element_add_pad (GST_ELEMENT (amrnbparse), amrnbparse->srcpad);
|
gst_element_add_pad (GST_ELEMENT (amrnbparse), amrnbparse->srcpad);
|
||||||
|
|
||||||
amrnbparse->adapter = gst_adapter_new ();
|
amrnbparse->adapter = gst_adapter_new ();
|
||||||
|
@ -369,15 +367,14 @@ done:
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
gst_amrnbparse_read_header (GstAmrnbParse * amrnbparse)
|
gst_amrnbparse_pull_header (GstAmrnbParse * amrnbparse)
|
||||||
{
|
{
|
||||||
GstBuffer *buffer;
|
GstBuffer *buffer;
|
||||||
GstFlowReturn ret;
|
GstFlowReturn ret;
|
||||||
guint8 *data;
|
guint8 *data;
|
||||||
gint size;
|
gint size;
|
||||||
|
|
||||||
ret =
|
ret = gst_pad_pull_range (amrnbparse->sinkpad, 0, 6, &buffer);
|
||||||
gst_pad_pull_range (amrnbparse->sinkpad, amrnbparse->offset, 6, &buffer);
|
|
||||||
if (ret != GST_FLOW_OK)
|
if (ret != GST_FLOW_OK)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
|
@ -389,8 +386,9 @@ gst_amrnbparse_read_header (GstAmrnbParse * amrnbparse)
|
||||||
if (memcmp (data, "#!AMR\n", 6))
|
if (memcmp (data, "#!AMR\n", 6))
|
||||||
goto no_header;
|
goto no_header;
|
||||||
|
|
||||||
amrnbparse->offset += 6;
|
gst_buffer_unref (buffer);
|
||||||
|
|
||||||
|
amrnbparse->offset = 6;
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
not_enough:
|
not_enough:
|
||||||
|
@ -421,27 +419,36 @@ gst_amrnbparse_loop (GstPad * pad)
|
||||||
|
|
||||||
/* init */
|
/* init */
|
||||||
if (amrnbparse->need_header) {
|
if (amrnbparse->need_header) {
|
||||||
gboolean got_header;
|
if (!gst_amrnbparse_pull_header (amrnbparse)) {
|
||||||
|
GST_ELEMENT_ERROR (amrnbparse, STREAM, WRONG_TYPE, (NULL), (NULL));
|
||||||
got_header = gst_amrnbparse_read_header (amrnbparse);
|
|
||||||
if (!got_header) {
|
|
||||||
GST_LOG_OBJECT (amrnbparse, "could not read header");
|
GST_LOG_OBJECT (amrnbparse, "could not read header");
|
||||||
goto need_pause;
|
goto need_pause;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GST_DEBUG_OBJECT (amrnbparse, "Sending newsegment event");
|
||||||
|
gst_pad_push_event (amrnbparse->srcpad,
|
||||||
|
gst_event_new_new_segment_full (FALSE, 1.0, 1.0,
|
||||||
|
GST_FORMAT_TIME, 0, -1, 0));
|
||||||
|
|
||||||
amrnbparse->need_header = FALSE;
|
amrnbparse->need_header = FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret =
|
ret =
|
||||||
gst_pad_pull_range (amrnbparse->sinkpad, amrnbparse->offset, 1, &buffer);
|
gst_pad_pull_range (amrnbparse->sinkpad, amrnbparse->offset, 1, &buffer);
|
||||||
if (ret != GST_FLOW_OK)
|
|
||||||
|
if (ret == GST_FLOW_UNEXPECTED)
|
||||||
|
goto eos;
|
||||||
|
else if (ret != GST_FLOW_OK)
|
||||||
goto need_pause;
|
goto need_pause;
|
||||||
|
|
||||||
data = GST_BUFFER_DATA (buffer);
|
data = GST_BUFFER_DATA (buffer);
|
||||||
size = GST_BUFFER_SIZE (buffer);
|
size = GST_BUFFER_SIZE (buffer);
|
||||||
|
|
||||||
/* EOS */
|
/* EOS */
|
||||||
if (size < 1)
|
if (size < 1) {
|
||||||
|
gst_buffer_unref (buffer);
|
||||||
goto eos;
|
goto eos;
|
||||||
|
}
|
||||||
|
|
||||||
/* get size */
|
/* get size */
|
||||||
mode = (data[0] >> 3) & 0x0F;
|
mode = (data[0] >> 3) & 0x0F;
|
||||||
|
@ -452,22 +459,43 @@ gst_amrnbparse_loop (GstPad * pad)
|
||||||
ret =
|
ret =
|
||||||
gst_pad_pull_range (amrnbparse->sinkpad, amrnbparse->offset, block,
|
gst_pad_pull_range (amrnbparse->sinkpad, amrnbparse->offset, block,
|
||||||
&buffer);
|
&buffer);
|
||||||
if (ret != GST_FLOW_OK)
|
|
||||||
|
if (ret == GST_FLOW_UNEXPECTED)
|
||||||
|
goto eos;
|
||||||
|
else if (ret != GST_FLOW_OK)
|
||||||
goto need_pause;
|
goto need_pause;
|
||||||
|
|
||||||
|
if (GST_BUFFER_SIZE (buffer) < block) {
|
||||||
|
gst_buffer_unref (buffer);
|
||||||
|
goto eos;
|
||||||
|
}
|
||||||
|
|
||||||
amrnbparse->offset += block;
|
amrnbparse->offset += block;
|
||||||
|
|
||||||
/* output */
|
/* output */
|
||||||
|
buffer = gst_buffer_make_metadata_writable (buffer);
|
||||||
GST_BUFFER_DURATION (buffer) = GST_SECOND * 160 / 8000;
|
GST_BUFFER_DURATION (buffer) = GST_SECOND * 160 / 8000;
|
||||||
GST_BUFFER_TIMESTAMP (buffer) = amrnbparse->ts;
|
GST_BUFFER_TIMESTAMP (buffer) = amrnbparse->ts;
|
||||||
amrnbparse->ts += GST_BUFFER_DURATION (buffer);
|
|
||||||
gst_buffer_set_caps (buffer,
|
gst_buffer_set_caps (buffer,
|
||||||
(GstCaps *) gst_pad_get_pad_template_caps (amrnbparse->srcpad));
|
(GstCaps *) gst_pad_get_pad_template_caps (amrnbparse->srcpad));
|
||||||
|
|
||||||
GST_DEBUG ("Pushing %d bytes of data", block);
|
GST_DEBUG_OBJECT (amrnbparse, "Pushing %2d bytes, ts=%" GST_TIME_FORMAT,
|
||||||
|
block, GST_TIME_ARGS (amrnbparse->ts));
|
||||||
|
|
||||||
ret = gst_pad_push (amrnbparse->srcpad, buffer);
|
ret = gst_pad_push (amrnbparse->srcpad, buffer);
|
||||||
if (ret != GST_FLOW_OK)
|
|
||||||
|
if (ret != GST_FLOW_OK) {
|
||||||
|
GST_DEBUG_OBJECT (amrnbparse, "Flow: %s", gst_flow_get_name (ret));
|
||||||
|
if (GST_FLOW_IS_FATAL (ret)) {
|
||||||
|
GST_ELEMENT_ERROR (amrnbparse, STREAM, FAILED, (NULL), /* _("Internal data flow error.")), */
|
||||||
|
("streaming task paused, reason: %s", gst_flow_get_name (ret)));
|
||||||
|
gst_pad_push_event (pad, gst_event_new_eos ());
|
||||||
|
}
|
||||||
goto need_pause;
|
goto need_pause;
|
||||||
|
}
|
||||||
|
|
||||||
|
amrnbparse->ts += GST_BUFFER_DURATION (buffer);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -479,7 +507,7 @@ need_pause:
|
||||||
}
|
}
|
||||||
eos:
|
eos:
|
||||||
{
|
{
|
||||||
GST_LOG_OBJECT (amrnbparse, "pausing task");
|
GST_LOG_OBJECT (amrnbparse, "pausing task (eos)");
|
||||||
gst_pad_push_event (amrnbparse->srcpad, gst_event_new_eos ());
|
gst_pad_push_event (amrnbparse->srcpad, gst_event_new_eos ());
|
||||||
gst_pad_pause_task (pad);
|
gst_pad_pause_task (pad);
|
||||||
return;
|
return;
|
||||||
|
|
Loading…
Reference in a new issue