diff --git a/common b/common index 9e5bbd5085..69b981f10c 160000 --- a/common +++ b/common @@ -1 +1 @@ -Subproject commit 9e5bbd508588961696e70c38e764492e0312ec4c +Subproject commit 69b981f10caa234ad0ff639179d0fda8505bd94b diff --git a/docs/plugins/gst-plugins-base-plugins.args b/docs/plugins/gst-plugins-base-plugins.args index 04f3a63980..ffb6e3fa81 100644 --- a/docs/plugins/gst-plugins-base-plugins.args +++ b/docs/plugins/gst-plugins-base-plugins.args @@ -711,7 +711,7 @@ GstMultiFdSink::buffers-max gint ->= G_MAXULONG +>= -1 rw Buffers max max number of buffers to queue for a client (-1 = no limit). @@ -731,7 +731,7 @@ GstMultiFdSink::buffers-soft-max gint ->= G_MAXULONG +>= -1 rw Buffers soft max Recover client when going over this limit (-1 = no limit). @@ -821,7 +821,7 @@ GstMultiFdSink::buffers-min gint ->= G_MAXULONG +>= -1 rw Buffers min min number of buffers to queue (-1 = as few as possible). @@ -851,7 +851,7 @@ GstMultiFdSink::bytes-min gint ->= G_MAXULONG +>= -1 rw Bytes min min number of bytes to queue (-1 = as little as possible). @@ -861,7 +861,7 @@ GstMultiFdSink::time-min gint64 ->= G_MAXULONG +>= -1 rw Time min min number of time to queue (-1 = as little as possible). @@ -881,7 +881,7 @@ GstMultiFdSink::units-max gint64 ->= G_MAXULONG +>= -1 rw Units max max number of units to queue (-1 = no limit). @@ -891,7 +891,7 @@ GstMultiFdSink::units-soft-max gint64 ->= G_MAXULONG +>= -1 rw Units soft max Recover client when going over this limit (-1 = no limit). @@ -901,7 +901,7 @@ GstMultiFdSink::qos-dscp gint -[G_MAXULONG,63] +[-1,63] rw QoS diff srv code point Quality of Service, differentiated services code point (-1 default). @@ -1081,7 +1081,7 @@ GstVorbisEnc::bitrate gint -[G_MAXULONG,250001] +[-1,250001] rw Target Bitrate Attempt to encode at a bitrate averaging this (in bps). This uses the bitrate management engine, and is not recommended for most users. Quality is a better alternative. (-1 == disabled). @@ -1111,7 +1111,7 @@ GstVorbisEnc::max-bitrate gint -[G_MAXULONG,250001] +[-1,250001] rw Maximum Bitrate Specify a maximum bitrate (in bps). Useful for streaming applications. (-1 == disabled). @@ -1121,7 +1121,7 @@ GstVorbisEnc::min-bitrate gint -[G_MAXULONG,250001] +[-1,250001] rw Minimum Bitrate Specify a minimum bitrate (in bps). Useful for encoding for a fixed-size channel. (-1 == disabled). @@ -1678,6 +1678,26 @@ FALSE + +GstVideoRate::average-period +guint64 +<= G_MAXINT64 +rw +Period over which to average +Period over which to average the framerate (in ns) (0 = disabled). +0 + + + +GstVideoRate::drop-only +gboolean + +rw +Only Drop +Only drop frames, no duplicates are produced. +FALSE + + GstAudioRate::add guint64 @@ -2201,7 +2221,7 @@ GstCdParanoiaSrc::read-speed gint ->= G_MAXULONG +>= -1 rw Read speed Read from device at specified speed. @@ -2211,7 +2231,7 @@ GstCdParanoiaSrc::search-overlap gint -[G_MAXULONG,75] +[-1,75] rw Search overlap Force minimum overlap search during verification to n sectors. @@ -2221,7 +2241,7 @@ GstCdParanoiaSrc::cache-size gint ->= G_MAXULONG +>= -1 rw Cache size Set CD cache size to n sectors (-1 = auto). @@ -2451,7 +2471,7 @@ GstURIDecodeBin::buffer-duration gint64 ->= G_MAXULONG +>= -1 rw Buffer duration (ns) Buffer duration when buffering streams (-1 default value). @@ -2461,7 +2481,7 @@ GstURIDecodeBin::buffer-size gint ->= G_MAXULONG +>= -1 rw Buffer size (bytes) Buffer size when buffering streams (-1 default value). @@ -2501,7 +2521,7 @@ GstURIDecodeBin::ring-buffer-max-size guint64 -<= G_MAXUINT +<= G_MAXULONG rw Max. ring buffer size (bytes) Max. amount of data in the ring buffer (bytes, 0 = ring buffer disabled). @@ -2671,7 +2691,7 @@ GstPlayBin2::current-audio gint ->= G_MAXULONG +>= -1 rw Current audio Currently playing audio stream (-1 = auto). @@ -2681,7 +2701,7 @@ GstPlayBin2::current-text gint ->= G_MAXULONG +>= -1 rw Current Text Currently playing text stream (-1 = auto). @@ -2691,7 +2711,7 @@ GstPlayBin2::current-video gint ->= G_MAXULONG +>= -1 rw Current Video Currently playing video stream (-1 = auto). @@ -2841,7 +2861,7 @@ GstPlayBin2::buffer-duration gint64 ->= G_MAXULONG +>= -1 rw Buffer duration (ns) Buffer duration when buffering network streams. @@ -2851,7 +2871,7 @@ GstPlayBin2::buffer-size gint ->= G_MAXULONG +>= -1 rw Buffer size (bytes) Buffer size when buffering network streams. @@ -2891,7 +2911,7 @@ GstPlayBin2::ring-buffer-max-size guint64 -<= G_MAXUINT +<= G_MAXULONG rw Max. ring buffer size (bytes) Max. amount of data in the ring buffer (bytes, 0 = ring buffer disabled). @@ -3231,7 +3251,7 @@ GstAppSrc::max-latency gint64 ->= G_MAXULONG +>= -1 rw Max Latency The maximum latency (-1 = unlimited). @@ -3241,7 +3261,7 @@ GstAppSrc::min-latency gint64 ->= G_MAXULONG +>= -1 rw Min Latency The minimum latency (-1 = default). @@ -3251,7 +3271,7 @@ GstAppSrc::size gint64 ->= G_MAXULONG +>= -1 rw Size The size of the data stream in bytes (-1 if unknown). diff --git a/gst-libs/gst/tag/lang.c b/gst-libs/gst/tag/lang.c index 3520383125..a0838fe1ef 100644 --- a/gst-libs/gst/tag/lang.c +++ b/gst-libs/gst/tag/lang.c @@ -411,7 +411,7 @@ gst_tag_get_language_code_iso_639_2X (const gchar * lang_code, guint8 flags) } else if (i > 0 && (iso_639_codes[i - 1].flags & flags) == flags && iso_639_codes[i].name_offset == iso_639_codes[i - 1].name_offset) { return iso_639_codes[i - 1].iso_639_2; - } else if (i < G_N_ELEMENTS (iso_639_codes) && + } else if ((i + 1) < G_N_ELEMENTS (iso_639_codes) && (iso_639_codes[i + 1].flags & flags) == flags && iso_639_codes[i].name_offset == iso_639_codes[i + 1].name_offset) { return iso_639_codes[i + 1].iso_639_2; diff --git a/gst-plugins-base.spec.in b/gst-plugins-base.spec.in index 7017af8e2f..097ea3c0b8 100644 --- a/gst-plugins-base.spec.in +++ b/gst-plugins-base.spec.in @@ -223,7 +223,7 @@ GStreamer Plugins Base library development and header files. %{_includedir}/gstreamer-%{majorminor}/gst/pbutils/gstdiscoverer.h %{_includedir}/gstreamer-%{majorminor}/gst/pbutils/gstpluginsbaseversion.h %{_includedir}/gstreamer-%{majorminor}/gst/tag/xmpwriter.h - +%{_includedir}/gstreamer-%{majorminor}/gst/audio/gstaudioiec61937.h %{_libdir}/libgstfft-%{majorminor}.so %{_libdir}/libgstrtsp-%{majorminor}.so diff --git a/gst/audioconvert/gstaudioconvert.c b/gst/audioconvert/gstaudioconvert.c index 1fb0cb8a2f..3c7084d9eb 100644 --- a/gst/audioconvert/gstaudioconvert.c +++ b/gst/audioconvert/gstaudioconvert.c @@ -497,15 +497,15 @@ append_with_other_format (GstCaps * caps, GstStructure * s, gboolean isfloat) if (isfloat) { s2 = gst_structure_copy (s); gst_structure_set_name (s2, "audio/x-raw-int"); - s = make_lossless_changes (s2, FALSE); + make_lossless_changes (s2, FALSE); /* If 64 bit float was allowed; remove width 64: we don't support it for * integer*/ - strip_width_64 (s); + strip_width_64 (s2); gst_caps_append_structure (caps, s2); } else { s2 = gst_structure_copy (s); gst_structure_set_name (s2, "audio/x-raw-float"); - s = make_lossless_changes (s2, TRUE); + make_lossless_changes (s2, TRUE); gst_caps_append_structure (caps, s2); } } diff --git a/gst/encoding/gstencodebin.c b/gst/encoding/gstencodebin.c index 6b2355b80a..4d3d7e2558 100644 --- a/gst/encoding/gstencodebin.c +++ b/gst/encoding/gstencodebin.c @@ -110,7 +110,7 @@ * Handling mp3!xing!idv3 and theora!ogg tagsetting scenarios: * Once we have chosen a muxer: * When a new stream is requested: - * If muxer is 'Formatter' OR doesn't have a TagSetter interface: + * If muxer isn't 'Formatter' OR doesn't have a TagSetter interface: * Find a Formatter for the given stream (preferably with TagSetter) * Insert that before muxer **/ @@ -162,6 +162,7 @@ struct _GstEncodeBin /* available muxers, encoders and parsers */ GList *muxers; + GList *formatters; GList *encoders; GList *parsers; @@ -205,6 +206,7 @@ struct _StreamGroup GstElement *parser; GstElement *smartencoder; GstElement *outfilter; /* Output capsfilter (streamprofile.format) */ + GstElement *formatter; GstElement *outqueue; /* Queue just before the muxer */ }; @@ -279,6 +281,9 @@ static void stream_group_remove (GstEncodeBin * ebin, StreamGroup * sgroup); static GstPad *gst_encode_bin_request_pad_signal (GstEncodeBin * encodebin, GstCaps * caps); +static inline GstElement *_get_formatter (GstEncodeBin * ebin, + GstEncodingProfile * sprof); + static void gst_encode_bin_class_init (GstEncodeBinClass * klass) { @@ -388,6 +393,9 @@ gst_encode_bin_dispose (GObject * object) if (ebin->muxers) gst_plugin_feature_list_free (ebin->muxers); + if (ebin->formatters) + gst_plugin_feature_list_free (ebin->formatters); + if (ebin->encoders) gst_plugin_feature_list_free (ebin->encoders); @@ -410,15 +418,14 @@ static void gst_encode_bin_init (GstEncodeBin * encode_bin) { GstPadTemplate *tmpl; - GList *formatters; encode_bin->muxers = gst_element_factory_list_get_elements (GST_ELEMENT_FACTORY_TYPE_MUXER, GST_RANK_MARGINAL); - formatters = + + encode_bin->formatters = gst_element_factory_list_get_elements (GST_ELEMENT_FACTORY_TYPE_FORMATTER, GST_RANK_SECONDARY); - encode_bin->muxers = g_list_concat (encode_bin->muxers, formatters); encode_bin->encoders = gst_element_factory_list_get_elements (GST_ELEMENT_FACTORY_TYPE_ENCODER, @@ -911,6 +918,16 @@ no_template: } } +static gboolean +_has_class (GstElement * element, const gchar * classname) +{ + GstElementClass *klass; + + klass = GST_ELEMENT_GET_CLASS (element); + + return strstr (klass->details.klass, classname) != NULL; +} + /* FIXME : Add handling of streams that don't need encoding */ /* FIXME : Add handling of streams that don't require conversion elements */ /* @@ -966,11 +983,12 @@ _create_stream_group (GstEncodeBin * ebin, GstEncodingProfile * sprof, muxerpad = get_compatible_muxer_sink_pad (ebin, NULL, format); if (G_UNLIKELY (muxerpad == NULL)) goto no_muxer_pad; + } /* Output Queue. * We only use a 1buffer long queue here, the actual queueing will be done - * in the intput queue */ + * in the input queue */ last = sgroup->outqueue = gst_element_factory_make ("queue", NULL); g_object_set (sgroup->outqueue, "max-size-buffers", (guint32) 1, "max-size-bytes", (guint32) 0, "max-size-time", (guint64) 0, NULL); @@ -988,6 +1006,26 @@ _create_stream_group (GstEncodeBin * ebin, GstEncodingProfile * sprof, } gst_object_unref (srcpad); + /* Check if we need a formatter + * If we have no muxer or + * if the muxer isn't a formatter and doesn't implement the tagsetter interface + */ + if (!ebin->muxer + || (!gst_element_implements_interface (ebin->muxer, GST_TYPE_TAG_SETTER) + || !_has_class (ebin->muxer, "Formatter"))) { + sgroup->formatter = _get_formatter (ebin, sprof); + if (sgroup->formatter) { + GST_DEBUG ("Adding formatter for %" GST_PTR_FORMAT, format); + + gst_bin_add (GST_BIN (ebin), sgroup->formatter); + tosync = g_list_append (tosync, sgroup->formatter); + if (G_UNLIKELY (!fast_element_link (sgroup->formatter, last))) + goto formatter_link_failure; + last = sgroup->formatter; + } + } + + /* Output capsfilter * This will receive the format caps from the streamprofile */ GST_DEBUG ("Adding output capsfilter for %" GST_PTR_FORMAT, format); @@ -1337,10 +1375,15 @@ muxer_link_failure: GST_ERROR_OBJECT (ebin, "Couldn't link encoder to muxer"); goto cleanup; -outfilter_link_failure: +formatter_link_failure: GST_ERROR_OBJECT (ebin, "Couldn't link output filter to output queue"); goto cleanup; +outfilter_link_failure: + GST_ERROR_OBJECT (ebin, + "Couldn't link output filter to output queue/formatter"); + goto cleanup; + passthrough_link_failure: GST_ERROR_OBJECT (ebin, "Failed linking splitter in passthrough mode"); goto cleanup; @@ -1404,10 +1447,49 @@ _factory_can_sink_caps (GstElementFactory * factory, const GstCaps * caps) return FALSE; } +static inline GstElement * +_get_formatter (GstEncodeBin * ebin, GstEncodingProfile * sprof) +{ + GList *formatters, *tmpfmtr; + GstElement *formatter = NULL; + GstElementFactory *formatterfact = NULL; + const GstCaps *format; + const gchar *preset; + + format = gst_encoding_profile_get_format (sprof); + preset = gst_encoding_profile_get_preset (sprof); + + GST_DEBUG ("Getting list of formatters for format %" GST_PTR_FORMAT, format); + + formatters = + gst_element_factory_list_filter (ebin->formatters, format, GST_PAD_SRC, + FALSE); + + if (formatters == NULL) + goto beach; + + /* FIXME : signal the user if he wants this */ + for (tmpfmtr = formatters; tmpfmtr; tmpfmtr = tmpfmtr->next) { + formatterfact = (GstElementFactory *) tmpfmtr->data; + + GST_DEBUG_OBJECT (ebin, "Trying formatter %s", + GST_PLUGIN_FEATURE_NAME (formatterfact)); + + if ((formatter = + _create_element_and_set_preset (formatterfact, preset, NULL))) + break; + } + + gst_plugin_feature_list_free (formatters); + +beach: + return formatter; +} + static inline GstElement * _get_muxer (GstEncodeBin * ebin) { - GList *muxers, *tmpmux; + GList *muxers, *formatters, *tmpmux; GstElement *muxer = NULL; GstElementFactory *muxerfact = NULL; const GList *tmp; @@ -1422,6 +1504,12 @@ _get_muxer (GstEncodeBin * ebin) muxers = gst_element_factory_list_filter (ebin->muxers, format, GST_PAD_SRC, TRUE); + formatters = + gst_element_factory_list_filter (ebin->formatters, format, GST_PAD_SRC, + TRUE); + + muxers = g_list_concat (muxers, formatters); + if (muxers == NULL) goto beach; @@ -1604,9 +1692,17 @@ stream_group_free (GstEncodeBin * ebin, StreamGroup * sgroup) if (sgroup->outqueue) gst_element_set_state (sgroup->outqueue, GST_STATE_NULL); - /* Capsfilter - outqueue */ - gst_element_set_state (sgroup->outfilter, GST_STATE_NULL); - gst_element_unlink (sgroup->outfilter, sgroup->outqueue); + if (sgroup->formatter) { + /* capsfilter - formatter - outqueue */ + gst_element_set_state (sgroup->formatter, GST_STATE_NULL); + gst_element_set_state (sgroup->outfilter, GST_STATE_NULL); + gst_element_unlink (sgroup->formatter, sgroup->outqueue); + gst_element_unlink (sgroup->outfilter, sgroup->formatter); + } else { + /* Capsfilter - outqueue */ + gst_element_set_state (sgroup->outfilter, GST_STATE_NULL); + gst_element_unlink (sgroup->outfilter, sgroup->outqueue); + } gst_element_set_state (sgroup->outqueue, GST_STATE_NULL); gst_bin_remove (GST_BIN (ebin), sgroup->outqueue);