diff options
author | Samuli Suominen <drac@gentoo.org> | 2007-11-18 20:19:26 +0000 |
---|---|---|
committer | Samuli Suominen <drac@gentoo.org> | 2007-11-18 20:19:26 +0000 |
commit | e4a48835ee6e39d17d37ce33ebb23c8409a9adb4 (patch) | |
tree | 8500b373da1949ceb7206b5bd882cdc2c61d04e7 /media-libs/gst-plugins-ugly | |
parent | add a check for flac cxx use flag, FLAC++ is needed here (diff) | |
download | gentoo-2-e4a48835ee6e39d17d37ce33ebb23c8409a9adb4.tar.gz gentoo-2-e4a48835ee6e39d17d37ce33ebb23c8409a9adb4.tar.bz2 gentoo-2-e4a48835ee6e39d17d37ce33ebb23c8409a9adb4.zip |
Update mpegaudioparse to CVS 20071117 to work with current core.
(Portage version: 2.1.3.19)
Diffstat (limited to 'media-libs/gst-plugins-ugly')
4 files changed, 869 insertions, 1 deletions
diff --git a/media-libs/gst-plugins-ugly/ChangeLog b/media-libs/gst-plugins-ugly/ChangeLog index b07c00f43647..63a0877bc720 100644 --- a/media-libs/gst-plugins-ugly/ChangeLog +++ b/media-libs/gst-plugins-ugly/ChangeLog @@ -1,6 +1,13 @@ # ChangeLog for media-libs/gst-plugins-ugly # Copyright 1999-2007 Gentoo Foundation; Distributed under the GPL v2 -# $Header: /var/cvsroot/gentoo-x86/media-libs/gst-plugins-ugly/ChangeLog,v 1.30 2007/10/11 14:54:34 corsair Exp $ +# $Header: /var/cvsroot/gentoo-x86/media-libs/gst-plugins-ugly/ChangeLog,v 1.31 2007/11/18 20:19:25 drac Exp $ + +*gst-plugins-ugly-0.10.6-r1 (18 Nov 2007) + + 18 Nov 2007; Samuli Suominen <drac@gentoo.org> + +files/gst-plugins-ugly-0.10.6-mpegaudioparse-cvs20071117.patch, + +gst-plugins-ugly-0.10.6-r1.ebuild: + Update mpegaudioparse to CVS 20071117 to work with current core. 11 Oct 2007; Markus Rothe <corsair@gentoo.org> gst-plugins-ugly-0.10.6.ebuild: diff --git a/media-libs/gst-plugins-ugly/files/digest-gst-plugins-ugly-0.10.6-r1 b/media-libs/gst-plugins-ugly/files/digest-gst-plugins-ugly-0.10.6-r1 new file mode 100644 index 000000000000..24b61c3cde29 --- /dev/null +++ b/media-libs/gst-plugins-ugly/files/digest-gst-plugins-ugly-0.10.6-r1 @@ -0,0 +1,3 @@ +MD5 f1016148ecbfba968c0ef1773066988b gst-plugins-ugly-0.10.6.tar.bz2 773777 +RMD160 6f2ce61800e1013f8695b8e09a3f03beee1c9af8 gst-plugins-ugly-0.10.6.tar.bz2 773777 +SHA256 9c514d4002fb2a2efc5c60e009c330be2ee05c28649d73de3aa45530161c2c62 gst-plugins-ugly-0.10.6.tar.bz2 773777 diff --git a/media-libs/gst-plugins-ugly/files/gst-plugins-ugly-0.10.6-mpegaudioparse-cvs20071117.patch b/media-libs/gst-plugins-ugly/files/gst-plugins-ugly-0.10.6-mpegaudioparse-cvs20071117.patch new file mode 100644 index 000000000000..28077b22298b --- /dev/null +++ b/media-libs/gst-plugins-ugly/files/gst-plugins-ugly-0.10.6-mpegaudioparse-cvs20071117.patch @@ -0,0 +1,794 @@ +Index: gst/mpegaudioparse/gstmpegaudioparse.c +=================================================================== +RCS file: /cvs/gstreamer/gst-plugins-ugly/gst/mpegaudioparse/gstmpegaudioparse.c,v +retrieving revision 1.62 +retrieving revision 1.74 +diff -u -r1.62 -r1.74 +--- gst/mpegaudioparse/gstmpegaudioparse.c 8 Jun 2007 08:39:43 -0000 1.62 ++++ gst/mpegaudioparse/gstmpegaudioparse.c 30 Oct 2007 12:27:32 -0000 1.74 +@@ -29,6 +29,7 @@ + GST_DEBUG_CATEGORY_STATIC (mp3parse_debug); + #define GST_CAT_DEFAULT mp3parse_debug + ++ + /* elementfactory information */ + static GstElementDetails mp3parse_details = { + "MPEG1 Audio Parser", +@@ -71,8 +72,9 @@ + + + static void gst_mp3parse_class_init (GstMPEGAudioParseClass * klass); +-static void gst_mp3parse_base_init (GstMPEGAudioParseClass * klass); +-static void gst_mp3parse_init (GstMPEGAudioParse * mp3parse); ++static void gst_mp3parse_base_init (gpointer klass); ++static void gst_mp3parse_init (GstMPEGAudioParse * mp3parse, ++ GstMPEGAudioParseClass * klass); + + static gboolean gst_mp3parse_sink_event (GstPad * pad, GstEvent * event); + static GstFlowReturn gst_mp3parse_chain (GstPad * pad, GstBuffer * buffer); +@@ -95,33 +97,9 @@ + static gboolean + mp3parse_total_bytes (GstMPEGAudioParse * mp3parse, gint64 * total); + +-static GstElementClass *parent_class = NULL; +- + /*static guint gst_mp3parse_signals[LAST_SIGNAL] = { 0 }; */ + +-GType +-gst_mp3parse_get_type (void) +-{ +- static GType mp3parse_type = 0; +- +- if (!mp3parse_type) { +- static const GTypeInfo mp3parse_info = { +- sizeof (GstMPEGAudioParseClass), +- (GBaseInitFunc) gst_mp3parse_base_init, +- NULL, +- (GClassInitFunc) gst_mp3parse_class_init, +- NULL, +- NULL, +- sizeof (GstMPEGAudioParse), +- 0, +- (GInstanceInitFunc) gst_mp3parse_init, +- }; +- +- mp3parse_type = g_type_register_static (GST_TYPE_ELEMENT, +- "GstMPEGAudioParse", &mp3parse_info, 0); +- } +- return mp3parse_type; +-} ++GST_BOILERPLATE (GstMPEGAudioParse, gst_mp3parse, GstElement, GST_TYPE_ELEMENT); + + static guint mp3types_bitrates[2][3][16] = { + { +@@ -218,13 +196,14 @@ + new = gst_caps_new_simple ("audio/mpeg", + "mpegversion", G_TYPE_INT, 1, + "layer", G_TYPE_INT, layer, +- "rate", G_TYPE_INT, samplerate, "channels", G_TYPE_INT, channels, NULL); ++ "rate", G_TYPE_INT, samplerate, ++ "channels", G_TYPE_INT, channels, "parsed", G_TYPE_BOOLEAN, TRUE, NULL); + + return new; + } + + static void +-gst_mp3parse_base_init (GstMPEGAudioParseClass * klass) ++gst_mp3parse_base_init (gpointer klass) + { + GstElementClass *element_class = GST_ELEMENT_CLASS (klass); + +@@ -265,8 +244,8 @@ + { + mp3parse->skip = 0; + mp3parse->resyncing = TRUE; +- mp3parse->cur_offset = -1; + mp3parse->next_ts = GST_CLOCK_TIME_NONE; ++ mp3parse->cur_offset = -1; + + mp3parse->tracked_offset = 0; + mp3parse->pending_ts = GST_CLOCK_TIME_NONE; +@@ -276,6 +255,7 @@ + + mp3parse->rate = mp3parse->channels = mp3parse->layer = -1; + mp3parse->version = 1; ++ mp3parse->max_bitreservoir = GST_CLOCK_TIME_NONE; + + mp3parse->avg_bitrate = 0; + mp3parse->bitrate_sum = 0; +@@ -285,21 +265,34 @@ + + mp3parse->xing_flags = 0; + mp3parse->xing_bitrate = 0; ++ ++ if (mp3parse->seek_table) { ++ g_list_foreach (mp3parse->seek_table, (GFunc) g_free, NULL); ++ mp3parse->seek_table = NULL; ++ } ++ ++ g_mutex_lock (mp3parse->pending_accurate_seeks_lock); ++ if (mp3parse->pending_accurate_seeks) { ++ g_slist_foreach (mp3parse->pending_accurate_seeks, (GFunc) g_free, NULL); ++ mp3parse->pending_accurate_seeks = NULL; ++ } ++ g_mutex_unlock (mp3parse->pending_accurate_seeks_lock); ++ ++ mp3parse->exact_position = FALSE; ++ gst_segment_init (&mp3parse->segment, GST_FORMAT_TIME); + } + + static void +-gst_mp3parse_init (GstMPEGAudioParse * mp3parse) ++gst_mp3parse_init (GstMPEGAudioParse * mp3parse, GstMPEGAudioParseClass * klass) + { + mp3parse->sinkpad = +- gst_pad_new_from_template (gst_static_pad_template_get +- (&mp3_sink_template), "sink"); ++ gst_pad_new_from_static_template (&mp3_sink_template, "sink"); + gst_pad_set_event_function (mp3parse->sinkpad, gst_mp3parse_sink_event); + gst_pad_set_chain_function (mp3parse->sinkpad, gst_mp3parse_chain); + gst_element_add_pad (GST_ELEMENT (mp3parse), mp3parse->sinkpad); + + mp3parse->srcpad = +- gst_pad_new_from_template (gst_static_pad_template_get +- (&mp3_src_template), "src"); ++ gst_pad_new_from_static_template (&mp3_src_template, "src"); + gst_pad_use_fixed_caps (mp3parse->srcpad); + gst_pad_set_event_function (mp3parse->srcpad, mp3parse_src_event); + gst_pad_set_query_function (mp3parse->srcpad, mp3parse_src_query); +@@ -307,6 +300,7 @@ + gst_element_add_pad (GST_ELEMENT (mp3parse), mp3parse->srcpad); + + mp3parse->adapter = gst_adapter_new (); ++ mp3parse->pending_accurate_seeks_lock = g_mutex_new (); + + gst_mp3parse_reset (mp3parse); + } +@@ -316,10 +310,14 @@ + { + GstMPEGAudioParse *mp3parse = GST_MP3PARSE (object); + ++ gst_mp3parse_reset (mp3parse); ++ + if (mp3parse->adapter) { + g_object_unref (mp3parse->adapter); + mp3parse->adapter = NULL; + } ++ g_mutex_free (mp3parse->pending_accurate_seeks_lock); ++ mp3parse->pending_accurate_seeks_lock = NULL; + + G_OBJECT_CLASS (parent_class)->dispose (object); + } +@@ -329,6 +327,7 @@ + { + gboolean res; + GstMPEGAudioParse *mp3parse; ++ GstEvent **eventp; + + mp3parse = GST_MP3PARSE (gst_pad_get_parent (pad)); + +@@ -343,6 +342,64 @@ + gst_event_parse_new_segment_full (event, &update, &rate, &applied_rate, + &format, &start, &stop, &pos); + ++ g_mutex_lock (mp3parse->pending_accurate_seeks_lock); ++ if (format == GST_FORMAT_BYTES && mp3parse->pending_accurate_seeks) { ++ MPEGAudioPendingAccurateSeek *seek = NULL; ++ GSList *node; ++ ++ for (node = mp3parse->pending_accurate_seeks; node; node = node->next) { ++ MPEGAudioPendingAccurateSeek *tmp = node->data; ++ ++ if (tmp->upstream_start == pos) { ++ seek = tmp; ++ break; ++ } ++ } ++ if (seek) { ++ GstSegment *s = &seek->segment; ++ ++ event = ++ gst_event_new_new_segment_full (FALSE, s->rate, s->applied_rate, ++ GST_FORMAT_TIME, s->start, s->stop, s->last_stop); ++ ++ mp3parse->segment = seek->segment; ++ ++ mp3parse->resyncing = FALSE; ++ mp3parse->cur_offset = pos; ++ mp3parse->next_ts = seek->timestamp_start; ++ mp3parse->pending_ts = GST_CLOCK_TIME_NONE; ++ mp3parse->tracked_offset = 0; ++ ++ gst_event_parse_new_segment_full (event, &update, &rate, ++ &applied_rate, &format, &start, &stop, &pos); ++ ++ GST_DEBUG_OBJECT (mp3parse, ++ "Pushing accurate newseg rate %g, applied rate %g, " ++ "format %d, start %lld, stop %lld, pos %lld\n", rate, ++ applied_rate, format, start, stop, pos); ++ ++ g_free (seek); ++ mp3parse->pending_accurate_seeks = ++ g_slist_delete_link (mp3parse->pending_accurate_seeks, node); ++ ++ g_mutex_unlock (mp3parse->pending_accurate_seeks_lock); ++ if (s->flags & GST_SEEK_FLAG_SEGMENT) { ++ gst_element_post_message (GST_ELEMENT_CAST (mp3parse), ++ gst_message_new_segment_start (GST_OBJECT_CAST (mp3parse), ++ s->format, s->last_stop)); ++ } ++ res = gst_pad_push_event (mp3parse->srcpad, event); ++ ++ return res; ++ } else { ++ GST_WARNING_OBJECT (mp3parse, ++ "Accurate seek not possible, didn't get an appropiate upstream segment"); ++ } ++ } ++ g_mutex_unlock (mp3parse->pending_accurate_seeks_lock); ++ ++ mp3parse->exact_position = FALSE; ++ + if (format == GST_FORMAT_BYTES) { + GstClockTime seg_start, seg_stop, seg_pos; + +@@ -356,8 +413,9 @@ + GST_FORMAT_TIME, seg_start, seg_stop, seg_pos); + format = GST_FORMAT_TIME; + GST_DEBUG_OBJECT (mp3parse, "Converted incoming segment to TIME. " +- "start = %" G_GINT64_FORMAT ", stop = %" G_GINT64_FORMAT +- "pos = %" G_GINT64_FORMAT, seg_start, seg_stop, seg_pos); ++ "start = %" GST_TIME_FORMAT ", stop = %" GST_TIME_FORMAT ++ ", pos = %" GST_TIME_FORMAT, GST_TIME_ARGS (seg_start), ++ GST_TIME_ARGS (seg_stop), GST_TIME_ARGS (seg_pos)); + } + } + +@@ -379,12 +437,22 @@ + GST_DEBUG_OBJECT (mp3parse, "Pushing newseg rate %g, applied rate %g, " + "format %d, start %lld, stop %lld, pos %lld\n", + rate, applied_rate, format, start, stop, pos); +- res = gst_pad_push_event (mp3parse->srcpad, event); ++ ++ gst_segment_set_newsegment_full (&mp3parse->segment, update, rate, ++ applied_rate, format, start, stop, pos); ++ ++ /* save the segment for later, right before we push a new buffer so that ++ * the caps are fixed and the next linked element can receive the segment. */ ++ eventp = &mp3parse->pending_segment; ++ gst_event_replace (eventp, event); ++ res = TRUE; + break; + } + case GST_EVENT_FLUSH_STOP: + /* Clear our adapter and set up for a new position */ + gst_adapter_clear (mp3parse->adapter); ++ eventp = &mp3parse->pending_segment; ++ gst_event_replace (eventp, NULL); + res = gst_pad_push_event (mp3parse->srcpad, event); + break; + default: +@@ -397,14 +465,26 @@ + return res; + } + ++static MPEGAudioSeekEntry * ++mp3parse_seek_table_last_entry (GstMPEGAudioParse * mp3parse) ++{ ++ MPEGAudioSeekEntry *ret = NULL; ++ ++ if (mp3parse->seek_table) { ++ ret = mp3parse->seek_table->data; ++ } ++ ++ return ret; ++} ++ + /* Prepare a buffer of the indicated size, timestamp it and output */ + static GstFlowReturn + gst_mp3parse_emit_frame (GstMPEGAudioParse * mp3parse, guint size) + { + GstBuffer *outbuf; + guint bitrate; +- +- GST_DEBUG_OBJECT (mp3parse, "pushing buffer of %d bytes", size); ++ GstFlowReturn ret = GST_FLOW_OK; ++ GstClockTime push_start; + + outbuf = gst_adapter_take_buffer (mp3parse->adapter, size); + +@@ -456,6 +536,22 @@ + } + } + ++ if (GST_BUFFER_TIMESTAMP (outbuf) == 0) ++ mp3parse->exact_position = TRUE; ++ ++ if (mp3parse->exact_position && (!mp3parse->seek_table || ++ (mp3parse_seek_table_last_entry (mp3parse))->byte < ++ GST_BUFFER_OFFSET (outbuf))) { ++ MPEGAudioSeekEntry *entry = g_new0 (MPEGAudioSeekEntry, 1); ++ ++ entry->byte = mp3parse->cur_offset; ++ entry->timestamp = GST_BUFFER_TIMESTAMP (outbuf); ++ mp3parse->seek_table = g_list_prepend (mp3parse->seek_table, entry); ++ GST_DEBUG_OBJECT (mp3parse, "Adding index entry %" GST_TIME_FORMAT ++ " @ offset 0x%08" G_GINT64_MODIFIER "x", ++ GST_TIME_ARGS (entry->timestamp), entry->byte); ++ } ++ + /* Update our byte offset tracking */ + if (mp3parse->cur_offset != -1) { + mp3parse->cur_offset += size; +@@ -483,7 +579,52 @@ + mp3parse->srcpad, taglist); + } + +- return gst_pad_push (mp3parse->srcpad, outbuf); ++ /* We start pushing 9 frames earlier (29 frames for MPEG2) than ++ * segment start to be able to decode the first frame we want. ++ * 9 (29) frames are the theoretical maximum of frames that contain ++ * data for the current frame (bit reservoir). ++ */ ++ ++ if (mp3parse->segment.start == 0) { ++ push_start = 0; ++ } else if (GST_CLOCK_TIME_IS_VALID (mp3parse->max_bitreservoir)) { ++ if (mp3parse->segment.start > mp3parse->max_bitreservoir) ++ push_start = mp3parse->segment.start - mp3parse->max_bitreservoir; ++ else ++ push_start = 0; ++ } else { ++ push_start = mp3parse->segment.start; ++ } ++ ++ if (G_UNLIKELY ((GST_CLOCK_TIME_IS_VALID (push_start) && ++ GST_BUFFER_TIMESTAMP (outbuf) + GST_BUFFER_DURATION (outbuf) ++ < push_start) ++ || (GST_CLOCK_TIME_IS_VALID (mp3parse->segment.stop) ++ && GST_BUFFER_TIMESTAMP (outbuf) >= mp3parse->segment.stop))) { ++ GST_DEBUG_OBJECT (mp3parse, ++ "Buffer outside of configured segment range %" GST_TIME_FORMAT ++ " to %" GST_TIME_FORMAT ", dropping, timestamp %" ++ GST_TIME_FORMAT ", offset 0x%08" G_GINT64_MODIFIER "x", ++ GST_TIME_ARGS (push_start), GST_TIME_ARGS (mp3parse->segment.stop), ++ GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (outbuf)), ++ GST_BUFFER_OFFSET (outbuf)); ++ gst_buffer_unref (outbuf); ++ ret = GST_FLOW_OK; ++ } else { ++ GST_DEBUG_OBJECT (mp3parse, ++ "pushing buffer of %d bytes, timestamp %" GST_TIME_FORMAT ++ ", offset 0x%08" G_GINT64_MODIFIER "x", size, ++ GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (outbuf)), ++ GST_BUFFER_OFFSET (outbuf)); ++ mp3parse->segment.last_stop = GST_BUFFER_TIMESTAMP (outbuf); ++ /* push any pending segment now */ ++ if (mp3parse->pending_segment) ++ gst_pad_push_event (mp3parse->srcpad, mp3parse->pending_segment); ++ mp3parse->pending_segment = NULL; ++ ret = gst_pad_push (mp3parse->srcpad, outbuf); ++ } ++ ++ return ret; + } + + #define XING_FRAMES_FLAG 0x0001 +@@ -610,14 +751,41 @@ + mp3parse->xing_bytes = 0; + + if (xing_flags & XING_TOC_FLAG) { +- gint i; ++ int i, percent = 0; ++ guchar *table = mp3parse->xing_seek_table; ++ ++ /* xing seek table: percent time -> 1/256 bytepos */ ++ memcpy (mp3parse->xing_seek_table, data, 100); + +- for (i = 0; i < 100; i++) { +- mp3parse->xing_seek_table[i] = data[0]; +- data++; ++ /* build inverse table: 1/256 bytepos -> 1/100 percent time */ ++ for (i = 0; i < 256; i++) { ++ while (percent < 99 && table[percent + 1] <= i) ++ percent++; ++ ++ if (table[percent] == i) { ++ mp3parse->xing_seek_table_inverse[i] = percent * 100; ++ } else if (table[percent] < i && percent < 99) { ++ gdouble fa, fb, fx; ++ gint a = percent, b = percent + 1; ++ ++ fa = table[a]; ++ fb = table[b]; ++ fx = (b - a) / (fb - fa) * (i - fa) + a; ++ mp3parse->xing_seek_table_inverse[i] = (guint16) (fx * 100); ++ } else if (percent == 98 && table[percent + 1] <= i) { ++ gdouble fa, fb, fx; ++ gint a = percent + 1, b = 100; ++ ++ fa = table[a]; ++ fb = 256.0; ++ fx = (b - a) / (fb - fa) * (i - fa) + a; ++ mp3parse->xing_seek_table_inverse[i] = (guint16) (fx * 100); ++ } + } ++ data += 100; + } else { + memset (mp3parse->xing_seek_table, 0, 100); ++ memset (mp3parse->xing_seek_table_inverse, 0, 256); + } + + if (xing_flags & XING_VBR_SCALE_FLAG) { +@@ -777,6 +945,9 @@ + mp3parse->spf = 1152; + } + ++ mp3parse->max_bitreservoir = gst_util_uint64_scale (GST_SECOND, ++ ((version == 1) ? 10 : 30) * mp3parse->spf, mp3parse->rate); ++ + /* Check the first frame for a Xing header to get our total length */ + if (mp3parse->frame_count == 0) { + /* For the first frame in the file, look for a Xing frame after +@@ -930,6 +1101,45 @@ + return result; + } + ++static gboolean ++mp3parse_total_bytes (GstMPEGAudioParse * mp3parse, gint64 * total) ++{ ++ GstFormat fmt = GST_FORMAT_BYTES; ++ ++ if (gst_pad_query_peer_duration (mp3parse->sinkpad, &fmt, total)) ++ return TRUE; ++ ++ if (mp3parse->xing_flags & XING_BYTES_FLAG) { ++ *total = mp3parse->xing_bytes; ++ return TRUE; ++ } ++ ++ return FALSE; ++} ++ ++static gboolean ++mp3parse_total_time (GstMPEGAudioParse * mp3parse, GstClockTime * total) ++{ ++ gint64 total_bytes; ++ ++ *total = GST_CLOCK_TIME_NONE; ++ ++ if (mp3parse->xing_flags & XING_FRAMES_FLAG) { ++ *total = mp3parse->xing_total_time; ++ return TRUE; ++ } ++ ++ /* Calculate time from the measured bitrate */ ++ if (!mp3parse_total_bytes (mp3parse, &total_bytes)) ++ return FALSE; ++ ++ if (total_bytes != -1 ++ && !mp3parse_bytepos_to_time (mp3parse, total_bytes, total)) ++ return FALSE; ++ ++ return TRUE; ++} ++ + /* Convert a timestamp to the file position required to start decoding that + * timestamp. For now, this just uses the avg bitrate. Later, use an + * incrementally accumulated seek table */ +@@ -937,12 +1147,38 @@ + mp3parse_time_to_bytepos (GstMPEGAudioParse * mp3parse, GstClockTime ts, + gint64 * bytepos) + { ++ gint64 total_bytes; ++ GstClockTime total_time; ++ + /* -1 always maps to -1 */ + if (ts == -1) { + *bytepos = -1; + return TRUE; + } + ++ /* If XING seek table exists use this for time->byte conversion */ ++ if ((mp3parse->xing_flags & XING_TOC_FLAG) && ++ mp3parse_total_bytes (mp3parse, &total_bytes) && ++ mp3parse_total_time (mp3parse, &total_time)) { ++ gdouble fa, fb, fx; ++ gdouble percent = ++ CLAMP ((100.0 * gst_util_guint64_to_gdouble (ts)) / ++ gst_util_guint64_to_gdouble (total_time), 0.0, 100.0); ++ gint index = CLAMP (percent, 0, 99); ++ ++ fa = mp3parse->xing_seek_table[index]; ++ if (index < 99) ++ fb = mp3parse->xing_seek_table[index + 1]; ++ else ++ fb = 256.0; ++ ++ fx = fa + (fb - fa) * (percent - index); ++ ++ *bytepos = (1.0 / 256.0) * fx * total_bytes; ++ ++ return TRUE; ++ } ++ + if (mp3parse->avg_bitrate == 0) + goto no_bitrate; + +@@ -958,6 +1194,9 @@ + mp3parse_bytepos_to_time (GstMPEGAudioParse * mp3parse, + gint64 bytepos, GstClockTime * ts) + { ++ gint64 total_bytes; ++ GstClockTime total_time; ++ + if (bytepos == -1) { + *ts = GST_CLOCK_TIME_NONE; + return TRUE; +@@ -968,61 +1207,33 @@ + return TRUE; + } + +- /* Cannot convert anything except 0 if we don't have a bitrate yet */ +- if (mp3parse->avg_bitrate == 0) +- return FALSE; +- +- *ts = (GstClockTime) gst_util_uint64_scale (GST_SECOND, bytepos * 8, +- mp3parse->avg_bitrate); +- return TRUE; +-} +- +-static gboolean +-mp3parse_total_bytes (GstMPEGAudioParse * mp3parse, gint64 * total) +-{ +- GstQuery *query; +- GstPad *peer; +- +- if ((peer = gst_pad_get_peer (mp3parse->sinkpad)) != NULL) { +- 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); +- gst_query_parse_duration (query, NULL, total); +- return TRUE; +- } +- gst_object_unref (peer); +- } +- +- if (mp3parse->xing_flags & XING_BYTES_FLAG) { +- *total = mp3parse->xing_bytes; +- return TRUE; +- } +- +- return FALSE; +-} ++ /* If XING seek table exists use this for byte->time conversion */ ++ if ((mp3parse->xing_flags & XING_TOC_FLAG) && ++ mp3parse_total_bytes (mp3parse, &total_bytes) && ++ mp3parse_total_time (mp3parse, &total_time)) { ++ gdouble fa, fb, fx; ++ gdouble pos = CLAMP ((bytepos * 256.0) / total_bytes, 0.0, 256.0); ++ gint index = CLAMP (pos, 0, 255); ++ ++ fa = mp3parse->xing_seek_table_inverse[index]; ++ if (index < 255) ++ fb = mp3parse->xing_seek_table_inverse[index + 1]; ++ else ++ fb = 10000.0; + +-static gboolean +-mp3parse_total_time (GstMPEGAudioParse * mp3parse, GstClockTime * total) +-{ +- gint64 total_bytes; ++ fx = fa + (fb - fa) * (pos - index); + +- *total = GST_CLOCK_TIME_NONE; ++ *ts = (1.0 / 10000.0) * fx * gst_util_guint64_to_gdouble (total_time); + +- if (mp3parse->xing_flags & XING_FRAMES_FLAG) { +- *total = mp3parse->xing_total_time; + return TRUE; + } + +- /* Calculate time from the measured bitrate */ +- if (!mp3parse_total_bytes (mp3parse, &total_bytes)) +- return FALSE; +- +- if (total_bytes != -1 +- && !mp3parse_bytepos_to_time (mp3parse, total_bytes, total)) ++ /* Cannot convert anything except 0 if we don't have a bitrate yet */ ++ if (mp3parse->avg_bitrate == 0) + return FALSE; + ++ *ts = (GstClockTime) gst_util_uint64_scale (GST_SECOND, bytepos * 8, ++ mp3parse->avg_bitrate); + return TRUE; + } + +@@ -1036,11 +1247,12 @@ + gint64 cur, stop; + gint64 byte_cur, byte_stop; + +- /* FIXME: Use GstSegment for tracking our position */ +- + gst_event_parse_seek (event, &rate, &format, &flags, &cur_type, &cur, + &stop_type, &stop); + ++ GST_DEBUG_OBJECT (mp3parse, "Performing seek to %" GST_TIME_FORMAT, ++ GST_TIME_ARGS (cur)); ++ + /* For any format other than TIME, see if upstream handles + * it directly or fail. For TIME, try upstream, but do it ourselves if + * it fails upstream */ +@@ -1055,6 +1267,90 @@ + + /* Handle TIME based seeks by converting to a BYTE position */ + ++ /* For accurate seeking get the frame 9 (MPEG1) or 29 (MPEG2) frames ++ * before the one we want to seek to and push them all to the decoder. ++ * ++ * This is necessary because of the bit reservoir. See ++ * http://www.mars.org/mailman/public/mad-dev/2002-May/000634.html ++ * ++ */ ++ ++ if (flags & GST_SEEK_FLAG_ACCURATE) { ++ MPEGAudioPendingAccurateSeek *seek = ++ g_new0 (MPEGAudioPendingAccurateSeek, 1); ++ GstClockTime start; ++ ++ seek->segment = mp3parse->segment; ++ ++ gst_segment_set_seek (&seek->segment, rate, GST_FORMAT_TIME, ++ flags, cur_type, cur, stop_type, stop, NULL); ++ ++ if (!mp3parse->seek_table) { ++ byte_cur = 0; ++ byte_stop = -1; ++ start = 0; ++ } else { ++ MPEGAudioSeekEntry *entry = NULL, *start_entry = NULL, *stop_entry = NULL; ++ GList *start_node, *stop_node; ++ ++ for (start_node = mp3parse->seek_table; start_node; ++ start_node = start_node->next) { ++ entry = start_node->data; ++ ++ if (cur - mp3parse->max_bitreservoir >= entry->timestamp) { ++ start_entry = entry; ++ break; ++ } ++ } ++ ++ if (!start_entry) { ++ start_entry = mp3parse->seek_table->data; ++ start = start_entry->timestamp; ++ byte_cur = start_entry->byte; ++ } else { ++ start = start_entry->timestamp; ++ byte_cur = start_entry->byte; ++ } ++ ++ for (stop_node = mp3parse->seek_table; stop_node; ++ stop_node = stop_node->next) { ++ entry = stop_node->data; ++ ++ if (stop >= entry->timestamp) { ++ stop_node = stop_node->prev; ++ stop_entry = (stop_node) ? stop_node->data : NULL; ++ break; ++ } ++ } ++ ++ if (!stop_entry) { ++ byte_stop = -1; ++ } else { ++ byte_stop = stop_entry->byte; ++ } ++ ++ } ++ g_mutex_lock (mp3parse->pending_accurate_seeks_lock); ++ event = gst_event_new_seek (rate, GST_FORMAT_BYTES, flags, cur_type, ++ byte_cur, stop_type, byte_stop); ++ if (gst_pad_push_event (mp3parse->sinkpad, event)) { ++ mp3parse->exact_position = TRUE; ++ seek->upstream_start = byte_cur; ++ seek->timestamp_start = start; ++ mp3parse->pending_accurate_seeks = ++ g_slist_prepend (mp3parse->pending_accurate_seeks, seek); ++ g_mutex_unlock (mp3parse->pending_accurate_seeks_lock); ++ return TRUE; ++ } else { ++ g_mutex_unlock (mp3parse->pending_accurate_seeks_lock); ++ mp3parse->exact_position = TRUE; ++ g_free (seek); ++ return TRUE; ++ } ++ } ++ ++ mp3parse->exact_position = FALSE; ++ + /* Convert the TIME to the appropriate BYTE position at which to resume + * decoding. */ + if (!mp3parse_time_to_bytepos (mp3parse, (GstClockTime) cur, &byte_cur)) +@@ -1069,6 +1365,11 @@ + event = gst_event_new_seek (rate, GST_FORMAT_BYTES, flags, cur_type, + byte_cur, stop_type, byte_stop); + ++ if (flags & GST_SEEK_FLAG_SEGMENT) { ++ gst_element_post_message (GST_ELEMENT_CAST (mp3parse), ++ gst_message_new_segment_start (GST_OBJECT_CAST (mp3parse), ++ GST_FORMAT_TIME, cur)); ++ } + return gst_pad_push_event (mp3parse->sinkpad, event); + no_pos: + GST_DEBUG_OBJECT (mp3parse, +Index: gst/mpegaudioparse/gstmpegaudioparse.h +=================================================================== +RCS file: /cvs/gstreamer/gst-plugins-ugly/gst/mpegaudioparse/gstmpegaudioparse.h,v +retrieving revision 1.16 +retrieving revision 1.20 +diff -u -r1.16 -r1.20 +--- gst/mpegaudioparse/gstmpegaudioparse.h 8 Jun 2007 08:39:43 -0000 1.16 ++++ gst/mpegaudioparse/gstmpegaudioparse.h 16 Aug 2007 11:52:57 -0000 1.20 +@@ -40,13 +40,29 @@ + + typedef struct _GstMPEGAudioParse GstMPEGAudioParse; + typedef struct _GstMPEGAudioParseClass GstMPEGAudioParseClass; ++typedef struct _MPEGAudioSeekEntry MPEGAudioSeekEntry; ++typedef struct _MPEGAudioPendingAccurateSeek MPEGAudioPendingAccurateSeek; ++ ++ ++struct _MPEGAudioSeekEntry { ++ gint64 byte; ++ GstClockTime timestamp; ++}; ++ ++struct _MPEGAudioPendingAccurateSeek { ++ GstSegment segment; ++ gint64 upstream_start; ++ GstClockTime timestamp_start; ++}; + + struct _GstMPEGAudioParse { + GstElement element; + + GstPad *sinkpad, *srcpad; + ++ GstSegment segment; + GstClockTime next_ts; ++ + /* Offset as supplied by incoming buffers */ + gint64 cur_offset; + +@@ -62,6 +78,7 @@ + guint skip; /* number of frames to skip */ + guint bit_rate; /* in kbps */ + gint channels, rate, layer, version; ++ GstClockTime max_bitreservoir; + gint spf; /* Samples per frame */ + + gboolean resyncing; /* True when attempting to resync (stricter checks are +@@ -79,9 +96,21 @@ + guint32 xing_frames; + GstClockTime xing_total_time; + guint32 xing_bytes; ++ /* percent -> filepos mapping */ + guchar xing_seek_table[100]; ++ /* filepos -> percent mapping */ ++ guint16 xing_seek_table_inverse[256]; + guint32 xing_vbr_scale; + guint xing_bitrate; ++ ++ /* Accurate seeking */ ++ GList *seek_table; ++ GMutex *pending_accurate_seeks_lock; ++ GSList *pending_accurate_seeks; ++ gboolean exact_position; ++ ++ /* pending segment */ ++ GstEvent *pending_segment; + }; + + struct _GstMPEGAudioParseClass { diff --git a/media-libs/gst-plugins-ugly/gst-plugins-ugly-0.10.6-r1.ebuild b/media-libs/gst-plugins-ugly/gst-plugins-ugly-0.10.6-r1.ebuild new file mode 100644 index 000000000000..f934289b3ee6 --- /dev/null +++ b/media-libs/gst-plugins-ugly/gst-plugins-ugly-0.10.6-r1.ebuild @@ -0,0 +1,64 @@ +# Copyright 1999-2007 Gentoo Foundation +# Distributed under the terms of the GNU General Public License v2 +# $Header: /var/cvsroot/gentoo-x86/media-libs/gst-plugins-ugly/gst-plugins-ugly-0.10.6-r1.ebuild,v 1.1 2007/11/18 20:19:25 drac Exp $ + +# order is important, gnome2 after gst-plugins +inherit gst-plugins-ugly gst-plugins10 gnome2 eutils flag-o-matic libtool + +DESCRIPTION="Basepack of plugins for gstreamer" +HOMEPAGE="http://gstreamer.sourceforge.net" +SRC_URI="http://gstreamer.freedesktop.org/src/${PN}/${P}.tar.bz2" + +LICENSE="GPL-2" +KEYWORDS="~alpha ~amd64 ~arm ~hppa ~ia64 ~ppc ~ppc64 ~sh ~sparc ~x86 ~x86-fbsd" + +RDEPEND=">=media-libs/gst-plugins-base-0.10.15 + >=media-libs/gstreamer-0.10.15 + >=dev-libs/liboil-0.3 + >=dev-libs/glib-2.6" +DEPEND="${RDEPEND} + >=sys-devel/gettext-0.11.5 + >=dev-util/pkgconfig-0.9" + +GST_PLUGINS_BUILD="" + +src_unpack() { + unpack ${A} + cd "${S}" + epatch "${FILESDIR}"/${P}-mpegaudioparse-cvs20071117.patch +} + +src_compile() { + elibtoolize + + # gst doesnt handle optimisations well + strip-flags + replace-flags "-O3" "-O2" + filter-flags "-fprefetch-loop-arrays" # see bug 22249 + + gst-plugins-ugly_src_configure + + emake || die "emake failed." +} + +# override eclass +src_install() { + gnome2_src_install +} + +DOCS="AUTHORS README RELEASE" + +pkg_postinst () { + gnome2_pkg_postinst + + elog "The Gstreamer plugins setup has changed quite a bit on Gentoo," + elog "applications now should provide the basic plugins needed." + elog "" + elog "The new seperate plugins are all named 'gst-plugins-<plugin>'." + elog "To get a listing of currently available plugins execute 'emerge -s gst-plugins-'." + elog "In most cases it shouldn't be needed though to emerge extra plugins." +} + +pkg_postrm() { + gnome2_pkg_postrm +} |