summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjep <jep@2b0047a9-a6d8-0310-accf-f7200b2a168c>2012-10-09 16:49:08 +0000
committerjep <jep@2b0047a9-a6d8-0310-accf-f7200b2a168c>2012-10-09 16:49:08 +0000
commitfd72a4e44999b22c0ca33951ca4795e0b6307b1b (patch)
tree369efe9185a3927a875c599e043c2af5992986d1
parent23efe406e7e0ef72ff185f92e40190a8d4c56894 (diff)
* src/flump3dec.c: (_reset), (_update_ts), (_conv_bytes_to_time),
(_total_bytes), (_total_time), (_time_to_bytepos), (_check_for_xing), (gst_flump3dec_flush), (gst_flump3dec_decode), (gst_flump3dec_sink_event), (gst_flump3dec_src_query), (gst_flump3dec_src_event), (gst_flump3dec_change_state), (gst_flump3dec_init): Some more code refactoring. git-svn-id: https://core.fluendo.com/gstreamer/svn/trunk/gst-fluendo-mp3@2390 2b0047a9-a6d8-0310-accf-f7200b2a168c
-rw-r--r--ChangeLog10
-rw-r--r--src/flump3dec.c530
2 files changed, 264 insertions, 276 deletions
diff --git a/ChangeLog b/ChangeLog
index cb4a633..058857c 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,15 @@
2012-10-09 Josep Torra <josep@fluendo.com>
+ * src/flump3dec.c: (_reset), (_update_ts), (_conv_bytes_to_time),
+ (_total_bytes), (_total_time), (_time_to_bytepos),
+ (_check_for_xing), (gst_flump3dec_flush), (gst_flump3dec_decode),
+ (gst_flump3dec_sink_event), (gst_flump3dec_src_query),
+ (gst_flump3dec_src_event), (gst_flump3dec_change_state),
+ (gst_flump3dec_init):
+ Some more code refactoring.
+
+2012-10-09 Josep Torra <josep@fluendo.com>
+
* src/bitstream.c: (bs_new), (bs_free), (bs_flush), (bs_set_data),
(bs_eat), (bs_consume), (bs_skipbits), (bs_seek_sync),
(bs_getbytes):
diff --git a/src/flump3dec.c b/src/flump3dec.c
index 5bf4e21..d3c44a2 100644
--- a/src/flump3dec.c
+++ b/src/flump3dec.c
@@ -44,8 +44,13 @@ GST_STATIC_PAD_TEMPLATE ("src",
"channels = (int) [ 1, 2 ]")
);
-static void
-gst_flump3dec_reset (GstFluMp3Dec * dec)
+#define XING_FRAMES_FLAG 0x0001
+#define XING_BYTES_FLAG 0x0002
+#define XING_TOC_FLAG 0x0004
+#define XING_VBR_SCALE_FLAG 0x0008
+
+static inline void
+_reset (GstFluMp3Dec * dec)
{
dec->rate = 0;
dec->channels = 0;
@@ -64,29 +69,139 @@ gst_flump3dec_reset (GstFluMp3Dec * dec)
gst_segment_init (&dec->segment, GST_FORMAT_TIME);
}
-static void
-gst_flump3dec_flush (GstFluMp3Dec * dec)
+static inline void
+_update_ts (GstFluMp3Dec * dec, GstClockTime new_ts,
+ const fr_header * mp3hdr)
{
- dec->last_dec_ts = GST_CLOCK_TIME_NONE;
- dec->in_ts = GST_CLOCK_TIME_NONE;
+ GstClockTimeDiff diff;
+ GstClockTime out_ts = dec->next_ts;
+ GstClockTime frame_dur = gst_util_uint64_scale (GST_SECOND,
+ mp3hdr->frame_samples, mp3hdr->sample_rate);
- mp3tl_flush (dec->dec);
- if (dec->pending_frame) {
- gst_buffer_unref (dec->pending_frame);
- dec->pending_frame = NULL;
+ /* Only take the new timestamp if it is more than half a frame from
+ * our current timestamp */
+ if (GST_CLOCK_TIME_IS_VALID (out_ts)) {
+ diff = ABS ((GstClockTimeDiff) (new_ts - out_ts));
+ if ((GstClockTime) diff > (frame_dur / 2)) {
+ GST_DEBUG_OBJECT (dec, "Got frame with new TS %"
+ G_GUINT64_FORMAT " - using.", new_ts);
+ out_ts = new_ts;
+ }
}
- dec->need_discont = TRUE;
- gst_adapter_clear (dec->adapter);
+ dec->next_ts = out_ts;
}
-#define XING_FRAMES_FLAG 0x0001
-#define XING_BYTES_FLAG 0x0002
-#define XING_TOC_FLAG 0x0004
-#define XING_VBR_SCALE_FLAG 0x0008
+static inline gboolean
+_conv_bytes_to_time (GstFluMp3Dec * dec, gint64 byteval, GstClockTime * timeval)
+{
+ if (dec->avg_bitrate == 0 || timeval == NULL)
+ return FALSE;
+
+ if (byteval == -1)
+ *timeval = -1;
+ else
+ *timeval = gst_util_uint64_scale (GST_SECOND, byteval * 8,
+ dec->avg_bitrate);
+
+ return TRUE;
+}
+
+static inline gboolean
+_total_bytes (GstFluMp3Dec * dec, guint64 * total)
+{
+ GstQuery *query;
+ GstPad *peer;
+
+ if ((peer = gst_pad_get_peer (dec->sinkpad)) == NULL)
+ return FALSE;
+
+ query = gst_query_new_duration (GST_FORMAT_BYTES);
+ gst_query_set_duration (query, GST_FORMAT_BYTES, -1);
+
+ if (!gst_pad_query (peer, query)) {
+ gst_object_unref (peer);
+ return FALSE;
+ }
+
+ gst_object_unref (peer);
+
+ gst_query_parse_duration (query, NULL, (gint64 *) total);
+
+ return TRUE;
+}
+
+static inline gboolean
+_total_time (GstFluMp3Dec * dec, GstClockTime * total)
+{
+ /* If we have a Xing header giving us the total number of frames,
+ * use that to get total time */
+ if (dec->xing_flags & XING_FRAMES_FLAG) {
+ *total = dec->xing_total_time;
+ } else {
+ /* Calculate time from our bitrate */
+ if (!_total_bytes (dec, total))
+ return FALSE;
+
+ if (*total != (guint64) - 1 && !_conv_bytes_to_time (dec, *total, total))
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+static inline gboolean
+_time_to_bytepos (GstFluMp3Dec * dec, GstClockTime ts,
+ gint64 * bytepos)
+{
+ /* 0 always maps to 0, and -1 to -1 */
+ if (ts == 0 || ts == (GstClockTime) (-1)) {
+ *bytepos = (gint64) ts;
+ return TRUE;
+ }
+
+ /* If we have a Xing seek table, determine a byte offset to seek to */
+ if (dec->xing_flags & XING_TOC_FLAG) {
+ gdouble new_pos_percent;
+ gint int_percent;
+ guint64 total;
+ gdouble fa, fb, fx;
+
+ if (!_total_time (dec, &total))
+ return FALSE;
+
+ /* We need to know what point in the file to go to, from 0-100% */
+ new_pos_percent = (100.0 * ts) / total;
+ new_pos_percent = CLAMP (new_pos_percent, 0.0, 100.0);
+
+ int_percent = CLAMP ((int) (new_pos_percent), 0, 99);
+
+ fa = dec->xing_seek_table[int_percent];
+ if (int_percent < 99)
+ fb = dec->xing_seek_table[int_percent + 1];
+ else
+ fb = 256.0;
+ fx = fa + (fb - fa) * (new_pos_percent - int_percent);
+
+ if (!_total_bytes (dec, &total))
+ return FALSE;
+
+ *bytepos = (gint64) ((fx / 256.0) * total);
+ GST_DEBUG ("Xing seeking for %g percent time mapped to %g in bytes\n",
+ new_pos_percent, fx * 100.0 / 256.0);
+ } else {
+ /* Otherwise, convert to bytes using bitrate and send upstream */
+ if (dec->avg_bitrate == 0)
+ return FALSE;
+
+ *bytepos = gst_util_uint64_scale (ts, dec->avg_bitrate, (8 * GST_SECOND));
+ }
+
+ return TRUE;
+}
static Mp3TlRetcode
-gst_flump3dec_check_for_xing (GstFluMp3Dec * dec, const fr_header * mp3hdr)
+_check_for_xing (GstFluMp3Dec * dec, const fr_header * mp3hdr)
{
const guint32 xing_id = 0x58696e67; /* 'Xing' in hex */
const guint32 info_id = 0x496e666f; /* 'Info' in hex - found in LAME CBR files */
@@ -179,26 +294,19 @@ gst_flump3dec_check_for_xing (GstFluMp3Dec * dec, const fr_header * mp3hdr)
}
static void
-gst_flump3dec_update_ts (GstFluMp3Dec * dec, GstClockTime new_ts,
- const fr_header * mp3hdr)
+gst_flump3dec_flush (GstFluMp3Dec * dec)
{
- GstClockTimeDiff diff;
- GstClockTime out_ts = dec->next_ts;
- GstClockTime frame_dur = gst_util_uint64_scale (GST_SECOND,
- mp3hdr->frame_samples, mp3hdr->sample_rate);
+ dec->last_dec_ts = GST_CLOCK_TIME_NONE;
+ dec->in_ts = GST_CLOCK_TIME_NONE;
- /* Only take the new timestamp if it is more than half a frame from
- * our current timestamp */
- if (GST_CLOCK_TIME_IS_VALID (out_ts)) {
- diff = ABS ((GstClockTimeDiff) (new_ts - out_ts));
- if ((GstClockTime) diff > (frame_dur / 2)) {
- GST_DEBUG_OBJECT (dec, "Got frame with new TS %"
- G_GUINT64_FORMAT " - using.", new_ts);
- out_ts = new_ts;
- }
+ mp3tl_flush (dec->dec);
+ if (dec->pending_frame) {
+ gst_buffer_unref (dec->pending_frame);
+ dec->pending_frame = NULL;
}
- dec->next_ts = out_ts;
+ dec->need_discont = TRUE;
+ gst_adapter_clear (dec->adapter);
}
static GstFlowReturn
@@ -207,7 +315,7 @@ gst_flump3dec_decode (GstFluMp3Dec * dec, gboolean more_data)
Mp3TlRetcode result;
const fr_header *mp3hdr = NULL;
GstBuffer *out_buf = NULL;
- GstFlowReturn ret = GST_FLOW_OK;
+ GstFlowReturn res = GST_FLOW_OK;
GstClockTime dec_ts = GST_CLOCK_TIME_NONE;
GstTagList *taglist = NULL;
guint8 *out_data;
@@ -232,14 +340,14 @@ gst_flump3dec_decode (GstFluMp3Dec * dec, gboolean more_data)
continue; /* Resync */
else {
/* Fatal decoder error */
- ret = GST_FLOW_ERROR;
+ res = GST_FLOW_ERROR;
goto decode_error;
}
}
if (!mp3hdr) {
/* Fatal decoder error */
- ret = GST_FLOW_ERROR;
+ res = GST_FLOW_ERROR;
goto decode_error;
}
@@ -272,7 +380,7 @@ gst_flump3dec_decode (GstFluMp3Dec * dec, gboolean more_data)
/* end setting the tag */
GST_DEBUG ("Checking first frame for Xing VBR header");
- result = gst_flump3dec_check_for_xing (dec, mp3hdr);
+ result = _check_for_xing (dec, mp3hdr);
if (result == MP3TL_ERR_NEED_DATA)
break;
@@ -321,9 +429,9 @@ gst_flump3dec_decode (GstFluMp3Dec * dec, gboolean more_data)
/* We have enough bytes in the store, decode a frame */
frame_size = mp3hdr->frame_samples * dec->bytes_per_sample;
- ret = gst_pad_alloc_buffer (dec->srcpad, GST_BUFFER_OFFSET_NONE,
+ res = gst_pad_alloc_buffer (dec->srcpad, GST_BUFFER_OFFSET_NONE,
frame_size, GST_PAD_CAPS (dec->srcpad), &out_buf);
- if (ret != GST_FLOW_OK) {
+ if (res != GST_FLOW_OK) {
goto alloc_error;
}
out_data = GST_BUFFER_DATA (out_buf);
@@ -351,7 +459,7 @@ gst_flump3dec_decode (GstFluMp3Dec * dec, gboolean more_data)
out_buf = gst_buffer_create_sub (dec->pending_frame, 0,
GST_BUFFER_SIZE (dec->pending_frame));
if (out_buf == NULL) {
- ret = GST_FLOW_ERROR;
+ res = GST_FLOW_ERROR;
goto no_buffer;
}
@@ -364,7 +472,7 @@ gst_flump3dec_decode (GstFluMp3Dec * dec, gboolean more_data)
continue;
}
} else {
- ret = GST_FLOW_ERROR;
+ res = GST_FLOW_ERROR;
goto decode_error;
}
}
@@ -383,7 +491,7 @@ gst_flump3dec_decode (GstFluMp3Dec * dec, gboolean more_data)
if (GST_CLOCK_TIME_IS_VALID (dec_ts) && dec_ts != dec->last_dec_ts) {
/* Use the new timestamp now, and store it so we don't repeat it. */
- gst_flump3dec_update_ts (dec, dec_ts, mp3hdr);
+ _update_ts (dec, dec_ts, mp3hdr);
dec->last_dec_ts = dec_ts;
}
@@ -410,9 +518,9 @@ gst_flump3dec_decode (GstFluMp3Dec * dec, gboolean more_data)
GST_TIME_FORMAT,
GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (dec->pending_frame)));
- ret = gst_pad_push (dec->srcpad, dec->pending_frame);
+ res = gst_pad_push (dec->srcpad, dec->pending_frame);
dec->pending_frame = out_buf;
- if (ret != GST_FLOW_OK)
+ if (res != GST_FLOW_OK)
goto beach;
}
}
@@ -420,12 +528,12 @@ gst_flump3dec_decode (GstFluMp3Dec * dec, gboolean more_data)
/* Might need to flush out the pending decoded frame */
if (!more_data && (dec->pending_frame != NULL)) {
GST_DEBUG_OBJECT (dec, "Pushing pending frame");
- ret = gst_pad_push (dec->srcpad, dec->pending_frame);
+ res = gst_pad_push (dec->srcpad, dec->pending_frame);
dec->pending_frame = NULL;
}
beach:
- return ret;
+ return res;
alloc_error:
GST_DEBUG_OBJECT (dec, "Couldn't allocate a buffer, skipping decode");
@@ -433,18 +541,18 @@ alloc_error:
mp3tl_skip_frame (dec->dec);
if (GST_CLOCK_TIME_IS_VALID (dec_ts) && dec_ts != dec->last_dec_ts) {
/* Use the new timestamp now, and store it so we don't repeat it. */
- gst_flump3dec_update_ts (dec, dec_ts, mp3hdr);
+ _update_ts (dec, dec_ts, mp3hdr);
dec->last_dec_ts = dec_ts;
}
- return ret;
+ return res;
no_buffer:
- if (ret <= GST_FLOW_NOT_NEGOTIATED) {
+ if (res <= GST_FLOW_NOT_NEGOTIATED) {
GST_ELEMENT_ERROR (dec, RESOURCE, FAILED, (NULL),
("Failed to allocate output buffer: reason %s",
- gst_flow_get_name (ret)));
+ gst_flow_get_name (res)));
}
- return ret;
+ return res;
decode_error:
{
@@ -457,7 +565,7 @@ decode_error:
else
GST_ELEMENT_ERROR (dec, RESOURCE, FAILED, (NULL),
("Failed in mp3 stream decoding: Unknown reason"));
- return ret;
+ return res;
}
negotiate_error:
@@ -516,32 +624,20 @@ gst_flump3dec_sink_chain (GstPad * pad, GstBuffer * buffer)
return res;
}
-static inline gboolean
-conv_bytes_to_time (GstFluMp3Dec * dec, gint64 byteval, GstClockTime * timeval)
-{
- if (dec->avg_bitrate == 0 || timeval == NULL)
- return FALSE;
-
- if (byteval == -1)
- *timeval = -1;
- else
- *timeval = gst_util_uint64_scale (GST_SECOND, byteval * 8,
- dec->avg_bitrate);
-
- return TRUE;
-}
-
/* Handle incoming events on the sink pad */
-static inline gboolean
-gst_flump3dec_handle_sink_event (GstFluMp3Dec * dec, GstEvent * event)
+static gboolean
+gst_flump3dec_sink_event (GstPad * pad, GstEvent * event)
{
+ GstFluMp3Dec *dec = GST_FLUMP3DEC (gst_pad_get_parent (pad));
+ gboolean res = FALSE;
+
switch (GST_EVENT_TYPE (event)) {
case GST_EVENT_NEWSEGMENT:
{
gdouble rate;
GstFormat format;
gint64 start, end, base;
- gboolean result, update;
+ gboolean update;
gboolean converted = FALSE;
gst_event_parse_new_segment (event, &update, &rate, &format,
@@ -557,9 +653,9 @@ gst_flump3dec_handle_sink_event (GstFluMp3Dec * dec, GstEvent * event)
if (format == GST_FORMAT_BYTES) {
GstClockTime disc_start, disc_end, disc_base;
- if (conv_bytes_to_time (dec, start, &disc_start) &&
- conv_bytes_to_time (dec, end, &disc_end) &&
- conv_bytes_to_time (dec, base, &disc_base)) {
+ if (_conv_bytes_to_time (dec, start, &disc_start) &&
+ _conv_bytes_to_time (dec, end, &disc_end) &&
+ _conv_bytes_to_time (dec, base, &disc_base)) {
gst_event_unref (event);
event = gst_event_new_new_segment (FALSE, rate, GST_FORMAT_TIME,
disc_start, disc_end, disc_base);
@@ -582,10 +678,6 @@ gst_flump3dec_handle_sink_event (GstFluMp3Dec * dec, GstEvent * event)
0, GST_CLOCK_TIME_NONE, 0);
dec->next_ts = 0;
}
-
- result = gst_pad_push_event (dec->srcpad, event);
-
- return result;
}
case GST_EVENT_FLUSH_STOP:
gst_flump3dec_flush (dec);
@@ -598,59 +690,10 @@ gst_flump3dec_handle_sink_event (GstFluMp3Dec * dec, GstEvent * event)
break;
}
- return gst_pad_push_event (dec->srcpad, event);
-}
+ res = gst_pad_push_event (dec->srcpad, event);
-static gboolean
-gst_flump3dec_sink_event (GstPad * pad, GstEvent * event)
-{
- GstFluMp3Dec *dec = GST_FLUMP3DEC (gst_pad_get_parent (pad));
- gboolean result = gst_flump3dec_handle_sink_event (dec, event);
gst_object_unref (dec);
- return result;
-}
-
-static inline gboolean
-gst_flump3dec_total_bytes (GstFluMp3Dec * dec, guint64 * total)
-{
- GstQuery *query;
- GstPad *peer;
-
- if ((peer = gst_pad_get_peer (dec->sinkpad)) == NULL)
- return FALSE;
-
- query = gst_query_new_duration (GST_FORMAT_BYTES);
- gst_query_set_duration (query, GST_FORMAT_BYTES, -1);
-
- if (!gst_pad_query (peer, query)) {
- gst_object_unref (peer);
- return FALSE;
- }
-
- gst_object_unref (peer);
-
- gst_query_parse_duration (query, NULL, (gint64 *) total);
-
- return TRUE;
-}
-
-static inline gboolean
-gst_flump3dec_total_time (GstFluMp3Dec * dec, GstClockTime * total)
-{
- /* If we have a Xing header giving us the total number of frames,
- * use that to get total time */
- if (dec->xing_flags & XING_FRAMES_FLAG) {
- *total = dec->xing_total_time;
- } else {
- /* Calculate time from our bitrate */
- if (!gst_flump3dec_total_bytes (dec, total))
- return FALSE;
-
- if (*total != (guint64) - 1 && !conv_bytes_to_time (dec, *total, total))
- return FALSE;
- }
-
- return TRUE;
+ return res;
}
static gboolean
@@ -727,20 +770,21 @@ gst_flump3dec_src_convert (GstFluMp3Dec * dec, GstFormat src_format,
}
static gboolean
-gst_flump3dec_handle_src_query (GstFluMp3Dec * dec, GstQuery * query)
+gst_flump3dec_src_query (GstPad * pad, GstQuery * query)
{
+ GstFluMp3Dec *dec = GST_FLUMP3DEC (gst_pad_get_parent (pad));
GstFormat format;
- gint64 cur;
- guint64 total;
GstPad *peer;
gboolean res = FALSE;
switch (GST_QUERY_TYPE (query)) {
case GST_QUERY_POSITION:
{
+ gint64 cur;
+
/* Can't answer any queries if the upstream peer got unlinked */
if ((peer = gst_pad_get_peer (dec->sinkpad)) == NULL)
- goto error;
+ goto beach;
gst_query_parse_position (query, &format, NULL);
@@ -751,7 +795,7 @@ gst_flump3dec_handle_src_query (GstFluMp3Dec * dec, GstQuery * query)
gst_pad_query (peer, query)) {
gst_object_unref (peer);
res = TRUE;
- goto out;
+ goto beach;
}
gst_object_unref (peer);
@@ -762,16 +806,18 @@ gst_flump3dec_handle_src_query (GstFluMp3Dec * dec, GstQuery * query)
!gst_flump3dec_src_convert (dec, GST_FORMAT_TIME, cur, &format,
&cur)) {
gst_query_set_position (query, format, -1);
- goto error;
+ goto beach;
}
gst_query_set_position (query, format, cur);
break;
}
case GST_QUERY_DURATION:
{
+ guint64 total;
+
/* Can't answer any queries if the upstream peer got unlinked */
if ((peer = gst_pad_get_peer (dec->sinkpad)) == NULL)
- goto error;
+ goto beach;
gst_query_parse_duration (query, &format, NULL);
@@ -782,20 +828,19 @@ gst_flump3dec_handle_src_query (GstFluMp3Dec * dec, GstQuery * query)
gst_pad_query (peer, query)) {
gst_object_unref (peer);
res = TRUE;
- goto out;
+ goto beach;
}
gst_object_unref (peer);
- peer = NULL;
- if (!gst_flump3dec_total_time (dec, &total))
- goto error;
+ if (!_total_time (dec, &total))
+ goto beach;
if (total != -1) {
if (format != GST_FORMAT_TIME &&
!gst_flump3dec_src_convert (dec, GST_FORMAT_TIME, total,
&format, (gint64 *) & total)) {
gst_query_set_duration (query, format, -1);
- goto error;
+ goto beach;
}
}
@@ -808,160 +853,93 @@ gst_flump3dec_handle_src_query (GstFluMp3Dec * dec, GstQuery * query)
break;
}
-out:
+beach:
+ gst_object_unref (dec);
return res;
-error:
- return FALSE;
}
static gboolean
-gst_flump3dec_src_query (GstPad * pad, GstQuery * query)
+gst_flump3dec_src_event (GstPad * pad, GstEvent * event)
{
GstFluMp3Dec *dec = GST_FLUMP3DEC (gst_pad_get_parent (pad));
- gboolean result = gst_flump3dec_handle_src_query (dec, query);
- gst_object_unref (dec);
- return result;
-}
-
-static gboolean
-gst_flump3dec_time_to_bytepos (GstFluMp3Dec * dec, GstClockTime ts,
- gint64 * bytepos)
-{
- /* 0 always maps to 0, and -1 to -1 */
- if (ts == 0 || ts == (GstClockTime) (-1)) {
- *bytepos = (gint64) ts;
- return TRUE;
- }
-
- /* If we have a Xing seek table, determine a byte offset to seek to */
- if (dec->xing_flags & XING_TOC_FLAG) {
- gdouble new_pos_percent;
- gint int_percent;
- guint64 total;
- gdouble fa, fb, fx;
-
- if (!gst_flump3dec_total_time (dec, &total))
- return FALSE;
-
- /* We need to know what point in the file to go to, from 0-100% */
- new_pos_percent = (100.0 * ts) / total;
- new_pos_percent = CLAMP (new_pos_percent, 0.0, 100.0);
-
- int_percent = CLAMP ((int) (new_pos_percent), 0, 99);
-
- fa = dec->xing_seek_table[int_percent];
- if (int_percent < 99)
- fb = dec->xing_seek_table[int_percent + 1];
- else
- fb = 256.0;
- fx = fa + (fb - fa) * (new_pos_percent - int_percent);
+ gboolean res = FALSE;
- if (!gst_flump3dec_total_bytes (dec, &total))
- return FALSE;
+ switch (GST_EVENT_TYPE (event)) {
+ case GST_EVENT_SEEK:
+ {
+ GstFormat format;
+ GstEvent *seek_event;
+ gint64 start, stop;
+ GstSeekType start_type, stop_type;
+ GstSeekFlags in_flags;
+ GstFormat in_format;
+ gdouble in_rate;
+
+ gst_event_parse_seek (event, &in_rate, &in_format, &in_flags,
+ &start_type, &start, &stop_type, &stop);
+ gst_event_unref (event);
+
+ GST_DEBUG_OBJECT (dec,
+ "Seek, format %d, flags %d, start type %d start %" G_GINT64_FORMAT
+ " stop type %d stop %" G_GINT64_FORMAT,
+ in_format, in_flags, start_type, start, stop_type, stop);
+
+ /* Convert request to time format if we can */
+ if (in_format == GST_FORMAT_DEFAULT || in_format == GST_FORMAT_BYTES) {
+ format = GST_FORMAT_TIME;
+ if (!gst_flump3dec_src_convert (dec, in_format, start, &format, &start))
+ goto beach;
+ if (!gst_flump3dec_src_convert (dec, in_format, stop, &format, &stop))
+ goto beach;
+ } else {
+ format = in_format;
+ }
- *bytepos = (gint64) ((fx / 256.0) * total);
- GST_DEBUG ("Xing seeking for %g percent time mapped to %g in bytes\n",
- new_pos_percent, fx * 100.0 / 256.0);
- } else {
- /* Otherwise, convert to bytes using bitrate and send upstream */
- if (dec->avg_bitrate == 0)
- return FALSE;
+ /* See if upstream can seek by our converted time, or by whatever the
+ * input format is */
+ seek_event = gst_event_new_seek (in_rate, format, in_flags, start_type,
+ start, stop_type, stop);
+ if (!seek_event)
+ goto beach;
- *bytepos = gst_util_uint64_scale (ts, dec->avg_bitrate, (8 * GST_SECOND));
- }
+ if (gst_pad_push_event (dec->sinkpad, seek_event)) {
+ res = TRUE;
+ goto beach;
+ }
- return TRUE;
-}
+ /* From here on, we can only support seeks based on TIME format */
+ if (format != GST_FORMAT_TIME)
+ goto beach;
-static inline gboolean
-gst_flump3dec_handle_src_event (GstFluMp3Dec * dec, GstEvent * event)
-{
- gboolean result;
+ /* Convert TIME to BYTES and send upstream */
+ if (!_time_to_bytepos (dec, (GstClockTime) start, &start))
+ goto beach;
+ if (!_time_to_bytepos (dec, (GstClockTime) stop, &stop))
+ goto beach;
- g_return_val_if_fail (dec != NULL, FALSE);
+ seek_event = gst_event_new_seek (in_rate, GST_FORMAT_BYTES, in_flags,
+ start_type, start, stop_type, stop);
+ if (!seek_event)
+ goto beach;
- if (GST_EVENT_TYPE (event) == GST_EVENT_SEEK) {
- GstFormat format;
- GstEvent *seek_event;
- gint64 start, stop;
- GstSeekType start_type, stop_type;
- GstSeekFlags in_flags;
- GstFormat in_format;
- gdouble in_rate;
-
- gst_event_parse_seek (event, &in_rate, &in_format, &in_flags,
- &start_type, &start, &stop_type, &stop);
- gst_event_unref (event);
- event = NULL;
-
- GST_DEBUG_OBJECT (dec,
- "Seek, format %d, flags %d, start type %d start %" G_GINT64_FORMAT
- " stop type %d stop %" G_GINT64_FORMAT,
- in_format, in_flags, start_type, start, stop_type, stop);
-
- /* Convert request to time format if we can */
- if (in_format == GST_FORMAT_DEFAULT || in_format == GST_FORMAT_BYTES) {
- format = GST_FORMAT_TIME;
- if (!gst_flump3dec_src_convert (dec, in_format, start, &format, &start))
- goto error;
- if (!gst_flump3dec_src_convert (dec, in_format, stop, &format, &stop))
- goto error;
- } else {
- format = in_format;
+ res = gst_pad_push_event (dec->sinkpad, seek_event);
}
-
- /* See if upstream can seek by our converted time, or by whatever the
- * input format is */
- seek_event = gst_event_new_seek (in_rate, format, in_flags, start_type,
- start, stop_type, stop);
- g_return_val_if_fail (seek_event != NULL, FALSE);
-
- if (gst_pad_push_event (dec->sinkpad, seek_event)) {
- result = TRUE;
- goto out;
+ default:
+ {
+ res = gst_pad_event_default (dec->srcpad, event);
+ break;
}
- seek_event = NULL;
-
- /* From here on, we can only support seeks based on TIME format */
- if (format != GST_FORMAT_TIME)
- goto error;
-
- /* Convert TIME to BYTES and send upstream */
- if (!gst_flump3dec_time_to_bytepos (dec, (GstClockTime) start, &start))
- goto error;
- if (!gst_flump3dec_time_to_bytepos (dec, (GstClockTime) stop, &stop))
- goto error;
-
- seek_event = gst_event_new_seek (in_rate, GST_FORMAT_BYTES, in_flags,
- start_type, start, stop_type, stop);
- if (!seek_event)
- goto error;
-
- result = gst_pad_push_event (dec->sinkpad, seek_event);
- } else {
- result = gst_pad_event_default (dec->srcpad, event);
- }
+ }
-out:
- return result;
-
-error:
- return FALSE;
-}
-
-static gboolean
-gst_flump3dec_src_event (GstPad * pad, GstEvent * event)
-{
- GstFluMp3Dec *dec = GST_FLUMP3DEC (gst_pad_get_parent (pad));
- gboolean result = gst_flump3dec_handle_src_event (dec, event);
+beach:
gst_object_unref (dec);
- return result;
+ return res;
}
static GstStateChangeReturn
gst_flump3dec_change_state (GstElement * element, GstStateChange transition)
{
- GstStateChangeReturn ret;
+ GstStateChangeReturn res;
GstFluMp3Dec *dec = GST_FLUMP3DEC (element);
g_return_val_if_fail (dec != NULL, GST_STATE_CHANGE_FAILURE);
@@ -969,13 +947,13 @@ gst_flump3dec_change_state (GstElement * element, GstStateChange transition)
switch (transition) {
case GST_STATE_CHANGE_READY_TO_PAUSED:
/* Prepare the decoder */
- gst_flump3dec_reset (dec);
+ _reset (dec);
break;
default:
break;
}
- ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
+ res = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
switch (transition) {
case GST_STATE_CHANGE_PAUSED_TO_READY:
@@ -985,7 +963,7 @@ gst_flump3dec_change_state (GstElement * element, GstStateChange transition)
default:
break;
}
- return ret;
+ return res;
}
static void
@@ -1087,7 +1065,7 @@ gst_flump3dec_init (GstFluMp3Dec * dec)
dec->dec = mp3tl_new (dec->bs, MP3TL_MODE_16BIT);
g_return_if_fail (dec->dec != NULL);
- gst_flump3dec_reset (dec);
+ _reset (dec);
}
/* Function implementations */