mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-27 04:01:08 +00:00
ext/faad/gstfaad.*: Do some timestamp smoothing (matroskademux apparently sends multiple buffers in a row with the sa...
Original commit message from CVS: * ext/faad/gstfaad.c: (gst_faad_base_init), (gst_faad_class_init), (gst_faad_init), (gst_faad_srcgetcaps), (gst_faad_event), (gst_faad_chain), (gst_faad_change_state): * ext/faad/gstfaad.h: Do some timestamp smoothing (matroskademux apparently sends multiple buffers in a row with the same timestamp); fix duration on outgoing buffers; fix change state function; use GST_DEBUG_FUNCPTR for pad functions.
This commit is contained in:
parent
f7d63a74e0
commit
a979bd99d1
3 changed files with 61 additions and 36 deletions
11
ChangeLog
11
ChangeLog
|
@ -1,3 +1,14 @@
|
||||||
|
2005-10-20 Tim-Philipp Müller <tim at centricular dot net>
|
||||||
|
|
||||||
|
* ext/faad/gstfaad.c: (gst_faad_base_init), (gst_faad_class_init),
|
||||||
|
(gst_faad_init), (gst_faad_srcgetcaps), (gst_faad_event),
|
||||||
|
(gst_faad_chain), (gst_faad_change_state):
|
||||||
|
* ext/faad/gstfaad.h:
|
||||||
|
Do some timestamp smoothing (matroskademux apparently sends
|
||||||
|
multiple buffers in a row with the same timestamp); fix
|
||||||
|
duration on outgoing buffers; fix change state function; use
|
||||||
|
GST_DEBUG_FUNCPTR for pad functions.
|
||||||
|
|
||||||
2005-10-19 Wim Taymans <wim@fluendo.com>
|
2005-10-19 Wim Taymans <wim@fluendo.com>
|
||||||
|
|
||||||
* gst/qtdemux/qtdemux.c: (gst_qtdemux_get_src_query_types),
|
* gst/qtdemux/qtdemux.c: (gst_qtdemux_get_src_query_types),
|
||||||
|
|
|
@ -22,6 +22,7 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <gst/audio/audio.h>
|
||||||
#include <gst/audio/multichannel.h>
|
#include <gst/audio/multichannel.h>
|
||||||
#include "gstfaad.h"
|
#include "gstfaad.h"
|
||||||
|
|
||||||
|
@ -135,6 +136,8 @@ gst_faad_base_init (GstFaadClass * klass)
|
||||||
gst_static_pad_template_get (&sink_template));
|
gst_static_pad_template_get (&sink_template));
|
||||||
|
|
||||||
gst_element_class_set_details (element_class, &faad_details);
|
gst_element_class_set_details (element_class, &faad_details);
|
||||||
|
|
||||||
|
GST_DEBUG_CATEGORY_INIT (faad_debug, "faad", 0, "AAC decoding");
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -144,9 +147,7 @@ gst_faad_class_init (GstFaadClass * klass)
|
||||||
|
|
||||||
parent_class = g_type_class_peek_parent (klass);
|
parent_class = g_type_class_peek_parent (klass);
|
||||||
|
|
||||||
gstelement_class->change_state = gst_faad_change_state;
|
gstelement_class->change_state = GST_DEBUG_FUNCPTR (gst_faad_change_state);
|
||||||
|
|
||||||
GST_DEBUG_CATEGORY_INIT (faad_debug, "faad", 0, "AAC decoding");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -160,6 +161,7 @@ gst_faad_init (GstFaad * faad)
|
||||||
faad->channel_positions = NULL;
|
faad->channel_positions = NULL;
|
||||||
faad->init = FALSE;
|
faad->init = FALSE;
|
||||||
faad->next_ts = 0;
|
faad->next_ts = 0;
|
||||||
|
faad->prev_ts = GST_CLOCK_TIME_NONE;
|
||||||
faad->bytes_in = 0;
|
faad->bytes_in = 0;
|
||||||
faad->sum_dur_out = 0;
|
faad->sum_dur_out = 0;
|
||||||
faad->packetised = FALSE;
|
faad->packetised = FALSE;
|
||||||
|
@ -168,16 +170,20 @@ gst_faad_init (GstFaad * faad)
|
||||||
gst_pad_new_from_template (gst_static_pad_template_get (&sink_template),
|
gst_pad_new_from_template (gst_static_pad_template_get (&sink_template),
|
||||||
"sink");
|
"sink");
|
||||||
gst_element_add_pad (GST_ELEMENT (faad), faad->sinkpad);
|
gst_element_add_pad (GST_ELEMENT (faad), faad->sinkpad);
|
||||||
gst_pad_set_event_function (faad->sinkpad, gst_faad_event);
|
gst_pad_set_event_function (faad->sinkpad,
|
||||||
gst_pad_set_setcaps_function (faad->sinkpad, gst_faad_setcaps);
|
GST_DEBUG_FUNCPTR (gst_faad_event));
|
||||||
gst_pad_set_chain_function (faad->sinkpad, gst_faad_chain);
|
gst_pad_set_setcaps_function (faad->sinkpad,
|
||||||
|
GST_DEBUG_FUNCPTR (gst_faad_setcaps));
|
||||||
|
gst_pad_set_chain_function (faad->sinkpad,
|
||||||
|
GST_DEBUG_FUNCPTR (gst_faad_chain));
|
||||||
|
|
||||||
faad->srcpad =
|
faad->srcpad =
|
||||||
gst_pad_new_from_template (gst_static_pad_template_get (&src_template),
|
gst_pad_new_from_template (gst_static_pad_template_get (&src_template),
|
||||||
"src");
|
"src");
|
||||||
gst_element_add_pad (GST_ELEMENT (faad), faad->srcpad);
|
gst_element_add_pad (GST_ELEMENT (faad), faad->srcpad);
|
||||||
gst_pad_use_fixed_caps (faad->srcpad);
|
gst_pad_use_fixed_caps (faad->srcpad);
|
||||||
gst_pad_set_getcaps_function (faad->srcpad, gst_faad_srcgetcaps);
|
gst_pad_set_getcaps_function (faad->srcpad,
|
||||||
|
GST_DEBUG_FUNCPTR (gst_faad_srcgetcaps));
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
|
@ -380,7 +386,7 @@ gst_faad_sinkconnect (GstPad * pad, const GstCaps * caps)
|
||||||
static GstCaps *
|
static GstCaps *
|
||||||
gst_faad_srcgetcaps (GstPad * pad)
|
gst_faad_srcgetcaps (GstPad * pad)
|
||||||
{
|
{
|
||||||
GstFaad *faad = GST_FAAD (GST_OBJECT_PARENT (pad));
|
GstFaad *faad = GST_FAAD (gst_pad_get_parent (pad));
|
||||||
static GstAudioChannelPosition *supported_positions = NULL;
|
static GstAudioChannelPosition *supported_positions = NULL;
|
||||||
static gint num_supported_positions = LFE_CHANNEL - FRONT_CHANNEL_CENTER + 1;
|
static gint num_supported_positions = LFE_CHANNEL - FRONT_CHANNEL_CENTER + 1;
|
||||||
GstCaps *templ;
|
GstCaps *templ;
|
||||||
|
@ -485,7 +491,7 @@ gst_faad_srcgetcaps (GstPad * pad)
|
||||||
gst_audio_set_caps_channel_positions_list (caps,
|
gst_audio_set_caps_channel_positions_list (caps,
|
||||||
supported_positions, num_supported_positions);
|
supported_positions, num_supported_positions);
|
||||||
}
|
}
|
||||||
|
gst_object_unref (faad);
|
||||||
return caps;
|
return caps;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -494,6 +500,7 @@ gst_faad_srcgetcaps (GstPad * pad)
|
||||||
gst_audio_set_caps_channel_positions_list (templ,
|
gst_audio_set_caps_channel_positions_list (templ,
|
||||||
supported_positions, num_supported_positions);
|
supported_positions, num_supported_positions);
|
||||||
|
|
||||||
|
gst_object_unref (faad);
|
||||||
return templ;
|
return templ;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -611,18 +618,18 @@ gst_faad_event (GstPad * pad, GstEvent * event)
|
||||||
|
|
||||||
faad = GST_FAAD (gst_pad_get_parent (pad));
|
faad = GST_FAAD (gst_pad_get_parent (pad));
|
||||||
|
|
||||||
GST_LOG ("handling event %d", GST_EVENT_TYPE (event));
|
GST_LOG ("Handling %s event", GST_EVENT_TYPE_NAME (event));
|
||||||
|
|
||||||
/* FIXME: we should probably handle FLUSH and also
|
/* FIXME: we should probably handle FLUSH and also
|
||||||
* SEEK in the case where we are not in a container
|
* SEEK in the case where we are not in a container
|
||||||
* (when our newsegment was in BYTES) */
|
* (when our newsegment was in BYTES) */
|
||||||
switch (GST_EVENT_TYPE (event)) {
|
switch (GST_EVENT_TYPE (event)) {
|
||||||
case GST_EVENT_EOS:
|
case GST_EVENT_EOS:
|
||||||
|
GST_STREAM_LOCK (pad);
|
||||||
if (faad->tempbuf != NULL) {
|
if (faad->tempbuf != NULL) {
|
||||||
gst_buffer_unref (faad->tempbuf);
|
gst_buffer_unref (faad->tempbuf);
|
||||||
faad->tempbuf = NULL;
|
faad->tempbuf = NULL;
|
||||||
}
|
}
|
||||||
GST_STREAM_LOCK (pad);
|
|
||||||
res = gst_pad_push_event (faad->srcpad, event);
|
res = gst_pad_push_event (faad->srcpad, event);
|
||||||
GST_STREAM_UNLOCK (pad);
|
GST_STREAM_UNLOCK (pad);
|
||||||
break;
|
break;
|
||||||
|
@ -672,18 +679,11 @@ gst_faad_event (GstPad * pad, GstEvent * event)
|
||||||
GST_STREAM_UNLOCK (pad);
|
GST_STREAM_UNLOCK (pad);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case GST_EVENT_FLUSH_START:
|
|
||||||
res = gst_pad_push_event (faad->srcpad, event);
|
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
GST_STREAM_LOCK (pad);
|
res = gst_pad_event_default (pad, event);
|
||||||
res = gst_pad_push_event (faad->srcpad, event);
|
|
||||||
GST_STREAM_UNLOCK (pad);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* res = gst_pad_event_default (faad->sinkpad, event); */
|
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -740,14 +740,20 @@ gst_faad_chain (GstPad * pad, GstBuffer * buffer)
|
||||||
void *out;
|
void *out;
|
||||||
gboolean run_loop = TRUE;
|
gboolean run_loop = TRUE;
|
||||||
|
|
||||||
faad = GST_FAAD (GST_OBJECT_PARENT (pad));
|
faad = GST_FAAD (gst_pad_get_parent (pad));
|
||||||
|
|
||||||
if (GST_BUFFER_TIMESTAMP (buffer) != GST_CLOCK_TIME_NONE) {
|
if (GST_BUFFER_TIMESTAMP (buffer) != GST_CLOCK_TIME_NONE) {
|
||||||
faad->next_ts = GST_BUFFER_TIMESTAMP (buffer);
|
/* some demuxers send multiple buffers in a row
|
||||||
GST_DEBUG ("Timestamp on incoming buffer: %" GST_TIME_FORMAT,
|
* with the same timestamp (e.g. matroskademux) */
|
||||||
|
if (GST_BUFFER_TIMESTAMP (buffer) != faad->prev_ts) {
|
||||||
|
faad->next_ts = GST_BUFFER_TIMESTAMP (buffer);
|
||||||
|
faad->prev_ts = GST_BUFFER_TIMESTAMP (buffer);
|
||||||
|
}
|
||||||
|
GST_DEBUG ("Timestamp on incoming buffer: %" GST_TIME_FORMAT
|
||||||
|
", next_ts: %" GST_TIME_FORMAT,
|
||||||
|
GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buffer)),
|
||||||
GST_TIME_ARGS (faad->next_ts));
|
GST_TIME_ARGS (faad->next_ts));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* buffer + remaining data */
|
/* buffer + remaining data */
|
||||||
if (faad->tempbuf) {
|
if (faad->tempbuf) {
|
||||||
buffer = gst_buffer_join (faad->tempbuf, buffer);
|
buffer = gst_buffer_join (faad->tempbuf, buffer);
|
||||||
|
@ -766,6 +772,7 @@ gst_faad_chain (GstPad * pad, GstBuffer * buffer)
|
||||||
if (init_res < 0) {
|
if (init_res < 0) {
|
||||||
GST_ELEMENT_ERROR (faad, STREAM, DECODE, (NULL),
|
GST_ELEMENT_ERROR (faad, STREAM, DECODE, (NULL),
|
||||||
("Failed to init decoder from stream"));
|
("Failed to init decoder from stream"));
|
||||||
|
gst_object_unref (faad);
|
||||||
return GST_FLOW_UNEXPECTED;
|
return GST_FLOW_UNEXPECTED;
|
||||||
}
|
}
|
||||||
skip_bytes = init_res;
|
skip_bytes = init_res;
|
||||||
|
@ -838,22 +845,20 @@ gst_faad_chain (GstPad * pad, GstBuffer * buffer)
|
||||||
|
|
||||||
/* play decoded data */
|
/* play decoded data */
|
||||||
if (info.samples > 0 && GST_PAD_PEER (faad->srcpad)) {
|
if (info.samples > 0 && GST_PAD_PEER (faad->srcpad)) {
|
||||||
GstFlowReturn r;
|
|
||||||
guint bufsize = info.samples * faad->bps;
|
guint bufsize = info.samples * faad->bps;
|
||||||
|
guint num_samples = info.samples / faad->channels;
|
||||||
|
|
||||||
/* note: info.samples is total samples, not per channel */
|
/* note: info.samples is total samples, not per channel */
|
||||||
r = gst_pad_alloc_buffer (faad->srcpad, 0, bufsize, caps, &outbuf);
|
ret = gst_pad_alloc_buffer (faad->srcpad, 0, bufsize, caps, &outbuf);
|
||||||
if (r != GST_FLOW_OK) {
|
if (ret != GST_FLOW_OK)
|
||||||
GST_DEBUG ("Failed to allocate buffer");
|
|
||||||
ret = r; //GST_FLOW_OK; /* CHECK: or return something else? */
|
|
||||||
goto out;
|
goto out;
|
||||||
}
|
|
||||||
|
|
||||||
memcpy (GST_BUFFER_DATA (outbuf), out, GST_BUFFER_SIZE (outbuf));
|
memcpy (GST_BUFFER_DATA (outbuf), out, GST_BUFFER_SIZE (outbuf));
|
||||||
GST_BUFFER_OFFSET (outbuf) =
|
GST_BUFFER_OFFSET (outbuf) =
|
||||||
(faad->next_ts * faad->samplerate) / GST_SECOND;
|
GST_CLOCK_TIME_TO_FRAMES (faad->next_ts, faad->samplerate);
|
||||||
GST_BUFFER_TIMESTAMP (outbuf) = faad->next_ts;
|
GST_BUFFER_TIMESTAMP (outbuf) = faad->next_ts;
|
||||||
GST_BUFFER_DURATION (outbuf) = (guint64) GST_SECOND *info.samples / (faad->samplerate * 2); ///////// over 2?
|
GST_BUFFER_DURATION (outbuf) =
|
||||||
|
GST_FRAMES_TO_CLOCK_TIME (num_samples, faad->samplerate);
|
||||||
|
|
||||||
faad->next_ts += GST_BUFFER_DURATION (outbuf);
|
faad->next_ts += GST_BUFFER_DURATION (outbuf);
|
||||||
faad->sum_dur_out += GST_BUFFER_DURATION (outbuf);
|
faad->sum_dur_out += GST_BUFFER_DURATION (outbuf);
|
||||||
|
@ -887,6 +892,7 @@ out:
|
||||||
gst_caps_unref (caps);
|
gst_caps_unref (caps);
|
||||||
|
|
||||||
gst_buffer_unref (buffer);
|
gst_buffer_unref (buffer);
|
||||||
|
gst_object_unref (faad);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -894,6 +900,7 @@ out:
|
||||||
static GstStateChangeReturn
|
static GstStateChangeReturn
|
||||||
gst_faad_change_state (GstElement * element, GstStateChange transition)
|
gst_faad_change_state (GstElement * element, GstStateChange transition)
|
||||||
{
|
{
|
||||||
|
GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS;
|
||||||
GstFaad *faad = GST_FAAD (element);
|
GstFaad *faad = GST_FAAD (element);
|
||||||
|
|
||||||
switch (transition) {
|
switch (transition) {
|
||||||
|
@ -913,6 +920,14 @@ gst_faad_change_state (GstElement * element, GstStateChange transition)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (GST_ELEMENT_CLASS (parent_class)->change_state)
|
||||||
|
ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
|
||||||
|
|
||||||
|
switch (transition) {
|
||||||
case GST_STATE_CHANGE_PAUSED_TO_READY:
|
case GST_STATE_CHANGE_PAUSED_TO_READY:
|
||||||
faad->samplerate = -1;
|
faad->samplerate = -1;
|
||||||
faad->channels = -1;
|
faad->channels = -1;
|
||||||
|
@ -921,6 +936,7 @@ gst_faad_change_state (GstElement * element, GstStateChange transition)
|
||||||
g_free (faad->channel_positions);
|
g_free (faad->channel_positions);
|
||||||
faad->channel_positions = NULL;
|
faad->channel_positions = NULL;
|
||||||
faad->next_ts = 0;
|
faad->next_ts = 0;
|
||||||
|
faad->prev_ts = GST_CLOCK_TIME_NONE;
|
||||||
break;
|
break;
|
||||||
case GST_STATE_CHANGE_READY_TO_NULL:
|
case GST_STATE_CHANGE_READY_TO_NULL:
|
||||||
faacDecClose (faad->handle);
|
faacDecClose (faad->handle);
|
||||||
|
@ -934,10 +950,7 @@ gst_faad_change_state (GstElement * element, GstStateChange transition)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (GST_ELEMENT_CLASS (parent_class)->change_state)
|
return ret;
|
||||||
return GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
|
|
||||||
|
|
||||||
return GST_STATE_CHANGE_SUCCESS;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
|
|
|
@ -57,7 +57,8 @@ typedef struct _GstFaad {
|
||||||
gboolean need_channel_setup;
|
gboolean need_channel_setup;
|
||||||
gboolean packetised; /* We must differentiate between raw and packetised streams */
|
gboolean packetised; /* We must differentiate between raw and packetised streams */
|
||||||
|
|
||||||
guint64 next_ts; /* timestamp of next buffer */
|
gint64 prev_ts; /* timestamp of previous buffer */
|
||||||
|
gint64 next_ts; /* timestamp of next buffer */
|
||||||
guint64 bytes_in; /* bytes received */
|
guint64 bytes_in; /* bytes received */
|
||||||
guint64 sum_dur_out; /* sum of durations of decoded buffers we sent out */
|
guint64 sum_dur_out; /* sum of durations of decoded buffers we sent out */
|
||||||
} GstFaad;
|
} GstFaad;
|
||||||
|
|
Loading…
Reference in a new issue