summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: e3f1717)
raw | patch | inline | side by side (parent: e3f1717)
author | Ronald S. Bultje <rbultje@ronald.bitfreak.net> | |
Mon, 6 Dec 2004 10:28:13 +0000 (10:28 +0000) | ||
committer | Ronald S. Bultje <rbultje@ronald.bitfreak.net> | |
Mon, 6 Dec 2004 10:28:13 +0000 (10:28 +0000) |
Original commit message from CVS:
* ext/a52dec/gsta52dec.c: (gst_a52dec_init),
(gst_a52dec_handle_event), (gst_a52dec_update_streaminfo),
(gst_a52dec_handle_frame), (gst_a52dec_chain),
(gst_a52dec_change_state), (plugin_init):
* ext/a52dec/gsta52dec.h:
Do something useful with timestamps. Make chain-based (since
there's really no reason to be loopbased).
* gst/avi/gstavidemux.c: (gst_avi_demux_process_next_entry):
Update current_byte/frame correctly.
* ext/a52dec/gsta52dec.c: (gst_a52dec_init),
(gst_a52dec_handle_event), (gst_a52dec_update_streaminfo),
(gst_a52dec_handle_frame), (gst_a52dec_chain),
(gst_a52dec_change_state), (plugin_init):
* ext/a52dec/gsta52dec.h:
Do something useful with timestamps. Make chain-based (since
there's really no reason to be loopbased).
* gst/avi/gstavidemux.c: (gst_avi_demux_process_next_entry):
Update current_byte/frame correctly.
ChangeLog | patch | blob | history | |
ext/a52dec/gsta52dec.c | patch | blob | history | |
ext/a52dec/gsta52dec.h | patch | blob | history |
diff --git a/ChangeLog b/ChangeLog
index edc94ef36ec83d8c1c6422314d724b2f2b1d3450..0b3fdfd1b4221a698fa6a89eb00ba28bf995849c 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
+2004-12-06 Ronald S. Bultje <rbultje@ronald.bitfreak.net>
+
+ * ext/a52dec/gsta52dec.c: (gst_a52dec_init),
+ (gst_a52dec_handle_event), (gst_a52dec_update_streaminfo),
+ (gst_a52dec_handle_frame), (gst_a52dec_chain),
+ (gst_a52dec_change_state), (plugin_init):
+ * ext/a52dec/gsta52dec.h:
+ Do something useful with timestamps. Make chain-based (since
+ there's really no reason to be loopbased).
+ * gst/avi/gstavidemux.c: (gst_avi_demux_process_next_entry):
+ Update current_byte/frame correctly.
+
2004-12-04 Ronald S. Bultje <rbultje@ronald.bitfreak.net>
* gst/apetag/apedemux.c: (gst_ape_demux_parse_tags),
diff --git a/ext/a52dec/gsta52dec.c b/ext/a52dec/gsta52dec.c
index 120045a4b9108d271b3d0386d08cb71700f65e6c..039b2a2d9b7def0cffae1ba81810c37300ea1b8d 100644 (file)
--- a/ext/a52dec/gsta52dec.c
+++ b/ext/a52dec/gsta52dec.c
ARG_DRC
};
-/*
- * "audio/a52", "audio/x-a52" and "audio/ac3" should not be used (deprecated names)
- * Only use "audio/x-ac3" in new code.
- */
static GstStaticPadTemplate sink_factory = GST_STATIC_PAD_TEMPLATE ("sink",
GST_PAD_SINK,
GST_PAD_ALWAYS,
static void gst_a52dec_class_init (GstA52DecClass * klass);
static void gst_a52dec_init (GstA52Dec * a52dec);
-static void gst_a52dec_loop (GstElement * element);
+static void gst_a52dec_chain (GstPad * pad, GstData * data);
static GstElementStateReturn gst_a52dec_change_state (GstElement * element);
static void gst_a52dec_set_property (GObject * object, guint prop_id,
static void
gst_a52dec_init (GstA52Dec * a52dec)
{
+ GST_FLAG_SET (GST_ELEMENT (a52dec), GST_ELEMENT_EVENT_AWARE);
+
/* create the sink and src pads */
a52dec->sinkpad =
gst_pad_new_from_template (gst_element_get_pad_template (GST_ELEMENT
(a52dec), "sink"), "sink");
+ gst_pad_set_chain_function (a52dec->sinkpad, gst_a52dec_chain);
gst_element_add_pad (GST_ELEMENT (a52dec), a52dec->sinkpad);
- gst_element_set_loop_function ((GstElement *) a52dec, gst_a52dec_loop);
a52dec->srcpad =
gst_pad_new_from_template (gst_element_get_pad_template (GST_ELEMENT
gst_pad_use_explicit_caps (a52dec->srcpad);
gst_element_add_pad (GST_ELEMENT (a52dec), a52dec->srcpad);
- GST_FLAG_SET (GST_ELEMENT (a52dec), GST_ELEMENT_EVENT_AWARE);
a52dec->dynamic_range_compression = FALSE;
+ a52dec->cache = NULL;
}
static int
return 0;
}
-/* END modified a52dec conversion code */
-
static gboolean
gst_a52dec_reneg (GstPad * pad)
{
}
static void
-gst_a52dec_handle_event (GstA52Dec * a52dec)
+gst_a52dec_handle_event (GstA52Dec * a52dec, GstEvent * event)
{
- guint32 remaining;
- GstEvent *event;
-
- gst_bytestream_get_status (a52dec->bs, &remaining, &event);
-
- if (!event) {
- g_warning ("a52dec: no bytestream event");
- return;
- }
-
GST_LOG ("Handling event of type %d timestamp %llu", GST_EVENT_TYPE (event),
GST_EVENT_TIMESTAMP (event));
+
switch (GST_EVENT_TYPE (event)) {
- case GST_EVENT_DISCONTINUOUS:
+ case GST_EVENT_DISCONTINUOUS:{
+ gint64 val;
+
+ if (!gst_event_discont_get_value (event, GST_FORMAT_TIME, &val)) {
+ GST_WARNING ("No time discont value in event %p", event);
+ } else {
+ a52dec->time = val;
+ }
+ }
+ /* fall-through */
case GST_EVENT_FLUSH:
- gst_bytestream_flush_fast (a52dec->bs, remaining);
+ if (a52dec->cache) {
+ gst_buffer_unref (a52dec->cache);
+ a52dec->cache = NULL;
+ }
break;
default:
break;
}
+
gst_pad_event_default (a52dec->sinkpad, event);
}
GST_TAG_BITRATE, (guint) a52dec->bit_rate, NULL);
gst_element_found_tags_for_pad (GST_ELEMENT (a52dec),
- GST_PAD (a52dec->srcpad), a52dec->current_ts, taglist);
+ GST_PAD (a52dec->srcpad), a52dec->time, taglist);
}
-static void
-gst_a52dec_loop (GstElement * element)
+static gboolean
+gst_a52dec_handle_frame (GstA52Dec * a52dec, guint8 * data,
+ guint length, gint flags, gint sample_rate, gint bit_rate)
{
- GstA52Dec *a52dec;
- guint8 *data;
- int i, length, flags, sample_rate, bit_rate;
- int channels;
- GstBuffer *buf = NULL;
- guint32 got_bytes;
- gboolean need_reneg;
- GstClockTime timestamp = 0;
-
- a52dec = GST_A52DEC (element);
-
- /* find and read header */
- bit_rate = a52dec->bit_rate;
- sample_rate = a52dec->sample_rate;
- flags = 0;
- do {
- gint skipped_bytes = 0;
-
- while (skipped_bytes < 3840) {
- got_bytes = gst_bytestream_peek_bytes (a52dec->bs, &data, 7);
- if (got_bytes < 7) {
- gst_a52dec_handle_event (a52dec);
- return;
- }
- length = a52_syncinfo (data, &flags, &sample_rate, &bit_rate);
- if (length == 0) {
- /* slide window to next 7 bytesa */
- gst_bytestream_flush_fast (a52dec->bs, 1);
- skipped_bytes++;
- GST_DEBUG ("Skipped");
- } else {
- GST_DEBUG ("Sync: %d", length);
- break;
- }
- }
- if (skipped_bytes >= 3840) {
- GST_LOG ("Sync failed");
- return;
- }
- }
- while (0);
+ gint channels, i;
+ gboolean need_reneg = FALSE;
+ /* update stream information, renegotiate or re-streaminfo if needed */
need_reneg = FALSE;
-
if (a52dec->sample_rate != sample_rate) {
need_reneg = TRUE;
a52dec->sample_rate = sample_rate;
gst_a52dec_update_streaminfo (a52dec);
}
- /* read the header + rest of frame */
- got_bytes = gst_bytestream_read (a52dec->bs, &buf, length);
- if (got_bytes < length) {
- gst_a52dec_handle_event (a52dec);
- return;
- }
- data = GST_BUFFER_DATA (buf);
- timestamp = gst_bytestream_get_timestamp (a52dec->bs);
- if (GST_CLOCK_TIME_IS_VALID (timestamp)) {
- if (timestamp == a52dec->last_ts) {
- timestamp = a52dec->current_ts;
- } else {
- a52dec->last_ts = timestamp;
- }
- }
-
/* process */
flags = a52dec->request_channels; /* | A52_ADJUST_LEVEL; */
a52dec->level = 1;
-
if (a52_frame (a52dec->state, data, &flags, &a52dec->level, a52dec->bias)) {
GST_WARNING ("a52_frame error");
- goto end;
+ return TRUE;
}
-
channels = flags & (A52_CHANNEL_MASK | A52_LFE);
-
if (a52dec->using_channels != channels) {
need_reneg = TRUE;
a52dec->using_channels = channels;
}
+ /* negotiate if required */
if (need_reneg == TRUE) {
GST_DEBUG ("a52dec reneg: sample_rate:%d stream_chans:%d using_chans:%d\n",
a52dec->sample_rate, a52dec->stream_channels, a52dec->using_channels);
- if (!gst_a52dec_reneg (a52dec->srcpad))
- goto end;
+ if (!gst_a52dec_reneg (a52dec->srcpad)) {
+ GST_ELEMENT_ERROR (a52dec, CORE, NEGOTIATION, (NULL), (NULL));
+ return FALSE;
+ }
}
if (a52dec->dynamic_range_compression == FALSE) {
a52_dynrng (a52dec->state, NULL, NULL);
}
+ /* each frame consists of 6 blocks */
for (i = 0; i < 6; i++) {
if (a52_block (a52dec->state)) {
GST_WARNING ("a52_block error %d", i);
- continue;
+ } else {
+ /* push on */
+ gst_a52dec_push (a52dec->srcpad, a52dec->using_channels,
+ a52dec->samples, a52dec->time);
}
- /* push on */
+ a52dec->time += 256 * GST_SECOND / a52dec->sample_rate;
+ }
- if (gst_a52dec_push (a52dec->srcpad, a52dec->using_channels,
- a52dec->samples, timestamp)) {
- GST_WARNING ("a52dec push error");
- } else {
+ return TRUE;
+}
- if (i % 2)
- timestamp += 256 * GST_SECOND / a52dec->sample_rate;
- }
+static void
+gst_a52dec_chain (GstPad * pad, GstData * _data)
+{
+ GstA52Dec *a52dec = GST_A52DEC (gst_pad_get_parent (pad));
+ GstBuffer *buf;
+ guint8 *data;
+ guint size;
+ gint length = 0, flags, sample_rate, bit_rate;
+
+ /* event handling */
+ if (GST_IS_EVENT (_data)) {
+ gst_a52dec_handle_event (a52dec, GST_EVENT (_data));
+ return;
}
- a52dec->current_ts = timestamp;
+ /* merge with cache, if any. Also make sure timestamps match */
+ buf = GST_BUFFER (_data);
+ if (GST_BUFFER_TIMESTAMP_IS_VALID (buf)) {
+ a52dec->time = GST_BUFFER_TIMESTAMP (buf);
+ }
+ if (a52dec->cache) {
+ buf = gst_buffer_join (a52dec->cache, buf);
+ a52dec->cache = NULL;
+ }
+ data = GST_BUFFER_DATA (buf);
+ size = GST_BUFFER_SIZE (buf);
-end:
+ /* find and read header */
+ bit_rate = a52dec->bit_rate;
+ sample_rate = a52dec->sample_rate;
+ flags = 0;
+ while (size >= 7) {
+ length = a52_syncinfo (data, &flags, &sample_rate, &bit_rate);
+ if (length == 0) {
+ /* no sync */
+ data++;
+ size--;
+ } else if (length <= size) {
+ GST_DEBUG ("Sync: %d", length);
+ if (!gst_a52dec_handle_frame (a52dec, data,
+ length, flags, sample_rate, bit_rate)) {
+ size = 0;
+ break;
+ }
+ size -= length;
+ data += length;
+ } else {
+ /* not enough data */
+ GST_LOG ("Not enough data available");
+ break;
+ }
+ }
+
+ /* keep cache */
+ if (length == 0) {
+ GST_LOG ("No sync found");
+ }
+ if (size > 0) {
+ a52dec->cache = gst_buffer_create_sub (buf,
+ GST_BUFFER_SIZE (buf) - size, size);
+ }
gst_buffer_unref (buf);
}
switch (GST_STATE_TRANSITION (element)) {
case GST_STATE_NULL_TO_READY:
- a52dec->bs = gst_bytestream_new (a52dec->sinkpad);
cpuflags = gst_cpu_get_flags ();
if (cpuflags & GST_CPU_FLAG_MMX)
a52_cpuflags |= MM_ACCEL_X86_MMX;
a52dec->using_channels = A52_CHANNEL;
a52dec->level = 1;
a52dec->bias = 0;
- a52dec->last_ts = 0;
- a52dec->current_ts = 0;
- a52dec->last_timestamp = 0;
- a52dec->last_diff = 0;
-
+ a52dec->time = 0;
break;
case GST_STATE_PAUSED_TO_PLAYING:
break;
case GST_STATE_PLAYING_TO_PAUSED:
break;
case GST_STATE_PAUSED_TO_READY:
- gst_bytestream_destroy (a52dec->bs);
- a52dec->bs = NULL;
a52dec->samples = NULL;
+ if (a52dec->cache) {
+ gst_buffer_unref (a52dec->cache);
+ a52dec->cache = NULL;
+ }
break;
case GST_STATE_READY_TO_NULL:
a52_free (a52dec->state);
plugin_init (GstPlugin * plugin)
{
- if (!gst_library_load ("gstbytestream") || !gst_library_load ("gstaudio"))
+ if (!gst_library_load ("gstaudio"))
return FALSE;
if (!gst_element_register (plugin, "a52dec", GST_RANK_PRIMARY,
diff --git a/ext/a52dec/gsta52dec.h b/ext/a52dec/gsta52dec.h
index eecbed5320831aa8dcf49bc66fde4994117100ac..9c1d32c88b5d71e68e71687eb0765601143fc28c 100644 (file)
--- a/ext/a52dec/gsta52dec.h
+++ b/ext/a52dec/gsta52dec.h
sample_t *samples;
a52_state_t *state;
- GstByteStream *bs;
-
- GstClockTime last_ts;
- GstClockTime current_ts;
-
- GstClockTime last_timestamp;
- GstClockTimeDiff last_diff;
+ GstBuffer *cache;
+ GstClockTime time;
};
struct _GstA52DecClass {