diff options
author | jep <jep@2b0047a9-a6d8-0310-accf-f7200b2a168c> | 2012-10-09 16:49:08 +0000 |
---|---|---|
committer | jep <jep@2b0047a9-a6d8-0310-accf-f7200b2a168c> | 2012-10-09 16:49:08 +0000 |
commit | fd72a4e44999b22c0ca33951ca4795e0b6307b1b (patch) | |
tree | 369efe9185a3927a875c599e043c2af5992986d1 | |
parent | 23efe406e7e0ef72ff185f92e40190a8d4c56894 (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-- | ChangeLog | 10 | ||||
-rw-r--r-- | src/flump3dec.c | 530 |
2 files changed, 264 insertions, 276 deletions
@@ -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 */ |