From f9c7be96394d68c68a0c9d6cf0eec23971563e34 Mon Sep 17 00:00:00 2001 From: Edward Hervey Date: Tue, 7 Dec 2010 17:35:14 +0100 Subject: [PATCH 001/254] rtsp: Move around the typedefs to make GIR happy Otherwise it will generate they symbols as _GstRTSP* (with the leading underscore). --- gst-libs/gst/rtsp/gstrtsptransport.h | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/gst-libs/gst/rtsp/gstrtsptransport.h b/gst-libs/gst/rtsp/gstrtsptransport.h index 9250b02981..995d753a3f 100644 --- a/gst-libs/gst/rtsp/gstrtsptransport.h +++ b/gst-libs/gst/rtsp/gstrtsptransport.h @@ -96,6 +96,9 @@ typedef enum { #define GST_TYPE_RTSP_LOWER_TRANS (gst_rtsp_lower_trans_get_type()) GType gst_rtsp_lower_trans_get_type (void); +typedef struct _GstRTSPRange GstRTSPRange; +typedef struct _GstRTSPTransport GstRTSPTransport; + /** * GstRTSPRange: * @min: minimum value of the range @@ -103,10 +106,11 @@ GType gst_rtsp_lower_trans_get_type (void); * * A type to specify a range. */ -typedef struct _GstRTSPRange { + +struct _GstRTSPRange { gint min; gint max; -} GstRTSPRange; +}; /** * GstRTSPTransport: @@ -128,7 +132,8 @@ typedef struct _GstRTSPRange { * * A structure holding the RTSP transport values. */ -typedef struct _GstRTSPTransport { + +struct _GstRTSPTransport { GstRTSPTransMode trans; GstRTSPProfile profile; GstRTSPLowerTrans lower_transport; @@ -151,7 +156,7 @@ typedef struct _GstRTSPTransport { /* RTP specific */ guint ssrc; -} GstRTSPTransport; +}; GstRTSPResult gst_rtsp_transport_new (GstRTSPTransport **transport); GstRTSPResult gst_rtsp_transport_init (GstRTSPTransport *transport); From 886ea051e76a69c53ccd5ec1f9625e0a81808092 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Stadler?= Date: Fri, 3 Dec 2010 18:08:58 +0200 Subject: [PATCH 002/254] typefind: fix E-AC-3 frame size parsing Frame size is given in words; it is already multiplied by two where needed, so the left shift is superfluous. This extra multiplication caused the code to inspect the third packet instead of the second, which would fail for files where the second packet has a size different from the first. --- gst/typefind/gsttypefindfunctions.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/gst/typefind/gsttypefindfunctions.c b/gst/typefind/gsttypefindfunctions.c index 030f7afdd5..de843bf0b8 100644 --- a/gst/typefind/gsttypefindfunctions.c +++ b/gst/typefind/gsttypefindfunctions.c @@ -1295,8 +1295,7 @@ ac3_type_find (GstTypeFind * tf, gpointer unused) DataScanCtx c_next = c; guint frame_size; - frame_size = ((((c.data[2] & 0x07) << 8) + - (c.data[3] & 0xff)) + 1) << 1; + frame_size = (((c.data[2] & 0x07) << 8) + (c.data[3] & 0xff)) + 1; GST_LOG ("possible E-AC3 frame sync at offset %" G_GUINT64_FORMAT ", size=%u", c.offset, frame_size); if (data_scan_ctx_ensure_data (tf, &c_next, (frame_size * 2) + 5)) { From cc65ba987a67231b3dcfec90906a2f4687e56778 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Stadler?= Date: Fri, 3 Dec 2010 16:14:15 +0200 Subject: [PATCH 003/254] typefind: stop scanning after suggesting E-AC-3 caps --- gst/typefind/gsttypefindfunctions.c | 1 + 1 file changed, 1 insertion(+) diff --git a/gst/typefind/gsttypefindfunctions.c b/gst/typefind/gsttypefindfunctions.c index de843bf0b8..d8fa5280de 100644 --- a/gst/typefind/gsttypefindfunctions.c +++ b/gst/typefind/gsttypefindfunctions.c @@ -1311,6 +1311,7 @@ ac3_type_find (GstTypeFind * tf, gpointer unused) prob = GST_TYPE_FIND_NEARLY_CERTAIN; gst_type_find_suggest (tf, prob, EAC3_CAPS); + return; } else { GST_LOG ("no second E-AC3 frame found, false sync"); } From 0e39c628785f13bcc728afeeb346b08d78941078 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Stadler?= Date: Fri, 3 Dec 2010 16:22:32 +0200 Subject: [PATCH 004/254] typefind: remove useless masking in (E-)AC-3 typefinders --- gst/typefind/gsttypefindfunctions.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/gst/typefind/gsttypefindfunctions.c b/gst/typefind/gsttypefindfunctions.c index d8fa5280de..3bfd78a067 100644 --- a/gst/typefind/gsttypefindfunctions.c +++ b/gst/typefind/gsttypefindfunctions.c @@ -1252,11 +1252,11 @@ ac3_type_find (GstTypeFind * tf, gpointer unused) break; if (c.data[0] == 0x0b && c.data[1] == 0x77) { - guint bsid = (c.data[5] >> 3) & 0x1F; + guint bsid = c.data[5] >> 3; if (bsid <= 8) { /* ac3 */ - guint fscod = (c.data[4] >> 6) & 0x03; + guint fscod = c.data[4] >> 6; guint frmsizecod = c.data[4] & 0x3f; if (fscod < 3 && frmsizecod < 38) { @@ -1270,7 +1270,7 @@ ac3_type_find (GstTypeFind * tf, gpointer unused) data_scan_ctx_advance (tf, &c_next, frame_size * 2); if (c_next.data[0] == 0x0b && c_next.data[1] == 0x77) { - guint fscod2 = (c_next.data[4] >> 6) & 0x03; + guint fscod2 = c_next.data[4] >> 6; guint frmsizecod2 = c_next.data[4] & 0x3f; if (fscod == fscod2 && frmsizecod == frmsizecod2) { @@ -1295,7 +1295,7 @@ ac3_type_find (GstTypeFind * tf, gpointer unused) DataScanCtx c_next = c; guint frame_size; - frame_size = (((c.data[2] & 0x07) << 8) + (c.data[3] & 0xff)) + 1; + frame_size = (((c.data[2] & 0x07) << 8) + c.data[3]) + 1; GST_LOG ("possible E-AC3 frame sync at offset %" G_GUINT64_FORMAT ", size=%u", c.offset, frame_size); if (data_scan_ctx_ensure_data (tf, &c_next, (frame_size * 2) + 5)) { From 725968c61290fc9f7ba178de187884cbbab894b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Stadler?= Date: Fri, 3 Dec 2010 16:54:21 +0200 Subject: [PATCH 005/254] typefind: accept consecutive AC-3 frames of different sizes This is perfectly valid and occurs in particular when there are (in)dependent substreams present. --- gst/typefind/gsttypefindfunctions.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/gst/typefind/gsttypefindfunctions.c b/gst/typefind/gsttypefindfunctions.c index 3bfd78a067..84644ca0d8 100644 --- a/gst/typefind/gsttypefindfunctions.c +++ b/gst/typefind/gsttypefindfunctions.c @@ -1270,13 +1270,14 @@ ac3_type_find (GstTypeFind * tf, gpointer unused) data_scan_ctx_advance (tf, &c_next, frame_size * 2); if (c_next.data[0] == 0x0b && c_next.data[1] == 0x77) { - guint fscod2 = c_next.data[4] >> 6; - guint frmsizecod2 = c_next.data[4] & 0x3f; + fscod = c_next.data[4] >> 6; + frmsizecod = c_next.data[4] & 0x3f; - if (fscod == fscod2 && frmsizecod == frmsizecod2) { + if (fscod < 3 && frmsizecod < 38) { GstTypeFindProbability prob; - GST_LOG ("found second AC3 frame, looks good"); + GST_LOG ("found second AC3 frame (size=%u), looks good", + ac3_frmsizecod_tbl[frmsizecod].frm_size[fscod]); if (c.offset == 0) prob = GST_TYPE_FIND_MAXIMUM; else From 1e75501c107cc61cdb3c6ecf8b30fdb90038484e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Stadler?= Date: Fri, 3 Dec 2010 17:33:40 +0200 Subject: [PATCH 006/254] typefind: ignore AC-3 BSIDs 9, 10 and >16 These are reserved for future extensions which will not be backwards compatible to E-AC-3. --- gst/typefind/gsttypefindfunctions.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/gst/typefind/gsttypefindfunctions.c b/gst/typefind/gsttypefindfunctions.c index 84644ca0d8..3b556824a9 100644 --- a/gst/typefind/gsttypefindfunctions.c +++ b/gst/typefind/gsttypefindfunctions.c @@ -1291,7 +1291,7 @@ ac3_type_find (GstTypeFind * tf, gpointer unused) } } } - } else { + } else if (bsid <= 16 && bsid > 10) { /* eac3 */ DataScanCtx c_next = c; guint frame_size; @@ -1317,6 +1317,8 @@ ac3_type_find (GstTypeFind * tf, gpointer unused) GST_LOG ("no second E-AC3 frame found, false sync"); } } + } else { + GST_LOG ("invalid AC3 BSID: %u", bsid); } } data_scan_ctx_advance (tf, &c, 1); From c05f45f05b43988f795c0fadec3a1395edc31cc3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Stadler?= Date: Tue, 7 Dec 2010 20:28:37 +0200 Subject: [PATCH 007/254] tests: add AC-3, E-AC-3 typefind tests --- tests/check/gst/typefindfunctions.c | 137 ++++++++++++++++++++++++++++ 1 file changed, 137 insertions(+) diff --git a/tests/check/gst/typefindfunctions.c b/tests/check/gst/typefindfunctions.c index cec594393d..cbe188a19e 100644 --- a/tests/check/gst/typefindfunctions.c +++ b/tests/check/gst/typefindfunctions.c @@ -174,6 +174,141 @@ GST_START_TEST (test_mpegts) GST_END_TEST; +struct ac3_frmsize +{ + unsigned frmsizecod; + unsigned frmsize; +}; + +static void +make_ac3_packet (guint8 * data, guint bytesize, guint bsid) +{ + /* Actually not a fully valid packet; if the typefinder starts to + * check e.g. the CRCs, this test needs to be improved as well. */ + const guint8 ac3_header[] = { + 0x0b, 0x77, /* syncword */ + 0x00, 0x00, /* crc1 */ + 0x00, /* fscod 0xc0, frmsizecod 0x3f */ + 0x00 /* bsid 0xf8, bsmod 0x07 */ + }; + const struct ac3_frmsize frmsize[] = { + {17, 256}, {26, 640} /* small subset of supported sizes */ + }; + guint wordsize = bytesize >> 1, frmsizecod = 0; + int i; + + fail_unless ((bytesize & 0x01) == 0); + fail_unless (bytesize >= sizeof (ac3_header)); + + for (i = 0; i < G_N_ELEMENTS (frmsize); i++) { + if (frmsize[i].frmsize == wordsize) { + frmsizecod = frmsize[i].frmsizecod; + break; + } + } + + fail_unless (frmsizecod); + + memcpy (data, ac3_header, sizeof (ac3_header)); + data[4] = (data[4] & ~0x3f) | (frmsizecod & 0x3f); + data[5] = (bsid & 0x1f) << 3; + memset (data + 6, 0, bytesize - 6); +} + +GST_START_TEST (test_ac3) +{ + GstTypeFindProbability prob; + const gchar *type; + GstBuffer *buf; + GstCaps *caps = NULL; + guint bsid; + + for (bsid = 0; bsid < 32; bsid++) { + buf = gst_buffer_new_and_alloc ((256 + 640) * 2); + make_ac3_packet (GST_BUFFER_DATA (buf), 256 * 2, bsid); + make_ac3_packet (GST_BUFFER_DATA (buf) + 256 * 2, 640 * 2, bsid); + + caps = gst_type_find_helper_for_buffer (NULL, buf, &prob); + if (bsid <= 8) { + fail_unless (caps != NULL); + GST_LOG ("Found type for BSID %u: %" GST_PTR_FORMAT, bsid, caps); + + type = gst_structure_get_name (gst_caps_get_structure (caps, 0)); + fail_unless_equals_string (type, "audio/x-ac3"); + fail_unless (prob > GST_TYPE_FIND_MINIMUM + && prob <= GST_TYPE_FIND_MAXIMUM); + gst_caps_unref (caps); + } else { + fail_unless (caps == NULL); + } + + gst_buffer_unref (buf); + } +} + +GST_END_TEST; + +static void +make_eac3_packet (guint8 * data, guint bytesize, guint bsid) +{ + /* Actually not a fully valid packet; if the typefinder starts to + * check e.g. the CRCs, this test needs to be improved as well. */ + const guint8 eac3_header[] = { + 0x0b, 0x77, /* syncword */ + 0x00, /* strmtyp 0xc0, substreamid 0x38, + * frmsize 0x07 (3 high bits) */ + 0x00, /* frmsize (low bits -> 11 total) */ + 0x00, /* fscod 0xc0, fscod2/numblocks 0x30, + * acmod 0x0e, lfeon 0x01 */ + 0x00 /* bsid 0xf8, dialnorm 0x07 (3 high bits) */ + }; + guint wordsize = bytesize >> 1; + + fail_unless ((bytesize & 0x01) == 0); + fail_unless (bytesize >= sizeof (eac3_header)); + + memcpy (data, eac3_header, sizeof (eac3_header)); + data[2] = (data[2] & ~0x07) | ((((wordsize - 1) & 0x700) >> 8) & 0xff); + data[3] = (wordsize - 1) & 0xff; + data[5] = (bsid & 0x1f) << 3; + memset (data + 6, 0, bytesize - 6); +} + +GST_START_TEST (test_eac3) +{ + GstTypeFindProbability prob; + const gchar *type; + GstBuffer *buf; + GstCaps *caps = NULL; + guint bsid; + + for (bsid = 0; bsid <= 32; bsid++) { + buf = gst_buffer_new_and_alloc (558 + 384); + make_eac3_packet (GST_BUFFER_DATA (buf), 558, bsid); + make_eac3_packet (GST_BUFFER_DATA (buf) + 558, 384, bsid); + + caps = gst_type_find_helper_for_buffer (NULL, buf, &prob); + if (bsid > 10 && bsid <= 16) { + /* Only BSIs 11..16 are valid for Annex E */ + fail_unless (caps != NULL); + GST_LOG ("Found type for BSID %u: %" GST_PTR_FORMAT, bsid, caps); + + type = gst_structure_get_name (gst_caps_get_structure (caps, 0)); + fail_unless_equals_string (type, "audio/x-eac3"); + fail_unless (prob > GST_TYPE_FIND_MINIMUM + && prob <= GST_TYPE_FIND_MAXIMUM); + gst_caps_unref (caps); + } else { + /* Invalid E-AC-3 BSID, must not be detected as anything: */ + fail_unless (caps == NULL); + } + + gst_buffer_unref (buf); + } +} + +GST_END_TEST; + #define TEST_RANDOM_DATA_SIZE (4*1024) /* typefind random data, to make sure all typefinders are called */ @@ -231,6 +366,8 @@ typefindfunctions_suite (void) tcase_add_test (tc_chain, test_broken_flac_in_ogg); tcase_add_test (tc_chain, test_jpeg_not_ac3); tcase_add_test (tc_chain, test_mpegts); + tcase_add_test (tc_chain, test_ac3); + tcase_add_test (tc_chain, test_eac3); tcase_add_test (tc_chain, test_random_data); return s; From ecb164675d42765f4ceab7b04381816ebf01dd31 Mon Sep 17 00:00:00 2001 From: Stefan Kost Date: Wed, 8 Dec 2010 12:09:45 +0200 Subject: [PATCH 008/254] docs: fix wrong use of Since: keyword --- gst-libs/gst/pbutils/gstdiscoverer-types.c | 68 +++++++++++----------- gst-libs/gst/pbutils/gstdiscoverer.c | 4 +- gst-libs/gst/rtp/gstrtpbuffer.c | 2 +- 3 files changed, 37 insertions(+), 37 deletions(-) diff --git a/gst-libs/gst/pbutils/gstdiscoverer-types.c b/gst-libs/gst/pbutils/gstdiscoverer-types.c index a3d6bf0fc0..c027ba4b06 100644 --- a/gst-libs/gst/pbutils/gstdiscoverer-types.c +++ b/gst-libs/gst/pbutils/gstdiscoverer-types.c @@ -385,7 +385,7 @@ gst_discoverer_stream_info_list_free (GList * infos) * Returns: A #GList of matching #GstDiscovererStreamInfo. The caller should * free it with #gst_discoverer_stream_info_list_free. * - * Since 0.10.31 + * Since: 0.10.31 */ GList * gst_discoverer_info_get_streams (GstDiscovererInfo * info, GType streamtype) @@ -411,7 +411,7 @@ gst_discoverer_info_get_streams (GstDiscovererInfo * info, GType streamtype) * Returns: A #GList of matching #GstDiscovererStreamInfo. The caller should * free it with #gst_discoverer_stream_info_list_free. * - * Since 0.10.31 + * Since: 0.10.31 */ GList * gst_discoverer_info_get_audio_streams (GstDiscovererInfo * info) @@ -428,7 +428,7 @@ gst_discoverer_info_get_audio_streams (GstDiscovererInfo * info) * Returns: A #GList of matching #GstDiscovererStreamInfo. The caller should * free it with #gst_discoverer_stream_info_list_free. * - * Since 0.10.31 + * Since: 0.10.31 */ GList * gst_discoverer_info_get_video_streams (GstDiscovererInfo * info) @@ -445,7 +445,7 @@ gst_discoverer_info_get_video_streams (GstDiscovererInfo * info) * Returns: A #GList of matching #GstDiscovererStreamInfo. The caller should * free it with #gst_discoverer_stream_info_list_free. * - * Since 0.10.31 + * Since: 0.10.31 */ GList * gst_discoverer_info_get_container_streams (GstDiscovererInfo * info) @@ -461,7 +461,7 @@ gst_discoverer_info_get_container_streams (GstDiscovererInfo * info) * Returns: a human readable name for the stream type of the given @info (ex : "audio", * "container",...). * - * Since 0.10.31 + * Since: 0.10.31 */ const gchar * gst_discoverer_stream_info_get_stream_type_nick (GstDiscovererStreamInfo * info) @@ -496,7 +496,7 @@ gst_discoverer_stream_info_get_stream_type_nick (GstDiscovererStreamInfo * info) * Returns: the previous #GstDiscovererStreamInfo in a chain. %NULL for starting * points. Unref with #gst_discoverer_stream_info_unref after usage. * - * Since 0.10.31 + * Since: 0.10.31 */ GstDiscovererStreamInfo * gst_discoverer_stream_info_get_previous (GstDiscovererStreamInfo * info) @@ -515,7 +515,7 @@ gst_discoverer_stream_info_get_previous (GstDiscovererStreamInfo * info) * Returns: the next #GstDiscovererStreamInfo in a chain. %NULL for final streams. * Unref with #gst_discoverer_stream_info_unref after usage. * - * Since 0.10.31 + * Since: 0.10.31 */ GstDiscovererStreamInfo * gst_discoverer_stream_info_get_next (GstDiscovererStreamInfo * info) @@ -534,7 +534,7 @@ gst_discoverer_stream_info_get_next (GstDiscovererStreamInfo * info) * * Returns: the #GstCaps of the stream. Unref with #gst_caps_unref after usage. * - * Since 0.10.31 + * Since: 0.10.31 */ GstCaps * gst_discoverer_stream_info_get_caps (GstDiscovererStreamInfo * info) @@ -553,7 +553,7 @@ gst_discoverer_stream_info_get_caps (GstDiscovererStreamInfo * info) * Returns: the tags contained in this stream. If you wish to use the tags after * the life-time of @info you will need to copy them. * - * Since 0.10.31 + * Since: 0.10.31 */ const GstTagList * @@ -572,7 +572,7 @@ gst_discoverer_stream_info_get_tags (GstDiscovererStreamInfo * info) * profile, etc..). If you wish to use the #GstStructure after the life-time of * @info you will need to copy it. * - * Since 0.10.31 + * Since: 0.10.31 */ const GstStructure * gst_discoverer_stream_info_get_misc (GstDiscovererStreamInfo * info) @@ -591,7 +591,7 @@ gst_discoverer_stream_info_get_misc (GstDiscovererStreamInfo * info) * Returns: the list of #GstDiscovererStreamInfo this container stream offers. * Free with #gst_discoverer_stream_info_list_free after usage. * - * Since 0.10.31 + * Since: 0.10.31 */ GList * @@ -622,7 +622,7 @@ gst_discoverer_container_info_get_streams (GstDiscovererContainerInfo * info) * * Returns: the number of channels in the stream. * - * Since 0.10.31 + * Since: 0.10.31 */ AUDIO_INFO_ACCESSOR_CODE (channels, guint, 0); @@ -633,7 +633,7 @@ AUDIO_INFO_ACCESSOR_CODE (channels, guint, 0); * * Returns: the sample rate of the stream in Hertz. * - * Since 0.10.31 + * Since: 0.10.31 */ AUDIO_INFO_ACCESSOR_CODE (sample_rate, guint, 0); @@ -644,7 +644,7 @@ AUDIO_INFO_ACCESSOR_CODE (sample_rate, guint, 0); * * Returns: the number of bits used per sample in each channel. * - * Since 0.10.31 + * Since: 0.10.31 */ AUDIO_INFO_ACCESSOR_CODE (depth, guint, 0); @@ -655,7 +655,7 @@ AUDIO_INFO_ACCESSOR_CODE (depth, guint, 0); * * Returns: the average or nominal bitrate of the stream in bits/second. * - * Since 0.10.31 + * Since: 0.10.31 */ AUDIO_INFO_ACCESSOR_CODE (bitrate, guint, 0); @@ -666,7 +666,7 @@ AUDIO_INFO_ACCESSOR_CODE (bitrate, guint, 0); * * Returns: the maximum bitrate of the stream in bits/second. * - * Since 0.10.31 + * Since: 0.10.31 */ AUDIO_INFO_ACCESSOR_CODE (max_bitrate, guint, 0); @@ -684,7 +684,7 @@ AUDIO_INFO_ACCESSOR_CODE (max_bitrate, guint, 0); * * Returns: the width of the video stream in pixels. * - * Since 0.10.31 + * Since: 0.10.31 */ VIDEO_INFO_ACCESSOR_CODE (width, guint, 0); @@ -695,7 +695,7 @@ VIDEO_INFO_ACCESSOR_CODE (width, guint, 0); * * Returns: the height of the video stream in pixels. * - * Since 0.10.31 + * Since: 0.10.31 */ VIDEO_INFO_ACCESSOR_CODE (height, guint, 0); @@ -707,7 +707,7 @@ VIDEO_INFO_ACCESSOR_CODE (height, guint, 0); * Returns: the depth in bits of the video stream (only relevant for * video streams). * - * Since 0.10.31 + * Since: 0.10.31 */ VIDEO_INFO_ACCESSOR_CODE (depth, guint, 0); @@ -718,7 +718,7 @@ VIDEO_INFO_ACCESSOR_CODE (depth, guint, 0); * * Returns: the framerate of the video stream (numerator). * - * Since 0.10.31 + * Since: 0.10.31 */ VIDEO_INFO_ACCESSOR_CODE (framerate_num, guint, 0); @@ -729,7 +729,7 @@ VIDEO_INFO_ACCESSOR_CODE (framerate_num, guint, 0); * * Returns: the framerate of the video stream (denominator). * - * Since 0.10.31 + * Since: 0.10.31 */ VIDEO_INFO_ACCESSOR_CODE (framerate_denom, guint, 0); @@ -740,7 +740,7 @@ VIDEO_INFO_ACCESSOR_CODE (framerate_denom, guint, 0); * * Returns: the Pixel Aspect Ratio (PAR) of the video stream (numerator). * - * Since 0.10.31 + * Since: 0.10.31 */ VIDEO_INFO_ACCESSOR_CODE (par_num, guint, 0); @@ -751,7 +751,7 @@ VIDEO_INFO_ACCESSOR_CODE (par_num, guint, 0); * * Returns: the Pixel Aspect Ratio (PAR) of the video stream (denominator). * - * Since 0.10.31 + * Since: 0.10.31 */ VIDEO_INFO_ACCESSOR_CODE (par_denom, guint, 0); @@ -762,7 +762,7 @@ VIDEO_INFO_ACCESSOR_CODE (par_denom, guint, 0); * * Returns: %TRUE if the stream is interlaced, else %FALSE. * - * Since 0.10.31 + * Since: 0.10.31 */ gboolean gst_discoverer_video_info_is_interlaced (const GstDiscovererVideoInfo * info) @@ -778,7 +778,7 @@ gst_discoverer_video_info_is_interlaced (const GstDiscovererVideoInfo * info) * * Returns: the average or nominal bitrate of the video stream in bits/second. * - * Since 0.10.31 + * Since: 0.10.31 */ VIDEO_INFO_ACCESSOR_CODE (bitrate, guint, 0); @@ -789,7 +789,7 @@ VIDEO_INFO_ACCESSOR_CODE (bitrate, guint, 0); * * Returns: the maximum bitrate of the video stream in bits/second. * - * Since 0.10.31 + * Since: 0.10.31 */ VIDEO_INFO_ACCESSOR_CODE (max_bitrate, guint, 0); @@ -801,7 +801,7 @@ VIDEO_INFO_ACCESSOR_CODE (max_bitrate, guint, 0); * Returns: #TRUE if the video stream corresponds to an image (i.e. only contains * one frame). * - * Since 0.10.31 + * Since: 0.10.31 */ gboolean gst_discoverer_video_info_is_image (const GstDiscovererVideoInfo * info) @@ -825,7 +825,7 @@ gst_discoverer_video_info_is_image (const GstDiscovererVideoInfo * info) * Returns: the URI to which this information corresponds to. Copy it if you * wish to use it after the life-time of @info. * - * Since 0.10.31 + * Since: 0.10.31 */ DISCOVERER_INFO_ACCESSOR_CODE (uri, const gchar *, NULL); @@ -836,7 +836,7 @@ DISCOVERER_INFO_ACCESSOR_CODE (uri, const gchar *, NULL); * * Returns: the result of the discovery as a #GstDiscovererResult. * - * Since 0.10.31 + * Since: 0.10.31 */ DISCOVERER_INFO_ACCESSOR_CODE (result, GstDiscovererResult, GST_DISCOVERER_OK); @@ -849,7 +849,7 @@ DISCOVERER_INFO_ACCESSOR_CODE (result, GstDiscovererResult, GST_DISCOVERER_OK); * This structure can be traversed to see the original hierarchy. Unref with * #gst_discoverer_stream_info_unref after usage. * - * Since 0.10.31 + * Since: 0.10.31 */ GstDiscovererStreamInfo * @@ -869,7 +869,7 @@ gst_discoverer_info_get_stream_info (GstDiscovererInfo * info) * Returns: the list of all streams contained in the #info. Free after usage * with #gst_discoverer_stream_info_list_free. * - * Since 0.10.31 + * Since: 0.10.31 */ GList * gst_discoverer_info_get_stream_list (GstDiscovererInfo * info) @@ -892,7 +892,7 @@ gst_discoverer_info_get_stream_list (GstDiscovererInfo * info) * * Returns: the duration of the URI in #GstClockTime (nanoseconds). * - * Since 0.10.31 + * Since: 0.10.31 */ DISCOVERER_INFO_ACCESSOR_CODE (duration, GstClockTime, GST_CLOCK_TIME_NONE); @@ -905,7 +905,7 @@ DISCOVERER_INFO_ACCESSOR_CODE (duration, GstClockTime, GST_CLOCK_TIME_NONE); * information about missing plugins). If you wish to use the #GstStructure * after the life-time of @info, you will need to copy it. * - * Since 0.10.31 + * Since: 0.10.31 */ DISCOVERER_INFO_ACCESSOR_CODE (misc, const GstStructure *, NULL); @@ -917,7 +917,7 @@ DISCOVERER_INFO_ACCESSOR_CODE (misc, const GstStructure *, NULL); * Returns: all tags contained in the %URI. If you wish to use the tags after * the life-time of @info, you will need to copy them. * - * Since 0.10.31 + * Since: 0.10.31 */ DISCOVERER_INFO_ACCESSOR_CODE (tags, const GstTagList *, NULL); diff --git a/gst-libs/gst/pbutils/gstdiscoverer.c b/gst-libs/gst/pbutils/gstdiscoverer.c index 61208ac41b..6a3aadc8f5 100644 --- a/gst-libs/gst/pbutils/gstdiscoverer.c +++ b/gst-libs/gst/pbutils/gstdiscoverer.c @@ -37,7 +37,7 @@ * * All the information is returned in a #GstDiscovererInfo structure. * - * Since 0.10.31 + * Since: 0.10.31 */ #ifdef HAVE_CONFIG_H @@ -1222,7 +1222,7 @@ gst_discoverer_start (GstDiscoverer * discoverer) * Stop the discovery of any pending URIs and clears the list of * pending URIS (if any). * - * Since 0.10.31 + * Since: 0.10.31 */ void gst_discoverer_stop (GstDiscoverer * discoverer) diff --git a/gst-libs/gst/rtp/gstrtpbuffer.c b/gst-libs/gst/rtp/gstrtpbuffer.c index 68fc67a95d..1cf608b1a0 100644 --- a/gst-libs/gst/rtp/gstrtpbuffer.c +++ b/gst-libs/gst/rtp/gstrtpbuffer.c @@ -739,7 +739,7 @@ gst_rtp_buffer_get_extension_data (GstBuffer * buffer, guint16 * bits, * * Returns: True if done. * - * Since : 0.10.18 + * Since: 0.10.18 */ gboolean gst_rtp_buffer_set_extension_data (GstBuffer * buffer, guint16 bits, From 3dad04935987f1d023b213c986fdd07ab8c7e057 Mon Sep 17 00:00:00 2001 From: Stefan Kost Date: Wed, 8 Dec 2010 12:28:32 +0200 Subject: [PATCH 009/254] tests: remove superflous ';' and reindent --- tests/check/libs/pbutils.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/tests/check/libs/pbutils.c b/tests/check/libs/pbutils.c index ae632214e7..144d9a6cc4 100644 --- a/tests/check/libs/pbutils.c +++ b/tests/check/libs/pbutils.c @@ -72,8 +72,7 @@ GST_START_TEST (test_pb_utils_post_missing_messages) bus = gst_element_get_bus (pipeline); /* first, test common assertion failure cases */ - ASSERT_CRITICAL (msg = gst_missing_uri_source_message_new (NULL, "http"); - ); + ASSERT_CRITICAL (msg = gst_missing_uri_source_message_new (NULL, "http")); ASSERT_CRITICAL (gst_missing_uri_source_message_new (pipeline, NULL)); ASSERT_CRITICAL (gst_missing_uri_sink_message_new (NULL, "http")); @@ -555,11 +554,11 @@ GST_START_TEST (test_pb_utils_install_plugins) ctx = gst_install_plugins_context_new (); - ASSERT_CRITICAL (ret = gst_install_plugins_sync (NULL, ctx);); + ASSERT_CRITICAL (ret = gst_install_plugins_sync (NULL, ctx)); ASSERT_CRITICAL (ret = - gst_install_plugins_async (NULL, ctx, result_cb, (gpointer) & marker);); + gst_install_plugins_async (NULL, ctx, result_cb, (gpointer) & marker)); ASSERT_CRITICAL (ret = - gst_install_plugins_async (details, ctx, NULL, (gpointer) & marker);); + gst_install_plugins_async (details, ctx, NULL, (gpointer) & marker)); /* make sure the functions return the right error code if the helper does * not exist */ From ea7349e4c75e8f0454130ae45a8acc3da0d32257 Mon Sep 17 00:00:00 2001 From: Mark Nauwelaerts Date: Wed, 8 Dec 2010 12:55:24 +0100 Subject: [PATCH 010/254] typefinding: improve iso media typefinding ... by also considering compatible brands rather than only aiming at major brand (of which there are a seemingly ever expanding great many). --- gst/typefind/gsttypefindfunctions.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/gst/typefind/gsttypefindfunctions.c b/gst/typefind/gsttypefindfunctions.c index 3b556824a9..a50ead34bb 100644 --- a/gst/typefind/gsttypefindfunctions.c +++ b/gst/typefind/gsttypefindfunctions.c @@ -2545,7 +2545,26 @@ qt_type_find (GstTypeFind * tf, gpointer unused) tip = 0; break; } + size = GST_READ_UINT32_BE (data); + /* check compatible brands rather than ever expaning major brands above */ + if ((STRNCMP (&data[4], "ftyp", 4) == 0) && (size >= 16)) { + new_offset = offset + 12; + while (new_offset + 4 <= offset + size) { + data = gst_type_find_peek (tf, new_offset, 4); + if (data == NULL) + goto done; + if (STRNCMP (&data[4], "isom", 4) == 0 || + STRNCMP (&data[4], "avc1", 4) == 0 || + STRNCMP (&data[4], "mp41", 4) == 0 || + STRNCMP (&data[4], "mp42", 4) == 0) { + tip = GST_TYPE_FIND_MAXIMUM; + variant = "iso"; + goto done; + } + new_offset += 4; + } + } if (size == 1) { guint8 *sizedata; @@ -2564,6 +2583,7 @@ qt_type_find (GstTypeFind * tf, gpointer unused) offset = new_offset; } +done: if (tip > 0) { if (variant) { GstCaps *caps = gst_caps_copy (QT_CAPS); From b00f8a5b363a8f2b5eeb0431c25d5d2b00b0af49 Mon Sep 17 00:00:00 2001 From: Gavin Stark Date: Thu, 9 Dec 2010 08:40:25 +0100 Subject: [PATCH 011/254] xvimagesink: Use gst_caps_can_intersect() instead of gst_caps_intersect() Fixes a memory leak and bug #636827. --- sys/xvimage/xvimagesink.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/xvimage/xvimagesink.c b/sys/xvimage/xvimagesink.c index 5f3eb21da0..f5ee8666c2 100644 --- a/sys/xvimage/xvimagesink.c +++ b/sys/xvimage/xvimagesink.c @@ -2089,7 +2089,7 @@ gst_xvimagesink_setcaps (GstBaseSink * bsink, GstCaps * caps) "In setcaps. Possible caps %" GST_PTR_FORMAT ", setting caps %" GST_PTR_FORMAT, xvimagesink->xcontext->caps, caps); - if (!gst_caps_intersect (xvimagesink->xcontext->caps, caps)) + if (!gst_caps_can_intersect (xvimagesink->xcontext->caps, caps)) goto incompatible_caps; structure = gst_caps_get_structure (caps, 0); From e9d9474330acd7ebb3d3130ba4bf92b28c60c5f8 Mon Sep 17 00:00:00 2001 From: Edward Hervey Date: Thu, 9 Dec 2010 16:57:35 +0100 Subject: [PATCH 012/254] pbutils: Add/Fix some media descriptions Fixes #623413 --- gst-libs/gst/pbutils/descriptions.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/gst-libs/gst/pbutils/descriptions.c b/gst-libs/gst/pbutils/descriptions.c index 9fa0c6eeb4..8ac2c39686 100644 --- a/gst-libs/gst/pbutils/descriptions.c +++ b/gst-libs/gst/pbutils/descriptions.c @@ -62,6 +62,7 @@ typedef struct static const FormatInfo formats[] = { /* container/tag formats with static descriptions */ + {"application/gxf", "General Exchange Format (GXF)", FLAG_CONTAINER}, {"application/ogg", "Ogg", FLAG_CONTAINER}, {"application/mxf", "MXF", FLAG_CONTAINER}, {"application/vnd.rn-realmedia", "Realmedia", FLAG_CONTAINER}, @@ -209,8 +210,8 @@ static const FormatInfo formats[] = { {"image/jpeg", "JPEG", 0}, {"image/jng", "JPEG Network Graphics (JNG)", 0}, {"image/png", "PNG", 0}, - {"image/pbm", "PBM", 0}, - {"image/ppm", "PPM", 0}, + {"image/pbm", "Portable BitMap (PBM)", 0}, + {"image/ppm", "Portable PixMap (PPM)", 0}, {"image/svg+xml", "Scalable Vector Graphics (SVG)", 0}, {"image/tiff", "TIFF", 0}, {"image/x-cmu-raster", "CMU Raster Format", 0}, @@ -218,8 +219,11 @@ static const FormatInfo formats[] = { {"image/x-j2c", "JPEG 2000", 0}, {"image/x-jpc", "JPEG 2000", 0}, {"image/jp2", "JPEG 2000", 0}, + {"image/x-pcx", "PCX", 0}, {"image/x-xcf", "XFC", 0}, {"image/x-pixmap", "XPM", 0}, + {"image/x-portable-anymap", "Portable AnyMap (PAM)", 0}, + {"image/x-portable-graymap", "Portable GrayMap (PGM)", 0}, {"image/x-xpixmap", "XPM", 0}, {"image/x-quicktime", "QuickTime Image Format (QTIF)", 0}, {"image/x-sun-raster", "Sun Raster Format (RAS)", 0}, From 5f36105915473450eebaceb28e28b0dd6438c02b Mon Sep 17 00:00:00 2001 From: Wim Taymans Date: Fri, 10 Dec 2010 18:57:56 +0100 Subject: [PATCH 013/254] appsink: unset flushing flag when starting When we start again after being stopped, clear the flushing flag or else it will always be TRUE. Fixes #636769 --- gst-libs/gst/app/gstappsink.c | 1 + 1 file changed, 1 insertion(+) diff --git a/gst-libs/gst/app/gstappsink.c b/gst-libs/gst/app/gstappsink.c index 9bcc91eac2..a6e8c3db0e 100644 --- a/gst-libs/gst/app/gstappsink.c +++ b/gst-libs/gst/app/gstappsink.c @@ -630,6 +630,7 @@ gst_app_sink_start (GstBaseSink * psink) g_mutex_lock (priv->mutex); GST_DEBUG_OBJECT (appsink, "starting"); + priv->flushing = FALSE; priv->started = TRUE; g_mutex_unlock (priv->mutex); From 42dee942d4e7877b8573263f07c01b7f27633e94 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= Date: Sat, 11 Dec 2010 17:14:36 +0100 Subject: [PATCH 014/254] decodebin2: Emit "remove-decoded-pad" signal when pads are removed from decodebin2 Fixes bug #636198. --- gst/playback/gstdecodebin2.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/gst/playback/gstdecodebin2.c b/gst/playback/gstdecodebin2.c index fbdfce0c99..c4be4af97f 100644 --- a/gst/playback/gstdecodebin2.c +++ b/gst/playback/gstdecodebin2.c @@ -2346,9 +2346,12 @@ gst_decode_chain_free_internal (GstDecodeChain * chain, gboolean hide) } if (chain->endpad) { - if (chain->endpad->exposed) + if (chain->endpad->exposed) { gst_element_remove_pad (GST_ELEMENT_CAST (chain->dbin), GST_PAD_CAST (chain->endpad)); + g_signal_emit (G_OBJECT (chain->dbin), + gst_decode_bin_signals[SIGNAL_REMOVED_DECODED_PAD], 0, chain->endpad); + } gst_ghost_pad_set_target (GST_GHOST_PAD_CAST (chain->endpad), NULL); chain->endpad->exposed = FALSE; From 09ff04a00ad506bde366d684b68809a1364cd3ea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= Date: Sat, 11 Dec 2010 17:18:49 +0100 Subject: [PATCH 015/254] decodebin2: Deprecate new-decoded-pad and removed-decoded-pad signals They're really the same as pad-added and pad-removed from GstElement and it doesn't make sense to have two signals for the same thing. --- gst/playback/gstdecodebin2.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/gst/playback/gstdecodebin2.c b/gst/playback/gstdecodebin2.c index c4be4af97f..bcf4731ab6 100644 --- a/gst/playback/gstdecodebin2.c +++ b/gst/playback/gstdecodebin2.c @@ -596,6 +596,9 @@ gst_decode_bin_class_init (GstDecodeBinClass * klass) * * This signal gets emitted as soon as a new pad of the same type as one of * the valid 'raw' types is added. + * + * Deprecated: Use GstElement::pad-added instead of this signal. + * */ gst_decode_bin_signals[SIGNAL_NEW_DECODED_PAD] = g_signal_new ("new-decoded-pad", G_TYPE_FROM_CLASS (klass), @@ -610,6 +613,9 @@ gst_decode_bin_class_init (GstDecodeBinClass * klass) * @pad: The pad that was removed * * This signal is emitted when a 'final' caps pad has been removed. + * + * Deprecated: Use GstElement::pad-removed instead of this signal. + * */ gst_decode_bin_signals[SIGNAL_REMOVED_DECODED_PAD] = g_signal_new ("removed-decoded-pad", G_TYPE_FROM_CLASS (klass), From 1611f8929825bd15bb8381932ed5b854fc7f443a Mon Sep 17 00:00:00 2001 From: "Zeeshan Ali (Khattak)" Date: Sat, 11 Dec 2010 19:33:33 +0200 Subject: [PATCH 016/254] videotestsrc: Add a missing return statement --- gst/videotestsrc/generate_sine_table.c | 1 + 1 file changed, 1 insertion(+) diff --git a/gst/videotestsrc/generate_sine_table.c b/gst/videotestsrc/generate_sine_table.c index 4d8e571505..432e1a56f9 100644 --- a/gst/videotestsrc/generate_sine_table.c +++ b/gst/videotestsrc/generate_sine_table.c @@ -39,4 +39,5 @@ main (int argc, char *argv[]) } printf ("};\n"); + return 0; } From 0b90d5d54cb0cd8c816fd54e40bcf722dc25e9f0 Mon Sep 17 00:00:00 2001 From: Stefan Kost Date: Mon, 13 Dec 2010 09:58:53 +0200 Subject: [PATCH 017/254] docs: move design doc to design folder --- docs/{ => design}/design-audiosinks.txt | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename docs/{ => design}/design-audiosinks.txt (100%) diff --git a/docs/design-audiosinks.txt b/docs/design/design-audiosinks.txt similarity index 100% rename from docs/design-audiosinks.txt rename to docs/design/design-audiosinks.txt From 7728f3d3a7eb3463378e8a9ebd66687f42435400 Mon Sep 17 00:00:00 2001 From: Stefan Kost Date: Mon, 13 Dec 2010 10:41:24 +0200 Subject: [PATCH 018/254] typefinders: name "aac" typefinder "audio/aac" This is in sync how we call the others. --- gst/typefind/gsttypefindfunctions.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gst/typefind/gsttypefindfunctions.c b/gst/typefind/gsttypefindfunctions.c index a50ead34bb..bca59c113c 100644 --- a/gst/typefind/gsttypefindfunctions.c +++ b/gst/typefind/gsttypefindfunctions.c @@ -4263,7 +4263,7 @@ plugin_init (GstPlugin * plugin) NULL, CMML_CAPS, NULL, NULL); TYPE_FIND_REGISTER_START_WITH (plugin, "application/x-executable", GST_RANK_MARGINAL, NULL, "\177ELF", 4, GST_TYPE_FIND_MAXIMUM); - TYPE_FIND_REGISTER (plugin, "aac", GST_RANK_SECONDARY, + TYPE_FIND_REGISTER (plugin, "audio/aac", GST_RANK_SECONDARY, aac_type_find, aac_exts, AAC_CAPS, NULL, NULL); TYPE_FIND_REGISTER_START_WITH (plugin, "audio/x-spc", GST_RANK_SECONDARY, spc_exts, "SNES-SPC700 Sound File Data", 27, GST_TYPE_FIND_MAXIMUM); From a7cf16528930205967ad0f778b217e8761c836d6 Mon Sep 17 00:00:00 2001 From: Mark Nauwelaerts Date: Mon, 13 Dec 2010 09:56:04 +0100 Subject: [PATCH 019/254] audioresample: provide as much valid output ts and offset as valid input ... by independently tracking time and offset, rather than having no offset leading to no output ts. --- gst/audioresample/gstaudioresample.c | 97 +++++++++++++++------------- gst/audioresample/gstaudioresample.h | 6 +- 2 files changed, 56 insertions(+), 47 deletions(-) diff --git a/gst/audioresample/gstaudioresample.c b/gst/audioresample/gstaudioresample.c index f61dac2c8f..1b6c99005b 100644 --- a/gst/audioresample/gstaudioresample.c +++ b/gst/audioresample/gstaudioresample.c @@ -240,8 +240,8 @@ gst_audio_resample_start (GstBaseTransform * base) resample->t0 = GST_CLOCK_TIME_NONE; resample->in_offset0 = GST_BUFFER_OFFSET_NONE; resample->out_offset0 = GST_BUFFER_OFFSET_NONE; - resample->next_in_offset = GST_BUFFER_OFFSET_NONE; - resample->next_out_offset = GST_BUFFER_OFFSET_NONE; + resample->samples_in = 0; + resample->samples_out = 0; resample->tmp_in = NULL; resample->tmp_in_size = 0; @@ -854,24 +854,29 @@ gst_audio_resample_push_drain (GstAudioResample * resample) return; } + /* time */ if (GST_CLOCK_TIME_IS_VALID (resample->t0)) { - GST_BUFFER_OFFSET (outbuf) = resample->next_out_offset; - GST_BUFFER_OFFSET_END (outbuf) = GST_BUFFER_OFFSET (outbuf) + out_processed; GST_BUFFER_TIMESTAMP (outbuf) = resample->t0 + - gst_util_uint64_scale_int_round (GST_BUFFER_OFFSET (outbuf) - - resample->out_offset0, GST_SECOND, resample->outrate); - GST_BUFFER_DURATION (outbuf) = resample->t0 + - gst_util_uint64_scale_int_round (GST_BUFFER_OFFSET_END (outbuf) - - resample->out_offset0, GST_SECOND, resample->outrate) - - GST_BUFFER_TIMESTAMP (outbuf); - resample->next_out_offset += out_processed; - resample->next_in_offset += 0; + gst_util_uint64_scale_int_round (resample->samples_out, GST_SECOND, + resample->outrate); + GST_BUFFER_DURATION (outbuf) = + gst_util_uint64_scale_int_round (resample->samples_out + out_processed, + GST_SECOND, resample->outrate) - GST_BUFFER_TIMESTAMP (outbuf); } else { - GST_BUFFER_OFFSET (outbuf) = GST_BUFFER_OFFSET_NONE; - GST_BUFFER_OFFSET_END (outbuf) = GST_BUFFER_OFFSET_NONE; GST_BUFFER_TIMESTAMP (outbuf) = GST_CLOCK_TIME_NONE; GST_BUFFER_DURATION (outbuf) = GST_CLOCK_TIME_NONE; } + /* offset */ + if (resample->out_offset0 != GST_BUFFER_OFFSET_NONE) { + GST_BUFFER_OFFSET (outbuf) = resample->out_offset0 + resample->samples_out; + GST_BUFFER_OFFSET_END (outbuf) = GST_BUFFER_OFFSET (outbuf) + out_processed; + } else { + GST_BUFFER_OFFSET (outbuf) = GST_BUFFER_OFFSET_NONE; + GST_BUFFER_OFFSET_END (outbuf) = GST_BUFFER_OFFSET_NONE; + } + /* move along */ + resample->samples_out += out_processed; + resample->samples_in += 0; GST_BUFFER_SIZE (outbuf) = out_processed * resample->channels * (resample->width / 8); @@ -904,8 +909,8 @@ gst_audio_resample_event (GstBaseTransform * base, GstEvent * event) resample->t0 = GST_CLOCK_TIME_NONE; resample->in_offset0 = GST_BUFFER_OFFSET_NONE; resample->out_offset0 = GST_BUFFER_OFFSET_NONE; - resample->next_in_offset = GST_BUFFER_OFFSET_NONE; - resample->next_out_offset = GST_BUFFER_OFFSET_NONE; + resample->samples_in = 0; + resample->samples_out = 0; resample->need_discont = TRUE; break; case GST_EVENT_NEWSEGMENT: @@ -914,8 +919,8 @@ gst_audio_resample_event (GstBaseTransform * base, GstEvent * event) resample->t0 = GST_CLOCK_TIME_NONE; resample->in_offset0 = GST_BUFFER_OFFSET_NONE; resample->out_offset0 = GST_BUFFER_OFFSET_NONE; - resample->next_in_offset = GST_BUFFER_OFFSET_NONE; - resample->next_out_offset = GST_BUFFER_OFFSET_NONE; + resample->samples_in = 0; + resample->samples_out = 0; resample->need_discont = TRUE; break; case GST_EVENT_EOS: @@ -941,21 +946,18 @@ gst_audio_resample_check_discont (GstAudioResample * resample, GstBuffer * buf) /* no valid timestamps or offsets to compare --> no discontinuity */ if (G_UNLIKELY (!(GST_BUFFER_TIMESTAMP_IS_VALID (buf) && - GST_CLOCK_TIME_IS_VALID (resample->t0) && - resample->in_offset0 != GST_BUFFER_OFFSET_NONE && - resample->next_in_offset != GST_BUFFER_OFFSET_NONE))) + GST_CLOCK_TIME_IS_VALID (resample->t0)))) return FALSE; /* convert the inbound timestamp to an offset. */ offset = - resample->in_offset0 + gst_util_uint64_scale_int_round (GST_BUFFER_TIMESTAMP (buf) - resample->t0, resample->inrate, GST_SECOND); /* many elements generate imperfect streams due to rounding errors, so we * permit a small error (up to one sample) without triggering a filter * flush/restart (if triggered incorrectly, this will be audible) */ - delta = ABS ((gint64) (offset - resample->next_in_offset)); + delta = ABS ((gint64) (offset - resample->samples_in)); if (delta <= 1) return FALSE; @@ -1030,24 +1032,29 @@ gst_audio_resample_process (GstAudioResample * resample, GstBuffer * inbuf, in_processed, in_len); } + /* time */ if (GST_CLOCK_TIME_IS_VALID (resample->t0)) { - GST_BUFFER_OFFSET (outbuf) = resample->next_out_offset; - GST_BUFFER_OFFSET_END (outbuf) = GST_BUFFER_OFFSET (outbuf) + out_processed; GST_BUFFER_TIMESTAMP (outbuf) = resample->t0 + - gst_util_uint64_scale_int_round (GST_BUFFER_OFFSET (outbuf) - - resample->out_offset0, GST_SECOND, resample->outrate); - GST_BUFFER_DURATION (outbuf) = resample->t0 + - gst_util_uint64_scale_int_round (GST_BUFFER_OFFSET_END (outbuf) - - resample->out_offset0, GST_SECOND, resample->outrate) - - GST_BUFFER_TIMESTAMP (outbuf); - resample->next_out_offset += out_processed; - resample->next_in_offset += in_len; + gst_util_uint64_scale_int_round (resample->samples_out, GST_SECOND, + resample->outrate); + GST_BUFFER_DURATION (outbuf) = + gst_util_uint64_scale_int_round (resample->samples_out + out_processed, + GST_SECOND, resample->outrate) - GST_BUFFER_TIMESTAMP (outbuf); } else { - GST_BUFFER_OFFSET (outbuf) = GST_BUFFER_OFFSET_NONE; - GST_BUFFER_OFFSET_END (outbuf) = GST_BUFFER_OFFSET_NONE; GST_BUFFER_TIMESTAMP (outbuf) = GST_CLOCK_TIME_NONE; GST_BUFFER_DURATION (outbuf) = GST_CLOCK_TIME_NONE; } + /* offset */ + if (resample->out_offset0 != GST_BUFFER_OFFSET_NONE) { + GST_BUFFER_OFFSET (outbuf) = resample->out_offset0 + resample->samples_out; + GST_BUFFER_OFFSET_END (outbuf) = GST_BUFFER_OFFSET (outbuf) + out_processed; + } else { + GST_BUFFER_OFFSET (outbuf) = GST_BUFFER_OFFSET_NONE; + GST_BUFFER_OFFSET_END (outbuf) = GST_BUFFER_OFFSET_NONE; + } + /* move along */ + resample->samples_out += out_processed; + resample->samples_in += in_len; GST_BUFFER_SIZE (outbuf) = out_processed * resample->channels * (resample->width / 8); @@ -1106,24 +1113,26 @@ gst_audio_resample_transform (GstBaseTransform * base, GstBuffer * inbuf, /* handle discontinuity */ if (G_UNLIKELY (resample->need_discont)) { + /* reset */ + resample->samples_in = 0; + resample->samples_out = 0; + GST_DEBUG_OBJECT (resample, "found discontinuity; resyncing"); /* resync the timestamp and offset counters if possible */ - if (GST_BUFFER_TIMESTAMP_IS_VALID (inbuf) && - GST_BUFFER_OFFSET_IS_VALID (inbuf)) { + if (GST_BUFFER_TIMESTAMP_IS_VALID (inbuf)) { resample->t0 = GST_BUFFER_TIMESTAMP (inbuf); + } else { + GST_DEBUG_OBJECT (resample, "... but new timestamp is invalid"); + resample->t0 = GST_CLOCK_TIME_NONE; + } + if (GST_BUFFER_OFFSET_IS_VALID (inbuf)) { resample->in_offset0 = GST_BUFFER_OFFSET (inbuf); resample->out_offset0 = gst_util_uint64_scale_int_round (resample->in_offset0, resample->outrate, resample->inrate); - resample->next_in_offset = resample->in_offset0; - resample->next_out_offset = resample->out_offset0; } else { - GST_DEBUG_OBJECT (resample, "found discontinuity but timestamp and/or " - "offset is invalid, cannot sync output timestamp and offset counter"); - resample->t0 = GST_CLOCK_TIME_NONE; + GST_DEBUG_OBJECT (resample, "... but new offset is invalid"); resample->in_offset0 = GST_BUFFER_OFFSET_NONE; resample->out_offset0 = GST_BUFFER_OFFSET_NONE; - resample->next_in_offset = GST_BUFFER_OFFSET_NONE; - resample->next_out_offset = GST_BUFFER_OFFSET_NONE; } /* set DISCONT flag on output buffer */ GST_DEBUG_OBJECT (resample, "marking this buffer with the DISCONT flag"); diff --git a/gst/audioresample/gstaudioresample.h b/gst/audioresample/gstaudioresample.h index 2f41b2cecb..b0733365b1 100644 --- a/gst/audioresample/gstaudioresample.h +++ b/gst/audioresample/gstaudioresample.h @@ -61,9 +61,9 @@ struct _GstAudioResample { GstClockTime t0; guint64 in_offset0; guint64 out_offset0; - guint64 next_in_offset; - guint64 next_out_offset; - + guint64 samples_in; + guint64 samples_out; + gint channels; gint inrate; gint outrate; From 93d68ec77d4b4c6d670168488c00cbc274a71fe4 Mon Sep 17 00:00:00 2001 From: Mark Nauwelaerts Date: Mon, 13 Dec 2010 10:05:00 +0100 Subject: [PATCH 020/254] audioresample: relax discont checking slightly --- gst/audioresample/gstaudioresample.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/gst/audioresample/gstaudioresample.c b/gst/audioresample/gstaudioresample.c index 1b6c99005b..42597e45c8 100644 --- a/gst/audioresample/gstaudioresample.c +++ b/gst/audioresample/gstaudioresample.c @@ -957,8 +957,10 @@ gst_audio_resample_check_discont (GstAudioResample * resample, GstBuffer * buf) /* many elements generate imperfect streams due to rounding errors, so we * permit a small error (up to one sample) without triggering a filter * flush/restart (if triggered incorrectly, this will be audible) */ + /* allow even up to more samples, since sink is not so strict anyway, + * so give that one a chance to handle this as configured */ delta = ABS ((gint64) (offset - resample->samples_in)); - if (delta <= 1) + if (delta <= (resample->inrate >> 5)) return FALSE; GST_WARNING_OBJECT (resample, From 2f1eb43c62df24576896109b426ea17e1aaba3c8 Mon Sep 17 00:00:00 2001 From: Stefan Kost Date: Mon, 13 Dec 2010 12:34:58 +0200 Subject: [PATCH 021/254] make: move the design doc also on the Makefile.am level (for dist) --- docs/Makefile.am | 1 - docs/design/Makefile.am | 1 + 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/Makefile.am b/docs/Makefile.am index 7ae8b996aa..b0d55f4298 100644 --- a/docs/Makefile.am +++ b/docs/Makefile.am @@ -12,7 +12,6 @@ SUBDIRS = design libs $(PLUGIN_DOCS_DIRS) DIST_SUBDIRS = design libs plugins EXTRA_DIST = \ - design-audiosinks.txt \ version.entities.in upload: diff --git a/docs/design/Makefile.am b/docs/design/Makefile.am index 8bb52366c1..f2e0b71b6d 100644 --- a/docs/design/Makefile.am +++ b/docs/design/Makefile.am @@ -2,6 +2,7 @@ SUBDIRS = EXTRA_DIST = \ + design-audiosinks.txt \ design-decodebin.txt \ design-orc-integration.txt \ draft-keyframe-force.txt \ From a0e083a7175d7b63d736e3f90466dc5849e47701 Mon Sep 17 00:00:00 2001 From: Mark Nauwelaerts Date: Mon, 13 Dec 2010 13:04:40 +0100 Subject: [PATCH 022/254] tests: audioresample: adjust unit test to relaxed discont checking --- tests/check/elements/audioresample.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/tests/check/elements/audioresample.c b/tests/check/elements/audioresample.c index a9a2e3b96a..a8a79a306b 100644 --- a/tests/check/elements/audioresample.c +++ b/tests/check/elements/audioresample.c @@ -327,18 +327,18 @@ test_discont_stream_instance (int inrate, int outrate, int samples, GST_START_TEST (test_discont_stream) { /* integral scalings */ - test_discont_stream_instance (48000, 24000, 500, 20); - test_discont_stream_instance (48000, 12000, 500, 20); - test_discont_stream_instance (12000, 24000, 500, 20); - test_discont_stream_instance (12000, 48000, 500, 20); + test_discont_stream_instance (48000, 24000, 5000, 20); + test_discont_stream_instance (48000, 12000, 5000, 20); + test_discont_stream_instance (12000, 24000, 5000, 20); + test_discont_stream_instance (12000, 48000, 5000, 20); /* non-integral scalings */ - test_discont_stream_instance (44100, 8000, 500, 20); - test_discont_stream_instance (8000, 44100, 500, 20); + test_discont_stream_instance (44100, 8000, 5000, 20); + test_discont_stream_instance (8000, 44100, 5000, 20); /* wacky scalings */ - test_discont_stream_instance (12345, 54321, 500, 20); - test_discont_stream_instance (101, 99, 500, 20); + test_discont_stream_instance (12345, 54321, 5000, 20); + test_discont_stream_instance (101, 99, 5000, 20); } GST_END_TEST; From da70200ea50643b1d067eea13e2669f4a62735ab Mon Sep 17 00:00:00 2001 From: Stefan Kost Date: Mon, 13 Dec 2010 16:23:04 +0200 Subject: [PATCH 023/254] Automatic update of common submodule From 011bcc8 to 20742ae --- common | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common b/common index 011bcc8a0f..20742aee03 160000 --- a/common +++ b/common @@ -1 +1 @@ -Subproject commit 011bcc8a0fc7f798ee874a7ba899123fb2470e22 +Subproject commit 20742aee033cc7c4aa9a817df005d15d5fa6ba85 From 4e8956c9f1497ce05ae004fb929bf2c601dc5857 Mon Sep 17 00:00:00 2001 From: Stefan Kost Date: Mon, 13 Dec 2010 16:20:23 +0200 Subject: [PATCH 024/254] discoverer: query seekability Besides the duration we can also query the seekability of a stream. Use the new API in the gst-discoverer tool. API: gst_discoverer_info_get_seekable --- gst-libs/gst/pbutils/gstdiscoverer-types.c | 11 ++++++++ gst-libs/gst/pbutils/gstdiscoverer.c | 33 +++++++++++++++++++--- gst-libs/gst/pbutils/gstdiscoverer.h | 1 + gst-libs/gst/pbutils/pbutils-private.h | 1 + tools/gst-discoverer.c | 10 ++++--- win32/common/libgstpbutils.def | 1 + 6 files changed, 49 insertions(+), 8 deletions(-) diff --git a/gst-libs/gst/pbutils/gstdiscoverer-types.c b/gst-libs/gst/pbutils/gstdiscoverer-types.c index c027ba4b06..2a5839b07b 100644 --- a/gst-libs/gst/pbutils/gstdiscoverer-types.c +++ b/gst-libs/gst/pbutils/gstdiscoverer-types.c @@ -897,6 +897,17 @@ gst_discoverer_info_get_stream_list (GstDiscovererInfo * info) DISCOVERER_INFO_ACCESSOR_CODE (duration, GstClockTime, GST_CLOCK_TIME_NONE); +/** + * gst_discoverer_info_get_seekable: + * @info: a #GstDiscovererInfo + * + * Returns: the wheter the URI is seekable. + * + * Since: 0.10.32 + */ + +DISCOVERER_INFO_ACCESSOR_CODE (seekable, gboolean, FALSE); + /** * gst_discoverer_info_get_misc: * @info: a #GstDiscovererInfo diff --git a/gst-libs/gst/pbutils/gstdiscoverer.c b/gst-libs/gst/pbutils/gstdiscoverer.c index 6a3aadc8f5..8955136e8d 100644 --- a/gst-libs/gst/pbutils/gstdiscoverer.c +++ b/gst-libs/gst/pbutils/gstdiscoverer.c @@ -105,6 +105,9 @@ struct _GstDiscovererPrivate GMainContext *ctx; guint sourceid; guint timeoutid; + + /* reusable queries */ + GstQuery *seeking_query; }; #define DISCO_LOCK(dc) g_mutex_lock (dc->priv->lock); @@ -242,6 +245,7 @@ static void gst_discoverer_init (GstDiscoverer * dc) { GstElement *tmp; + GstFormat format = GST_FORMAT_TIME; dc->priv = G_TYPE_INSTANCE_GET_PRIVATE (dc, GST_TYPE_DISCOVERER, GstDiscovererPrivate); @@ -284,6 +288,9 @@ gst_discoverer_init (GstDiscoverer * dc) tmp = gst_element_factory_make ("decodebin2", NULL); dc->priv->decodebin2_type = G_OBJECT_TYPE (tmp); gst_object_unref (tmp); + + /* create queries */ + dc->priv->seeking_query = gst_query_new_seeking (format); } static void @@ -322,6 +329,11 @@ gst_discoverer_dispose (GObject * obj) g_mutex_free (dc->priv->lock); dc->priv->lock = NULL; } + + if (dc->priv->seeking_query) { + gst_query_unref (dc->priv->seeking_query); + dc->priv->seeking_query = NULL; + } } static void @@ -859,18 +871,31 @@ discoverer_collect (GstDiscoverer * dc) if (dc->priv->streams) { /* FIXME : Make this querying optional */ if (TRUE) { + GstElement *pipeline = (GstElement *) dc->priv->pipeline; GstFormat format = GST_FORMAT_TIME; gint64 dur; GST_DEBUG ("Attempting to query duration"); - if (gst_element_query_duration ((GstElement *) dc->priv->pipeline, - &format, &dur)) { + if (gst_element_query_duration (pipeline, &format, &dur)) { if (format == GST_FORMAT_TIME) { GST_DEBUG ("Got duration %" GST_TIME_FORMAT, GST_TIME_ARGS (dur)); dc->priv->current_info->duration = (guint64) dur; } } + + if (dc->priv->seeking_query) { + if (gst_element_query (pipeline, dc->priv->seeking_query)) { + gboolean seekable; + + gst_query_parse_seeking (dc->priv->seeking_query, &format, + &seekable, NULL, NULL); + if (format == GST_FORMAT_TIME) { + GST_DEBUG ("Got seekable %d", seekable); + dc->priv->current_info->seekable = seekable; + } + } + } } if (dc->priv->current_topology) @@ -894,8 +919,8 @@ discoverer_collect (GstDiscoverer * dc) gst_caps_get_structure (dc->priv->current_info->stream_info->caps, 0); if (g_str_has_prefix (gst_structure_get_name (st), "image/")) - ((GstDiscovererVideoInfo *) dc->priv->current_info-> - stream_info)->is_image = TRUE; + ((GstDiscovererVideoInfo *) dc->priv->current_info->stream_info)-> + is_image = TRUE; } } diff --git a/gst-libs/gst/pbutils/gstdiscoverer.h b/gst-libs/gst/pbutils/gstdiscoverer.h index 9a80de02c0..da8eb58b32 100644 --- a/gst-libs/gst/pbutils/gstdiscoverer.h +++ b/gst-libs/gst/pbutils/gstdiscoverer.h @@ -179,6 +179,7 @@ GstDiscovererResult gst_discoverer_info_get_result(const GstDiscovererInfo GstDiscovererStreamInfo* gst_discoverer_info_get_stream_info(GstDiscovererInfo* info); GList* gst_discoverer_info_get_stream_list(GstDiscovererInfo* info); GstClockTime gst_discoverer_info_get_duration(const GstDiscovererInfo* info); +gboolean gst_discoverer_info_get_seekable(const GstDiscovererInfo* info); const GstStructure* gst_discoverer_info_get_misc(const GstDiscovererInfo* info); const GstTagList* gst_discoverer_info_get_tags(const GstDiscovererInfo* info); diff --git a/gst-libs/gst/pbutils/pbutils-private.h b/gst-libs/gst/pbutils/pbutils-private.h index 04bcd4c340..5031df0345 100644 --- a/gst-libs/gst/pbutils/pbutils-private.h +++ b/gst-libs/gst/pbutils/pbutils-private.h @@ -78,6 +78,7 @@ struct _GstDiscovererInfo { GstClockTime duration; GstStructure *misc; GstTagList *tags; + gboolean seekable; }; /* missing-plugins.c */ diff --git a/tools/gst-discoverer.c b/tools/gst-discoverer.c index bc25409914..bff1b7945e 100644 --- a/tools/gst-discoverer.c +++ b/tools/gst-discoverer.c @@ -241,10 +241,12 @@ print_topology (GstDiscovererStreamInfo * info, gint depth) } static void -print_duration (GstDiscovererInfo * info, gint tab) +print_properties (GstDiscovererInfo * info, gint tab) { - g_print ("%*s%" GST_TIME_FORMAT "\n", tab + 1, " ", + g_print ("%*sDuration: %" GST_TIME_FORMAT "\n", tab + 1, " ", GST_TIME_ARGS (gst_discoverer_info_get_duration (info))); + g_print ("%*sSeekable: %s\n", tab + 1, " ", + (gst_discoverer_info_get_seekable (info) ? "yes" : "no")); } static void @@ -296,8 +298,8 @@ print_info (GstDiscovererInfo * info, GError * err) if ((sinfo = gst_discoverer_info_get_stream_info (info))) { g_print ("\nTopology:\n"); print_topology (sinfo, 1); - g_print ("\nDuration:\n"); - print_duration (info, 1); + g_print ("\nProperties:\n"); + print_properties (info, 1); gst_discoverer_stream_info_unref (sinfo); } diff --git a/win32/common/libgstpbutils.def b/win32/common/libgstpbutils.def index 5f96c969f9..34c79dc635 100644 --- a/win32/common/libgstpbutils.def +++ b/win32/common/libgstpbutils.def @@ -26,6 +26,7 @@ EXPORTS gst_discoverer_info_get_duration gst_discoverer_info_get_misc gst_discoverer_info_get_result + gst_discoverer_info_get_seekable gst_discoverer_info_get_stream_info gst_discoverer_info_get_stream_list gst_discoverer_info_get_streams From 799037923743d8a2ef5ad1d78e2c923d644b8bf3 Mon Sep 17 00:00:00 2001 From: Stefan Kost Date: Mon, 13 Dec 2010 18:05:41 +0200 Subject: [PATCH 025/254] pbutils: spell out two more container formats --- gst-libs/gst/pbutils/descriptions.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gst-libs/gst/pbutils/descriptions.c b/gst-libs/gst/pbutils/descriptions.c index 8ac2c39686..ca99344243 100644 --- a/gst-libs/gst/pbutils/descriptions.c +++ b/gst-libs/gst/pbutils/descriptions.c @@ -64,7 +64,7 @@ static const FormatInfo formats[] = { /* container/tag formats with static descriptions */ {"application/gxf", "General Exchange Format (GXF)", FLAG_CONTAINER}, {"application/ogg", "Ogg", FLAG_CONTAINER}, - {"application/mxf", "MXF", FLAG_CONTAINER}, + {"application/mxf", "Material eXchange Format (MXF)", FLAG_CONTAINER}, {"application/vnd.rn-realmedia", "Realmedia", FLAG_CONTAINER}, {"application/x-id3", N_("ID3 tag"), FLAG_CONTAINER}, {"application/x-ape", N_("APE tag"), FLAG_CONTAINER}, @@ -79,7 +79,7 @@ static const FormatInfo formats[] = { {"video/x-matroska", "Matroska", FLAG_CONTAINER}, {"video/webm", "WebM", FLAG_CONTAINER}, {"video/x-ms-asf", "Advanced Streaming Format (ASF)", FLAG_CONTAINER}, - {"video/x-msvideo", "AVI", FLAG_CONTAINER}, + {"video/x-msvideo", "Audio Video Interleave (AVI)", FLAG_CONTAINER}, {"video/x-quicktime", "Quicktime", FLAG_CONTAINER}, {"video/quicktime", "Quicktime", FLAG_CONTAINER}, {"video/mj2", "Motion JPEG 2000", FLAG_CONTAINER}, From 525776df79844c013088b169deed346e7adb554a Mon Sep 17 00:00:00 2001 From: David Schleef Date: Tue, 14 Dec 2010 00:16:13 -0800 Subject: [PATCH 026/254] typefind: Add check for yuv4mpeg --- gst/typefind/gsttypefindfunctions.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/gst/typefind/gsttypefindfunctions.c b/gst/typefind/gsttypefindfunctions.c index bca59c113c..5944c70ff1 100644 --- a/gst/typefind/gsttypefindfunctions.c +++ b/gst/typefind/gsttypefindfunctions.c @@ -4063,6 +4063,7 @@ plugin_init (GstPlugin * plugin) static const gchar *msword_exts[] = { "doc", NULL }; static const gchar *dsstore_exts[] = { "DS_Store", NULL }; static const gchar *psd_exts[] = { "psd", NULL }; + static const gchar *y4m_exts[] = { "y4m", NULL }; GST_DEBUG_CATEGORY_INIT (type_find_debug, "typefindfunctions", GST_DEBUG_FG_GREEN | GST_DEBUG_BG_RED, "generic type find functions"); @@ -4321,6 +4322,8 @@ plugin_init (GstPlugin * plugin) TYPE_FIND_REGISTER_START_WITH (plugin, "image/vnd.adobe.photoshop", GST_RANK_SECONDARY, psd_exts, "8BPS\000\001\000\000\000\000", 10, GST_TYPE_FIND_LIKELY); + TYPE_FIND_REGISTER_START_WITH (plugin, "application/x-yuv4mpeg", + GST_RANK_SECONDARY, y4m_exts, "YUV4MPEG2 ", 10, GST_TYPE_FIND_LIKELY); #ifdef USE_GIO TYPE_FIND_REGISTER (plugin, "xdgmime-base", GST_RANK_MARGINAL, From 3457bc71495332c54cdfa35bf86762c8c59efaa1 Mon Sep 17 00:00:00 2001 From: Stefan Kost Date: Wed, 15 Dec 2010 12:21:05 +0200 Subject: [PATCH 027/254] configure: use the -Bsymbolic-functions linker flag if supported This feature turns intra library calls into direct function calls and thus makes them a little faster. The downside is that this causes problems for e.g. LD_PRELOAD based tools. Thus add a configure option to turn it off. --- configure.ac | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/configure.ac b/configure.ac index 91553b63b0..b1df1c68e4 100644 --- a/configure.ac +++ b/configure.ac @@ -337,6 +337,22 @@ AC_COMPILE_IFELSE( ]) AM_CONDITIONAL(HAVE_LINUX_JOYSTICK_HEADERS, test "x$HAVE_LINUX_JOYSTICK_HEADERS" = "xyes") +dnl Check for -Bsymbolic-functions linker flag used to avoid +dnl intra-library PLT jumps, if available. +AC_ARG_ENABLE(Bsymbolic, + [AC_HELP_STRING([--disable-Bsymbolic], + [avoid linking with -Bsymbolic])],, + [SAVED_LDFLAGS="${LDFLAGS}" + AC_MSG_CHECKING([for -Bsymbolic-functions linker flag]) + LDFLAGS=-Wl,-Bsymbolic-functions + AC_TRY_LINK([], [int main (void) { return 0; }], + AC_MSG_RESULT(yes) + enable_Bsymbolic=yes, + AC_MSG_RESULT(no) + enable_Bsymbolic=no) + LDFLAGS="${SAVED_LDFLAGS}"]) + + dnl *** set variables based on configure arguments *** dnl set license and copyright notice @@ -870,6 +886,9 @@ AC_SUBST(GST_LIBS) dnl LDFLAGS really should only contain flags, not libs - they get added before dnl whatevertarget_LIBS and -L flags here affect the rest of the linking GST_ALL_LDFLAGS="-no-undefined" +if test "x${enable_Bsymbolic}" == "xyes"; then + GST_ALL_LDFLAGS="$GST_ALL_LDFLAGS -Wl,-Bsymbolic-functions" +fi AC_SUBST(GST_ALL_LDFLAGS) dnl GST_LIB_LDFLAGS From 82b4f9bfef332393f95325d00d28d97ae784748c Mon Sep 17 00:00:00 2001 From: Edward Hervey Date: Fri, 13 Aug 2010 17:27:52 +0200 Subject: [PATCH 028/254] pbutils: New Profile library https://bugzilla.gnome.org/show_bug.cgi?id=627476 --- docs/design/Makefile.am | 1 + docs/design/design-encoding.txt | 571 +++++++++++++ docs/libs/gst-plugins-base-libs-docs.sgml | 1 + docs/libs/gst-plugins-base-libs-sections.txt | 85 ++ docs/libs/gst-plugins-base-libs.types | 11 + gst-libs/gst/pbutils/Makefile.am | 4 + gst-libs/gst/pbutils/encoding-profile.c | 834 +++++++++++++++++++ gst-libs/gst/pbutils/encoding-profile.h | 184 ++++ gst-libs/gst/pbutils/encoding-target.c | 724 ++++++++++++++++ gst-libs/gst/pbutils/encoding-target.h | 104 +++ tests/check/Makefile.am | 7 + tests/check/libs/.gitignore | 1 + tests/check/libs/profile.c | 454 ++++++++++ win32/common/libgstpbutils.def | 40 + 14 files changed, 3021 insertions(+) create mode 100644 docs/design/design-encoding.txt create mode 100644 gst-libs/gst/pbutils/encoding-profile.c create mode 100644 gst-libs/gst/pbutils/encoding-profile.h create mode 100644 gst-libs/gst/pbutils/encoding-target.c create mode 100644 gst-libs/gst/pbutils/encoding-target.h create mode 100644 tests/check/libs/profile.c diff --git a/docs/design/Makefile.am b/docs/design/Makefile.am index f2e0b71b6d..357af4ce99 100644 --- a/docs/design/Makefile.am +++ b/docs/design/Makefile.am @@ -4,6 +4,7 @@ SUBDIRS = EXTRA_DIST = \ design-audiosinks.txt \ design-decodebin.txt \ + design-encoding.txt \ design-orc-integration.txt \ draft-keyframe-force.txt \ draft-va.txt \ diff --git a/docs/design/design-encoding.txt b/docs/design/design-encoding.txt new file mode 100644 index 0000000000..dda79addf6 --- /dev/null +++ b/docs/design/design-encoding.txt @@ -0,0 +1,571 @@ +Encoding and Muxing +------------------- + +Summary +------- + A. Problems + B. Goals + 1. EncodeBin + 2. Encoding Profile System + 3. Helper Library for Profiles + I. Use-cases researched + + +A. Problems this proposal attempts to solve +------------------------------------------- + +* Duplication of pipeline code for gstreamer-based applications + wishing to encode and or mux streams, leading to subtle differences + and inconsistencies accross those applications. + +* No unified system for describing encoding targets for applications + in a user-friendly way. + +* No unified system for creating encoding targets for applications, + resulting in duplication of code accross all applications, + differences and inconsistencies that come with that duplication, + and applications hardcoding element names and settings resulting in + poor portability. + + + +B. Goals +-------- + +1. Convenience encoding element + + Create a convenience GstBin for encoding and muxing several streams, + hereafter called 'EncodeBin'. + + This element will only contain one single property, which is a + profile. + +2. Define a encoding profile system + +2. Encoding profile helper library + + Create a helper library to: + * create EncodeBin instances based on profiles, and + * help applications to create/load/save/browse those profiles. + + + + +1. EncodeBin +------------ + +1.1 Proposed API +---------------- + + EncodeBin is a GstBin subclass. + + It implements the GstTagSetter interface, by which it will proxy the + calls to the muxer. + + Only two introspectable property (i.e. usable without extra API): + * A GstEncodingProfile* + * The name of the profile to use + + When a profile is selected, encodebin will: + * Add REQUEST sinkpads for all the GstStreamProfile + * Create the muxer and expose the source pad + + Whenever a request pad is created, encodebin will: + * Create the chain of elements for that pad + * Ghost the sink pad + * Return that ghost pad + + This allows reducing the code to the minimum for applications + wishing to encode a source for a given profile: + + ... + + encbin = gst_element_factory_make("encodebin, NULL); + g_object_set (encbin, "profile", "N900/H264 HQ", NULL); + gst_element_link (encbin, filesink); + + ... + + vsrcpad = gst_element_get_src_pad(source, "src1"); + vsinkpad = gst_element_get_request_pad (encbin, "video_%d"); + gst_pad_link(vsrcpad, vsinkpad); + + ... + + +1.2 Explanation of the Various stages in EncodeBin +-------------------------------------------------- + + This describes the various stages which can happen in order to end + up with a multiplexed stream that can then be stored or streamed. + +1.2.1 Incoming streams + + The streams fed to EncodeBin can be of various types: + + * Video + * Uncompressed (but maybe subsampled) + * Compressed + * Audio + * Uncompressed (audio/x-raw-{int|float}) + * Compressed + * Timed text + * Private streams + + +1.2.2 Steps involved for raw video encoding + +(0) Incoming Stream + +(1) Transform raw video feed (optional) + + Here we modify the various fundamental properties of a raw video + stream to be compatible with the intersection of: + * The encoder GstCaps and + * The specified "Stream Restriction" of the profile/target + + The fundamental properties that can be modified are: + * width/height + This is done with a video scaler. + The DAR (Display Aspect Ratio) MUST be respected. + If needed, black borders can be added to comply with the target DAR. + * framerate + * format/colorspace/depth + All of this is done with a colorspace converter + +(2) Actual encoding (optional for raw streams) + + An encoder (with some optional settings) is used. + +(3) Muxing + + A muxer (with some optional settings) is used. + +(4) Outgoing encoded and muxed stream + + +1.2.3 Steps involved for raw audio encoding + + This is roughly the same as for raw video, expect for (1) + +(1) Transform raw audo feed (optional) + + We modify the various fundamental properties of a raw audio stream to + be compatible with the intersection of: + * The encoder GstCaps and + * The specified "Stream Restriction" of the profile/target + + The fundamental properties that can be modifier are: + * Number of channels + * Type of raw audio (integer or floating point) + * Depth (number of bits required to encode one sample) + + +1.2.4 Steps involved for encoded audio/video streams + + Steps (1) and (2) are replaced by a parser if a parser is available + for the given format. + + +1.2.5 Steps involved for other streams + + Other streams will just be forwarded as-is to the muxer, provided the + muxer accepts the stream type. + + + + +2. Encoding Profile System +-------------------------- + + This work is based on: + * The existing GstPreset system for elements [0] + * The gnome-media GConf audio profile system [1] + * The investigation done into device profiles by Arista and + Transmageddon [2 and 3] + +2.2 Terminology +--------------- + +* Encoding Target Category + A Target Category is a classification of devices/systems/use-cases + for encoding. + + Such a classification is required in order for: + * Applications with a very-specific use-case to limit the number of + profiles they can offer the user. A screencasting application has + no use with the online services targets for example. + * Offering the user some initial classification in the case of a + more generic encoding application (like a video editor or a + transcoder). + + Ex: + Consumer devices + Online service + Intermediate Editing Format + Screencast + Capture + Computer + +* Encoding Profile Target + A Profile Target describes a specific entity for which we wish to + encode. + A Profile Target must belong to at least one Target Category. + It will define at least one Encoding Profile. + + Ex (with category): + Nokia N900 (Consumer device) + Sony PlayStation 3 (Consumer device) + Youtube (Online service) + DNxHD (Intermediate editing format) + HuffYUV (Screencast) + Theora (Computer) + +* Encoding Profile + A specific combination of muxer, encoders, presets and limitations. + + Ex: + Nokia N900/H264 HQ + Ipod/High Quality + DVD/Pal + Youtube/High Quality + HTML5/Low Bandwith + DNxHD + +2.3 Encoding Profile +-------------------- + +An encoding profile requires the following information: + + * Name + This string is not translatable and must be unique. + A recommendation to guarantee uniqueness of the naming could be: + / + * Description + This is a translatable string describing the profile + * Muxing format + This is a string containing the GStreamer media-type of the + container format. + * Muxing preset + This is an optional string describing the preset(s) to use on the + muxer. + * Multipass setting + This is a boolean describing whether the profile requires several + passes. + * List of Stream Profile + +2.3.1 Stream Profiles + +A Stream Profile consists of: + + * Type + The type of stream profile (audio, video, text, private-data) + * Encoding Format + This is a string containing the GStreamer media-type of the encoding + format to be used. If encoding is not to be applied, the raw audio + media type will be used. + * Encoding preset + This is an optional string describing the preset(s) to use on the + encoder. + * Restriction + This is an optional GstCaps containing the restriction of the + stream that can be fed to the encoder. + This will generally containing restrictions in video + width/heigh/framerate or audio depth. + * presence + This is an integer specifying how many streams can be used in the + containing profile. 0 means that any number of streams can be + used. + * pass + This is an integer which is only meaningful if the multipass flag + has been set in the profile. If it has been set it indicates which + pass this Stream Profile corresponds to. + +2.4 Example profile +------------------- + +The representation used here is XML only as an example. No decision is +made as to which formatting to use for storing targets and profiles. + + + Nokia N900 + Consumer Device + + Nokia N900/H264 HQ + Nokia N900/MP3 + Nokia N900/AAC + + + + + Nokia N900/H264 HQ + + High Quality H264/AAC for the Nokia N900 + + video/quicktime,variant=iso + + + audio + audio/mpeg,mpegversion=4 + Quality High/Main + audio/x-raw-int,channels=[1,2] + 1 + + + video + video/x-h264 + Profile Baseline/Quality High + + video/x-raw-yuv,width=[16, 800],\ + height=[16, 480],framerate=[1/1, 30000/1001] + + 1 + + + + + +2.5 API +------- + A proposed C API is contained in the gstprofile.h file in this directory. + + +2.6 Modifications required in the existing GstPreset system +----------------------------------------------------------- + +2.6.1. Temporary preset. + + Currently a preset needs to be saved on disk in order to be + used. + + This makes it impossible to have temporary presets (that exist only + during the lifetime of a process), which might be required in the + new proposed profile system + +2.6.2 Categorisation of presets. + + Currently presets are just aliases of a group of property/value + without any meanings or explanation as to how they exclude each + other. + + Take for example the H264 encoder. It can have presets for: + * passes (1,2 or 3 passes) + * profiles (Baseline, Main, ...) + * quality (Low, medium, High) + + In order to programmatically know which presets exclude each other, + we here propose the categorisation of these presets. + + This can be done in one of two ways + 1. in the name (by making the name be [:]) + This would give for example: "Quality:High", "Profile:Baseline" + 2. by adding a new _meta key + This would give for example: _meta/category:quality + +2.6.3 Aggregation of presets. + + There can be more than one choice of presets to be done for an + element (quality, profile, pass). + + This means that one can not currently describe the full + configuration of an element with a single string but with many. + + The proposal here is to extend the GstPreset API to be able to set + all presets using one string and a well-known separator ('/'). + + This change only requires changes in the core preset handling code. + + This would allow doing the following: + gst_preset_load_preset (h264enc, + "pass:1/profile:baseline/quality:high"); + +2.7 Points to be determined +--------------------------- + + This document hasn't determined yet how to solve the following + problems: + +2.7.1 Storage of profiles + + One proposal for storage would be to use a system wide directory + (like $prefix/share/gstreamer-0.10/profiles) and store XML files for + every individual profiles. + + Users could then add their own profiles in ~/.gstreamer-0.10/profiles + + This poses some limitations as to what to do if some applications + want to have some profiles limited to their own usage. + + +3. Helper library for profiles +------------------------------ + + These helper methods could also be added to existing libraries (like + GstPreset, GstPbUtils, ..). + + The various API proposed are in the accompanying gstprofile.h file. + +3.1 Getting user-readable names for formats + + This is already provided by GstPbUtils. + +3.2 Hierarchy of profiles + + The goal is for applications to be able to present to the user a list + of combo-boxes for choosing their output profile: + + [ Category ] # optional, depends on the application + [ Device/Site/.. ] # optional, depends on the application + [ Profile ] + + Convenience methods are offered to easily get lists of categories, + devices, and profiles. + +3.3 Creating Profiles + + The goal is for applications to be able to easily create profiles. + + The applications needs to be able to have a fast/efficient way to: + * select a container format and see all compatible streams he can use + with it. + * select a codec format and see which container formats he can use + with it. + + The remaining parts concern the restrictions to encoder + input. + +3.4 Ensuring availability of plugins for Profiles + + When an application wishes to use a Profile, it should be able to + query whether it has all the needed plugins to use it. + + This part will use GstPbUtils to query, and if needed install the + missing plugins through the installed distribution plugin installer. + + +I. Use-cases researched +----------------------- + + This is a list of various use-cases where encoding/muxing is being + used. + +* Transcoding + + The goal is to convert with as minimal loss of quality any input + file for a target use. + A specific variant of this is transmuxing (see below). + + Example applications: Arista, Transmageddon + +* Rendering timelines + + The incoming streams are a collection of various segments that need + to be rendered. + Those segments can vary in nature (i.e. the video width/height can + change). + This requires the use of identiy with the single-segment property + activated to transform the incoming collection of segments to a + single continuous segment. + + Example applications: PiTiVi, Jokosher + +* Encoding of live sources + + The major risk to take into account is the encoder not encoding the + incoming stream fast enough. This is outside of the scope of + encodebin, and should be solved by using queues between the sources + and encodebin, as well as implementing QoS in encoders and sources + (the encoders emitting QoS events, and the upstream elements + adapting themselves accordingly). + + Example applications: camerabin, cheese + +* Screencasting applications + + This is similar to encoding of live sources. + The difference being that due to the nature of the source (size and + amount/frequency of updates) one might want to do the encoding in + two parts: + * The actual live capture is encoded with a 'almost-lossless' codec + (such as huffyuv) + * Once the capture is done, the file created in the first step is + then rendered to the desired target format. + + Fixing sources to only emit region-updates and having encoders + capable of encoding those streams would fix the need for the first + step but is outside of the scope of encodebin. + + Example applications: Istanbul, gnome-shell, recordmydesktop + +* Live transcoding + + This is the case of an incoming live stream which will be + broadcasted/transmitted live. + One issue to take into account is to reduce the encoding latency to + a minimum. This should mostly be done by picking low-latency + encoders. + + Example applications: Rygel, Coherence + +* Transmuxing + + Given a certain file, the aim is to remux the contents WITHOUT + decoding into either a different container format or the same + container format. + Remuxing into the same container format is useful when the file was + not created properly (for example, the index is missing). + Whenever available, parsers should be applied on the encoded streams + to validate and/or fix the streams before muxing them. + + Metadata from the original file must be kept in the newly created + file. + + Example applications: Arista, Transmaggedon + +* Loss-less cutting + + Given a certain file, the aim is to extract a certain part of the + file without going through the process of decoding and re-encoding + that file. + This is similar to the transmuxing use-case. + + Example applications: PiTiVi, Transmageddon, Arista, ... + +* Multi-pass encoding + + Some encoders allow doing a multi-pass encoding. + The initial pass(es) are only used to collect encoding estimates and + are not actually muxed and outputted. + The final pass uses previously collected information, and the output + is then muxed and outputted. + +* Archiving and intermediary format + + The requirement is to have lossless + +* CD ripping + + Example applications: Sound-juicer + +* DVD ripping + + Example application: Thoggen + + + +* Research links + + Some of these are still active documents, some other not + +[0] GstPreset API documentation + http://gstreamer.freedesktop.org/data/doc/gstreamer/head/gstreamer/html/GstPreset.html + +[1] gnome-media GConf profiles + http://www.gnome.org/~bmsmith/gconf-docs/C/gnome-media.html + +[2] Research on a Device Profile API + http://gstreamer.freedesktop.org/wiki/DeviceProfile + +[3] Research on defining presets usage + http://gstreamer.freedesktop.org/wiki/PresetDesign + diff --git a/docs/libs/gst-plugins-base-libs-docs.sgml b/docs/libs/gst-plugins-base-libs-docs.sgml index 94a34519a3..b7b61a70a7 100644 --- a/docs/libs/gst-plugins-base-libs-docs.sgml +++ b/docs/libs/gst-plugins-base-libs-docs.sgml @@ -206,6 +206,7 @@ + diff --git a/docs/libs/gst-plugins-base-libs-sections.txt b/docs/libs/gst-plugins-base-libs-sections.txt index aff1cdb04f..da6134bce0 100644 --- a/docs/libs/gst-plugins-base-libs-sections.txt +++ b/docs/libs/gst-plugins-base-libs-sections.txt @@ -1907,6 +1907,91 @@ gst_codec_utils_mpeg4video_get_level gst_codec_utils_mpeg4video_caps_set_level_and_profile +
+encoding-profile +gst/pbutils/encoding-profile.h +GstEncodingProfile +gst_encoding_profile_unref +gst_encoding_profile_ref +gst_encoding_profile_get_name +gst_encoding_profile_get_description +gst_encoding_profile_get_format +gst_encoding_profile_get_preset +gst_encoding_profile_get_presence +gst_encoding_profile_get_restriction +gst_encoding_profile_set_name +gst_encoding_profile_set_description +gst_encoding_profile_set_format +gst_encoding_profile_set_preset +gst_encoding_profile_set_restriction +gst_encoding_profile_set_presence +gst_encoding_profile_is_equal +gst_encoding_profile_get_output_caps +gst_encoding_profile_get_type_nick + +GstEncodingContainerProfile +gst_encoding_container_profile_new +gst_encoding_container_profile_add_profile +gst_encoding_container_profile_contains_profile +gst_encoding_container_profile_get_profiles + +GstEncodingAudioProfile +gst_encoding_audio_profile_new + +GstEncodingVideoProfile +gst_encoding_video_profile_new +gst_encoding_video_profile_get_pass +gst_encoding_video_profile_get_variableframerate +gst_encoding_video_profile_set_pass +gst_encoding_video_profile_set_variableframerate + +GST_ENCODING_CATEGORY_DEVICE +GST_ENCODING_CATEGORY_ONLINE_SERVICE +GST_ENCODING_CATEGORY_STORAGE_EDITING +GST_ENCODING_CATEGORY_CAPTURE +GstEncodingTarget +gst_encoding_target_unref +gst_encoding_target_ref +gst_encoding_target_new +gst_encoding_target_get_name +gst_encoding_target_get_category +gst_encoding_target_get_description +gst_encoding_target_get_profiles +gst_encoding_target_add_profile +gst_encoding_target_save +gst_encoding_target_save_to +gst_encoding_target_load +gst_encoding_target_load_from + +GST_ENCODING_PROFILE +GST_IS_ENCODING_PROFILE +GST_TYPE_ENCODING_PROFILE +gst_encoding_profile_get_type +GST_ENCODING_TARGET +GST_IS_ENCODING_TARGET +GST_TYPE_ENCODING_TARGET +gst_encoding_target_get_type +GstEncodingProfileClass +GST_TYPE_ENCODING_CONTAINER_PROFILE +GST_ENCODING_CONTAINER_PROFILE +gst_encoding_container_profile_get_type +GST_TYPE_ENCODING_VIDEO_PROFILE +GST_ENCODING_VIDEO_PROFILE +GST_IS_ENCODING_VIDEO_PROFILE +GstEncodingVideoProfileClass +gst_encoding_video_profile_get_type +GST_TYPE_ENCODING_AUDIO_PROFILE +GST_ENCODING_AUDIO_PROFILE +GST_IS_ENCODING_AUDIO_PROFILE +GstEncodingAudioProfileClass +gst_encoding_audio_profile_get_type +GST_IS_ENCODING_CONTAINER_PROFILE +GstEncodingContainerProfileClass +GstEncodingTargetClass +
+ + + # video
diff --git a/docs/libs/gst-plugins-base-libs.types b/docs/libs/gst-plugins-base-libs.types index db3818a1d3..f6c06af2cd 100644 --- a/docs/libs/gst-plugins-base-libs.types +++ b/docs/libs/gst-plugins-base-libs.types @@ -59,3 +59,14 @@ gst_video_sink_get_type #include gst_discoverer_get_type + +#include +#include +gst_encoding_profile_get_type +gst_encoding_video_profile_get_type +gst_encoding_video_profile_get_type +gst_encoding_audio_profile_get_type +gst_encoding_container_profile_get_type +gst_encoding_target_get_type + + diff --git a/gst-libs/gst/pbutils/Makefile.am b/gst-libs/gst/pbutils/Makefile.am index 9a261f51b7..73251e1aef 100644 --- a/gst-libs/gst/pbutils/Makefile.am +++ b/gst-libs/gst/pbutils/Makefile.am @@ -4,6 +4,8 @@ headers_pbutils = \ pbutils.h \ codec-utils.h \ descriptions.h \ + encoding-profile.h \ + encoding-target.h \ install-plugins.h \ missing-plugins.h \ gstdiscoverer.h @@ -22,6 +24,8 @@ libgstpbutils_@GST_MAJORMINOR@_la_SOURCES = \ pbutils.c \ codec-utils.c \ descriptions.c \ + encoding-profile.c \ + encoding-target.c \ install-plugins.c \ missing-plugins.c \ gstdiscoverer.c \ diff --git a/gst-libs/gst/pbutils/encoding-profile.c b/gst-libs/gst/pbutils/encoding-profile.c new file mode 100644 index 0000000000..8c364c8878 --- /dev/null +++ b/gst-libs/gst/pbutils/encoding-profile.c @@ -0,0 +1,834 @@ +/* GStreamer encoding profiles library + * Copyright (C) 2009-2010 Edward Hervey + * (C) 2009-2010 Nokia Corporation + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +/** + * SECTION:encoding-profile + * @short_description: Encoding profile library + * + * + * + * Functions to create and handle encoding profiles. + * + * + * Encoding profiles describe the media types and settings one wishes to use for + * an encoding process. The top-level profiles are commonly + * #GstEncodingContainerProfile(s) (which contains user-readable name and + * description along with which container format to use) which references one or + * more #GstEncodingProfile(s) which indicate which encoding format should be + * used on each individual streams. + * + * + * #GstEncodingProfile(s) can be provided to the 'encodebin' element, which will take + * care of selecting and setting up the required elements to produce an output stream + * conforming to the specifications of the profile. + * + * + * Unlike other systems, the encoding profiles do not specify which #GstElement to use + * for the various encoding and muxing steps, but instead relies on specifying the format + * one wishes to use. + * + * + * Encoding profiles can be created at runtime by the application or loaded from (and saved + * to) file using the #GstEncodingTarget API. + * + * + * + * Example: Creating a profile + * + * |[ + * #include + * ... + * GstEncodingProfile * + * create_ogg_theora_profile(void) + *{ + * GstEncodingContainerProfile *prof; + * GstCaps *caps; + * + * caps = gst_caps_from_string("application/ogg"); + * prof = gst_encoding_container_profile_new("Ogg audio/video", + * "Standard OGG/THEORA/VORBIS", + * caps, NULL); + * gst_caps_unref (caps); + * + * caps = gst_caps_from_string("video/x-theora"); + * sprof = gst_encoding_container_profile_add_profile( + * (GstEncodingProfile*) gst_encoding_video_profile_new(caps, NULL, NULL, 0)); + * gst_caps_unref (caps); + * + * caps = gst_caps_from_string("audio/x-vorbis"); + * sprof = gst_encoding_container_profile_add_profile( + * (GstEncodingProfile*) gst_encoding_audio_profile_new(caps, NULL, NULL, 0)); + * gst_caps_unref (caps); + * + * return (GstEncodingProfile*) prof; + *} + * + * + * ]| + * + * + * + * Example: Loading a profile from disk + * + * |[ + * #include + * ... + *GstEncodingProfile * + *get_ogg_theora_profile(const gchar *path, const gchar *profilename) + *{ + * GstEncodingProfile *prof = NULL; + * GstEncodingTarget *target = NULL; + * GList *tmp; + * + * target = gst_encoding_target_load_from (path); + * if (target == NULL) + * return NULL; + * + * for (tmp = target->profiles; tmp; tmp = tmp->next) { + * GstEncodingProfile *ptmp = (GstEncodingProfile*) tmp->data; + * + * if (!strcmp(gst_encoding_profile_get_name(ptmp), profilename)) { + * prof = ptmp; + * break; + * } + * } + * + * return prof; + *} + * ]| + * + * + * + * Since: 0.10.32 + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include "encoding-profile.h" + +/* GstEncodingProfile API */ + +struct _GstEncodingProfile +{ + GstMiniObject parent; + + /*< public > */ + gchar *name; + gchar *description; + GstCaps *format; + gchar *preset; + guint presence; + GstCaps *restriction; +}; + +G_DEFINE_TYPE (GstEncodingProfile, gst_encoding_profile, GST_TYPE_MINI_OBJECT); + +static void +gst_encoding_profile_init (GstEncodingProfile * prof) +{ + /* Nothing to initialize */ +} + +static void +gst_encoding_profile_finalize (GstEncodingProfile * prof) +{ + if (prof->name) + g_free (prof->name); + if (prof->format) + gst_caps_unref (prof->format); + if (prof->preset) + g_free (prof->preset); + if (prof->description) + g_free (prof->description); + if (prof->restriction) + gst_caps_unref (prof->restriction); +} + +static void +gst_encoding_profile_class_init (GstMiniObjectClass * klass) +{ + klass->finalize = + (GstMiniObjectFinalizeFunction) gst_encoding_profile_finalize; +} + +/** + * gst_encoding_profile_get_name: + * @profile: a #GstEncodingProfile + * + * Since: 0.10.32 + * + * Returns: the name of the profile, can be %NULL. + */ +const gchar * +gst_encoding_profile_get_name (GstEncodingProfile * profile) +{ + return profile->name; +} + +/** + * gst_encoding_profile_get_description: + * @profile: a #GstEncodingProfile + * + * Since: 0.10.32 + * + * Returns: the description of the profile, can be %NULL. + */ +const gchar * +gst_encoding_profile_get_description (GstEncodingProfile * profile) +{ + return profile->description; +} + +/** + * gst_encoding_profile_get_format: + * @profile: a #GstEncodingProfile + * + * Since: 0.10.32 + * + * Returns: the media format used in the profile. + */ +const GstCaps * +gst_encoding_profile_get_format (GstEncodingProfile * profile) +{ + return profile->format; +} + +/** + * gst_encoding_profile_get_preset: + * @profile: a #GstEncodingProfile + * + * Since: 0.10.32 + * + * Returns: the preset to be used in the profile. + */ +const gchar * +gst_encoding_profile_get_preset (GstEncodingProfile * profile) +{ + return profile->preset; +} + +/** + * gst_encoding_profile_get_presence: + * @profile: a #GstEncodingProfile + * + * Since: 0.10.32 + * + * Returns: The number of time the profile is used in its parent + * container profile. If 0, it is not a mandatory stream + */ +const guint +gst_encoding_profile_get_presence (GstEncodingProfile * profile) +{ + return profile->presence; +} + +/** + * gst_encoding_profile_get_restriction: + * @profile: a #GstEncodingProfile + * + * Since: 0.10.32 + * + * Returns: The restriction #GstCaps to apply before the encoder + * that will be used in the profile. Does not apply to #GstEncodingContainerProfile. + * Can be %NULL. + */ +const GstCaps * +gst_encoding_profile_get_restriction (GstEncodingProfile * profile) +{ + return profile->restriction; +} + +/** + * gst_encoding_profile_set_name: + * @profile: a #GstEncodingProfile + * @name: the name to set on the profile + * + * Since: 0.10.32 + * + * Set @name as the given name for the @profile. A copy of @name will be made + * internally. + */ +void +gst_encoding_profile_set_name (GstEncodingProfile * profile, const gchar * name) +{ + if (profile->name) + g_free (profile->name); + profile->name = g_strdup (name); +} + +/** + * gst_encoding_profile_set_description: + * @profile: a #GstEncodingProfile + * @description: the description to set on the profile + * + * Since: 0.10.32 + * + * Set @description as the given description for the @profile. A copy of @description will be made + * internally. + */ +void +gst_encoding_profile_set_description (GstEncodingProfile * profile, + const gchar * description) +{ + if (profile->description) + g_free (profile->description); + profile->description = g_strdup (description); +} + +/** + * gst_encoding_profile_set_format: + * @profile: a #GstEncodingProfile + * @format: the media format to use in the profile. + * + * Since: 0.10.32 + * + * Sets the media format used in the profile. + */ +void +gst_encoding_profile_set_format (GstEncodingProfile * profile, GstCaps * format) +{ + if (profile->format) + gst_caps_unref (profile->format); + profile->format = gst_caps_ref (format); +} + +/** + * gst_encoding_profile_set_preset: + * @profile: a #GstEncodingProfile + * @preset: the element preset to use + * + * Since: 0.10.32 + * + * Sets the preset to use for the profile. + */ +void +gst_encoding_profile_set_preset (GstEncodingProfile * profile, + const gchar * preset) +{ + if (profile->preset) + g_free (profile->preset); + profile->preset = g_strdup (preset); +} + +/** + * gst_encoding_profile_set_presence: + * @profile: a #GstEncodingProfile + * @presence: the number of time the profile can be used + * + * Since: 0.10.32 + * + * Set the number of time the profile is used in its parent + * container profile. If 0, it is not a mandatory stream + */ +void +gst_encoding_profile_set_presence (GstEncodingProfile * profile, guint presence) +{ + profile->presence = presence; +} + +/** + * gst_encoding_profile_set_restriction: + * @profile: a #GstEncodingProfile + * @restriction: the restriction to apply + * + * Since: 0.10.32 + * + * Set the restriction #GstCaps to apply before the encoder + * that will be used in the profile. Does not apply to #GstEncodingContainerProfile. + */ +void +gst_encoding_profile_set_restriction (GstEncodingProfile * profile, + GstCaps * restriction) +{ + if (profile->restriction) + gst_caps_unref (profile->restriction); + profile->restriction = restriction; +} + +/* Container profiles */ + +struct _GstEncodingContainerProfile +{ + GstEncodingProfile parent; + + GList *encodingprofiles; +}; + +G_DEFINE_TYPE (GstEncodingContainerProfile, gst_encoding_container_profile, + GST_TYPE_ENCODING_PROFILE); + +static void +gst_encoding_container_profile_init (GstEncodingContainerProfile * prof) +{ + /* Nothing to initialize */ +} + +static void +gst_encoding_container_profile_finalize (GstEncodingContainerProfile * prof) +{ + g_list_foreach (prof->encodingprofiles, (GFunc) gst_mini_object_unref, NULL); + g_list_free (prof->encodingprofiles); + + GST_MINI_OBJECT_CLASS (gst_encoding_container_profile_parent_class)->finalize + ((GstMiniObject *) prof); +} + +static void +gst_encoding_container_profile_class_init (GstMiniObjectClass * klass) +{ + klass->finalize = + (GstMiniObjectFinalizeFunction) gst_encoding_container_profile_finalize; +} + +const GList * +gst_encoding_container_profile_get_profiles (GstEncodingContainerProfile * + profile) +{ + return profile->encodingprofiles; +} + +/* Video profiles */ + +struct _GstEncodingVideoProfile +{ + GstEncodingProfile parent; + + guint pass; + gboolean variableframerate; +}; + +G_DEFINE_TYPE (GstEncodingVideoProfile, gst_encoding_video_profile, + GST_TYPE_ENCODING_PROFILE); + +static void +gst_encoding_video_profile_init (GstEncodingVideoProfile * prof) +{ + /* Nothing to initialize */ +} + +static void +gst_encoding_video_profile_class_init (GstMiniObjectClass * klass) +{ +} + +/** + * gst_encoding_video_profile_get_pass: + * @prof: a #GstEncodingVideoProfile + * + * Since: 0.10.32 + * + * Returns: The pass number if this is part of a multi-pass profile. Starts at + * 1 for multi-pass. 0 if this is not a multi-pass profile + **/ +guint +gst_encoding_video_profile_get_pass (GstEncodingVideoProfile * prof) +{ + return prof->pass; +} + +/** + * gst_encoding_video_profile_get_variableframerate: + * @prof: a #GstEncodingVideoProfile + * + * Since: 0.10.32 + * + * Returns: Whether non-constant video framerate is allowed for encoding. + */ +gboolean +gst_encoding_video_profile_get_variableframerate (GstEncodingVideoProfile * + prof) +{ + return prof->variableframerate; +} + +/** + * gst_encoding_video_profile_set_pass: + * @prof: a #GstEncodingVideoProfile + * @pass: the pass number for this profile + * + * Since: 0.10.32 + * + * Sets the pass number of this video profile. The first pass profile should have + * this value set to 1. If this video profile isn't part of a multi-pass profile, + * you may set it to 0 (the default value). + */ +void +gst_encoding_video_profile_set_pass (GstEncodingVideoProfile * prof, guint pass) +{ + prof->pass = pass; +} + +/** + * gst_encoding_video_profile_set_variableframerate: + * @prof: a #GstEncodingVideoProfile + * @variableframerate: a boolean + * + * Since: 0.10.32 + * + * If set to %TRUE, then the incoming streamm will be allowed to have non-constant + * framerate. If set to %FALSE (default value), then the incoming stream will + * be normalized by dropping/duplicating frames in order to produce a + * constance framerate. + */ +void +gst_encoding_video_profile_set_variableframerate (GstEncodingVideoProfile * + prof, gboolean variableframerate) +{ + prof->variableframerate = variableframerate; +} + +/* Audio profiles */ + +struct _GstEncodingAudioProfile +{ + GstEncodingProfile parent; +}; + +G_DEFINE_TYPE (GstEncodingAudioProfile, gst_encoding_audio_profile, + GST_TYPE_ENCODING_PROFILE); + +static void +gst_encoding_audio_profile_init (GstEncodingAudioProfile * prof) +{ + /* Nothing to initialize */ +} + +static void +gst_encoding_audio_profile_class_init (GstMiniObjectClass * klass) +{ +} + +static inline gboolean +_gst_caps_is_equal_safe (GstCaps * a, GstCaps * b) +{ + if (a == b) + return TRUE; + if ((a == NULL) || (b == NULL)) + return FALSE; + return gst_caps_is_equal (a, b); +} + +static gint +_compare_container_encoding_profiles (GstEncodingContainerProfile * ca, + GstEncodingContainerProfile * cb) +{ + GList *tmp; + + if (g_list_length (ca->encodingprofiles) != + g_list_length (cb->encodingprofiles)) + return -1; + + for (tmp = ca->encodingprofiles; tmp; tmp = tmp->next) { + GstEncodingProfile *prof = (GstEncodingProfile *) tmp->data; + if (!gst_encoding_container_profile_contains_profile (ca, prof)) + return -1; + } + + return 0; +} + +static gint +_compare_encoding_profiles (const GstEncodingProfile * a, + const GstEncodingProfile * b) +{ + if ((G_TYPE_FROM_INSTANCE (a) != G_TYPE_FROM_INSTANCE (b)) || + !_gst_caps_is_equal_safe (a->format, b->format) || + (g_strcmp0 (a->preset, b->preset) != 0) || + (g_strcmp0 (a->name, b->name) != 0) || + (g_strcmp0 (a->description, b->description) != 0)) + return -1; + + if (GST_IS_ENCODING_CONTAINER_PROFILE (a)) + return + _compare_container_encoding_profiles (GST_ENCODING_CONTAINER_PROFILE + (a), GST_ENCODING_CONTAINER_PROFILE (b)); + + if (GST_IS_ENCODING_VIDEO_PROFILE (a)) { + GstEncodingVideoProfile *va = (GstEncodingVideoProfile *) a; + GstEncodingVideoProfile *vb = (GstEncodingVideoProfile *) b; + + if ((va->pass != vb->pass) + || (va->variableframerate != vb->variableframerate)) + return -1; + } + + return 0; +} + +/** + * gst_encoding_container_profile_contains_profile: + * @container: a #GstEncodingContainerProfile + * @profile: a #GstEncodingProfile + * + * Checks if @container contains a #GstEncodingProfile identical to + * @profile. + * + * Since: 0.10.32 + * + * Returns: %TRUE if @container contains a #GstEncodingProfile identical + * to @profile, else %FALSE. + */ +gboolean +gst_encoding_container_profile_contains_profile (GstEncodingContainerProfile * + container, GstEncodingProfile * profile) +{ + g_return_val_if_fail (GST_IS_ENCODING_CONTAINER_PROFILE (container), FALSE); + g_return_val_if_fail (GST_IS_ENCODING_PROFILE (profile), FALSE); + + return (g_list_find_custom (container->encodingprofiles, profile, + (GCompareFunc) _compare_encoding_profiles) != NULL); +} + +/** + * gst_encoding_container_profile_add_profile: + * @container: the #GstEncodingContainerProfile to use + * @profile: the #GstEncodingProfile to add. + * + * Add a #GstEncodingProfile to the list of profiles handled by @container. + * + * No copy of @profile will be made, if you wish to use it elsewhere after this + * method you should increment its reference count. + * + * Since: 0.10.32 + * + * Returns: %TRUE if the @stream was properly added, else %FALSE. + */ +gboolean +gst_encoding_container_profile_add_profile (GstEncodingContainerProfile * + container, GstEncodingProfile * profile) +{ + g_return_val_if_fail (GST_IS_ENCODING_CONTAINER_PROFILE (container), FALSE); + g_return_val_if_fail (GST_IS_ENCODING_PROFILE (profile), FALSE); + + if (g_list_find_custom (container->encodingprofiles, profile, + (GCompareFunc) _compare_encoding_profiles)) { + GST_ERROR + ("Encoding profile already contains an identical GstEncodingProfile"); + return FALSE; + } + + container->encodingprofiles = + g_list_append (container->encodingprofiles, profile); + + return TRUE; +} + +static GstEncodingProfile * +common_creation (GType objtype, GstCaps * format, const gchar * preset, + const gchar * name, const gchar * description, GstCaps * restriction, + guint presence) +{ + GstEncodingProfile *prof; + + prof = (GstEncodingProfile *) gst_mini_object_new (objtype); + + if (name) + prof->name = g_strdup (name); + if (description) + prof->description = g_strdup (description); + if (preset) + prof->preset = g_strdup (preset); + if (format) + prof->format = gst_caps_ref (format); + if (restriction) + prof->restriction = gst_caps_ref (restriction); + prof->presence = presence; + + return prof; +} + +/** + * gst_encoding_container_profile_new: + * @name: The name of the container profile, can be %NULL + * @description: The description of the container profile, can be %NULL + * @format: The format to use for this profile + * @preset: The preset to use for this profile + * + * Creates a new #GstEncodingContainerProfile. + * + * Since: 0.10.32 + * + * Returns: The newly created #GstEncodingContainerProfile. + */ +GstEncodingContainerProfile * +gst_encoding_container_profile_new (const gchar * name, + const gchar * description, GstCaps * format, const gchar * preset) +{ + return (GstEncodingContainerProfile *) + common_creation (GST_TYPE_ENCODING_CONTAINER_PROFILE, format, preset, + name, description, NULL, 0); +} + +/** + * gst_encoding_video_profile_new: + * @format: the #GstCaps + * @preset: the preset(s) to use on the encoder, can be #NULL + * @restriction: the #GstCaps used to restrict the input to the encoder, can be + * NULL. + * @presence: the number of time this stream must be used. 0 means any number of + * times (including never) + * + * Creates a new #GstEncodingVideoProfile + * + * All provided allocatable arguments will be internally copied, so can be + * safely freed/unreferenced after calling this method. + * + * If you wish to control the pass number (in case of multi-pass scenarios), + * please refer to the gst_encoding_video_profile_set_pass() documentation. + * + * If you wish to use/force a constant framerate please refer to the + * gst_encoding_video_profile_set_variableframerate() documentation. + * + * Since: 0.10.32 + * + * Returns: the newly created #GstEncodingVideoProfile. + */ +GstEncodingVideoProfile * +gst_encoding_video_profile_new (GstCaps * format, const gchar * preset, + GstCaps * restriction, guint presence) +{ + return (GstEncodingVideoProfile *) + common_creation (GST_TYPE_ENCODING_VIDEO_PROFILE, format, preset, NULL, + NULL, restriction, presence); +} + +/** + * gst_encoding_audio_profile_new: + * @format: the #GstCaps + * @preset: the preset(s) to use on the encoder, can be #NULL + * @restriction: the #GstCaps used to restrict the input to the encoder, can be + * NULL. + * @presence: the number of time this stream must be used. 0 means any number of + * times (including never) + * + * Creates a new #GstEncodingAudioProfile + * + * All provided allocatable arguments will be internally copied, so can be + * safely freed/unreferenced after calling this method. + * + * Since: 0.10.32 + * + * Returns: the newly created #GstEncodingAudioProfile. + */ +GstEncodingAudioProfile * +gst_encoding_audio_profile_new (GstCaps * format, const gchar * preset, + GstCaps * restriction, guint presence) +{ + return (GstEncodingAudioProfile *) + common_creation (GST_TYPE_ENCODING_AUDIO_PROFILE, format, preset, NULL, + NULL, restriction, presence); +} + + +/** + * gst_encoding_profile_is_equal: + * @a: a #GstEncodingProfile + * @b: a #GstEncodingProfile + * + * Checks whether the two #GstEncodingProfile are equal + * + * Since: 0.10.32 + * + * Returns: %TRUE if @a and @b are equal, else %FALSE. + */ +gboolean +gst_encoding_profile_is_equal (GstEncodingProfile * a, GstEncodingProfile * b) +{ + return (_compare_encoding_profiles (a, b) == 0); +} + + +/** + * gst_encoding_profile_get_output_caps: + * @profile: a #GstEncodingProfile + * + * Computes the full output caps that this @profile will be able to consume. + * + * Since: 0.10.32 + * + * Returns: The full caps the given @profile can consume. Call gst_caps_unref() + * when you are done with the caps. + */ +GstCaps * +gst_encoding_profile_get_output_caps (GstEncodingProfile * profile) +{ + GstCaps *out, *tmp; + GList *ltmp; + GstStructure *st, *outst; + GQuark out_name; + guint i, len; + const GstCaps *fcaps; + + if (GST_IS_ENCODING_CONTAINER_PROFILE (profile)) { + GstCaps *res = gst_caps_new_empty (); + + for (ltmp = GST_ENCODING_CONTAINER_PROFILE (profile)->encodingprofiles; + ltmp; ltmp = ltmp->next) { + GstEncodingProfile *sprof = (GstEncodingProfile *) ltmp->data; + gst_caps_merge (res, gst_encoding_profile_get_output_caps (sprof)); + } + return res; + } + + fcaps = profile->format; + + /* fast-path */ + if ((profile->restriction == NULL) || gst_caps_is_any (profile->restriction)) + return gst_caps_copy (fcaps); + + /* Combine the format with the restriction caps */ + outst = gst_caps_get_structure (fcaps, 0); + out_name = gst_structure_get_name_id (outst); + tmp = gst_caps_new_empty (); + len = gst_caps_get_size (profile->restriction); + + for (i = 0; i < len; i++) { + st = gst_structure_copy (gst_caps_get_structure (profile->restriction, i)); + st->name = out_name; + gst_caps_append_structure (tmp, st); + } + + out = gst_caps_intersect (tmp, fcaps); + gst_caps_unref (tmp); + + return out; +} + +/** + * gst_encoding_profile_get_type_nick: + * @profile: a #GstEncodingProfile + * + * Since: 0.10.32 + * + * Returns: the human-readable name of the type of @profile. + */ +const gchar * +gst_encoding_profile_get_type_nick (GstEncodingProfile * profile) +{ + if (GST_IS_ENCODING_CONTAINER_PROFILE (profile)) + return "container"; + if (GST_IS_ENCODING_VIDEO_PROFILE (profile)) + return "video"; + if (GST_IS_ENCODING_AUDIO_PROFILE (profile)) + return "audio"; + return NULL; +} diff --git a/gst-libs/gst/pbutils/encoding-profile.h b/gst-libs/gst/pbutils/encoding-profile.h new file mode 100644 index 0000000000..3c6f3c3d37 --- /dev/null +++ b/gst-libs/gst/pbutils/encoding-profile.h @@ -0,0 +1,184 @@ +/* GStreamer encoding profiles library + * Copyright (C) 2009-2010 Edward Hervey + * (C) 2009-2010 Nokia Corporation + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef __GST_PROFILE_H__ +#define __GST_PROFILE_H__ + +#include + +G_BEGIN_DECLS + +#include + +/** + * GstEncodingProfile: + * + * The opaque base class object for all encoding profiles. This contains generic + * information like name, description, format and preset. + * + * Since: 0.10.32 + */ + +#define GST_TYPE_ENCODING_PROFILE \ + (gst_encoding_profile_get_type ()) +#define GST_ENCODING_PROFILE(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_ENCODING_PROFILE, GstEncodingProfile)) +#define GST_IS_ENCODING_PROFILE(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_ENCODING_PROFILE)) +typedef struct _GstEncodingProfile GstEncodingProfile; +typedef GstMiniObjectClass GstEncodingProfileClass; +GType gst_encoding_profile_get_type (void); + + + +/** + * GstEncodingContainerProfile: + * + * Encoding profiles for containers. Keeps track of a list of #GstEncodingProfile + * + * Since: 0.10.32 + */ +#define GST_TYPE_ENCODING_CONTAINER_PROFILE \ + (gst_encoding_container_profile_get_type ()) +#define GST_ENCODING_CONTAINER_PROFILE(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_ENCODING_CONTAINER_PROFILE, GstEncodingContainerProfile)) +#define GST_IS_ENCODING_CONTAINER_PROFILE(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_ENCODING_CONTAINER_PROFILE)) +typedef struct _GstEncodingContainerProfile GstEncodingContainerProfile; +typedef GstEncodingProfileClass GstEncodingContainerProfileClass; +GType gst_encoding_container_profile_get_type (void); + + + +/** + * GstEncodingVideoProfile: + * + * Variant of #GstEncodingProfile for video streams, allows specifying the @pass. + * + * Since: 0.10.32 + */ +#define GST_TYPE_ENCODING_VIDEO_PROFILE \ + (gst_encoding_video_profile_get_type ()) +#define GST_ENCODING_VIDEO_PROFILE(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_ENCODING_VIDEO_PROFILE, GstEncodingVideoProfile)) +#define GST_IS_ENCODING_VIDEO_PROFILE(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_ENCODING_VIDEO_PROFILE)) +typedef struct _GstEncodingVideoProfile GstEncodingVideoProfile; +typedef GstEncodingProfileClass GstEncodingVideoProfileClass; +GType gst_encoding_video_profile_get_type (void); + + + +/** + * GstEncodingAudioProfile: + * + * Variant of #GstEncodingProfile for audio streams. + * + * Since: 0.10.32 + */ +#define GST_TYPE_ENCODING_AUDIO_PROFILE \ + (gst_encoding_audio_profile_get_type ()) +#define GST_ENCODING_AUDIO_PROFILE(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_ENCODING_AUDIO_PROFILE, GstEncodingAudioProfile)) +#define GST_IS_ENCODING_AUDIO_PROFILE(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_ENCODING_AUDIO_PROFILE)) +typedef struct _GstEncodingAudioProfile GstEncodingAudioProfile; +typedef GstEncodingProfileClass GstEncodingAudioProfileClass; +GType gst_encoding_audio_profile_get_type (void); + + + +/* GstEncodingProfile API */ + +/** + * gst_encoding_profile_unref: + * @profile: a #GstEncodingProfile + * + * Decreases the reference count of the @profile, possibly freeing the @profile. + * + * Since: 0.10.32 + */ +#define gst_encoding_profile_unref(profile) (gst_mini_object_unref ((GstMiniObject*) profile)) + +/** + * gst_encoding_profile_ref: + * @profile: a #GstEncodingProfile + * + * Increases the reference count of the @profile. + * + * Since: 0.10.32 + */ +#define gst_encoding_profile_ref(profile) (gst_mini_object_ref ((GstMiniObject*) profile)) + +const gchar * gst_encoding_profile_get_name(GstEncodingProfile *profile); +const gchar * gst_encoding_profile_get_description(GstEncodingProfile *profile); +const GstCaps * gst_encoding_profile_get_format(GstEncodingProfile *profile); +const gchar * gst_encoding_profile_get_preset(GstEncodingProfile *profile); +const guint gst_encoding_profile_get_presence(GstEncodingProfile *profile); +const GstCaps * gst_encoding_profile_get_restriction(GstEncodingProfile *profile); + +void gst_encoding_profile_set_name(GstEncodingProfile *profile, const gchar *name); +void gst_encoding_profile_set_description(GstEncodingProfile *profile, const gchar *description); +void gst_encoding_profile_set_format(GstEncodingProfile *profile, GstCaps *format); +void gst_encoding_profile_set_preset(GstEncodingProfile *profile, const gchar *preset); +void gst_encoding_profile_set_restriction(GstEncodingProfile *profile, GstCaps *restriction); +void gst_encoding_profile_set_presence(GstEncodingProfile *profile, guint presence); + +gboolean gst_encoding_profile_is_equal (GstEncodingProfile *a, + GstEncodingProfile *b); +GstCaps * gst_encoding_profile_get_output_caps (GstEncodingProfile *profile); + +const gchar *gst_encoding_profile_get_type_nick (GstEncodingProfile *profile); + +/* GstEncodingContainerProfile API */ +gboolean gst_encoding_container_profile_add_profile (GstEncodingContainerProfile *container, + GstEncodingProfile *profile); +gboolean gst_encoding_container_profile_contains_profile (GstEncodingContainerProfile * container, + GstEncodingProfile *profile); +const GList *gst_encoding_container_profile_get_profiles (GstEncodingContainerProfile *profile); + + +GstEncodingContainerProfile * gst_encoding_container_profile_new (const gchar *name, + const gchar *description, + GstCaps *format, + const gchar *preset); + + +/* Invidual stream encodingprofile API */ +GstEncodingVideoProfile * gst_encoding_video_profile_new (GstCaps *format, + const gchar *preset, + GstCaps *restriction, + guint presence); +GstEncodingAudioProfile * gst_encoding_audio_profile_new (GstCaps *format, + const gchar *preset, + GstCaps *restriction, + guint presence); + +guint gst_encoding_video_profile_get_pass (GstEncodingVideoProfile *prof); +gboolean gst_encoding_video_profile_get_variableframerate (GstEncodingVideoProfile *prof); + +void gst_encoding_video_profile_set_pass (GstEncodingVideoProfile *prof, + guint pass); +void gst_encoding_video_profile_set_variableframerate (GstEncodingVideoProfile *prof, + gboolean variableframerate); + +G_END_DECLS + +#endif /* __GST_PROFILE_H__ */ diff --git a/gst-libs/gst/pbutils/encoding-target.c b/gst-libs/gst/pbutils/encoding-target.c new file mode 100644 index 0000000000..19065e8fe7 --- /dev/null +++ b/gst-libs/gst/pbutils/encoding-target.c @@ -0,0 +1,724 @@ +/* GStreamer encoding profile registry + * Copyright (C) 2010 Edward Hervey + * (C) 2010 Nokia Corporation + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include +#include "encoding-target.h" + +/* + * File format + * + * GKeyFile style. + * + * [_gstencodingtarget_] + * name : + * category : + * description : #translatable + * + * [profile-] + * name : + * description : #optional + * format : + * preset : + * + * [streamprofile-] + * parent : [,..] + * type : # "audio", "video", "text" + * format : + * preset : + * restriction : + * presence : + * pass : + * variableframerate : + * */ + +#define GST_ENCODING_TARGET_HEADER "_gstencodingtarget_" + +struct _GstEncodingTarget +{ + GstMiniObject parent; + + gchar *name; + gchar *category; + gchar *description; + GList *profiles; + + /*< private > */ + gchar *keyfile; +}; + +G_DEFINE_TYPE (GstEncodingTarget, gst_encoding_target, GST_TYPE_MINI_OBJECT); + +static void +gst_encoding_target_init (GstEncodingTarget * target) +{ + /* Nothing to initialize */ +} + +static void +gst_encoding_target_finalize (GstEncodingTarget * target) +{ + GST_DEBUG ("Finalizing"); + + if (target->name) + g_free (target->name); + if (target->category) + g_free (target->category); + if (target->description) + g_free (target->description); + + g_list_foreach (target->profiles, (GFunc) gst_mini_object_unref, NULL); + g_list_free (target->profiles); +} + +static void +gst_encoding_target_class_init (GstMiniObjectClass * klass) +{ + klass->finalize = + (GstMiniObjectFinalizeFunction) gst_encoding_target_finalize; +} + +/** + * gst_encoding_target_get_name: + * @target: a #GstEncodingTarget + * + * Since: 0.10.32 + * + * Returns: The name of the @target. + */ +const gchar * +gst_encoding_target_get_name (GstEncodingTarget * target) +{ + return target->name; +} + +/** + * gst_encoding_target_get_category: + * @target: a #GstEncodingTarget + * + * Since: 0.10.32 + * + * Returns: The category of the @target. + */ +const gchar * +gst_encoding_target_get_category (GstEncodingTarget * target) +{ + return target->category; +} + +/** + * gst_encoding_target_get_description: + * @target: a #GstEncodingTarget + * + * Since: 0.10.32 + * + * Returns: The description of the @target. + */ +const gchar * +gst_encoding_target_get_description (GstEncodingTarget * target) +{ + return target->description; +} + +/** + * gst_encoding_target_get_profiles: + * @target: a #GstEncodingTarget + * + * Since: 0.10.32 + * + * Returns: A list of #GstEncodingProfile(s) this @target handles. + */ +const GList * +gst_encoding_target_get_profiles (GstEncodingTarget * target) +{ + return target->profiles; +} + + +/** + * gst_encoding_target_new: + * @name: The name of the target. + * @category: The name of the category to which this @target belongs. + * @description: A description of #GstEncodingTarget in the current locale. + * @profiles: A #GList of #GstEncodingProfile. + * + * Creates a new #GstEncodingTarget. + * + * Since: 0.10.32 + * + * Returns: The newly created #GstEncodingTarget or %NULL if there was an + * error. + */ + +GstEncodingTarget * +gst_encoding_target_new (const gchar * name, const gchar * category, + const gchar * description, const GList * profiles) +{ + GstEncodingTarget *res; + + g_return_val_if_fail (name != NULL, NULL); + g_return_val_if_fail (category != NULL, NULL); + g_return_val_if_fail (description != NULL, NULL); + + res = (GstEncodingTarget *) gst_mini_object_new (GST_TYPE_ENCODING_TARGET); + res->name = g_strdup (name); + res->category = g_strdup (category); + res->description = g_strdup (description); + + while (profiles) { + GstEncodingProfile *prof = (GstEncodingProfile *) profiles->data; + + res->profiles = + g_list_append (res->profiles, gst_encoding_profile_ref (prof)); + profiles = profiles->next; + } + + return res; +} + +/** + * gst_encoding_target_add_profile: + * @target: the #GstEncodingTarget to add a profile to + * @profile: the #GstEncodingProfile to add + * + * Adds the given @profile to the @target. + * + * The @target will steal a reference to the @profile. If you wish to use + * the profile after calling this method, you should increase its reference + * count. + * + * Since: 0.10.32 + * + * Returns: %TRUE if the profile was added, else %FALSE. + **/ + +gboolean +gst_encoding_target_add_profile (GstEncodingTarget * target, + GstEncodingProfile * profile) +{ + GList *tmp; + + g_return_val_if_fail (GST_IS_ENCODING_TARGET (target), FALSE); + g_return_val_if_fail (GST_IS_ENCODING_PROFILE (profile), FALSE); + + /* Make sure profile isn't already controlled by this target */ + for (tmp = target->profiles; tmp; tmp = tmp->next) { + GstEncodingProfile *prof = (GstEncodingProfile *) tmp->data; + + if (!g_strcmp0 (gst_encoding_profile_get_name (profile), + gst_encoding_profile_get_name (prof))) { + GST_WARNING ("Profile already present in target"); + return FALSE; + } + } + + target->profiles = g_list_append (target->profiles, profile); + + return TRUE; +} + +static gboolean +serialize_stream_profiles (GKeyFile * out, GstEncodingProfile * sprof, + const gchar * profilename, guint id) +{ + gchar *sprofgroupname; + gchar *tmpc; + const GstCaps *format, *restriction; + const gchar *preset, *name, *description; + + sprofgroupname = g_strdup_printf ("streamprofile-%s-%d", profilename, id); + + /* Write the parent profile */ + g_key_file_set_value (out, sprofgroupname, "parent", profilename); + + g_key_file_set_value (out, sprofgroupname, "type", + gst_encoding_profile_get_type_nick (sprof)); + + format = gst_encoding_profile_get_format (sprof); + if (format) { + tmpc = gst_caps_to_string (format); + g_key_file_set_value (out, sprofgroupname, "format", tmpc); + g_free (tmpc); + } + + name = gst_encoding_profile_get_name (sprof); + if (name) + g_key_file_set_string (out, sprofgroupname, "name", name); + + description = gst_encoding_profile_get_description (sprof); + if (description) + g_key_file_set_string (out, sprofgroupname, "description", description); + + preset = gst_encoding_profile_get_preset (sprof); + if (preset) + g_key_file_set_string (out, sprofgroupname, "preset", preset); + + restriction = gst_encoding_profile_get_restriction (sprof); + if (restriction) { + tmpc = gst_caps_to_string (restriction); + g_key_file_set_value (out, sprofgroupname, "restriction", tmpc); + g_free (tmpc); + } + g_key_file_set_integer (out, sprofgroupname, "presence", + gst_encoding_profile_get_presence (sprof)); + + if (GST_IS_ENCODING_VIDEO_PROFILE (sprof)) { + GstEncodingVideoProfile *vp = (GstEncodingVideoProfile *) sprof; + + g_key_file_set_integer (out, sprofgroupname, "pass", + gst_encoding_video_profile_get_pass (vp)); + g_key_file_set_boolean (out, sprofgroupname, "variableframerate", + gst_encoding_video_profile_get_variableframerate (vp)); + } + + g_free (sprofgroupname); + return TRUE; +} + +/* Serialize the top-level profiles + * Note: They don't have to be containerprofiles */ +static gboolean +serialize_encoding_profile (GKeyFile * out, GstEncodingProfile * prof) +{ + gchar *profgroupname; + const GList *tmp; + guint i; + const gchar *profname, *profdesc, *profpreset, *proftype; + const GstCaps *profformat, *profrestriction; + + profname = gst_encoding_profile_get_name (prof); + profdesc = gst_encoding_profile_get_description (prof); + profformat = gst_encoding_profile_get_format (prof); + profpreset = gst_encoding_profile_get_preset (prof); + proftype = gst_encoding_profile_get_type_nick (prof); + profrestriction = gst_encoding_profile_get_restriction (prof); + + profgroupname = g_strdup_printf ("profile-%s", profname); + + g_key_file_set_string (out, profgroupname, "name", profname); + + g_key_file_set_value (out, profgroupname, "type", + gst_encoding_profile_get_type_nick (prof)); + + if (profdesc) + g_key_file_set_locale_string (out, profgroupname, "description", + setlocale (LC_ALL, NULL), profdesc); + if (profformat) { + gchar *tmpc = gst_caps_to_string (profformat); + g_key_file_set_string (out, profgroupname, "format", tmpc); + g_free (tmpc); + } + if (profpreset) + g_key_file_set_string (out, profgroupname, "preset", profpreset); + + /* stream profiles */ + if (GST_IS_ENCODING_CONTAINER_PROFILE (prof)) { + for (tmp = + gst_encoding_container_profile_get_profiles + (GST_ENCODING_CONTAINER_PROFILE (prof)), i = 0; tmp; + tmp = tmp->next, i++) { + GstEncodingProfile *sprof = (GstEncodingProfile *) tmp->data; + + if (!serialize_stream_profiles (out, sprof, profname, i)) + return FALSE; + } + } + g_free (profgroupname); + return TRUE; +} + +static gboolean +serialize_target (GKeyFile * out, GstEncodingTarget * target) +{ + GList *tmp; + + g_key_file_set_string (out, GST_ENCODING_TARGET_HEADER, "name", target->name); + g_key_file_set_string (out, GST_ENCODING_TARGET_HEADER, "category", + target->category); + g_key_file_set_string (out, GST_ENCODING_TARGET_HEADER, "description", + target->description); + + for (tmp = target->profiles; tmp; tmp = tmp->next) { + GstEncodingProfile *prof = (GstEncodingProfile *) tmp->data; + if (!serialize_encoding_profile (out, prof)) + return FALSE; + } + + return TRUE; +} + +/** + * parse_encoding_profile: + * @in: a #GKeyFile + * @parentprofilename: the parent profile name (including 'profile-' or 'streamprofile-' header) + * @profilename: the profile name group to parse + * @nbgroups: the number of top-level groups + * @groups: the top-level groups + */ +static GstEncodingProfile * +parse_encoding_profile (GKeyFile * in, gchar * parentprofilename, + gchar * profilename, gsize nbgroups, gchar ** groups) +{ + GstEncodingProfile *sprof = NULL; + gchar **parent; + gchar *proftype, *format, *preset, *restriction, *pname, *description; + GstCaps *formatcaps = NULL; + GstCaps *restrictioncaps = NULL; + gboolean variableframerate; + gint pass, presence; + gsize i, nbencprofiles; + + GST_DEBUG ("parentprofilename : %s , profilename : %s", + parentprofilename, profilename); + + if (parentprofilename) { + gboolean found = FALSE; + + parent = + g_key_file_get_string_list (in, profilename, "parent", + &nbencprofiles, NULL); + if (!parent || !nbencprofiles) { + return NULL; + } + + /* Check if this streamprofile is used in */ + for (i = 0; i < nbencprofiles; i++) { + if (!g_strcmp0 (parent[i], parentprofilename)) { + found = TRUE; + break; + } + } + g_strfreev (parent); + + if (!found) { + GST_DEBUG ("Stream profile '%s' isn't used in profile '%s'", + profilename, parentprofilename); + return NULL; + } + } + + pname = g_key_file_get_value (in, profilename, "name", NULL); + + /* First try to get localized description */ + description = + g_key_file_get_locale_string (in, profilename, "description", + setlocale (LC_ALL, NULL), NULL); + if (description == NULL) + description = g_key_file_get_value (in, profilename, "description", NULL); + + /* Parse the remaining fields */ + proftype = g_key_file_get_value (in, profilename, "type", NULL); + if (!proftype) { + GST_WARNING ("Missing 'type' field for streamprofile %s", profilename); + return NULL; + } + + format = g_key_file_get_value (in, profilename, "format", NULL); + if (format) { + formatcaps = gst_caps_from_string (format); + g_free (format); + } + + preset = g_key_file_get_value (in, profilename, "preset", NULL); + + restriction = g_key_file_get_value (in, profilename, "restriction", NULL); + if (restriction) { + restrictioncaps = gst_caps_from_string (restriction); + g_free (restriction); + } + + presence = g_key_file_get_integer (in, profilename, "presence", NULL); + pass = g_key_file_get_integer (in, profilename, "pass", NULL); + variableframerate = + g_key_file_get_boolean (in, profilename, "variableframerate", NULL); + + /* Build the streamprofile ! */ + if (!g_strcmp0 (proftype, "container")) { + GstEncodingProfile *pprof; + + sprof = + (GstEncodingProfile *) gst_encoding_container_profile_new (pname, + description, formatcaps, preset); + /* Now look for the stream profiles */ + for (i = 0; i < nbgroups; i++) { + if (!g_ascii_strncasecmp (groups[i], "streamprofile-", 13)) { + pprof = parse_encoding_profile (in, pname, groups[i], nbgroups, groups); + if (pprof) { + gst_encoding_container_profile_add_profile ( + (GstEncodingContainerProfile *) sprof, pprof); + } + } + } + } else if (!g_strcmp0 (proftype, "video")) { + sprof = + (GstEncodingProfile *) gst_encoding_video_profile_new (formatcaps, + preset, restrictioncaps, presence); + gst_encoding_video_profile_set_variableframerate ((GstEncodingVideoProfile + *) sprof, variableframerate); + gst_encoding_video_profile_set_pass ((GstEncodingVideoProfile *) sprof, + pass); + } else if (!g_strcmp0 (proftype, "audio")) { + sprof = + (GstEncodingProfile *) gst_encoding_audio_profile_new (formatcaps, + preset, restrictioncaps, presence); + } else + GST_ERROR ("Unknown profile format '%s'", proftype); + + if (restrictioncaps) + gst_caps_unref (restrictioncaps); + if (formatcaps) + gst_caps_unref (formatcaps); + + if (pname) + g_free (pname); + if (description) + g_free (description); + if (preset) + g_free (preset); + if (proftype) + g_free (proftype); + + return sprof; +} + +static GstEncodingTarget * +parse_keyfile (GKeyFile * in, gchar * targetname, gchar * categoryname, + gchar * description) +{ + GstEncodingTarget *res = NULL; + GstEncodingProfile *prof; + gchar **groups; + gsize i, nbgroups; + + res = gst_encoding_target_new (targetname, categoryname, description, NULL); + + /* Figure out the various profiles */ + groups = g_key_file_get_groups (in, &nbgroups); + for (i = 0; i < nbgroups; i++) { + if (!g_ascii_strncasecmp (groups[i], "profile-", 8)) { + prof = parse_encoding_profile (in, NULL, groups[i], nbgroups, groups); + if (prof) + gst_encoding_target_add_profile (res, prof); + } + } + + g_strfreev (groups); + + if (targetname) + g_free (targetname); + if (categoryname) + g_free (categoryname); + if (description) + g_free (description); + + return res; +} + +static GKeyFile * +load_file_and_read_header (const gchar * path, gchar ** targetname, + gchar ** categoryname, gchar ** description, GError ** error) +{ + GKeyFile *in; + gboolean res; + + in = g_key_file_new (); + + GST_DEBUG ("path:%s", path); + + res = + g_key_file_load_from_file (in, path, + G_KEY_FILE_KEEP_COMMENTS | G_KEY_FILE_KEEP_TRANSLATIONS, error); + if (!res || error != NULL) + goto load_error; + + *targetname = + g_key_file_get_value (in, GST_ENCODING_TARGET_HEADER, "name", error); + if (!*targetname) + goto empty_name; + + *categoryname = + g_key_file_get_value (in, GST_ENCODING_TARGET_HEADER, "category", NULL); + *description = + g_key_file_get_value (in, GST_ENCODING_TARGET_HEADER, "description", + NULL); + + return in; + +load_error: + { + GST_WARNING ("Unable to read GstEncodingTarget file %s: %s", + path, (*error)->message); + g_key_file_free (in); + return NULL; + } + +empty_name: + { + GST_WARNING ("Wrong header in file %s: %s", path, (*error)->message); + g_key_file_free (in); + return NULL; + } +} + +/** + * gst_encoding_target_load_from: + * @path: The file to load the #GstEncodingTarget from + * @error: If an error occured, this field will be filled in. + * + * Opens the provided file and returns the contained #GstEncodingTarget. + * + * Since: 0.10.32 + * + * Returns: The #GstEncodingTarget contained in the file, else %NULL + */ + +GstEncodingTarget * +gst_encoding_target_load_from (const gchar * path, GError ** error) +{ + GKeyFile *in; + gchar *targetname, *categoryname, *description; + GstEncodingTarget *res = NULL; + + in = load_file_and_read_header (path, &targetname, &categoryname, + &description, error); + if (!in) + goto beach; + + res = parse_keyfile (in, targetname, categoryname, description); + + g_key_file_free (in); + +beach: + return res; +} + +/** + * gst_encoding_target_load: + * @name: the name of the #GstEncodingTarget to load. + * @error: If an error occured, this field will be filled in. + * + * Searches for the #GstEncodingTarget with the given name, loads it + * and returns it. + * + * Warning: NOT IMPLEMENTED. + * + * Since: 0.10.32 + * + * Returns: The #GstEncodingTarget if available, else %NULL + */ + +GstEncodingTarget * +gst_encoding_target_load (const gchar * name, GError ** error) +{ + /* FIXME : IMPLEMENT */ + return NULL; +} + +/** + * gst_encoding_target_save: + * @target: a #GstEncodingTarget + * @error: If an error occured, this field will be filled in. + * + * Saves the @target to the default location. + * + * Warning: NOT IMPLEMENTED. + * + * Since: 0.10.32 + * + * Returns: %TRUE if the target was correctly saved, else %FALSE. + **/ + +gboolean +gst_encoding_target_save (GstEncodingTarget * target, GError ** error) +{ + g_return_val_if_fail (GST_IS_ENCODING_TARGET (target), FALSE); + + /* FIXME : IMPLEMENT */ + return FALSE; +} + +/** + * gst_encoding_target_save_to: + * @target: a #GstEncodingTarget + * @path: the location to store the @target at. + * @error: If an error occured, this field will be filled in. + * + * Saves the @target to the provided location. + * + * Since: 0.10.32 + * + * Returns: %TRUE if the target was correctly saved, else %FALSE. + **/ + +gboolean +gst_encoding_target_save_to (GstEncodingTarget * target, const gchar * path, + GError ** error) +{ + GKeyFile *out; + gchar *data; + gsize data_size; + + g_return_val_if_fail (GST_IS_ENCODING_TARGET (target), FALSE); + g_return_val_if_fail (path != NULL, FALSE); + + /* FIXME : Check path is valid and writable + * FIXME : Strip out profiles already present in system target */ + + /* Get unique name... */ + + /* Create output GKeyFile */ + out = g_key_file_new (); + + if (!serialize_target (out, target)) + goto serialize_failure; + + if (!(data = g_key_file_to_data (out, &data_size, error))) + goto convert_failed; + + if (!g_file_set_contents (path, data, data_size, error)) + goto write_failed; + + g_key_file_free (out); + g_free (data); + + return TRUE; + +serialize_failure: + { + GST_ERROR ("Failure serializing target"); + g_key_file_free (out); + return FALSE; + } + +convert_failed: + { + GST_ERROR ("Failure converting keyfile: %s", (*error)->message); + g_key_file_free (out); + g_free (data); + return FALSE; + } + +write_failed: + { + GST_ERROR ("Unable to write file %s: %s", path, (*error)->message); + g_key_file_free (out); + g_free (data); + return FALSE; + } +} diff --git a/gst-libs/gst/pbutils/encoding-target.h b/gst-libs/gst/pbutils/encoding-target.h new file mode 100644 index 0000000000..c23f526609 --- /dev/null +++ b/gst-libs/gst/pbutils/encoding-target.h @@ -0,0 +1,104 @@ +/* GStreamer encoding profile registry + * Copyright (C) 2010 Edward Hervey + * (C) 2010 Nokia Corporation + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef __GST_PROFILE_REGISTRY_H__ +#define __GST_PROFILE_REGISTRY_H__ + +#include + +G_BEGIN_DECLS + + +/* FIXME/UNKNOWNS + * + * Should encoding categories be well-known strings/quarks ? + * + */ + +#define GST_ENCODING_CATEGORY_DEVICE "device" +#define GST_ENCODING_CATEGORY_ONLINE_SERVICE "online-service" +#define GST_ENCODING_CATEGORY_STORAGE_EDITING "storage-editing" +#define GST_ENCODING_CATEGORY_CAPTURE "capture" + +/** + * GstEncodingTarget: + * + * Collection of #GstEncodingProfile for a specific target or use-case. + * + * Since: 0.10.32 + */ +#define GST_TYPE_ENCODING_TARGET \ + (gst_encoding_target_get_type ()) +#define GST_ENCODING_TARGET(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_ENCODING_TARGET, GstEncodingTarget)) +#define GST_IS_ENCODING_TARGET(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_ENCODING_TARGET)) + +typedef struct _GstEncodingTarget GstEncodingTarget; +typedef GstMiniObjectClass GstEncodingTargetClass; + +GType gst_encoding_target_get_type (void); + +/** + * gst_encoding_target_unref: + * @target: a #GstEncodingTarget + * + * Decreases the reference count of the @target, possibly freeing it. + * + * Since: 0.10.32 + */ +#define gst_encoding_target_unref(target) \ + (gst_mini_object_unref ((GstMiniObject*) target)) + +/** + * gst_encoding_target_ref: + * @target: a #GstEncodingTarget + * + * Increases the reference count of the @target. + * + * Since: 0.10.32 + */ +#define gst_encoding_target_ref(target) \ + (gst_mini_object_ref ((GstMiniObject*) target)) + +GstEncodingTarget * +gst_encoding_target_new (const gchar *name, const gchar *category, + const gchar *description, const GList *profiles); +const gchar *gst_encoding_target_get_name (GstEncodingTarget *target); +const gchar *gst_encoding_target_get_category (GstEncodingTarget *target); +const gchar *gst_encoding_target_get_description (GstEncodingTarget *target); +const GList *gst_encoding_target_get_profiles (GstEncodingTarget *target); + +gboolean +gst_encoding_target_add_profile (GstEncodingTarget *target, GstEncodingProfile *profile); + +gboolean gst_encoding_target_save (GstEncodingTarget *target, + GError **error); +gboolean gst_encoding_target_save_to (GstEncodingTarget *target, + const gchar *path, + GError **error); +GstEncodingTarget *gst_encoding_target_load (const gchar *name, + GError **error); +GstEncodingTarget *gst_encoding_target_load_from (const gchar *path, + GError **error); + +G_END_DECLS + +#endif /* __GST_PROFILE_REGISTRY_H__ */ diff --git a/tests/check/Makefile.am b/tests/check/Makefile.am index 15f2ec82f9..59ba7403f8 100644 --- a/tests/check/Makefile.am +++ b/tests/check/Makefile.am @@ -127,6 +127,7 @@ check_PROGRAMS = \ libs/navigation \ libs/netbuffer \ libs/pbutils \ + libs/profile \ libs/rtp \ libs/tag \ libs/video \ @@ -238,6 +239,12 @@ libs_pbutils_LDADD = \ $(top_builddir)/gst-libs/gst/video/libgstvideo-@GST_MAJORMINOR@.la \ $(GST_BASE_LIBS) $(LDADD) +libs_profile_CFLAGS = \ + $(GST_PLUGINS_BASE_CFLAGS) \ + $(AM_CFLAGS) +libs_profile_LDADD = \ + $(top_builddir)/gst-libs/gst/pbutils/libgstpbutils-@GST_MAJORMINOR@.la $(LDADD) + elements_appsink_CFLAGS = \ $(GST_PLUGINS_BASE_CFLAGS) \ $(AM_CFLAGS) diff --git a/tests/check/libs/.gitignore b/tests/check/libs/.gitignore index cd372588c4..326c47aa4e 100644 --- a/tests/check/libs/.gitignore +++ b/tests/check/libs/.gitignore @@ -6,6 +6,7 @@ mixer navigation netbuffer pbutils +profile rtp tag utils diff --git a/tests/check/libs/profile.c b/tests/check/libs/profile.c new file mode 100644 index 0000000000..a5640a646a --- /dev/null +++ b/tests/check/libs/profile.c @@ -0,0 +1,454 @@ +/* GStreamer unit test for gstprofile + * + * Copyright (C) <2009> Edward Hervey + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +/* #include */ +#include +#include +#include +#include + +#include +#include + +#define CHECK_PROFILE(profile, name, description, format, preset, presence, restriction) \ + { \ + fail_if(profile == NULL); \ + fail_unless_equals_string (gst_encoding_profile_get_name (profile), name); \ + fail_unless_equals_string (gst_encoding_profile_get_description (profile), description); \ + fail_unless (gst_caps_is_equal (gst_encoding_profile_get_format (profile), format)); \ + fail_unless_equals_string (gst_encoding_profile_get_preset (profile), preset); \ + fail_unless_equals_int (gst_encoding_profile_get_presence (profile), presence); \ + fail_unless (gst_caps_is_equal (gst_encoding_profile_get_restriction (profile), restriction)); \ + } + +GST_START_TEST (test_profile_creation) +{ + GstEncodingProfile *encprof; + GstEncodingAudioProfile *audioprof; + GstEncodingVideoProfile *videoprof; + GstCaps *ogg, *vorbis, *theora; + GstCaps *test1, *test2; + + ogg = gst_caps_new_simple ("application/ogg", NULL); + vorbis = gst_caps_new_simple ("audio/x-vorbis", NULL); + theora = gst_caps_new_simple ("video/x-theora", NULL); + + encprof = (GstEncodingProfile *) gst_encoding_container_profile_new ((gchar *) + "ogg-theora-vorbis", "dumb-profile", ogg, (gchar *) "dumb-preset"); + CHECK_PROFILE (encprof, "ogg-theora-vorbis", "dumb-profile", ogg, + "dumb-preset", 0, NULL); + + audioprof = gst_encoding_audio_profile_new (vorbis, (gchar *) "HQ", NULL, 0); + CHECK_PROFILE ((GstEncodingProfile *) audioprof, NULL, NULL, vorbis, "HQ", 0, + NULL); + + videoprof = gst_encoding_video_profile_new (theora, (gchar *) "HQ", NULL, 0); + CHECK_PROFILE ((GstEncodingProfile *) videoprof, NULL, NULL, theora, "HQ", + 0, NULL); + + fail_unless (gst_encoding_container_profile_add_profile ( + (GstEncodingContainerProfile *) encprof, + (GstEncodingProfile *) audioprof)); + fail_unless (gst_encoding_container_profile_add_profile ( + (GstEncodingContainerProfile *) encprof, + (GstEncodingProfile *) videoprof)); + + /* Test caps */ + test1 = gst_caps_from_string ("video/x-theora; audio/x-vorbis"); + test2 = gst_encoding_profile_get_output_caps (encprof); + fail_unless (gst_caps_is_equal (test1, test2)); + gst_caps_unref (test1); + gst_caps_unref (test2); + + gst_encoding_profile_unref (encprof); + gst_caps_unref (ogg); + gst_caps_unref (theora); + gst_caps_unref (vorbis); +} + +GST_END_TEST; + + +GST_START_TEST (test_profile_output_caps) +{ + GstEncodingProfile *sprof; + GstCaps *vorbis; + GstCaps *out, *restriction, *test1; + + vorbis = gst_caps_new_simple ("audio/x-vorbis", NULL); + + /* Simple case, no restriction */ + sprof = (GstEncodingProfile *) + gst_encoding_audio_profile_new (vorbis, NULL, NULL, 0); + fail_if (sprof == NULL); + + out = gst_encoding_profile_get_output_caps (sprof); + fail_if (out == NULL); + fail_unless (gst_caps_is_equal (out, vorbis)); + gst_caps_unref (out); + gst_encoding_profile_unref (sprof); + + /* One simple restriction */ + restriction = gst_caps_from_string ("audio/x-raw-int,channels=2,rate=44100"); + test1 = gst_caps_from_string ("audio/x-vorbis,channels=2,rate=44100"); + fail_if (restriction == NULL); + + sprof = (GstEncodingProfile *) + gst_encoding_audio_profile_new (vorbis, NULL, restriction, 0); + fail_if (sprof == NULL); + + out = gst_encoding_profile_get_output_caps (sprof); + fail_if (out == NULL); + GST_DEBUG ("got caps %" GST_PTR_FORMAT, out); + fail_unless (gst_caps_is_equal (out, test1)); + gst_caps_unref (out); + gst_caps_unref (restriction); + gst_caps_unref (test1); + gst_encoding_profile_unref (sprof); + + gst_caps_unref (vorbis); +} + +GST_END_TEST; + +GST_START_TEST (test_containerless_profile) +{ + GstEncodingProfile *encprof; + GstEncodingAudioProfile *audioprof; + GstCaps *container = NULL, *vorbis; + GstCaps *test1, *test2; + + vorbis = gst_caps_new_simple ("audio/x-vorbis", NULL); + + GST_DEBUG ("Creating container profile without any caps"); + encprof = (GstEncodingProfile *) gst_encoding_container_profile_new ((gchar *) + "container-vorbis", "dumb-profile", container, (gchar *) "dumb-preset"); + CHECK_PROFILE (encprof, "container-vorbis", "dumb-profile", NULL, + "dumb-preset", 0, 0); + + GST_DEBUG ("Creating audio profile"); + audioprof = gst_encoding_audio_profile_new (vorbis, (gchar *) "HQ", NULL, 0); + CHECK_PROFILE ((GstEncodingProfile *) audioprof, NULL, NULL, vorbis, "HQ", 0, + 0); + + GST_DEBUG ("Adding audio profile to container"); + /* We can add one stream profile to container-less profiles.. */ + fail_unless (gst_encoding_container_profile_add_profile ( + (GstEncodingContainerProfile *) encprof, + (GstEncodingProfile *) audioprof)); + GST_DEBUG ("Adding audio profile to container a second time (should fail)"); + /* .. but not two */ + fail_if (gst_encoding_container_profile_add_profile ( + (GstEncodingContainerProfile *) encprof, + (GstEncodingProfile *) audioprof)); + + GST_DEBUG ("Checking caps"); + /* Test caps */ + test1 = gst_caps_from_string ("audio/x-vorbis"); + test2 = gst_encoding_profile_get_output_caps (encprof); + fail_unless (gst_caps_is_equal (test1, test2)); + gst_caps_unref (test1); + gst_caps_unref (test2); + + gst_encoding_profile_unref (encprof); + gst_caps_unref (vorbis); +} + +GST_END_TEST; + +static GstEncodingTarget * +create_saveload_target (void) +{ + GstEncodingTarget *target; + GstEncodingProfile *profile, *sprof; + GstCaps *caps, *caps2; + + GST_DEBUG ("Creating target"); + + target = gst_encoding_target_new ("myponytarget", "herding", + "Plenty of pony glitter profiles", NULL); + caps = gst_caps_from_string ("animal/x-pony"); + profile = + (GstEncodingProfile *) gst_encoding_container_profile_new ("pony", + "I don't want a description !", caps, NULL); + gst_caps_unref (caps); + gst_encoding_target_add_profile (target, profile); + + caps = gst_caps_from_string ("audio/x-pony-song,pretty=True"); + caps2 = gst_caps_from_string ("audio/x-raw-int,channels=1,rate=44100"); + sprof = + (GstEncodingProfile *) gst_encoding_audio_profile_new (caps, NULL, caps2, + 1); + gst_encoding_container_profile_add_profile ((GstEncodingContainerProfile *) + profile, sprof); + gst_caps_unref (caps); + gst_caps_unref (caps2); + + caps = gst_caps_from_string ("video/x-glitter,sparkling=True"); + caps2 = + gst_caps_from_string + ("video/x-raw-yuv,width=640,height=480,framerate=15/1"); + sprof = (GstEncodingProfile *) + gst_encoding_video_profile_new (caps, "seriously glittery", caps2, 0); + gst_encoding_video_profile_set_variableframerate ((GstEncodingVideoProfile *) + sprof, TRUE); + gst_encoding_container_profile_add_profile ((GstEncodingContainerProfile *) + profile, sprof); + gst_caps_unref (caps); + gst_caps_unref (caps2); + + return target; +} + +GST_START_TEST (test_saving_profile) +{ + GstEncodingTarget *orig, *loaded = NULL; + GstEncodingProfile *proforig, *profloaded; + gchar *profile_file_name; + + /* Create and store a target */ + profile_file_name = g_build_filename (g_get_home_dir (), ".gstreamer-0.10", + "profile", "TestProfile2.profile", NULL); + orig = create_saveload_target (); + GST_DEBUG ("Saving target to '%s'", profile_file_name); + fail_unless (gst_encoding_target_save_to (orig, profile_file_name, NULL)); + + /* Check we can load it */ + GST_DEBUG ("Loading target from '%s'", profile_file_name); + loaded = gst_encoding_target_load_from (profile_file_name, NULL); + fail_unless (loaded != NULL); + g_free (profile_file_name); + + GST_DEBUG ("Checking targets are equal"); + /* Check targets are identical */ + /* 1. at the target level */ + fail_unless_equals_string (gst_encoding_target_get_name (orig), + gst_encoding_target_get_name (loaded)); + fail_unless_equals_string (gst_encoding_target_get_category (orig), + gst_encoding_target_get_category (loaded)); + fail_unless_equals_string (gst_encoding_target_get_description (orig), + gst_encoding_target_get_description (loaded)); + fail_unless_equals_int (g_list_length ((GList *) + gst_encoding_target_get_profiles (loaded)), 1); + + /* 2. at the profile level */ + profloaded = + (GstEncodingProfile *) gst_encoding_target_get_profiles (loaded)->data; + proforig = + (GstEncodingProfile *) gst_encoding_target_get_profiles (orig)->data; + + fail_unless_equals_int (G_TYPE_FROM_INSTANCE (profloaded), + G_TYPE_FROM_INSTANCE (proforig)); + GST_DEBUG ("Comparing loaded:%p to original:%p", profloaded, proforig); + fail_unless (gst_encoding_profile_is_equal (profloaded, proforig)); + + gst_encoding_target_unref (orig); + gst_encoding_target_unref (loaded); +} + +GST_END_TEST; + +GST_START_TEST (test_loading_profile) +{ + GstEncodingTarget *target; + gchar *profile_file_name; + GstEncodingProfile *prof; + GstCaps *tmpcaps, *tmpcaps2; + GstEncodingProfile *sprof1, *sprof2; + + profile_file_name = g_build_filename (g_get_home_dir (), ".gstreamer-0.10", + "profile", "TestProfile.profile", NULL); + + GST_DEBUG ("Loading target from '%s'", profile_file_name); + target = gst_encoding_target_load_from (profile_file_name, NULL); + g_free (profile_file_name); + fail_unless (target != NULL); + + GST_DEBUG ("Checking the target properties"); + /* Check the target */ + fail_unless_equals_string (gst_encoding_target_get_name (target), + "myponytarget"); + fail_unless_equals_string (gst_encoding_target_get_category (target), + "herding"); + fail_unless_equals_string (gst_encoding_target_get_description (target), + "Plenty of pony glitter profiles"); + + GST_DEBUG ("Checking the number of profiles the target contains"); + fail_unless_equals_int (g_list_length ((GList *) + gst_encoding_target_get_profiles (target)), 1); + + + GST_DEBUG ("Checking the container profile"); + /* Check the profile */ + prof = (GstEncodingProfile *) gst_encoding_target_get_profiles (target)->data; + tmpcaps = gst_caps_from_string ("animal/x-pony"); + CHECK_PROFILE (prof, "pony", "I don't want a description !", tmpcaps, NULL, 0, + 0); + gst_caps_unref (tmpcaps); + + GST_DEBUG ("Checking the container profile has 2 stream profiles"); + /* Check the stream profiles */ + fail_unless_equals_int (g_list_length ((GList *) + gst_encoding_container_profile_get_profiles ( + (GstEncodingContainerProfile *) prof)), 2); + + GST_DEBUG ("Checking the container profile has the audio/x-pony-song stream"); + tmpcaps = gst_caps_from_string ("audio/x-pony-song,pretty=True"); + tmpcaps2 = gst_caps_from_string ("audio/x-raw-int,channels=1,rate=44100"); + sprof1 = + (GstEncodingProfile *) gst_encoding_audio_profile_new (tmpcaps, NULL, + tmpcaps2, 1); + fail_unless (gst_encoding_container_profile_contains_profile ( + (GstEncodingContainerProfile *) prof, sprof1)); + gst_encoding_profile_unref (sprof1); + gst_caps_unref (tmpcaps); + gst_caps_unref (tmpcaps2); + + GST_DEBUG ("Checking the container profile has the video//x-glitter stream"); + tmpcaps = gst_caps_from_string ("video/x-glitter,sparkling=True"); + tmpcaps2 = + gst_caps_from_string + ("video/x-raw-yuv,width=640,height=480,framerate=15/1"); + sprof2 = (GstEncodingProfile *) + gst_encoding_video_profile_new (tmpcaps, "seriously glittery", tmpcaps2, + 0); + gst_encoding_video_profile_set_variableframerate ((GstEncodingVideoProfile *) + sprof2, TRUE); + fail_unless (gst_encoding_container_profile_contains_profile ( + (GstEncodingContainerProfile *) prof, sprof2)); + gst_encoding_profile_unref (sprof2); + gst_caps_unref (tmpcaps); + gst_caps_unref (tmpcaps2); + + gst_encoding_target_unref (target); +} + +GST_END_TEST; + +static const gchar *profile_string = "\ +[_gstencodingtarget_]\n\ +name=myponytarget\n\ +category=herding\n\ +description=Plenty of pony glitter profiles\n\ +\n\ +[profile-pony1]\n\ +name=pony\n\ +type=container\n\ +description=I don't want a description !\n\ +format=animal/x-pony\n\ +\n\ +[streamprofile-pony11]\n\ +parent=pony\n\ +type=audio\n\ +format=audio/x-pony-song,pretty=True\n\ +restriction=audio/x-raw-int,channels=1,rate=44100\n\ +presence=1\n\ +\n\ +[streamprofile-pony12]\n\ +parent=pony\n\ +type=video\n\ +preset=seriously glittery\n\ +format=video/x-glitter,sparkling=True\n\ +restriction=video/x-raw-yuv,width=640,height=480,framerate=15/1\n\ +presence=0\n\ +variableframerate=true\n\ +"; + +static void +remove_profile_file (void) +{ + gchar *profile_file_name; + + profile_file_name = g_build_filename (g_get_home_dir (), ".gstreamer-0.10", + "profile", "TestProfile.profile", NULL); + g_unlink (profile_file_name); + g_free (profile_file_name); + profile_file_name = g_build_filename (g_get_home_dir (), ".gstreamer-0.10", + "profile", "TestProfile2.profile", NULL); + g_unlink (profile_file_name); + g_free (profile_file_name); +} + +static void +create_profile_file (void) +{ + gchar *profile_file_name; + gchar *profile_dir; + GError *error = NULL; + + profile_dir = + g_build_filename (g_get_home_dir (), ".gstreamer-0.10", "profile", NULL); + profile_file_name = + g_build_filename (g_get_home_dir (), ".gstreamer-0.10", "profile", + "TestProfile.profile", NULL); + g_mkdir_with_parents (profile_dir, S_IRUSR | S_IWUSR | S_IXUSR); + if (!g_file_set_contents (profile_file_name, profile_string, + strlen (profile_string), &error)) + GST_WARNING ("Couldn't write contents to file : %s", error->message); + g_free (profile_dir); + g_free (profile_file_name); +} + +static void +test_setup (void) +{ + create_profile_file (); +} + +static void +test_teardown (void) +{ + remove_profile_file (); +} + + +static Suite * +profile_suite (void) +{ + Suite *s = suite_create ("profile support library"); + TCase *tc_chain = tcase_create ("general"); + gboolean can_write; + gchar *gst_dir; + + /* cehck if we can create profiles */ + gst_dir = g_build_filename (g_get_home_dir (), ".gstreamer-0.10", NULL); + can_write = (g_access (gst_dir, R_OK | W_OK | X_OK) == 0); + g_free (gst_dir); + + suite_add_tcase (s, tc_chain); + + tcase_add_test (tc_chain, test_profile_creation); + tcase_add_test (tc_chain, test_profile_output_caps); + tcase_add_test (tc_chain, test_containerless_profile); + if (can_write) { + tcase_add_test (tc_chain, test_loading_profile); + tcase_add_test (tc_chain, test_saving_profile); + } + + tcase_add_unchecked_fixture (tc_chain, test_setup, test_teardown); + + return s; +} + +GST_CHECK_MAIN (profile); diff --git a/win32/common/libgstpbutils.def b/win32/common/libgstpbutils.def index 34c79dc635..6f43ee4e86 100644 --- a/win32/common/libgstpbutils.def +++ b/win32/common/libgstpbutils.def @@ -58,6 +58,46 @@ EXPORTS gst_discoverer_video_info_get_width gst_discoverer_video_info_is_image gst_discoverer_video_info_is_interlaced + gst_encoding_audio_profile_get_type + gst_encoding_audio_profile_new + gst_encoding_container_profile_add_profile + gst_encoding_container_profile_contains_profile + gst_encoding_container_profile_get_profiles + gst_encoding_container_profile_get_type + gst_encoding_container_profile_new + gst_encoding_profile_get_description + gst_encoding_profile_get_format + gst_encoding_profile_get_name + gst_encoding_profile_get_output_caps + gst_encoding_profile_get_presence + gst_encoding_profile_get_preset + gst_encoding_profile_get_restriction + gst_encoding_profile_get_type + gst_encoding_profile_get_type_nick + gst_encoding_profile_is_equal + gst_encoding_profile_set_description + gst_encoding_profile_set_format + gst_encoding_profile_set_name + gst_encoding_profile_set_presence + gst_encoding_profile_set_preset + gst_encoding_profile_set_restriction + gst_encoding_target_add_profile + gst_encoding_target_get_category + gst_encoding_target_get_description + gst_encoding_target_get_name + gst_encoding_target_get_profiles + gst_encoding_target_get_type + gst_encoding_target_load + gst_encoding_target_load_from + gst_encoding_target_new + gst_encoding_target_save + gst_encoding_target_save_to + gst_encoding_video_profile_get_pass + gst_encoding_video_profile_get_type + gst_encoding_video_profile_get_variableframerate + gst_encoding_video_profile_new + gst_encoding_video_profile_set_pass + gst_encoding_video_profile_set_variableframerate gst_install_plugins_async gst_install_plugins_context_free gst_install_plugins_context_get_type From 8a3b45aa1f5d6fcff5d8020a6ceddc0b7fc84353 Mon Sep 17 00:00:00 2001 From: Edward Hervey Date: Fri, 13 Aug 2010 17:36:38 +0200 Subject: [PATCH 029/254] gst: New encoding plugin https://bugzilla.gnome.org/show_bug.cgi?id=627476 --- configure.ac | 2 + docs/plugins/Makefile.am | 3 +- .../gst-plugins-base-plugins-docs.sgml | 2 + .../gst-plugins-base-plugins-sections.txt | 16 + docs/plugins/gst-plugins-base-plugins.args | 100 + .../gst-plugins-base-plugins.hierarchy | 1 + .../gst-plugins-base-plugins.interfaces | 1 + docs/plugins/gst-plugins-base-plugins.signals | 8 + docs/plugins/inspect/plugin-encoding.xml | 46 + docs/plugins/inspect/plugin-libvisual.xml | 168 -- gst/encoding/.gitignore | 1 + gst/encoding/Makefile.am | 41 + gst/encoding/gstencode-marshal.list | 1 + gst/encoding/gstencodebin.c | 1658 +++++++++++++++++ gst/encoding/gstencodebin.h | 39 + gst/encoding/gstsmartencoder.c | 701 +++++++ gst/encoding/gstsmartencoder.h | 71 + gst/encoding/gststreamcombiner.c | 276 +++ gst/encoding/gststreamcombiner.h | 60 + gst/encoding/gststreamsplitter.c | 431 +++++ gst/encoding/gststreamsplitter.h | 62 + tests/check/Makefile.am | 4 + tests/check/elements/.gitignore | 1 + tests/check/elements/encodebin.c | 742 ++++++++ 24 files changed, 4266 insertions(+), 169 deletions(-) create mode 100644 docs/plugins/inspect/plugin-encoding.xml create mode 100644 gst/encoding/.gitignore create mode 100644 gst/encoding/Makefile.am create mode 100644 gst/encoding/gstencode-marshal.list create mode 100644 gst/encoding/gstencodebin.c create mode 100644 gst/encoding/gstencodebin.h create mode 100644 gst/encoding/gstsmartencoder.c create mode 100644 gst/encoding/gstsmartencoder.h create mode 100644 gst/encoding/gststreamcombiner.c create mode 100644 gst/encoding/gststreamcombiner.h create mode 100644 gst/encoding/gststreamsplitter.c create mode 100644 gst/encoding/gststreamsplitter.h create mode 100644 tests/check/elements/encodebin.c diff --git a/configure.ac b/configure.ac index b1df1c68e4..64f877cf65 100644 --- a/configure.ac +++ b/configure.ac @@ -417,6 +417,7 @@ AG_GST_CHECK_PLUGIN(app) AG_GST_CHECK_PLUGIN(audioconvert) AG_GST_CHECK_PLUGIN(audiorate) AG_GST_CHECK_PLUGIN(audiotestsrc) +AG_GST_CHECK_PLUGIN(encoding) AG_GST_CHECK_PLUGIN(ffmpegcolorspace) AG_GST_CHECK_PLUGIN(gdp) AG_GST_CHECK_PLUGIN(playback) @@ -914,6 +915,7 @@ gst/app/Makefile gst/audioconvert/Makefile gst/audiorate/Makefile gst/audiotestsrc/Makefile +gst/encoding/Makefile gst/ffmpegcolorspace/Makefile gst/gdp/Makefile gst/playback/Makefile diff --git a/docs/plugins/Makefile.am b/docs/plugins/Makefile.am index 4b784337dd..9beea7e55f 100644 --- a/docs/plugins/Makefile.am +++ b/docs/plugins/Makefile.am @@ -50,7 +50,7 @@ MKDB_OPTIONS=--sgml-mode # Extra options to supply to gtkdoc-fixref. FIXXREF_OPTIONS=--extra-dir=$(GLIB_PREFIX)/share/gtk-doc/html \ --extra-dir=$(GST_PREFIX)/share/gtk-doc/html \ - --extra-dir=$(datadir)/gtk-doc/html + --extra-dir=$(datadir)/gtk-doc/html # Used for dependencies. HFILE_GLOB=$(DOC_SOURCE_DIR)/*/*/*.h @@ -102,6 +102,7 @@ EXTRA_HFILES = \ $(top_srcdir)/gst/audioconvert/audioconvert.h \ $(top_srcdir)/gst/audioconvert/gstaudioconvert.h \ $(top_srcdir)/gst/audiotestsrc/gstaudiotestsrc.h \ + $(top_srcdir)/gst/encoding/gstencodebin.h \ $(top_srcdir)/gst/ffmpegcolorspace/gstffmpegcolorspace.h \ $(top_srcdir)/gst/gdp/gstgdpdepay.h \ $(top_srcdir)/gst/gdp/gstgdppay.h \ diff --git a/docs/plugins/gst-plugins-base-plugins-docs.sgml b/docs/plugins/gst-plugins-base-plugins-docs.sgml index 9bcbbf895c..ea603d6012 100644 --- a/docs/plugins/gst-plugins-base-plugins-docs.sgml +++ b/docs/plugins/gst-plugins-base-plugins-docs.sgml @@ -31,6 +31,7 @@ + @@ -80,6 +81,7 @@ + diff --git a/docs/plugins/gst-plugins-base-plugins-sections.txt b/docs/plugins/gst-plugins-base-plugins-sections.txt index e241371f65..e94c450985 100644 --- a/docs/plugins/gst-plugins-base-plugins-sections.txt +++ b/docs/plugins/gst-plugins-base-plugins-sections.txt @@ -247,6 +247,22 @@ GstDecodeBin2
+
+element-encodebin +encodebin +GstEncodeBin + +GST_ENCODE_BIN +GST_ENCODE_BIN_CLASS +GST_IS_ENCODE_BIN +GST_IS_ENCODE_BIN_CLASS +GST_TYPE_ENCODE_BIN +GstEncodeBinClass +gst_encode_bin_get_type +
+ + +
element-ffmpegcolorspace ffmpegcolorspace diff --git a/docs/plugins/gst-plugins-base-plugins.args b/docs/plugins/gst-plugins-base-plugins.args index 05ef80fc0d..d3a40c5156 100644 --- a/docs/plugins/gst-plugins-base-plugins.args +++ b/docs/plugins/gst-plugins-base-plugins.args @@ -158,6 +158,26 @@ TRUE + +GstXvImageSink::window-height +guint64 + +r +window-height +Height of the window. +0 + + + +GstXvImageSink::window-width +guint64 + +r +window-width +Width of the window. +0 + + GstXImageSink::display gchar* @@ -218,6 +238,26 @@ TRUE + +GstXImageSink::window-height +guint64 + +r +window-height +Height of the window. +0 + + + +GstXImageSink::window-width +guint64 + +r +window-width +Width of the window. +0 + + GstV4lSrc::autoprobe gboolean @@ -3378,3 +3418,63 @@ NULL + +GstEncodeBin::audio-jitter-tolerance +guint64 + +rw +Audio jitter tolerance +Amount of timestamp jitter/imperfection to allow on audio streams before inserting/dropping samples (ns). +20000000 + + + +GstEncodeBin::avoid-reencoding +gboolean + +rw +Avoid re-encoding +Whether to re-encode portions of compatible video streams that lay on segment boundaries. +FALSE + + + +GstEncodeBin::profile +GstEncodingProfile* + +rw +Profile +The GstEncodingProfile to use. + + + + +GstEncodeBin::queue-buffers-max +guint + +rw +Max. size (buffers) +Max. number of buffers in the queue (0=disable). +200 + + + +GstEncodeBin::queue-bytes-max +guint + +rw +Max. size (kB) +Max. amount of data in the queue (bytes, 0=disable). +10485760 + + + +GstEncodeBin::queue-time-max +guint64 + +rw +Max. size (ns) +Max. amount of data in the queue (in ns, 0=disable). +1000000000 + + diff --git a/docs/plugins/gst-plugins-base-plugins.hierarchy b/docs/plugins/gst-plugins-base-plugins.hierarchy index 4a355e6596..80aed2e9a5 100644 --- a/docs/plugins/gst-plugins-base-plugins.hierarchy +++ b/docs/plugins/gst-plugins-base-plugins.hierarchy @@ -56,6 +56,7 @@ GObject GstBin GstDecodeBin GstDecodeBin2 + GstEncodeBin GstPipeline GstPlayBaseBin GstPlayBin diff --git a/docs/plugins/gst-plugins-base-plugins.interfaces b/docs/plugins/gst-plugins-base-plugins.interfaces index 36963b528f..630084dd30 100644 --- a/docs/plugins/gst-plugins-base-plugins.interfaces +++ b/docs/plugins/gst-plugins-base-plugins.interfaces @@ -8,6 +8,7 @@ GstPlaySink GstChildProxy GstSubtitleOverlay GstChildProxy GstDecodeBin2 GstChildProxy GstURIDecodeBin GstChildProxy +GstEncodeBin GstChildProxy GstCddaBaseSrc GstURIHandler GstCdParanoiaSrc GstURIHandler GstAlsaSrc GstImplementsInterface GstMixer GstPropertyProbe diff --git a/docs/plugins/gst-plugins-base-plugins.signals b/docs/plugins/gst-plugins-base-plugins.signals index 2f5fab5ae5..621f880b3f 100644 --- a/docs/plugins/gst-plugins-base-plugins.signals +++ b/docs/plugins/gst-plugins-base-plugins.signals @@ -471,3 +471,11 @@ GstPlaySink *gstplaysink GstCaps *arg1 + +GstEncodeBin::request-pad +GstPad* +la +GstEncodeBin *gstencodebin +GstCaps *arg1 + + diff --git a/docs/plugins/inspect/plugin-encoding.xml b/docs/plugins/inspect/plugin-encoding.xml new file mode 100644 index 0000000000..ab61ef771b --- /dev/null +++ b/docs/plugins/inspect/plugin-encoding.xml @@ -0,0 +1,46 @@ + + encoding + various encoding-related elements + ../../gst/encoding/.libs/libgstencodebin.so + libgstencodebin.so + 0.10.31.1 + LGPL + gst-plugins-base + GStreamer Base Plug-ins git + Unknown package origin + + + encodebin + Encoder Bin + Generic/Bin/Encoder + Convenience encoding/muxing element + Edward Hervey <edward.hervey@collabora.co.uk> + + + audio_%d + sink + request +
ANY
+
+ + private_%d + sink + request +
ANY
+
+ + video_%d + sink + request +
ANY
+
+ + src + source + always +
ANY
+
+
+
+
+
\ No newline at end of file diff --git a/docs/plugins/inspect/plugin-libvisual.xml b/docs/plugins/inspect/plugin-libvisual.xml index 22f4e8f048..0af3fc75d5 100644 --- a/docs/plugins/inspect/plugin-libvisual.xml +++ b/docs/plugins/inspect/plugin-libvisual.xml @@ -9,173 +9,5 @@ GStreamer Base Plug-ins git Unknown package origin - - libvisual_bumpscope - libvisual Bumpscope plugin plugin v.0.0.1 - Visualization - Bumpscope visual plugin - Benjamin Otte <otte@gnome.org> - - - sink - sink - always -
audio/x-raw-int, width=(int)16, depth=(int)16, endianness=(int)1234, signed=(boolean)true, channels=(int){ 1, 2 }, rate=(int){ 8000, 11250, 22500, 32000, 44100, 48000, 96000 }
-
- - src - source - always -
video/x-raw-rgb, bpp=(int)32, depth=(int)24, endianness=(int)4321, red_mask=(int)65280, green_mask=(int)16711680, blue_mask=(int)-16777216, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]; video/x-raw-rgb, bpp=(int)24, depth=(int)24, endianness=(int)4321, red_mask=(int)255, green_mask=(int)65280, blue_mask=(int)16711680, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]; video/x-raw-rgb, bpp=(int)16, depth=(int)16, endianness=(int)1234, red_mask=(int)63488, green_mask=(int)2016, blue_mask=(int)31, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]
-
-
-
- - libvisual_corona - libvisual libvisual corona plugin plugin v.0.1 - Visualization - Libvisual corona plugin - Benjamin Otte <otte@gnome.org> - - - sink - sink - always -
audio/x-raw-int, width=(int)16, depth=(int)16, endianness=(int)1234, signed=(boolean)true, channels=(int){ 1, 2 }, rate=(int){ 8000, 11250, 22500, 32000, 44100, 48000, 96000 }
-
- - src - source - always -
video/x-raw-rgb, bpp=(int)32, depth=(int)24, endianness=(int)4321, red_mask=(int)65280, green_mask=(int)16711680, blue_mask=(int)-16777216, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]; video/x-raw-rgb, bpp=(int)24, depth=(int)24, endianness=(int)4321, red_mask=(int)255, green_mask=(int)65280, blue_mask=(int)16711680, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]; video/x-raw-rgb, bpp=(int)16, depth=(int)16, endianness=(int)1234, red_mask=(int)63488, green_mask=(int)2016, blue_mask=(int)31, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]
-
-
-
- - libvisual_infinite - libvisual infinite plugin plugin v.0.1 - Visualization - Infinite visual plugin - Benjamin Otte <otte@gnome.org> - - - sink - sink - always -
audio/x-raw-int, width=(int)16, depth=(int)16, endianness=(int)1234, signed=(boolean)true, channels=(int){ 1, 2 }, rate=(int){ 8000, 11250, 22500, 32000, 44100, 48000, 96000 }
-
- - src - source - always -
video/x-raw-rgb, bpp=(int)32, depth=(int)24, endianness=(int)4321, red_mask=(int)65280, green_mask=(int)16711680, blue_mask=(int)-16777216, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]; video/x-raw-rgb, bpp=(int)24, depth=(int)24, endianness=(int)4321, red_mask=(int)255, green_mask=(int)65280, blue_mask=(int)16711680, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]; video/x-raw-rgb, bpp=(int)16, depth=(int)16, endianness=(int)1234, red_mask=(int)63488, green_mask=(int)2016, blue_mask=(int)31, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]
-
-
-
- - libvisual_jakdaw - libvisual Jakdaw plugin plugin v.0.0.1 - Visualization - jakdaw visual plugin - Benjamin Otte <otte@gnome.org> - - - sink - sink - always -
audio/x-raw-int, width=(int)16, depth=(int)16, endianness=(int)1234, signed=(boolean)true, channels=(int){ 1, 2 }, rate=(int){ 8000, 11250, 22500, 32000, 44100, 48000, 96000 }
-
- - src - source - always -
video/x-raw-rgb, bpp=(int)32, depth=(int)24, endianness=(int)4321, red_mask=(int)65280, green_mask=(int)16711680, blue_mask=(int)-16777216, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]; video/x-raw-rgb, bpp=(int)24, depth=(int)24, endianness=(int)4321, red_mask=(int)255, green_mask=(int)65280, blue_mask=(int)16711680, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]; video/x-raw-rgb, bpp=(int)16, depth=(int)16, endianness=(int)1234, red_mask=(int)63488, green_mask=(int)2016, blue_mask=(int)31, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]
-
-
-
- - libvisual_jess - libvisual jess plugin plugin v.0.1 - Visualization - Jess visual plugin - Benjamin Otte <otte@gnome.org> - - - sink - sink - always -
audio/x-raw-int, width=(int)16, depth=(int)16, endianness=(int)1234, signed=(boolean)true, channels=(int){ 1, 2 }, rate=(int){ 8000, 11250, 22500, 32000, 44100, 48000, 96000 }
-
- - src - source - always -
video/x-raw-rgb, bpp=(int)32, depth=(int)24, endianness=(int)4321, red_mask=(int)65280, green_mask=(int)16711680, blue_mask=(int)-16777216, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]; video/x-raw-rgb, bpp=(int)24, depth=(int)24, endianness=(int)4321, red_mask=(int)255, green_mask=(int)65280, blue_mask=(int)16711680, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]; video/x-raw-rgb, bpp=(int)16, depth=(int)16, endianness=(int)1234, red_mask=(int)63488, green_mask=(int)2016, blue_mask=(int)31, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]
-
-
-
- - libvisual_lv_analyzer - libvisual libvisual analyzer plugin v.1.0 - Visualization - Libvisual analyzer plugin - Benjamin Otte <otte@gnome.org> - - - sink - sink - always -
audio/x-raw-int, width=(int)16, depth=(int)16, endianness=(int)1234, signed=(boolean)true, channels=(int){ 1, 2 }, rate=(int){ 8000, 11250, 22500, 32000, 44100, 48000, 96000 }
-
- - src - source - always -
video/x-raw-rgb, bpp=(int)32, depth=(int)24, endianness=(int)4321, red_mask=(int)65280, green_mask=(int)16711680, blue_mask=(int)-16777216, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]; video/x-raw-rgb, bpp=(int)24, depth=(int)24, endianness=(int)4321, red_mask=(int)255, green_mask=(int)65280, blue_mask=(int)16711680, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]; video/x-raw-rgb, bpp=(int)16, depth=(int)16, endianness=(int)1234, red_mask=(int)63488, green_mask=(int)2016, blue_mask=(int)31, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]
-
-
-
- - libvisual_lv_scope - libvisual libvisual scope plugin v.0.1 - Visualization - Libvisual scope plugin - Benjamin Otte <otte@gnome.org> - - - sink - sink - always -
audio/x-raw-int, width=(int)16, depth=(int)16, endianness=(int)1234, signed=(boolean)true, channels=(int){ 1, 2 }, rate=(int){ 8000, 11250, 22500, 32000, 44100, 48000, 96000 }
-
- - src - source - always -
video/x-raw-rgb, bpp=(int)32, depth=(int)24, endianness=(int)4321, red_mask=(int)65280, green_mask=(int)16711680, blue_mask=(int)-16777216, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]; video/x-raw-rgb, bpp=(int)24, depth=(int)24, endianness=(int)4321, red_mask=(int)255, green_mask=(int)65280, blue_mask=(int)16711680, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]; video/x-raw-rgb, bpp=(int)16, depth=(int)16, endianness=(int)1234, red_mask=(int)63488, green_mask=(int)2016, blue_mask=(int)31, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]
-
-
-
- - libvisual_oinksie - libvisual oinksie plugin plugin v.0.1 - Visualization - Libvisual Oinksie visual plugin - Benjamin Otte <otte@gnome.org> - - - sink - sink - always -
audio/x-raw-int, width=(int)16, depth=(int)16, endianness=(int)1234, signed=(boolean)true, channels=(int){ 1, 2 }, rate=(int){ 8000, 11250, 22500, 32000, 44100, 48000, 96000 }
-
- - src - source - always -
video/x-raw-rgb, bpp=(int)32, depth=(int)24, endianness=(int)4321, red_mask=(int)65280, green_mask=(int)16711680, blue_mask=(int)-16777216, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]; video/x-raw-rgb, bpp=(int)24, depth=(int)24, endianness=(int)4321, red_mask=(int)255, green_mask=(int)65280, blue_mask=(int)16711680, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]; video/x-raw-rgb, bpp=(int)16, depth=(int)16, endianness=(int)1234, red_mask=(int)63488, green_mask=(int)2016, blue_mask=(int)31, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]
-
-
-
\ No newline at end of file diff --git a/gst/encoding/.gitignore b/gst/encoding/.gitignore new file mode 100644 index 0000000000..ff44545891 --- /dev/null +++ b/gst/encoding/.gitignore @@ -0,0 +1 @@ +gstencode-marshal.[ch] diff --git a/gst/encoding/Makefile.am b/gst/encoding/Makefile.am new file mode 100644 index 0000000000..0e287fad13 --- /dev/null +++ b/gst/encoding/Makefile.am @@ -0,0 +1,41 @@ +# variables used for enum/marshal generation +glib_enum_define = GST_ENCODE +glib_gen_prefix = gst_encode +glib_gen_basename = gstencode + +built_sources = gstencode-marshal.c +built_headers = gstencode-marshal.h + +plugindir = $(libdir)/gstreamer-@GST_MAJORMINOR@ + +plugin_LTLIBRARIES = libgstencodebin.la + +libgstencodebin_la_SOURCES = \ + gstencodebin.c \ + gstsmartencoder.c \ + gststreamcombiner.c \ + gststreamsplitter.c + +nodist_libgstencodebin_la_SOURCES = $(built_sources) +libgstencodebin_la_CFLAGS = $(GST_PLUGINS_BASE_CFLAGS) $(GST_CFLAGS) +libgstencodebin_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS) +libgstencodebin_la_LIBADD = \ + $(top_builddir)/gst-libs/gst/pbutils/libgstpbutils-@GST_MAJORMINOR@.la \ + $(GST_LIBS) +libgstencodebin_la_LIBTOOLFLAGS = --tag=disable-static + +noinst_HEADERS = \ + gstencodebin.h \ + gststreamcombiner.h \ + gststreamsplitter.h \ + gstsmartencoder.h + + +BUILT_SOURCES = $(built_headers) $(built_sources) + +EXTRA_DIST = gstencode-marshal.list + +CLEANFILES = $(BUILT_SOURCES) + +include $(top_srcdir)/common/gst-glib-gen.mak + diff --git a/gst/encoding/gstencode-marshal.list b/gst/encoding/gstencode-marshal.list new file mode 100644 index 0000000000..00f26ed2bc --- /dev/null +++ b/gst/encoding/gstencode-marshal.list @@ -0,0 +1 @@ +OBJECT:BOXED diff --git a/gst/encoding/gstencodebin.c b/gst/encoding/gstencodebin.c new file mode 100644 index 0000000000..3ba5a403dd --- /dev/null +++ b/gst/encoding/gstencodebin.c @@ -0,0 +1,1658 @@ +/* GStreamer encoding bin + * Copyright (C) 2009 Edward Hervey + * (C) 2009 Nokia Corporation + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include "gstencodebin.h" +#include "gstsmartencoder.h" +#include "gststreamsplitter.h" +#include "gststreamcombiner.h" +#include + +/** + * SECTION:element-encodebin + * + * encodebin provides a bin for encoding/muxing various streams according to + * a specified #GstEncodingProfile. + * + * + */ + + +/* TODO/FIXME + * + * 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: + * Find a Formatter for the given stream (preferably with TagSetter) + * Insert that before muxer + **/ + +#define fast_pad_link(a,b) gst_pad_link_full((a),(b),GST_PAD_LINK_CHECK_NOTHING) +#define fast_element_link(a,b) gst_element_link_pads_full((a),"src",(b),"sink",GST_PAD_LINK_CHECK_NOTHING) + +/* generic templates */ +static GstStaticPadTemplate muxer_src_template = +GST_STATIC_PAD_TEMPLATE ("src", GST_PAD_SRC, GST_PAD_ALWAYS, + GST_STATIC_CAPS_ANY); + +static GstStaticPadTemplate video_sink_template = +GST_STATIC_PAD_TEMPLATE ("video_%d", + GST_PAD_SINK, + GST_PAD_REQUEST, + GST_STATIC_CAPS_ANY); +static GstStaticPadTemplate audio_sink_template = +GST_STATIC_PAD_TEMPLATE ("audio_%d", + GST_PAD_SINK, + GST_PAD_REQUEST, + GST_STATIC_CAPS_ANY); +/* static GstStaticPadTemplate text_sink_template = */ +/* GST_STATIC_PAD_TEMPLATE ("text_%d", */ +/* GST_PAD_SINK, */ +/* GST_PAD_REQUEST, */ +/* GST_STATIC_CAPS_ANY); */ +static GstStaticPadTemplate private_sink_template = +GST_STATIC_PAD_TEMPLATE ("private_%d", + GST_PAD_SINK, + GST_PAD_REQUEST, + GST_STATIC_CAPS_ANY); + +struct _GstEncodeBin +{ + GstBin parent; + + /* the profile field is only valid if it could be entirely setup */ + GstEncodingProfile *profile; + + GList *streams; /* List of StreamGroup, not sorted */ + + GstElement *muxer; + GstPad *srcpad; + + /* TRUE if in PAUSED/PLAYING */ + gboolean active; + + /* available muxers, encoders and parsers */ + GList *muxers; + GList *encoders; + GList *parsers; + + /* Increasing counter for unique pad name */ + guint last_pad_id; + + /* Cached caps for identification */ + GstCaps *raw_video_caps; + GstCaps *raw_audio_caps; + /* GstCaps *raw_text_caps; */ + + guint queue_buffers_max; + guint queue_bytes_max; + guint64 queue_time_max; + + guint64 tolerance; + gboolean avoid_reencoding; +}; + +struct _GstEncodeBinClass +{ + GstBinClass parent; + + /* Action Signals */ + GstPad *(*request_pad) (GstEncodeBin * encodebin, GstCaps * caps); +}; + +typedef struct _StreamGroup StreamGroup; + +struct _StreamGroup +{ + GstEncodeBin *ebin; + GstEncodingProfile *profile; + GstPad *ghostpad; /* Sink ghostpad */ + GstElement *inqueue; /* Queue just after the ghostpad */ + GstElement *splitter; + GList *converters; /* List of conversion GstElement */ + GstElement *capsfilter; /* profile->restriction (if non-NULL/ANY) */ + GstElement *encoder; /* Encoder (can be NULL) */ + GstElement *combiner; + GstElement *parser; + GstElement *smartencoder; + GstElement *outfilter; /* Output capsfilter (streamprofile.format) */ + GstElement *outqueue; /* Queue just before the muxer */ +}; + +/* Default for queues (same defaults as queue element) */ +#define DEFAULT_QUEUE_BUFFERS_MAX 200 +#define DEFAULT_QUEUE_BYTES_MAX 10 * 1024 * 1024 +#define DEFAULT_QUEUE_TIME_MAX GST_SECOND +#define DEFAULT_AUDIO_JITTER_TOLERANCE 20 * GST_MSECOND +#define DEFAULT_AVOID_REENCODING FALSE + +#define DEFAULT_RAW_CAPS \ + "video/x-raw-yuv; " \ + "video/x-raw-rgb; " \ + "video/x-raw-gray; " \ + "audio/x-raw-int; " \ + "audio/x-raw-float; " \ + "text/plain; " \ + "text/x-pango-markup; " \ + "video/x-dvd-subpicture; " \ + "subpicture/x-pgs" + +/* Properties */ +enum +{ + PROP_0, + PROP_PROFILE, + PROP_QUEUE_BUFFERS_MAX, + PROP_QUEUE_BYTES_MAX, + PROP_QUEUE_TIME_MAX, + PROP_AUDIO_JITTER_TOLERANCE, + PROP_AVOID_REENCODING, + PROP_LAST +}; + +/* Signals */ +enum +{ + SIGNAL_REQUEST_PAD, + LAST_SIGNAL +}; + +static guint gst_encode_bin_signals[LAST_SIGNAL] = { 0 }; + +static GstStaticCaps default_raw_caps = GST_STATIC_CAPS (DEFAULT_RAW_CAPS); + +GST_DEBUG_CATEGORY_STATIC (gst_encode_bin_debug); +#define GST_CAT_DEFAULT gst_encode_bin_debug + +G_DEFINE_TYPE (GstEncodeBin, gst_encode_bin, GST_TYPE_BIN); + +static void gst_encode_bin_dispose (GObject * object); +static void gst_encode_bin_set_property (GObject * object, guint prop_id, + const GValue * value, GParamSpec * pspec); +static void gst_encode_bin_get_property (GObject * object, guint prop_id, + GValue * value, GParamSpec * pspec); +static GstStateChangeReturn gst_encode_bin_change_state (GstElement * element, + GstStateChange transition); + +static GstPad *gst_encode_bin_request_new_pad (GstElement * element, + GstPadTemplate * templ, const gchar * name); +static void gst_encode_bin_release_pad (GstElement * element, GstPad * pad); + +static gboolean +gst_encode_bin_set_profile (GstEncodeBin * ebin, GstEncodingProfile * profile); +static void gst_encode_bin_tear_down_profile (GstEncodeBin * ebin); +static gboolean gst_encode_bin_setup_profile (GstEncodeBin * ebin, + GstEncodingProfile * profile); + +static StreamGroup *_create_stream_group (GstEncodeBin * ebin, + GstEncodingProfile * sprof, const gchar * sinkpadname, GstCaps * sinkcaps); +static void stream_group_remove (GstEncodeBin * ebin, StreamGroup * sgroup); +static GstPad *gst_encode_bin_request_pad_signal (GstEncodeBin * encodebin, + GstCaps * caps); + +static void +gst_encode_bin_class_init (GstEncodeBinClass * klass) +{ + GObjectClass *gobject_klass; + GstElementClass *gstelement_klass; + + gobject_klass = (GObjectClass *) klass; + gstelement_klass = (GstElementClass *) klass; + + gobject_klass->dispose = gst_encode_bin_dispose; + gobject_klass->set_property = gst_encode_bin_set_property; + gobject_klass->get_property = gst_encode_bin_get_property; + + /* Properties */ + g_object_class_install_property (gobject_klass, PROP_PROFILE, + gst_param_spec_mini_object ("profile", "Profile", + "The GstEncodingProfile to use", GST_TYPE_ENCODING_PROFILE, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + + g_object_class_install_property (gobject_klass, PROP_QUEUE_BUFFERS_MAX, + g_param_spec_uint ("queue-bytes-max", "Max. size (kB)", + "Max. amount of data in the queue (bytes, 0=disable)", + 0, G_MAXUINT, DEFAULT_QUEUE_BYTES_MAX, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + + g_object_class_install_property (gobject_klass, PROP_QUEUE_BYTES_MAX, + g_param_spec_uint ("queue-buffers-max", "Max. size (buffers)", + "Max. number of buffers in the queue (0=disable)", 0, G_MAXUINT, + DEFAULT_QUEUE_BUFFERS_MAX, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + + g_object_class_install_property (gobject_klass, PROP_QUEUE_TIME_MAX, + g_param_spec_uint64 ("queue-time-max", "Max. size (ns)", + "Max. amount of data in the queue (in ns, 0=disable)", 0, G_MAXUINT64, + DEFAULT_QUEUE_TIME_MAX, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + + g_object_class_install_property (gobject_klass, PROP_AUDIO_JITTER_TOLERANCE, + g_param_spec_uint64 ("audio-jitter-tolerance", "Audio jitter tolerance", + "Amount of timestamp jitter/imperfection to allow on audio streams before inserting/dropping samples (ns)", + 0, G_MAXUINT64, DEFAULT_AUDIO_JITTER_TOLERANCE, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + + g_object_class_install_property (gobject_klass, PROP_AVOID_REENCODING, + g_param_spec_boolean ("avoid-reencoding", "Avoid re-encoding", + "Whether to re-encode portions of compatible video streams that lay on segment boundaries", + DEFAULT_AVOID_REENCODING, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + + /* Signals */ + gst_encode_bin_signals[SIGNAL_REQUEST_PAD] = + g_signal_new ("request-pad", G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION, G_STRUCT_OFFSET (GstEncodeBinClass, + request_pad), NULL, NULL, gst_encode_marshal_OBJECT__BOXED, + GST_TYPE_PAD, 1, GST_TYPE_CAPS); + + klass->request_pad = gst_encode_bin_request_pad_signal; + + gst_element_class_add_pad_template (gstelement_klass, + gst_static_pad_template_get (&muxer_src_template)); + gst_element_class_add_pad_template (gstelement_klass, + gst_static_pad_template_get (&video_sink_template)); + gst_element_class_add_pad_template (gstelement_klass, + gst_static_pad_template_get (&audio_sink_template)); + /* gst_element_class_add_pad_template (gstelement_klass, */ + /* gst_static_pad_template_get (&text_sink_template)); */ + gst_element_class_add_pad_template (gstelement_klass, + gst_static_pad_template_get (&private_sink_template)); + + gstelement_klass->change_state = + GST_DEBUG_FUNCPTR (gst_encode_bin_change_state); + gstelement_klass->request_new_pad = + GST_DEBUG_FUNCPTR (gst_encode_bin_request_new_pad); + gstelement_klass->release_pad = + GST_DEBUG_FUNCPTR (gst_encode_bin_release_pad); + + gst_element_class_set_details_simple (gstelement_klass, + "Encoder Bin", + "Generic/Bin/Encoder", + "Convenience encoding/muxing element", + "Edward Hervey "); +} + +static void +gst_encode_bin_dispose (GObject * object) +{ + GstEncodeBin *ebin = (GstEncodeBin *) object; + + if (ebin->muxers) + gst_plugin_feature_list_free (ebin->muxers); + + if (ebin->encoders) + gst_plugin_feature_list_free (ebin->encoders); + + if (ebin->parsers) + gst_plugin_feature_list_free (ebin->parsers); + + gst_encode_bin_tear_down_profile (ebin); + + if (ebin->raw_video_caps) + gst_caps_unref (ebin->raw_video_caps); + if (ebin->raw_audio_caps) + gst_caps_unref (ebin->raw_audio_caps); + /* if (ebin->raw_text_caps) */ + /* gst_caps_unref (ebin->raw_text_caps); */ + + G_OBJECT_CLASS (gst_encode_bin_parent_class)->dispose (object); +} + +static void +gst_encode_bin_init (GstEncodeBin * encode_bin) +{ + GstPadTemplate *tmpl; + + encode_bin->muxers = + gst_element_factory_list_get_elements (GST_ELEMENT_FACTORY_TYPE_MUXER, + GST_RANK_MARGINAL); + encode_bin->encoders = + gst_element_factory_list_get_elements (GST_ELEMENT_FACTORY_TYPE_ENCODER, + GST_RANK_MARGINAL); + encode_bin->parsers = + gst_element_factory_list_get_elements (GST_ELEMENT_FACTORY_TYPE_PARSER, + GST_RANK_MARGINAL); + + encode_bin->raw_video_caps = + gst_caps_from_string ("video/x-raw-yuv;video/x-raw-rgb;video/x-raw-gray"); + encode_bin->raw_audio_caps = + gst_caps_from_string ("audio/x-raw-int;audio/x-raw-float"); + /* encode_bin->raw_text_caps = */ + /* gst_caps_from_string ("text/plain;text/x-pango-markup"); */ + + encode_bin->queue_buffers_max = DEFAULT_QUEUE_BUFFERS_MAX; + encode_bin->queue_bytes_max = DEFAULT_QUEUE_BYTES_MAX; + encode_bin->queue_time_max = DEFAULT_QUEUE_TIME_MAX; + encode_bin->tolerance = DEFAULT_AUDIO_JITTER_TOLERANCE; + encode_bin->avoid_reencoding = DEFAULT_AVOID_REENCODING; + + tmpl = gst_static_pad_template_get (&muxer_src_template); + encode_bin->srcpad = gst_ghost_pad_new_no_target_from_template ("src", tmpl); + gst_object_unref (tmpl); + gst_element_add_pad (GST_ELEMENT_CAST (encode_bin), encode_bin->srcpad); +} + +static void +gst_encode_bin_set_property (GObject * object, guint prop_id, + const GValue * value, GParamSpec * pspec) +{ + GstEncodeBin *ebin = (GstEncodeBin *) object; + + switch (prop_id) { + case PROP_PROFILE: + gst_encode_bin_set_profile (ebin, + (GstEncodingProfile *) gst_value_get_mini_object (value)); + break; + case PROP_QUEUE_BUFFERS_MAX: + ebin->queue_buffers_max = g_value_get_uint (value); + break; + case PROP_QUEUE_BYTES_MAX: + ebin->queue_bytes_max = g_value_get_uint (value); + break; + case PROP_QUEUE_TIME_MAX: + ebin->queue_time_max = g_value_get_uint64 (value); + break; + case PROP_AUDIO_JITTER_TOLERANCE: + ebin->tolerance = g_value_get_uint64 (value); + break; + case PROP_AVOID_REENCODING: + ebin->avoid_reencoding = g_value_get_boolean (value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +gst_encode_bin_get_property (GObject * object, guint prop_id, + GValue * value, GParamSpec * pspec) +{ + GstEncodeBin *ebin = (GstEncodeBin *) object; + + switch (prop_id) { + case PROP_PROFILE: + gst_value_set_mini_object (value, (GstMiniObject *) ebin->profile); + break; + case PROP_QUEUE_BUFFERS_MAX: + g_value_set_uint (value, ebin->queue_buffers_max); + break; + case PROP_QUEUE_BYTES_MAX: + g_value_set_uint (value, ebin->queue_bytes_max); + break; + case PROP_QUEUE_TIME_MAX: + g_value_set_uint64 (value, ebin->queue_time_max); + break; + case PROP_AUDIO_JITTER_TOLERANCE: + g_value_set_uint64 (value, ebin->tolerance); + break; + case PROP_AVOID_REENCODING: + g_value_set_boolean (value, ebin->avoid_reencoding); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static inline gboolean +are_raw_caps (const GstCaps * caps) +{ + GstCaps *raw = gst_static_caps_get (&default_raw_caps); + + if (gst_caps_can_intersect (caps, raw)) { + gst_caps_unref (raw); + return TRUE; + } + gst_caps_unref (raw); + return FALSE; +} + +/* Returns the number of time a given stream profile is currently used + * in encodebin */ +static inline guint +stream_profile_used_count (GstEncodeBin * ebin, GstEncodingProfile * sprof) +{ + guint nbprofused = 0; + GList *tmp; + + for (tmp = ebin->streams; tmp; tmp = tmp->next) { + StreamGroup *sgroup = (StreamGroup *) tmp->data; + + if (sgroup->profile == sprof) + nbprofused++; + } + + return nbprofused; +} + +static inline GstEncodingProfile * +next_unused_stream_profile (GstEncodeBin * ebin, GType ptype, GstCaps * caps) +{ + GST_DEBUG_OBJECT (ebin, "ptype:%d, caps:%" GST_PTR_FORMAT, ptype, caps); + + if (G_UNLIKELY (ptype == G_TYPE_NONE && caps != NULL)) { + /* Identify the profile type based on raw caps */ + if (gst_caps_can_intersect (ebin->raw_video_caps, caps)) + ptype = GST_TYPE_ENCODING_VIDEO_PROFILE; + else if (gst_caps_can_intersect (ebin->raw_audio_caps, caps)) + ptype = GST_TYPE_ENCODING_AUDIO_PROFILE; + /* else if (gst_caps_can_intersect (ebin->raw_text_caps, caps)) */ + /* ptype = GST_TYPE_ENCODING_TEXT_PROFILE; */ + GST_DEBUG_OBJECT (ebin, "Detected profile type as being %d", ptype); + } + + if (GST_IS_ENCODING_CONTAINER_PROFILE (ebin->profile)) { + const GList *tmp; + + for (tmp = + gst_encoding_container_profile_get_profiles + (GST_ENCODING_CONTAINER_PROFILE (ebin->profile)); tmp; + tmp = tmp->next) { + GstEncodingProfile *sprof = (GstEncodingProfile *) tmp->data; + + /* Pick an available Stream profile for which: + * * either it is of the compatibly raw type, + * * OR we can pass it through directly without encoding + */ + if (G_TYPE_FROM_INSTANCE (sprof) == ptype) { + guint presence = gst_encoding_profile_get_presence (sprof); + GST_DEBUG ("Found a stream profile with the same type"); + if ((presence == 0) + || (presence > stream_profile_used_count (ebin, sprof))) + return sprof; + } else if ((caps != NULL) && (ptype == G_TYPE_NONE)) { + GstCaps *outcaps; + gboolean res; + + outcaps = gst_encoding_profile_get_output_caps (sprof); + GST_DEBUG ("Unknown stream, seeing if it's compatible with %" + GST_PTR_FORMAT, outcaps); + res = gst_caps_can_intersect (outcaps, caps); + gst_caps_unref (outcaps); + + if (res) + return sprof; + } + } + } + + return NULL; +} + +static GstPad * +gst_encode_bin_request_new_pad (GstElement * element, + GstPadTemplate * templ, const gchar * name) +{ + GstEncodeBin *ebin = (GstEncodeBin *) element; + GType ptype; + StreamGroup *sgroup; + GstEncodingProfile *sprof; + + GST_DEBUG_OBJECT (element, "templ:%s, name:%s", templ->name_template, name); + + /* Identify the stream group */ + + if (!strcmp (templ->name_template, "video_%d")) + ptype = GST_TYPE_ENCODING_VIDEO_PROFILE; + else if (!strcmp (templ->name_template, "audio_%d")) + ptype = GST_TYPE_ENCODING_AUDIO_PROFILE; + /* else if (!strcmp (templ->name_template, "text_%d")) */ + /* ptype = GST_TYPE_ENCODING_TEXT_PROFILE; */ + else + ptype = G_TYPE_NONE; + + /* FIXME : Check uniqueness of pad */ + /* FIXME : Check that the requested number is the last one, and if not, + * update the last_pad_id variable so that we don't create a pad with + * the same name/number in the future */ + + /* Find GstEncodingProfile which we need */ + sprof = next_unused_stream_profile (ebin, ptype, NULL); + if (G_UNLIKELY (sprof == NULL)) + goto no_stream_profile; + + sgroup = _create_stream_group (ebin, sprof, name, NULL); + if (G_UNLIKELY (sgroup == NULL)) + goto no_stream_group; + + return sgroup->ghostpad; + +no_stream_profile: + { + GST_WARNING_OBJECT (ebin, "Couldn't find a compatible stream profile"); + return NULL; + } + +no_stream_group: + { + GST_WARNING_OBJECT (ebin, "Couldn't create a StreamGroup"); + return NULL; + } +} + +static GstPad * +gst_encode_bin_request_pad_signal (GstEncodeBin * encodebin, GstCaps * caps) +{ + GstEncodingProfile *sprof; + StreamGroup *sgroup; + + GST_DEBUG_OBJECT (encodebin, "caps:%" GST_PTR_FORMAT, caps); + + /* Figure out if we have a unused GstEncodingProfile we can use for + * these caps */ + sprof = next_unused_stream_profile (encodebin, G_TYPE_NONE, caps); + if (G_UNLIKELY (sprof == NULL)) + goto no_stream_profile; + + sgroup = _create_stream_group (encodebin, sprof, NULL, caps); + if (G_UNLIKELY (sgroup == NULL)) + goto no_stream_group; + + return sgroup->ghostpad; + +no_stream_profile: + { + GST_WARNING_OBJECT (encodebin, "Couldn't find a compatible stream profile"); + return NULL; + } + +no_stream_group: + { + GST_WARNING_OBJECT (encodebin, "Couldn't create a StreamGroup"); + return NULL; + } +} + +static inline StreamGroup * +find_stream_group_from_pad (GstEncodeBin * ebin, GstPad * pad) +{ + GList *tmp; + + for (tmp = ebin->streams; tmp; tmp = tmp->next) { + StreamGroup *sgroup = (StreamGroup *) tmp->data; + if (G_UNLIKELY (sgroup->ghostpad == pad)) + return sgroup; + } + + return NULL; +} + +static void +gst_encode_bin_release_pad (GstElement * element, GstPad * pad) +{ + GstEncodeBin *ebin = (GstEncodeBin *) element; + StreamGroup *sgroup; + + /* Find the associated StreamGroup */ + + sgroup = find_stream_group_from_pad (ebin, pad); + if (G_UNLIKELY (sgroup == NULL)) + goto no_stream_group; + + /* Release objects/data associated with the StreamGroup */ + stream_group_remove (ebin, sgroup); + + return; + +no_stream_group: + { + GST_WARNING_OBJECT (ebin, "Couldn't find corresponding StreamGroup"); + return; + } +} + +/* Create a parser for the given stream profile */ +static inline GstElement * +_get_parser (GstEncodeBin * ebin, GstEncodingProfile * sprof) +{ + GList *parsers1, *parsers, *tmp; + GstElement *parser = NULL; + GstElementFactory *parserfact = NULL; + const GstCaps *format; + + format = gst_encoding_profile_get_format (sprof); + + GST_DEBUG ("Getting list of parsers for format %" GST_PTR_FORMAT, format); + + /* FIXME : requesting twice the parsers twice is a bit ugly, we should + * have a method to request on more than one condition */ + parsers1 = + gst_element_factory_list_filter (ebin->parsers, format, + GST_PAD_SRC, FALSE); + parsers = + gst_element_factory_list_filter (parsers1, format, GST_PAD_SINK, FALSE); + gst_plugin_feature_list_free (parsers1); + + if (G_UNLIKELY (parsers == NULL)) { + GST_DEBUG ("Couldn't find any compatible parsers"); + return NULL; + } + + for (tmp = parsers; tmp; tmp = tmp->next) { + /* FIXME : We're only picking the first one so far */ + /* FIXME : signal the user if he wants this */ + parserfact = (GstElementFactory *) tmp->data; + break; + } + + if (parserfact) + parser = gst_element_factory_create (parserfact, NULL); + + gst_plugin_feature_list_free (parsers); + + return parser; +} + +static GstElement * +_create_element_and_set_preset (GstElementFactory * factory, + const gchar * preset, const gchar * name) +{ + GstElement *res = NULL; + + GST_DEBUG ("Creating element from factory %s", + GST_PLUGIN_FEATURE_NAME (factory)); + res = gst_element_factory_create (factory, name); + if (preset && GST_IS_PRESET (res) && + !gst_preset_load_preset (GST_PRESET (res), preset)) { + GST_WARNING ("Couldn't set preset [%s] on element [%s]", + preset, GST_PLUGIN_FEATURE_NAME (factory)); + gst_object_unref (res); + res = NULL; + } + + return res; +} + +/* Create the encoder for the given stream profile */ +static inline GstElement * +_get_encoder (GstEncodeBin * ebin, GstEncodingProfile * sprof) +{ + GList *encoders, *tmp; + GstElement *encoder = NULL; + GstElementFactory *encoderfact = 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 encoders for format %" GST_PTR_FORMAT, format); + + /* If stream caps are raw, return identity */ + if (G_UNLIKELY (are_raw_caps (format))) { + GST_DEBUG ("Stream format is raw, returning identity as the encoder"); + encoder = gst_element_factory_make ("identity", NULL); + goto beach; + } + + encoders = + gst_element_factory_list_filter (ebin->encoders, format, + GST_PAD_SRC, FALSE); + + if (G_UNLIKELY (encoders == NULL)) { + GST_DEBUG ("Couldn't find any compatible encoders"); + goto beach; + } + + for (tmp = encoders; tmp; tmp = tmp->next) { + encoderfact = (GstElementFactory *) tmp->data; + if ((encoder = _create_element_and_set_preset (encoderfact, preset, NULL))) + break; + } + + gst_plugin_feature_list_free (encoders); + +beach: + return encoder; +} + +static GstPad * +gst_element_request_pad (GstElement * element, GstPadTemplate * templ, + const gchar * name) +{ + GstPad *newpad = NULL; + GstElementClass *oclass; + + oclass = GST_ELEMENT_GET_CLASS (element); + + if (oclass->request_new_pad) + newpad = (oclass->request_new_pad) (element, templ, name); + + if (newpad) + gst_object_ref (newpad); + + return newpad; +} + +static GstPad * +gst_element_get_pad_from_template (GstElement * element, GstPadTemplate * templ) +{ + GstPad *ret = NULL; + GstPadPresence presence; + + /* If this function is ever exported, we need check the validity of `element' + * and `templ', and to make sure the template actually belongs to the + * element. */ + + presence = GST_PAD_TEMPLATE_PRESENCE (templ); + + switch (presence) { + case GST_PAD_ALWAYS: + case GST_PAD_SOMETIMES: + ret = gst_element_get_static_pad (element, templ->name_template); + if (!ret && presence == GST_PAD_ALWAYS) + g_warning + ("Element %s has an ALWAYS template %s, but no pad of the same name", + GST_OBJECT_NAME (element), templ->name_template); + break; + + case GST_PAD_REQUEST: + ret = gst_element_request_pad (element, templ, NULL); + break; + } + + return ret; +} + +/* FIXME : Improve algorithm for finding compatible muxer sink pad */ +static inline GstPad * +get_compatible_muxer_sink_pad (GstEncodeBin * ebin, GstElement * encoder, + const GstCaps * sinkcaps) +{ + GstPad *sinkpad; + GstPadTemplate *srctempl = NULL; + GstPadTemplate *sinktempl; + + if (encoder) { + GstPad *srcpad; + srcpad = gst_element_get_static_pad (encoder, "src"); + + srctempl = gst_pad_get_pad_template (srcpad); + + GST_DEBUG_OBJECT (ebin, + "Attempting to find pad from muxer %s compatible with %s:%s", + GST_ELEMENT_NAME (ebin->muxer), GST_DEBUG_PAD_NAME (srcpad)); + + gst_object_unref (srcpad); + sinktempl = gst_element_get_compatible_pad_template (ebin->muxer, srctempl); + } else { + srctempl = + gst_pad_template_new ("whatever", GST_PAD_SRC, GST_PAD_ALWAYS, + gst_caps_copy (sinkcaps)); + g_assert (srctempl != NULL); + sinktempl = gst_element_get_compatible_pad_template (ebin->muxer, srctempl); + g_object_unref (srctempl); + } + + if (G_UNLIKELY (sinktempl == NULL)) + goto no_template; + + sinkpad = gst_element_get_pad_from_template (ebin->muxer, sinktempl); + + return sinkpad; + +no_template: + { + GST_WARNING_OBJECT (ebin, "No compatible pad available on muxer"); + return NULL; + } +} + +/* FIXME : Add handling of streams that don't need encoding */ +/* FIXME : Add handling of streams that don't require conversion elements */ +/* + * Create the elements, StreamGroup, add the sink pad, link it to the muxer + * + * sinkpadname: If non-NULL, that name will be assigned to the sink ghost pad + * sinkcaps: If non-NULL will be used to figure out how to setup the group */ +static StreamGroup * +_create_stream_group (GstEncodeBin * ebin, GstEncodingProfile * sprof, + const gchar * sinkpadname, GstCaps * sinkcaps) +{ + StreamGroup *sgroup = NULL; + GstPad *sinkpad, *srcpad, *muxerpad; + /* Element we will link to the encoder */ + GstElement *last = NULL; + GList *tmp, *tosync = NULL; + const GstCaps *format; + const GstCaps *restriction; + + format = gst_encoding_profile_get_format (sprof); + restriction = gst_encoding_profile_get_restriction (sprof); + + GST_DEBUG ("Creating group. format %" GST_PTR_FORMAT ", for caps %" + GST_PTR_FORMAT, format, sinkcaps); + GST_DEBUG ("avoid_reencoding:%d", ebin->avoid_reencoding); + + sgroup = g_slice_new0 (StreamGroup); + sgroup->ebin = ebin; + sgroup->profile = sprof; + + /* NOTE for people reading this code: + * + * We construct the group starting by the furthest downstream element + * and making our way up adding/syncing/linking as we go. + * + * There are two parallel paths: + * * One for raw data which goes through converters and encoders + * * One for already encoded data + */ + + /* Exception to the rule above: + * We check if we have an available encoder so we can abort early */ + /* FIXME : What if we only want to do passthrough ??? */ + GST_LOG ("Checking for encoder availability"); + sgroup->encoder = _get_encoder (ebin, sprof); + if (G_UNLIKELY (sgroup->encoder == NULL)) + goto no_encoder; + + /* Muxer + * We first figure out if the muxer has a sinkpad compatible with the selected + * profile */ + 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 */ + 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); + + gst_bin_add (GST_BIN (ebin), sgroup->outqueue); + tosync = g_list_append (tosync, sgroup->outqueue); + srcpad = gst_element_get_static_pad (sgroup->outqueue, "src"); + if (G_UNLIKELY (fast_pad_link (srcpad, muxerpad) != GST_PAD_LINK_OK)) { + goto muxer_link_failure; + } + gst_object_unref (srcpad); + gst_object_unref (muxerpad); + + /* Output capsfilter + * This will receive the format caps from the streamprofile */ + GST_DEBUG ("Adding output capsfilter for %" GST_PTR_FORMAT, format); + sgroup->outfilter = gst_element_factory_make ("capsfilter", NULL); + g_object_set (sgroup->outfilter, "caps", format, NULL); + + gst_bin_add (GST_BIN (ebin), sgroup->outfilter); + tosync = g_list_append (tosync, sgroup->outfilter); + if (G_UNLIKELY (!fast_element_link (sgroup->outfilter, last))) + goto outfilter_link_failure; + last = sgroup->outfilter; + + + /* FIXME : + * + * The usage of parsers in encoding/muxing scenarios is + * just too undefined to just use as-is. + * + * Take the use-case where you want to re-mux a stream of type + * "my/media". You create a StreamEncodingProfile with that type + * as the target (as-is). And you use decodebin2/uridecodebin + * upstream. + * + * * demuxer exposes "my/media" + * * a parser is available for "my/media" which has a source pad + * caps of "my/media,parsed=True" + * * decodebin2/uridecodebin exposes a new pad with the parsed caps + * * You request a new stream from encodebin, which will match the + * streamprofile and creates a group (i.e. going through this method) + * There is a matching parser (the same used in the decoder) whose + * source pad caps intersects with the stream profile caps, you + * therefore use it... + * * ... but that parser has a "my/media,parsed=False" sink pad caps + * * ... and you can't link your decodebin pad to encodebin. + * + * In the end, it comes down to parsers only taking into account the + * decoding use-cases. + * + * One way to solve that might be to : + * * Make parsers sink pad caps be "framed={False,True}" and the + * source pad caps be "framed=True" + * * Modify decodebin2 accordingly to avoid looping and chaining + * an infinite number of parsers + * + * Another way would be to have "well-known" caps properties to specify + * whether a stream has been parsed or not. + * * currently we fail. aacparse uses 'framed' and mp3parse uses 'parsed' + */ + /* FIXME : Re-enable once parser situation is un-$#*@(%$#ed */ +#if 0 + /* Parser. + * FIXME : identify smart parsers (used for re-encoding) */ + sgroup->parser = _get_parser (ebin, sprof); + + if (sgroup->parser != NULL) { + GST_DEBUG ("Got a parser %s", GST_ELEMENT_NAME (sgroup->parser)); + gst_bin_add (GST_BIN (ebin), sgroup->parser); + tosync = g_list_append (tosync, sgroup->parser); + if (G_UNLIKELY (!gst_element_link (sgroup->parser, last))) + goto parser_link_failure; + last = sgroup->parser; + } +#endif + + /* Stream combiner */ + sgroup->combiner = g_object_new (GST_TYPE_STREAM_COMBINER, NULL); + + gst_bin_add (GST_BIN (ebin), sgroup->combiner); + tosync = g_list_append (tosync, sgroup->combiner); + if (G_UNLIKELY (!fast_element_link (sgroup->combiner, last))) + goto combiner_link_failure; + + + /* Stream splitter */ + sgroup->splitter = g_object_new (GST_TYPE_STREAM_SPLITTER, NULL); + + gst_bin_add (GST_BIN (ebin), sgroup->splitter); + tosync = g_list_append (tosync, sgroup->splitter); + + /* Input queue + * FIXME : figure out what max-size to use for the input queue */ + sgroup->inqueue = gst_element_factory_make ("queue", NULL); + g_object_set (sgroup->inqueue, "max-size-buffers", + (guint32) ebin->queue_buffers_max, "max-size-bytes", + (guint32) ebin->queue_bytes_max, "max-size-time", + (guint64) ebin->queue_time_max, NULL); + + gst_bin_add (GST_BIN (ebin), sgroup->inqueue); + tosync = g_list_append (tosync, sgroup->inqueue); + if (G_UNLIKELY (!fast_element_link (sgroup->inqueue, sgroup->splitter))) + goto splitter_link_failure; + + /* Expose input queue sink pad as ghostpad */ + sinkpad = gst_element_get_static_pad (sgroup->inqueue, "sink"); + if (sinkpadname == NULL) { + gchar *pname = + g_strdup_printf ("%s_%d", gst_encoding_profile_get_type_nick (sprof), + ebin->last_pad_id++); + GST_DEBUG ("Adding ghost pad %s", pname); + sgroup->ghostpad = gst_ghost_pad_new (pname, sinkpad); + g_free (pname); + } else + sgroup->ghostpad = gst_ghost_pad_new (sinkpadname, sinkpad); + gst_object_unref (sinkpad); + + + /* Path 1 : Already-encoded data */ + sinkpad = gst_element_request_pad (sgroup->combiner, NULL, "passthroughsink"); + if (G_UNLIKELY (sinkpad == NULL)) + goto no_combiner_sinkpad; + + if (ebin->avoid_reencoding) { + GstCaps *tmpcaps; + + GST_DEBUG ("Asked to use Smart Encoder"); + sgroup->smartencoder = g_object_new (GST_TYPE_SMART_ENCODER, NULL); + + /* Check if stream format is compatible */ + srcpad = gst_element_get_static_pad (sgroup->smartencoder, "src"); + tmpcaps = gst_pad_get_caps (srcpad); + if (!gst_caps_can_intersect (tmpcaps, format)) { + GST_DEBUG ("We don't have a smart encoder for the stream format"); + gst_object_unref (sgroup->smartencoder); + sgroup->smartencoder = NULL; + } else { + gst_bin_add ((GstBin *) ebin, sgroup->smartencoder); + fast_pad_link (srcpad, sinkpad); + tosync = g_list_append (tosync, sgroup->smartencoder); + sinkpad = gst_element_get_static_pad (sgroup->smartencoder, "sink"); + } + gst_caps_unref (tmpcaps); + g_object_unref (srcpad); + } + + srcpad = gst_element_request_pad (sgroup->splitter, NULL, "passthroughsrc"); + if (G_UNLIKELY (srcpad == NULL)) + goto no_splitter_srcpad; + + /* Go straight to splitter */ + if (G_UNLIKELY (fast_pad_link (srcpad, sinkpad) != GST_PAD_LINK_OK)) + goto passthrough_link_failure; + g_object_unref (sinkpad); + g_object_unref (srcpad); + + + /* Path 2 : Conversion / Encoding */ + + /* 1. Create the encoder */ + GST_LOG ("Adding encoder"); + last = sgroup->encoder; + gst_bin_add ((GstBin *) ebin, sgroup->encoder); + tosync = g_list_append (tosync, sgroup->encoder); + + sinkpad = gst_element_request_pad (sgroup->combiner, NULL, "encodingsink"); + if (G_UNLIKELY (sinkpad == NULL)) + goto no_combiner_sinkpad; + srcpad = gst_element_get_static_pad (sgroup->encoder, "src"); + if (G_UNLIKELY (fast_pad_link (srcpad, sinkpad) != GST_PAD_LINK_OK)) + goto encoder_link_failure; + g_object_unref (sinkpad); + g_object_unref (srcpad); + + + /* 3. Create the conversion/restriction elements */ + /* 3.1. capsfilter */ + if (restriction && !gst_caps_is_any (restriction)) { + GST_LOG ("Adding capsfilter for restriction caps : %" GST_PTR_FORMAT, + restriction); + + last = sgroup->capsfilter = gst_element_factory_make ("capsfilter", NULL); + g_object_set (sgroup->capsfilter, "caps", restriction, NULL); + gst_bin_add ((GstBin *) ebin, sgroup->capsfilter); + tosync = g_list_append (tosync, sgroup->capsfilter); + fast_element_link (sgroup->capsfilter, sgroup->encoder); + } + + /* 3.2. restriction elements */ + /* FIXME : Once we have properties for specific converters, use those */ + if (GST_IS_ENCODING_VIDEO_PROFILE (sprof)) { + GstElement *cspace, *scale, *vrate, *cspace2; + + GST_LOG ("Adding conversion elements for video stream"); + + cspace = gst_element_factory_make ("ffmpegcolorspace", NULL); + scale = gst_element_factory_make ("videoscale", NULL); + /* 4-tap scaling and black borders */ + g_object_set (scale, "method", 2, "add-borders", TRUE, NULL); + cspace2 = gst_element_factory_make ("ffmpegcolorspace", NULL); + + gst_bin_add_many ((GstBin *) ebin, cspace, scale, cspace2, NULL); + tosync = g_list_append (tosync, cspace); + tosync = g_list_append (tosync, scale); + tosync = g_list_append (tosync, cspace2); + + sgroup->converters = g_list_prepend (sgroup->converters, cspace); + sgroup->converters = g_list_prepend (sgroup->converters, scale); + sgroup->converters = g_list_prepend (sgroup->converters, cspace2); + + if (!fast_element_link (cspace, scale) || + !fast_element_link (scale, cspace2)) + goto converter_link_failure; + + if (!gst_encoding_video_profile_get_variableframerate + (GST_ENCODING_VIDEO_PROFILE (sprof))) { + vrate = gst_element_factory_make ("videorate", NULL); + gst_bin_add ((GstBin *) ebin, vrate); + tosync = g_list_prepend (tosync, vrate); + sgroup->converters = g_list_prepend (sgroup->converters, vrate); + if (!fast_element_link (cspace2, vrate) || + !fast_element_link (vrate, last)) + goto converter_link_failure; + } else if (!fast_element_link (cspace2, last)) + goto converter_link_failure; + + last = cspace; + + } else if (GST_IS_ENCODING_AUDIO_PROFILE (sprof)) { + GstElement *aconv, *ares, *arate; + + GST_LOG ("Adding conversion elements for audio stream"); + + arate = gst_element_factory_make ("audiorate", NULL); + g_object_set (arate, "tolerance", (guint64) ebin->tolerance, NULL); + aconv = gst_element_factory_make ("audioconvert", NULL); + ares = gst_element_factory_make ("audioresample", NULL); + + gst_bin_add_many ((GstBin *) ebin, arate, aconv, ares, NULL); + tosync = g_list_append (tosync, arate); + tosync = g_list_append (tosync, aconv); + tosync = g_list_append (tosync, ares); + if (!fast_element_link (arate, aconv) || + !fast_element_link (aconv, ares) || !fast_element_link (ares, last)) + goto converter_link_failure; + + sgroup->converters = g_list_prepend (sgroup->converters, arate); + sgroup->converters = g_list_prepend (sgroup->converters, aconv); + sgroup->converters = g_list_prepend (sgroup->converters, ares); + + last = arate; + } + + /* Link to stream splitter */ + sinkpad = gst_element_get_static_pad (last, "sink"); + srcpad = gst_element_request_pad (sgroup->splitter, NULL, "encodingsrc"); + if (G_UNLIKELY (srcpad == NULL)) + goto no_splitter_srcpad; + if (G_UNLIKELY (fast_pad_link (srcpad, sinkpad) != GST_PAD_LINK_OK)) + goto splitter_encoding_failure; + g_object_unref (sinkpad); + g_object_unref (srcpad); + + /* End of Stream 2 setup */ + + /* Sync all elements to parent state */ + for (tmp = tosync; tmp; tmp = tmp->next) + gst_element_sync_state_with_parent ((GstElement *) tmp->data); + g_list_free (tosync); + + /* Add ghostpad */ + GST_DEBUG ("Adding ghostpad %s:%s", GST_DEBUG_PAD_NAME (sgroup->ghostpad)); + gst_pad_set_active (sgroup->ghostpad, TRUE); + gst_element_add_pad ((GstElement *) ebin, sgroup->ghostpad); + + /* Add StreamGroup to our list of streams */ + + GST_DEBUG + ("Done creating elements, adding StreamGroup to our controlled stream list"); + + ebin->streams = g_list_prepend (ebin->streams, sgroup); + + return sgroup; + +splitter_encoding_failure: + GST_ERROR_OBJECT (ebin, "Error linking splitter to encoding stream"); + goto cleanup; + +no_encoder: + GST_ERROR_OBJECT (ebin, "Couldn't create encoder for format %" GST_PTR_FORMAT, + format); + goto cleanup; + +no_muxer_pad: + GST_ERROR_OBJECT (ebin, + "Couldn't find a compatible muxer pad to link encoder to"); + goto cleanup; + +encoder_link_failure: + GST_ERROR_OBJECT (ebin, "Failed to link the encoder"); + goto cleanup; + +muxer_link_failure: + GST_ERROR_OBJECT (ebin, "Couldn't link encoder to muxer"); + goto cleanup; + +outfilter_link_failure: + GST_ERROR_OBJECT (ebin, "Couldn't link output filter to output queue"); + goto cleanup; + +passthrough_link_failure: + GST_ERROR_OBJECT (ebin, "Failed linking splitter in passthrough mode"); + goto cleanup; + +no_splitter_srcpad: + GST_ERROR_OBJECT (ebin, "Couldn't get a source pad from the splitter"); + goto cleanup; + +no_combiner_sinkpad: + GST_ERROR_OBJECT (ebin, "Couldn't get a sink pad from the combiner"); + goto cleanup; + +splitter_link_failure: + GST_ERROR_OBJECT (ebin, "Failure linking to the splitter"); + goto cleanup; + +combiner_link_failure: + GST_ERROR_OBJECT (ebin, "Failure linking to the combiner"); + goto cleanup; + +#if 0 +parser_link_failure: + GST_ERROR_OBJECT (ebin, "Failure linking the parser"); + goto cleanup; +#endif + +converter_link_failure: + GST_ERROR_OBJECT (ebin, "Failure linking the video converters"); + goto cleanup; + +cleanup: + /* FIXME : Actually properly cleanup everything */ + g_slice_free (StreamGroup, sgroup); + return NULL; +} + +static gboolean +_factory_can_sink_caps (GstElementFactory * factory, const GstCaps * caps) +{ + GList *templates = factory->staticpadtemplates; + + while (templates) { + GstStaticPadTemplate *template = (GstStaticPadTemplate *) templates->data; + + if (template->direction == GST_PAD_SINK) { + GstCaps *tmp = gst_static_caps_get (&template->static_caps); + + if (gst_caps_can_intersect (tmp, caps)) { + gst_caps_unref (tmp); + return TRUE; + } + gst_caps_unref (tmp); + } + templates = g_list_next (templates); + } + + return FALSE; +} + +static inline GstElement * +_get_muxer (GstEncodeBin * ebin) +{ + GList *muxers, *tmpmux; + GstElement *muxer = NULL; + GstElementFactory *muxerfact = NULL; + const GList *tmp; + const GstCaps *format; + const gchar *preset; + + format = gst_encoding_profile_get_format (ebin->profile); + preset = gst_encoding_profile_get_preset (ebin->profile); + + if (format == NULL) { + GST_DEBUG ("Container-less profile, using identity"); + muxer = gst_element_factory_make ("identity", NULL); + goto beach; + } + + GST_DEBUG ("Getting list of muxers for format %" GST_PTR_FORMAT, format); + + muxers = + gst_element_factory_list_filter (ebin->muxers, format, GST_PAD_SRC, TRUE); + + if (muxers == NULL) + goto beach; + + /* FIXME : signal the user if he wants this */ + for (tmpmux = muxers; tmpmux; tmpmux = tmpmux->next) { + gboolean cansinkstreams = TRUE; + const GList *profiles = + gst_encoding_container_profile_get_profiles + (GST_ENCODING_CONTAINER_PROFILE (ebin->profile)); + + muxerfact = (GstElementFactory *) tmpmux->data; + + GST_DEBUG ("Trying muxer %s", GST_PLUGIN_FEATURE_NAME (muxerfact)); + + /* See if the muxer can sink all of our stream profile caps */ + for (tmp = profiles; tmp; tmp = tmp->next) { + GstEncodingProfile *sprof = (GstEncodingProfile *) tmp->data; + + if (!_factory_can_sink_caps (muxerfact, + gst_encoding_profile_get_format (sprof))) { + GST_DEBUG ("Skipping muxer because it can't sink caps %" GST_PTR_FORMAT, + gst_encoding_profile_get_format (sprof)); + cansinkstreams = FALSE; + break; + } + } + + /* Only use a muxer than can use all streams and than can accept the + * preset (which may be present or not) */ + if (cansinkstreams && (muxer = + _create_element_and_set_preset (muxerfact, preset, "muxer"))) + break; + } + + gst_plugin_feature_list_free (muxers); + +beach: + return muxer; +} + +static gboolean +create_elements_and_pads (GstEncodeBin * ebin) +{ + gboolean ret = TRUE; + GstElement *muxer; + GstPad *muxerpad; + const GList *tmp, *profiles; + GstEncodingProfile *sprof; + + GST_DEBUG ("Current profile : %s", + gst_encoding_profile_get_name (ebin->profile)); + + /* 1. Get the compatible muxer */ + muxer = _get_muxer (ebin); + if (G_UNLIKELY (muxer == NULL)) + goto no_muxer; + + /* Record the muxer */ + ebin->muxer = muxer; + gst_bin_add ((GstBin *) ebin, muxer); + + /* 2. Ghost the muxer source pad */ + + /* FIXME : We should figure out if it's a static/request/dyamic pad, + * but for the time being let's assume it's a static pad :) */ + muxerpad = gst_element_get_static_pad (muxer, "src"); + if (G_UNLIKELY (muxerpad == NULL)) + goto no_muxer_pad; + + if (!gst_ghost_pad_set_target (GST_GHOST_PAD (ebin->srcpad), muxerpad)) + goto no_muxer_ghost_pad; + + gst_object_unref (muxerpad); + + /* 3. Activate fixed presence streams */ + profiles = + gst_encoding_container_profile_get_profiles + (GST_ENCODING_CONTAINER_PROFILE (ebin->profile)); + for (tmp = profiles; tmp; tmp = tmp->next) { + sprof = (GstEncodingProfile *) tmp->data; + + GST_DEBUG ("Trying stream profile with presence %d", + gst_encoding_profile_get_presence (sprof)); + + if (gst_encoding_profile_get_presence (sprof) != 0) { + if (G_UNLIKELY (_create_stream_group (ebin, sprof, NULL, NULL) == NULL)) + goto stream_error; + } + } + + return ret; + +no_muxer: + { + GST_WARNING ("No available muxer for %" GST_PTR_FORMAT, + gst_encoding_profile_get_format (ebin->profile)); + return FALSE; + } + +no_muxer_pad: + { + GST_WARNING ("Can't get source pad from muxer (%s)", + GST_ELEMENT_NAME (muxer)); + gst_bin_remove (GST_BIN (ebin), muxer); + return FALSE; + } + +no_muxer_ghost_pad: + { + GST_WARNING ("Couldn't set %s:%s as source ghostpad target", + GST_DEBUG_PAD_NAME (muxerpad)); + gst_bin_remove (GST_BIN (ebin), muxer); + gst_object_unref (muxerpad); + return FALSE; + } + +stream_error: + { + GST_WARNING ("Could not create Streams"); + gst_element_remove_pad ((GstElement *) ebin, ebin->srcpad); + gst_bin_remove (GST_BIN (ebin), muxer); + ebin->muxer = NULL; + ebin->srcpad = NULL; + return FALSE; + } +} + +static void +release_pads (GstPad * pad, GstElement * elt) +{ + GstPad *peer = NULL; + + GST_DEBUG_OBJECT (elt, "Releasing pad %s:%s", GST_DEBUG_PAD_NAME (pad)); + + /* Unlink from its peer pad */ + if ((peer = gst_pad_get_peer (pad))) { + if (GST_PAD_DIRECTION (peer) == GST_PAD_SRC) + gst_pad_unlink (peer, pad); + else + gst_pad_unlink (pad, peer); + gst_object_unref (peer); + } + + /* Release it from the object */ + gst_element_release_request_pad (elt, pad); + + /* And remove the reference added by the iterator */ + gst_object_unref (pad); +} + +static void inline +stream_group_free (GstEncodeBin * ebin, StreamGroup * sgroup) +{ + GList *tmp; + GstPad *tmppad; + GstPad *pad; + + GST_DEBUG_OBJECT (ebin, "Freeing StreamGroup %p", sgroup); + + /* outqueue - Muxer */ + tmppad = gst_element_get_static_pad (sgroup->outqueue, "src"); + pad = gst_pad_get_peer (tmppad); + + /* Remove muxer request sink pad */ + gst_pad_unlink (tmppad, pad); + gst_element_release_request_pad (ebin->muxer, pad); + gst_object_unref (tmppad); + gst_object_unref (pad); + 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); + gst_bin_remove (GST_BIN (ebin), sgroup->outqueue); + + /* streamcombiner - parser - capsfilter */ + if (sgroup->parser) { + gst_element_set_state (sgroup->parser, GST_STATE_NULL); + gst_element_unlink (sgroup->parser, sgroup->outfilter); + gst_element_unlink (sgroup->combiner, sgroup->parser); + } + + /* Sink Ghostpad */ + if (sgroup->ghostpad) + gst_element_remove_pad (GST_ELEMENT_CAST (ebin), sgroup->ghostpad); + + if (sgroup->inqueue) + gst_element_set_state (sgroup->inqueue, GST_STATE_NULL); + + if (sgroup->encoder) + gst_element_set_state (sgroup->encoder, GST_STATE_NULL); + if (sgroup->outfilter) + gst_element_set_state (sgroup->outfilter, GST_STATE_NULL); + if (sgroup->smartencoder) + gst_element_set_state (sgroup->smartencoder, GST_STATE_NULL); + + if (sgroup->capsfilter) { + gst_element_set_state (sgroup->capsfilter, GST_STATE_NULL); + gst_element_unlink (sgroup->capsfilter, sgroup->encoder); + gst_bin_remove ((GstBin *) ebin, sgroup->capsfilter); + } + + for (tmp = sgroup->converters; tmp; tmp = tmp->next) { + GstElement *elt = (GstElement *) tmp->data; + + gst_element_set_state (elt, GST_STATE_NULL); + gst_bin_remove ((GstBin *) ebin, elt); + } + if (sgroup->converters) + g_list_free (sgroup->converters); + + if (sgroup->combiner) { + GstIterator *it = gst_element_iterate_sink_pads (sgroup->combiner); + GstIteratorResult itret = GST_ITERATOR_OK; + + while (itret == GST_ITERATOR_OK || itret == GST_ITERATOR_RESYNC) { + itret = gst_iterator_foreach (it, (GFunc) release_pads, sgroup->combiner); + gst_iterator_resync (it); + } + gst_iterator_free (it); + } + + if (sgroup->splitter) { + GstIterator *it = gst_element_iterate_src_pads (sgroup->splitter); + GstIteratorResult itret = GST_ITERATOR_OK; + while (itret == GST_ITERATOR_OK || itret == GST_ITERATOR_RESYNC) { + itret = gst_iterator_foreach (it, (GFunc) release_pads, sgroup->splitter); + gst_iterator_resync (it); + } + gst_iterator_free (it); + } + + if (sgroup->inqueue) + gst_bin_remove ((GstBin *) ebin, sgroup->inqueue); + if (sgroup->encoder) + gst_bin_remove ((GstBin *) ebin, sgroup->encoder); + if (sgroup->smartencoder) + gst_bin_remove ((GstBin *) ebin, sgroup->smartencoder); + + g_slice_free (StreamGroup, sgroup); +} + +static void +stream_group_remove (GstEncodeBin * ebin, StreamGroup * sgroup) +{ + ebin->streams = g_list_remove (ebin->streams, sgroup); + + stream_group_free (ebin, sgroup); +} + +static void +gst_encode_bin_tear_down_profile (GstEncodeBin * ebin) +{ + if (G_UNLIKELY (ebin->profile == NULL)) + return; + + GST_DEBUG ("Tearing down profile %s", + gst_encoding_profile_get_name (ebin->profile)); + + while (ebin->streams) + stream_group_remove (ebin, (StreamGroup *) ebin->streams->data); + + /* free/clear profile */ + gst_encoding_profile_unref (ebin->profile); + ebin->profile = NULL; +} + +static gboolean +gst_encode_bin_setup_profile (GstEncodeBin * ebin, GstEncodingProfile * profile) +{ + gboolean res; + + g_return_val_if_fail (ebin->profile == NULL, FALSE); + + GST_DEBUG ("Setting up profile %s", gst_encoding_profile_get_name (profile)); + + ebin->profile = profile; + gst_mini_object_ref ((GstMiniObject *) ebin->profile); + + /* Create elements */ + res = create_elements_and_pads (ebin); + if (res == FALSE) + gst_encode_bin_tear_down_profile (ebin); + + return res; +} + +static gboolean +gst_encode_bin_set_profile (GstEncodeBin * ebin, GstEncodingProfile * profile) +{ + GST_DEBUG_OBJECT (ebin, "profile : %s", + gst_encoding_profile_get_name (profile)); + + if (G_UNLIKELY (ebin->active)) { + GST_WARNING_OBJECT (ebin, "Element already active, can't change profile"); + return FALSE; + } + + /* If we're not active, we can deactivate the previous profile */ + if (ebin->profile) + gst_encoding_profile_unref (ebin->profile); + ebin->profile = NULL; + + return gst_encode_bin_setup_profile (ebin, profile); +} + +static inline gboolean +gst_encode_bin_activate (GstEncodeBin * ebin) +{ + ebin->active = ebin->profile != NULL; + return ebin->active; +} + +static void +gst_encode_bin_deactivate (GstEncodeBin * ebin) +{ + ebin->active = FALSE; +} + +static GstStateChangeReturn +gst_encode_bin_change_state (GstElement * element, GstStateChange transition) +{ + GstStateChangeReturn ret; + GstEncodeBin *ebin = (GstEncodeBin *) element; + + switch (transition) { + case GST_STATE_CHANGE_READY_TO_PAUSED: + case GST_STATE_CHANGE_PAUSED_TO_PLAYING: + if (!gst_encode_bin_activate (ebin)) { + ret = GST_STATE_CHANGE_FAILURE; + goto beach; + } + break; + default: + break; + } + + ret = + GST_ELEMENT_CLASS (gst_encode_bin_parent_class)->change_state (element, + transition); + if (ret == GST_STATE_CHANGE_FAILURE) + goto beach; + + switch (transition) { + case GST_STATE_CHANGE_PAUSED_TO_READY: + gst_encode_bin_deactivate (ebin); + break; + default: + break; + } + +beach: + return ret; +} + + +static gboolean +plugin_init (GstPlugin * plugin) +{ + gboolean res; + + GST_DEBUG_CATEGORY_INIT (gst_encode_bin_debug, "encodebin", 0, "encoder bin"); + +#ifdef ENABLE_NLS + GST_DEBUG ("binding text domain %s to locale dir %s", GETTEXT_PACKAGE, + LOCALEDIR); + bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR); + bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8"); +#endif /* ENABLE_NLS */ + + + res = gst_element_register (plugin, "encodebin", GST_RANK_NONE, + GST_TYPE_ENCODE_BIN); + + return res; +} + +GST_PLUGIN_DEFINE (GST_VERSION_MAJOR, + GST_VERSION_MINOR, + "encoding", + "various encoding-related elements", plugin_init, VERSION, GST_LICENSE, + GST_PACKAGE_NAME, GST_PACKAGE_ORIGIN) diff --git a/gst/encoding/gstencodebin.h b/gst/encoding/gstencodebin.h new file mode 100644 index 0000000000..8082817de3 --- /dev/null +++ b/gst/encoding/gstencodebin.h @@ -0,0 +1,39 @@ +/* GStreamer encoding bin + * Copyright (C) 2009 Edward Hervey + * (C) 2009 Nokia Corporation + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef __GST_ENCODEBIN_H__ +#define __GST_ENCODEBIN_H__ + +#include +#include +#include "gstencode-marshal.h" + +#define GST_TYPE_ENCODE_BIN (gst_encode_bin_get_type()) +#define GST_ENCODE_BIN(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_ENCODE_BIN,GstEncodeBin)) +#define GST_ENCODE_BIN_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_ENCODE_BIN,GstEncodeBinClass)) +#define GST_IS_ENCODE_BIN(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_ENCODE_BIN)) +#define GST_IS_ENCODE_BIN_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_ENCODE_BIN)) + +typedef struct _GstEncodeBin GstEncodeBin; +typedef struct _GstEncodeBinClass GstEncodeBinClass; + +GType gst_encode_bin_get_type(void); + +#endif /* __GST_ENCODEBIN_H__ */ diff --git a/gst/encoding/gstsmartencoder.c b/gst/encoding/gstsmartencoder.c new file mode 100644 index 0000000000..ed0e42bd5c --- /dev/null +++ b/gst/encoding/gstsmartencoder.c @@ -0,0 +1,701 @@ +/* GStreamer Smart Video Encoder element + * Copyright (C) <2010> Edward Hervey + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +/* TODO: + * * Implement get_caps/set_caps (store/forward caps) + * * Adjust template caps to the formats we can support + **/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include "gstsmartencoder.h" + +GST_DEBUG_CATEGORY_STATIC (smart_encoder_debug); +#define GST_CAT_DEFAULT smart_encoder_debug + +/* FIXME : Update this with new caps */ +/* WARNING : We can only allow formats with closed-GOP */ +#define ALLOWED_CAPS "video/x-h263;video/x-intel-h263;"\ + "video/mpeg,mpegversion=(int)1,systemstream=(boolean)false;"\ + "video/mpeg,mpegversion=(int)2,systemstream=(boolean)false;" + +static GstStaticPadTemplate src_template = +GST_STATIC_PAD_TEMPLATE ("src", GST_PAD_SRC, + GST_PAD_ALWAYS, + GST_STATIC_CAPS (ALLOWED_CAPS) + ); + +static GstStaticPadTemplate sink_template = GST_STATIC_PAD_TEMPLATE ("sink", + GST_PAD_SINK, + GST_PAD_ALWAYS, + GST_STATIC_CAPS (ALLOWED_CAPS) + ); + +static GQuark INTERNAL_ELEMENT; + +/* GstSmartEncoder signals and args */ +enum +{ + /* FILL ME */ + LAST_SIGNAL +}; + +enum +{ + ARG_0 + /* FILL ME */ +}; + +static void +_do_init (void) +{ + INTERNAL_ELEMENT = g_quark_from_string ("internal-element"); +}; + +G_DEFINE_TYPE_EXTENDED (GstSmartEncoder, gst_smart_encoder, GST_TYPE_ELEMENT, 0, + _do_init ()); + +static void gst_smart_encoder_dispose (GObject * object); + +static gboolean setup_recoder_pipeline (GstSmartEncoder * smart_encoder); + +static GstFlowReturn gst_smart_encoder_chain (GstPad * pad, GstBuffer * buf); +static gboolean smart_encoder_sink_event (GstPad * pad, GstEvent * event); +static GstCaps *smart_encoder_sink_getcaps (GstPad * pad); +static GstStateChangeReturn +gst_smart_encoder_change_state (GstElement * element, + GstStateChange transition); + +static void +gst_smart_encoder_class_init (GstSmartEncoderClass * klass) +{ + GObjectClass *gobject_class; + GstElementClass *element_class; + + element_class = (GstElementClass *) klass; + gobject_class = G_OBJECT_CLASS (klass); + + gst_smart_encoder_parent_class = g_type_class_peek_parent (klass); + + gst_element_class_add_pad_template (element_class, + gst_static_pad_template_get (&src_template)); + gst_element_class_add_pad_template (element_class, + gst_static_pad_template_get (&sink_template)); + + gst_element_class_set_details_simple (element_class, "Smart Video Encoder", + "Codec/Recoder/Video", + "Re-encodes portions of Video that lay on segment boundaries", + "Edward Hervey "); + + gobject_class->dispose = (GObjectFinalizeFunc) (gst_smart_encoder_dispose); + element_class->change_state = gst_smart_encoder_change_state; + + GST_DEBUG_CATEGORY_INIT (smart_encoder_debug, "smartencoder", 0, + "Smart Encoder"); +} + +static void +smart_encoder_reset (GstSmartEncoder * smart_encoder) +{ + gst_segment_init (smart_encoder->segment, GST_FORMAT_UNDEFINED); + + if (smart_encoder->encoder) { + /* Clean up/remove elements */ + gst_element_set_state (smart_encoder->encoder, GST_STATE_NULL); + gst_element_set_state (smart_encoder->decoder, GST_STATE_NULL); + gst_element_set_bus (smart_encoder->encoder, NULL); + gst_element_set_bus (smart_encoder->decoder, NULL); + gst_pad_set_active (smart_encoder->internal_srcpad, FALSE); + gst_pad_set_active (smart_encoder->internal_sinkpad, FALSE); + gst_object_unref (smart_encoder->encoder); + gst_object_unref (smart_encoder->decoder); + gst_object_unref (smart_encoder->internal_srcpad); + gst_object_unref (smart_encoder->internal_sinkpad); + + smart_encoder->encoder = NULL; + smart_encoder->decoder = NULL; + smart_encoder->internal_sinkpad = NULL; + smart_encoder->internal_srcpad = NULL; + } + + if (smart_encoder->newsegment) { + gst_event_unref (smart_encoder->newsegment); + smart_encoder->newsegment = NULL; + } +} + + +static void +gst_smart_encoder_init (GstSmartEncoder * smart_encoder) +{ + smart_encoder->sinkpad = + gst_pad_new_from_static_template (&sink_template, "sink"); + gst_pad_set_chain_function (smart_encoder->sinkpad, gst_smart_encoder_chain); + gst_pad_set_event_function (smart_encoder->sinkpad, smart_encoder_sink_event); + gst_pad_set_getcaps_function (smart_encoder->sinkpad, + smart_encoder_sink_getcaps); + gst_element_add_pad (GST_ELEMENT (smart_encoder), smart_encoder->sinkpad); + + smart_encoder->srcpad = + gst_pad_new_from_static_template (&src_template, "src"); + gst_pad_use_fixed_caps (smart_encoder->srcpad); + gst_element_add_pad (GST_ELEMENT (smart_encoder), smart_encoder->srcpad); + + smart_encoder->segment = gst_segment_new (); + + smart_encoder_reset (smart_encoder); +} + +void +gst_smart_encoder_dispose (GObject * object) +{ + GstSmartEncoder *smart_encoder = (GstSmartEncoder *) object; + + if (smart_encoder->segment) + gst_segment_free (smart_encoder->segment); + smart_encoder->segment = NULL; + if (smart_encoder->available_caps) + gst_caps_unref (smart_encoder->available_caps); + smart_encoder->available_caps = NULL; + G_OBJECT_CLASS (gst_smart_encoder_parent_class)->dispose (object); +} + +static GstFlowReturn +gst_smart_encoder_reencode_gop (GstSmartEncoder * smart_encoder) +{ + GstFlowReturn res = GST_FLOW_OK; + GList *tmp; + + if (smart_encoder->encoder == NULL) { + if (!setup_recoder_pipeline (smart_encoder)) + return GST_FLOW_ERROR; + } + + /* Activate elements */ + /* Set elements to PAUSED */ + gst_element_set_state (smart_encoder->encoder, GST_STATE_PAUSED); + gst_element_set_state (smart_encoder->decoder, GST_STATE_PAUSED); + + GST_INFO ("Pushing Flush start/stop to clean decoder/encoder"); + gst_pad_push_event (smart_encoder->internal_srcpad, + gst_event_new_flush_start ()); + gst_pad_push_event (smart_encoder->internal_srcpad, + gst_event_new_flush_stop ()); + + /* push newsegment */ + GST_INFO ("Pushing newsegment %" GST_PTR_FORMAT, smart_encoder->newsegment); + gst_pad_push_event (smart_encoder->internal_srcpad, + gst_event_ref (smart_encoder->newsegment)); + + /* Push buffers through our pads */ + GST_DEBUG ("Pushing pending buffers"); + + for (tmp = smart_encoder->pending_gop; tmp; tmp = tmp->next) { + GstBuffer *buf = (GstBuffer *) tmp->data; + + res = gst_pad_push (smart_encoder->internal_srcpad, buf); + if (G_UNLIKELY (res != GST_FLOW_OK)) + break; + } + + if (G_UNLIKELY (res != GST_FLOW_OK)) { + GST_WARNING ("Error pushing pending buffers : %s", gst_flow_get_name (res)); + /* Remove pending bfufers */ + for (tmp = smart_encoder->pending_gop; tmp; tmp = tmp->next) { + gst_buffer_unref ((GstBuffer *) tmp->data); + } + } else { + GST_INFO ("Pushing out EOS to flush out decoder/encoder"); + gst_pad_push_event (smart_encoder->internal_srcpad, gst_event_new_eos ()); + } + + /* Activate elements */ + /* Set elements to PAUSED */ + gst_element_set_state (smart_encoder->encoder, GST_STATE_NULL); + gst_element_set_state (smart_encoder->decoder, GST_STATE_NULL); + + g_list_free (smart_encoder->pending_gop); + smart_encoder->pending_gop = NULL; + + return res; +} + +static GstFlowReturn +gst_smart_encoder_push_pending_gop (GstSmartEncoder * smart_encoder) +{ + gint64 cstart, cstop; + GList *tmp; + GstFlowReturn res = GST_FLOW_OK; + + GST_DEBUG ("Pushing pending GOP (%" GST_TIME_FORMAT " -- %" GST_TIME_FORMAT + ")", GST_TIME_ARGS (smart_encoder->gop_start), + GST_TIME_ARGS (smart_encoder->gop_stop)); + + /* If GOP is entirely within segment, just push downstream */ + if (gst_segment_clip (smart_encoder->segment, GST_FORMAT_TIME, + smart_encoder->gop_start, smart_encoder->gop_stop, &cstart, &cstop)) { + if ((cstart != smart_encoder->gop_start) + || (cstop != smart_encoder->gop_stop)) { + GST_DEBUG ("GOP needs to be re-encoded from %" GST_TIME_FORMAT " to %" + GST_TIME_FORMAT, GST_TIME_ARGS (cstart), GST_TIME_ARGS (cstop)); + res = gst_smart_encoder_reencode_gop (smart_encoder); + } else { + /* The whole GOP is within the segment, push all pending buffers downstream */ + GST_DEBUG ("GOP doesn't need to be modified, pushing downstream"); + for (tmp = smart_encoder->pending_gop; tmp; tmp = tmp->next) { + GstBuffer *buf = (GstBuffer *) tmp->data; + res = gst_pad_push (smart_encoder->srcpad, buf); + if (G_UNLIKELY (res != GST_FLOW_OK)) + break; + } + } + } else { + /* The whole GOP is outside the segment, there's most likely + * a bug somewhere. */ + GST_WARNING + ("GOP is entirely outside of the segment, upstream gave us too much data"); + for (tmp = smart_encoder->pending_gop; tmp; tmp = tmp->next) { + gst_buffer_unref ((GstBuffer *) tmp->data); + } + } + + if (smart_encoder->pending_gop) { + g_list_free (smart_encoder->pending_gop); + smart_encoder->pending_gop = NULL; + } + smart_encoder->gop_start = GST_CLOCK_TIME_NONE; + smart_encoder->gop_stop = GST_CLOCK_TIME_NONE; + + return res; +} + +static GstFlowReturn +gst_smart_encoder_chain (GstPad * pad, GstBuffer * buf) +{ + GstSmartEncoder *smart_encoder; + GstFlowReturn res = GST_FLOW_OK; + gboolean discont, keyframe; + + smart_encoder = GST_SMART_ENCODER (gst_object_get_parent (GST_OBJECT (pad))); + + discont = GST_BUFFER_IS_DISCONT (buf); + keyframe = !GST_BUFFER_FLAG_IS_SET (buf, GST_BUFFER_FLAG_DELTA_UNIT); + + GST_DEBUG ("New buffer %s %s %" GST_TIME_FORMAT, + discont ? "discont" : "", + keyframe ? "keyframe" : "", GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buf))); + + if (keyframe) { + GST_DEBUG ("Got a keyframe"); + + /* If there's a pending GOP, flush it out */ + if (smart_encoder->pending_gop) { + /* Mark gop_stop */ + smart_encoder->gop_stop = GST_BUFFER_TIMESTAMP (buf); + + /* flush pending */ + res = gst_smart_encoder_push_pending_gop (smart_encoder); + if (G_UNLIKELY (res != GST_FLOW_OK)) + goto beach; + } + + /* Mark gop_start for new gop */ + smart_encoder->gop_start = GST_BUFFER_TIMESTAMP (buf); + } + + /* Store buffer */ + smart_encoder->pending_gop = g_list_append (smart_encoder->pending_gop, buf); + /* Update GOP stop position */ + if (GST_BUFFER_TIMESTAMP_IS_VALID (buf)) { + smart_encoder->gop_stop = GST_BUFFER_TIMESTAMP (buf); + if (GST_BUFFER_DURATION_IS_VALID (buf)) + smart_encoder->gop_stop += GST_BUFFER_DURATION (buf); + } + + GST_DEBUG ("Buffer stored , Current GOP : %" GST_TIME_FORMAT " -- %" + GST_TIME_FORMAT, GST_TIME_ARGS (smart_encoder->gop_start), + GST_TIME_ARGS (smart_encoder->gop_stop)); + +beach: + gst_object_unref (smart_encoder); + return res; +} + +static gboolean +smart_encoder_sink_event (GstPad * pad, GstEvent * event) +{ + gboolean res = TRUE; + GstSmartEncoder *smart_encoder = GST_SMART_ENCODER (gst_pad_get_parent (pad)); + + switch (GST_EVENT_TYPE (event)) { + case GST_EVENT_FLUSH_STOP: + smart_encoder_reset (smart_encoder); + break; + case GST_EVENT_NEWSEGMENT: + { + GstFormat format; + gdouble rate, arate; + gint64 start, stop, time; + gboolean update; + + gst_event_parse_new_segment_full (event, &update, &rate, &arate, &format, + &start, &stop, &time); + GST_DEBUG_OBJECT (smart_encoder, + "newsegment: update %d, rate %g, arate %g, start %" GST_TIME_FORMAT + ", stop %" GST_TIME_FORMAT ", time %" GST_TIME_FORMAT, + update, rate, arate, GST_TIME_ARGS (start), GST_TIME_ARGS (stop), + GST_TIME_ARGS (time)); + if (format != GST_FORMAT_TIME) + GST_ERROR + ("smart_encoder can not handle streams not specified in GST_FORMAT_TIME"); + + /* now configure the values */ + gst_segment_set_newsegment_full (smart_encoder->segment, update, + rate, arate, format, start, stop, time); + + /* And keep a copy for further usage */ + if (smart_encoder->newsegment) + gst_event_unref (smart_encoder->newsegment); + smart_encoder->newsegment = gst_event_ref (event); + } + break; + case GST_EVENT_EOS: + GST_DEBUG ("Eos, flushing remaining data"); + gst_smart_encoder_push_pending_gop (smart_encoder); + break; + default: + break; + } + + res = gst_pad_push_event (smart_encoder->srcpad, event); + + gst_object_unref (smart_encoder); + return res; +} + +static GstCaps * +smart_encoder_sink_getcaps (GstPad * pad) +{ + GstCaps *peer, *tmpl, *res; + GstSmartEncoder *smart_encoder = GST_SMART_ENCODER (gst_pad_get_parent (pad)); + + /* Try getting it from downstream */ + peer = gst_pad_peer_get_caps_reffed (smart_encoder->srcpad); + + /* Use computed caps */ + if (smart_encoder->available_caps) + tmpl = gst_caps_ref (smart_encoder->available_caps); + else + tmpl = gst_static_pad_template_get_caps (&src_template); + + if (peer == NULL) { + res = tmpl; + } else { + res = gst_caps_intersect (peer, tmpl); + gst_caps_unref (peer); + gst_caps_unref (tmpl); + } + + gst_object_unref (smart_encoder); + return res; +} + +/***************************************** + * Internal encoder/decoder pipeline * + ******************************************/ + +static GstElementFactory * +get_decoder_factory (GstCaps * caps) +{ + GstElementFactory *fact = NULL; + GList *decoders, *tmp; + + tmp = + gst_element_factory_list_get_elements (GST_ELEMENT_FACTORY_TYPE_DECODER, + GST_RANK_MARGINAL); + decoders = gst_element_factory_list_filter (tmp, caps, GST_PAD_SINK, FALSE); + gst_plugin_feature_list_free (tmp); + + for (tmp = decoders; tmp; tmp = tmp->next) { + /* We just pick the first one */ + fact = (GstElementFactory *) tmp->data; + gst_object_ref (fact); + break; + } + + gst_plugin_feature_list_free (decoders); + + return fact; +} + +static GstElementFactory * +get_encoder_factory (GstCaps * caps) +{ + GstElementFactory *fact = NULL; + GList *encoders, *tmp; + + tmp = + gst_element_factory_list_get_elements (GST_ELEMENT_FACTORY_TYPE_ENCODER, + GST_RANK_MARGINAL); + encoders = gst_element_factory_list_filter (tmp, caps, GST_PAD_SRC, FALSE); + gst_plugin_feature_list_free (tmp); + + for (tmp = encoders; tmp; tmp = tmp->next) { + /* We just pick the first one */ + fact = (GstElementFactory *) tmp->data; + gst_object_ref (fact); + break; + } + + gst_plugin_feature_list_free (encoders); + + return fact; +} + +static GstElement * +get_decoder (GstCaps * caps) +{ + GstElementFactory *fact = get_decoder_factory (caps); + GstElement *res = NULL; + + if (fact) { + res = gst_element_factory_create (fact, "internal-decoder"); + gst_object_unref (fact); + } + return res; +} + +static GstElement * +get_encoder (GstCaps * caps) +{ + GstElementFactory *fact = get_encoder_factory (caps); + GstElement *res = NULL; + + if (fact) { + res = gst_element_factory_create (fact, "internal-encoder"); + gst_object_unref (fact); + } + return res; +} + +static GstFlowReturn +internal_chain (GstPad * pad, GstBuffer * buf) +{ + GstSmartEncoder *smart_encoder = + g_object_get_qdata ((GObject *) pad, INTERNAL_ELEMENT); + + return gst_pad_push (smart_encoder->srcpad, buf); +} + +static gboolean +setup_recoder_pipeline (GstSmartEncoder * smart_encoder) +{ + GstPad *tmppad; + + /* Fast path */ + if (G_UNLIKELY (smart_encoder->encoder)) + return TRUE; + + GST_DEBUG ("Creating internal decoder and encoder"); + + /* Create decoder/encoder */ + smart_encoder->decoder = get_decoder (GST_PAD_CAPS (smart_encoder->sinkpad)); + if (G_UNLIKELY (smart_encoder->decoder == NULL)) + goto no_decoder; + gst_element_set_bus (smart_encoder->decoder, GST_ELEMENT_BUS (smart_encoder)); + + smart_encoder->encoder = get_encoder (GST_PAD_CAPS (smart_encoder->sinkpad)); + if (G_UNLIKELY (smart_encoder->encoder == NULL)) + goto no_encoder; + gst_element_set_bus (smart_encoder->encoder, GST_ELEMENT_BUS (smart_encoder)); + + GST_DEBUG ("Creating internal pads"); + + /* Create internal pads */ + + /* Source pad which we'll use to feed data to decoders */ + smart_encoder->internal_srcpad = gst_pad_new ("internal_src", GST_PAD_SRC); + g_object_set_qdata ((GObject *) smart_encoder->internal_srcpad, + INTERNAL_ELEMENT, smart_encoder); + gst_pad_set_caps (smart_encoder->internal_srcpad, + GST_PAD_CAPS (smart_encoder->sinkpad)); + gst_pad_set_active (smart_encoder->internal_srcpad, TRUE); + + /* Sink pad which will get the buffers from the encoder. + * Note: We don't need an event function since we'll be discarding all + * of them. */ + smart_encoder->internal_sinkpad = gst_pad_new ("internal_sink", GST_PAD_SINK); + g_object_set_qdata ((GObject *) smart_encoder->internal_sinkpad, + INTERNAL_ELEMENT, smart_encoder); + gst_pad_set_caps (smart_encoder->internal_sinkpad, + GST_PAD_CAPS (smart_encoder->sinkpad)); + gst_pad_set_chain_function (smart_encoder->internal_sinkpad, internal_chain); + gst_pad_set_active (smart_encoder->internal_sinkpad, TRUE); + + GST_DEBUG ("Linking pads to elements"); + + /* Link everything */ + tmppad = gst_element_get_static_pad (smart_encoder->encoder, "src"); + if (GST_PAD_LINK_FAILED (gst_pad_link (tmppad, + smart_encoder->internal_sinkpad))) + goto sinkpad_link_fail; + gst_object_unref (tmppad); + + if (!gst_element_link (smart_encoder->decoder, smart_encoder->encoder)) + goto encoder_decoder_link_fail; + + tmppad = gst_element_get_static_pad (smart_encoder->decoder, "sink"); + if (GST_PAD_LINK_FAILED (gst_pad_link (smart_encoder->internal_srcpad, + tmppad))) + goto srcpad_link_fail; + gst_object_unref (tmppad); + + GST_DEBUG ("Done creating internal elements/pads"); + + return TRUE; + +no_decoder: + { + GST_WARNING ("Couldn't find a decoder for %" GST_PTR_FORMAT, + GST_PAD_CAPS (smart_encoder->sinkpad)); + return FALSE; + } + +no_encoder: + { + GST_WARNING ("Couldn't find an encoder for %" GST_PTR_FORMAT, + GST_PAD_CAPS (smart_encoder->sinkpad)); + return FALSE; + } + +srcpad_link_fail: + { + gst_object_unref (tmppad); + GST_WARNING ("Couldn't link internal srcpad to decoder"); + return FALSE; + } + +sinkpad_link_fail: + { + gst_object_unref (tmppad); + GST_WARNING ("Couldn't link encoder to internal sinkpad"); + return FALSE; + } + +encoder_decoder_link_fail: + { + GST_WARNING ("Couldn't link decoder to encoder"); + return FALSE; + } +} + +static GstStateChangeReturn +gst_smart_encoder_find_elements (GstSmartEncoder * smart_encoder) +{ + guint i, n; + GstCaps *tmpl, *st, *res; + GstElementFactory *dec, *enc; + GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS; + + if (G_UNLIKELY (smart_encoder->available_caps)) + goto beach; + + /* Iterate over all pad template caps and see if we have both an + * encoder and a decoder for those media types */ + tmpl = gst_static_pad_template_get_caps (&src_template); + res = gst_caps_new_empty (); + n = gst_caps_get_size (tmpl); + + for (i = 0; i < n; i++) { + st = gst_caps_copy_nth (tmpl, i); + GST_DEBUG_OBJECT (smart_encoder, + "Checking for available decoder and encoder for %" GST_PTR_FORMAT, st); + if (!(dec = get_decoder_factory (st))) { + gst_caps_unref (st); + continue; + } + gst_object_unref (dec); + if (!(enc = get_encoder_factory (st))) { + gst_caps_unref (st); + continue; + } + gst_object_unref (enc); + GST_DEBUG_OBJECT (smart_encoder, "OK"); + gst_caps_append (res, st); + } + + gst_caps_unref (tmpl); + + if (gst_caps_is_empty (res)) + ret = GST_STATE_CHANGE_FAILURE; + else + smart_encoder->available_caps = res; + + GST_DEBUG_OBJECT (smart_encoder, "Done, available_caps:%" GST_PTR_FORMAT, + smart_encoder->available_caps); + +beach: + return ret; +} + +/****************************************** + * GstElement vmethod implementations * + ******************************************/ + +static GstStateChangeReturn +gst_smart_encoder_change_state (GstElement * element, GstStateChange transition) +{ + GstSmartEncoder *smart_encoder; + GstStateChangeReturn ret; + + g_return_val_if_fail (GST_IS_SMART_ENCODER (element), + GST_STATE_CHANGE_FAILURE); + + smart_encoder = GST_SMART_ENCODER (element); + + switch (transition) { + case GST_STATE_CHANGE_NULL_TO_READY: + /* Figure out which elements are available */ + if ((ret = + gst_smart_encoder_find_elements (smart_encoder)) == + GST_STATE_CHANGE_FAILURE) + goto beach; + break; + default: + break; + } + + ret = + GST_ELEMENT_CLASS (gst_smart_encoder_parent_class)->change_state (element, + transition); + + switch (transition) { + case GST_STATE_CHANGE_PAUSED_TO_READY: + smart_encoder_reset (smart_encoder); + break; + default: + break; + } + +beach: + return ret; +} diff --git a/gst/encoding/gstsmartencoder.h b/gst/encoding/gstsmartencoder.h new file mode 100644 index 0000000000..15366269c8 --- /dev/null +++ b/gst/encoding/gstsmartencoder.h @@ -0,0 +1,71 @@ +/* GStreamer video re-encoder element + * Copyright (C) <2010> Edward Hervey + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ +#ifndef __SMART_ENCODER_H__ +#define __SMART_ENCODER_H__ + +#include + +G_BEGIN_DECLS + +#define GST_TYPE_SMART_ENCODER \ + (gst_smart_encoder_get_type()) +#define GST_SMART_ENCODER(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_SMART_ENCODER,GstSmartEncoder)) +#define GST_SMART_ENCODER_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_SMART_ENCODER,GstSmartEncoderClass)) +#define GST_IS_SMART_ENCODER(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_SMART_ENCODER)) +#define GST_IS_SMART_ENCODER_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_SMART_ENCODER)) + +typedef struct _GstSmartEncoder GstSmartEncoder; +typedef struct _GstSmartEncoderClass GstSmartEncoderClass; + +struct _GstSmartEncoder { + GstElement element; + + GstPad *sinkpad, *srcpad; + + GstSegment *segment; + GstEvent *newsegment; + + /* Pending GOP to be checked */ + GList *pending_gop; + guint64 gop_start; /* GOP start in running time */ + guint64 gop_stop; /* GOP end in running time */ + + /* Internal recoding elements */ + GstPad *internal_sinkpad; + GstPad *internal_srcpad; + GstElement *decoder; + GstElement *encoder; + + /* Available caps at runtime */ + GstCaps *available_caps; +}; + +struct _GstSmartEncoderClass { + GstElementClass parent_class; +}; + +GType gst_smart_encoder_get_type(void); + +G_END_DECLS + +#endif /* __SMART_ENCODER_H__ */ diff --git a/gst/encoding/gststreamcombiner.c b/gst/encoding/gststreamcombiner.c new file mode 100644 index 0000000000..72d40fe756 --- /dev/null +++ b/gst/encoding/gststreamcombiner.c @@ -0,0 +1,276 @@ +/* GStreamer Stream Combiner + * Copyright (C) 2010 Edward Hervey + * (C) 2009 Nokia Corporation + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "gststreamcombiner.h" + +static GstStaticPadTemplate src_template = +GST_STATIC_PAD_TEMPLATE ("src", GST_PAD_SRC, GST_PAD_ALWAYS, + GST_STATIC_CAPS_ANY); + +static GstStaticPadTemplate sink_template = GST_STATIC_PAD_TEMPLATE ("sink_%d", + GST_PAD_SINK, + GST_PAD_REQUEST, + GST_STATIC_CAPS_ANY); + +GST_DEBUG_CATEGORY_STATIC (gst_stream_combiner_debug); +#define GST_CAT_DEFAULT gst_stream_combiner_debug + +G_DEFINE_TYPE (GstStreamCombiner, gst_stream_combiner, GST_TYPE_ELEMENT); + +#define STREAMS_LOCK(obj) (g_mutex_lock(obj->lock)) +#define STREAMS_UNLOCK(obj) (g_mutex_unlock(obj->lock)) + +static void gst_stream_combiner_dispose (GObject * object); + +static GstPad *gst_stream_combiner_request_new_pad (GstElement * element, + GstPadTemplate * templ, const gchar * name); +static void gst_stream_combiner_release_pad (GstElement * element, + GstPad * pad); + +static void +gst_stream_combiner_class_init (GstStreamCombinerClass * klass) +{ + GObjectClass *gobject_klass; + GstElementClass *gstelement_klass; + + gobject_klass = (GObjectClass *) klass; + gstelement_klass = (GstElementClass *) klass; + + gobject_klass->dispose = gst_stream_combiner_dispose; + + GST_DEBUG_CATEGORY_INIT (gst_stream_combiner_debug, "streamcombiner", 0, + "Stream Combiner"); + + gst_element_class_add_pad_template (gstelement_klass, + gst_static_pad_template_get (&src_template)); + gst_element_class_add_pad_template (gstelement_klass, + gst_static_pad_template_get (&sink_template)); + + gstelement_klass->request_new_pad = + GST_DEBUG_FUNCPTR (gst_stream_combiner_request_new_pad); + gstelement_klass->release_pad = + GST_DEBUG_FUNCPTR (gst_stream_combiner_release_pad); + + gst_element_class_set_details_simple (gstelement_klass, + "streamcombiner", "Generic", + "Recombines streams splitted by the streamsplitter element", + "Edward Hervey "); +} + +static void +gst_stream_combiner_dispose (GObject * object) +{ + GstStreamCombiner *stream_combiner = (GstStreamCombiner *) object; + + if (stream_combiner->lock) { + g_mutex_free (stream_combiner->lock); + stream_combiner->lock = NULL; + } + + G_OBJECT_CLASS (gst_stream_combiner_parent_class)->dispose (object); +} + +static GstFlowReturn +gst_stream_combiner_chain (GstPad * pad, GstBuffer * buf) +{ + GstStreamCombiner *stream_combiner = + (GstStreamCombiner *) GST_PAD_PARENT (pad); + /* FIXME : IMPLEMENT */ + + /* with lock taken, check if we're the active stream, if not drop */ + return gst_pad_push (stream_combiner->srcpad, buf); +} + +static gboolean +gst_stream_combiner_sink_event (GstPad * pad, GstEvent * event) +{ + GstStreamCombiner *stream_combiner = + (GstStreamCombiner *) GST_PAD_PARENT (pad); + /* FIXME : IMPLEMENT */ + + GST_DEBUG_OBJECT (pad, "Got event %s", GST_EVENT_TYPE_NAME (event)); + + switch (GST_EVENT_TYPE (event)) { + case GST_EVENT_CUSTOM_DOWNSTREAM: + if (gst_event_has_name (event, "stream-switching-eos")) { + gst_event_unref (event); + event = gst_event_new_eos (); + } + break; + default: + break; + } + + /* NEW_SEGMENT : lock, wait for other stream to EOS, select stream, unlock, push */ + /* EOS : lock, mark pad as unused, unlock , drop event */ + /* CUSTOM_REAL_EOS : push EOS downstream */ + /* FLUSH_START : lock, mark as flushing, unlock. if wasn't flushing forward */ + /* FLUSH_STOP : lock, unmark as flushing, unlock, if was flushing forward */ + /* OTHER : if selected pad forward */ + return gst_pad_push_event (stream_combiner->srcpad, event); +} + +static GstCaps * +gst_stream_combiner_sink_getcaps (GstPad * pad) +{ + GstStreamCombiner *stream_combiner = + (GstStreamCombiner *) GST_PAD_PARENT (pad); + + return gst_pad_peer_get_caps_reffed (stream_combiner->srcpad); +} + +static gboolean +gst_stream_combiner_sink_setcaps (GstPad * pad, GstCaps * caps) +{ + GstStreamCombiner *stream_combiner = + (GstStreamCombiner *) GST_PAD_PARENT (pad); + GstPad *peer; + gboolean res = FALSE; + + GST_DEBUG_OBJECT (pad, "caps:%" GST_PTR_FORMAT, caps); + + peer = gst_pad_get_peer (stream_combiner->srcpad); + if (peer) { + GST_DEBUG_OBJECT (peer, "Setting caps"); + res = gst_pad_set_caps (peer, caps); + gst_object_unref (peer); + } else + GST_WARNING_OBJECT (stream_combiner, "sourcepad has no peer !"); + return res; +} + +static gboolean +gst_stream_combiner_src_event (GstPad * pad, GstEvent * event) +{ + GstStreamCombiner *stream_combiner = + (GstStreamCombiner *) GST_PAD_PARENT (pad); + GstPad *sinkpad = NULL; + + STREAMS_LOCK (stream_combiner); + if (stream_combiner->current) + sinkpad = stream_combiner->current; + else if (stream_combiner->sinkpads) + sinkpad = (GstPad *) stream_combiner->sinkpads->data; + STREAMS_UNLOCK (stream_combiner); + + if (sinkpad) + /* Forward upstream as is */ + return gst_pad_push_event (sinkpad, event); + return FALSE; +} + +static gboolean +gst_stream_combiner_src_query (GstPad * pad, GstQuery * query) +{ + GstStreamCombiner *stream_combiner = + (GstStreamCombiner *) GST_PAD_PARENT (pad); + + GstPad *sinkpad = NULL; + + STREAMS_LOCK (stream_combiner); + if (stream_combiner->current) + sinkpad = stream_combiner->current; + else if (stream_combiner->sinkpads) + sinkpad = (GstPad *) stream_combiner->sinkpads->data; + STREAMS_UNLOCK (stream_combiner); + + if (sinkpad) + /* Forward upstream as is */ + return gst_pad_peer_query (sinkpad, query); + return FALSE; +} + +static void +gst_stream_combiner_init (GstStreamCombiner * stream_combiner) +{ + stream_combiner->srcpad = + gst_pad_new_from_static_template (&src_template, "src"); + gst_pad_set_event_function (stream_combiner->srcpad, + gst_stream_combiner_src_event); + gst_pad_set_query_function (stream_combiner->srcpad, + gst_stream_combiner_src_query); + gst_element_add_pad (GST_ELEMENT (stream_combiner), stream_combiner->srcpad); + + stream_combiner->lock = g_mutex_new (); +} + +static GstPad * +gst_stream_combiner_request_new_pad (GstElement * element, + GstPadTemplate * templ, const gchar * name) +{ + GstStreamCombiner *stream_combiner = (GstStreamCombiner *) element; + GstPad *sinkpad; + + GST_DEBUG_OBJECT (element, "templ:%p, name:%s", templ, name); + + sinkpad = gst_pad_new_from_static_template (&sink_template, name); + /* FIXME : No buffer alloc for the time being, it will resort to the fallback */ + /* gst_pad_set_bufferalloc_function (sinkpad, gst_stream_combiner_buffer_alloc); */ + gst_pad_set_chain_function (sinkpad, gst_stream_combiner_chain); + gst_pad_set_event_function (sinkpad, gst_stream_combiner_sink_event); + gst_pad_set_getcaps_function (sinkpad, gst_stream_combiner_sink_getcaps); + gst_pad_set_setcaps_function (sinkpad, gst_stream_combiner_sink_setcaps); + + STREAMS_LOCK (stream_combiner); + stream_combiner->sinkpads = + g_list_append (stream_combiner->sinkpads, sinkpad); + gst_pad_set_active (sinkpad, TRUE); + gst_element_add_pad (element, sinkpad); + stream_combiner->cookie++; + STREAMS_UNLOCK (stream_combiner); + + GST_DEBUG_OBJECT (element, "Returning pad %p", sinkpad); + + return sinkpad; +} + +static void +gst_stream_combiner_release_pad (GstElement * element, GstPad * pad) +{ + GstStreamCombiner *stream_combiner = (GstStreamCombiner *) element; + GList *tmp; + + GST_DEBUG_OBJECT (element, "pad %s:%s", GST_DEBUG_PAD_NAME (pad)); + + STREAMS_LOCK (stream_combiner); + tmp = g_list_find (stream_combiner->sinkpads, pad); + if (tmp) { + GstPad *pad = (GstPad *) tmp->data; + + stream_combiner->sinkpads = + g_list_delete_link (stream_combiner->sinkpads, tmp); + stream_combiner->cookie++; + + if (pad == stream_combiner->current) { + /* Deactivate current flow */ + GST_DEBUG_OBJECT (element, "Removed pad was the current one"); + stream_combiner->current = NULL; + } + GST_DEBUG_OBJECT (element, "Removing pad from ourself"); + gst_element_remove_pad (element, pad); + } + STREAMS_UNLOCK (stream_combiner); + + return; +} diff --git a/gst/encoding/gststreamcombiner.h b/gst/encoding/gststreamcombiner.h new file mode 100644 index 0000000000..ce67277d72 --- /dev/null +++ b/gst/encoding/gststreamcombiner.h @@ -0,0 +1,60 @@ +/* GStreamer Stream Combiner + * Copyright (C) 2010 Edward Hervey + * (C) 2009 Nokia Corporation + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef __GST_STREAMCOMBINER_H__ +#define __GST_STREAMCOMBINER_H__ + +#include + +#define GST_TYPE_STREAM_COMBINER (gst_stream_combiner_get_type()) +#define GST_STREAM_COMBINER(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_STREAM_COMBINER,GstStreamCombiner)) +#define GST_STREAM_COMBINER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_STREAM_COMBINER,GstStreamCombinerClass)) +#define GST_IS_STREAM_COMBINER(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_STREAM_COMBINER)) +#define GST_IS_STREAM_COMBINER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_STREAM_COMBINER)) + +typedef struct _GstStreamCombiner GstStreamCombiner; +typedef struct _GstStreamCombinerClass GstStreamCombinerClass; + +struct _GstStreamCombiner { + GstElement parent; + + GstPad *srcpad; + + /* lock protects: + * * the current pad + * * the list of srcpads + */ + GMutex *lock; + /* Currently activated srcpad */ + GstPad *current; + GList *sinkpads; + guint32 cookie; + +}; + +struct _GstStreamCombinerClass { + GstElementClass parent; +}; + +GType gst_stream_combiner_get_type(void); + +GstElement *gst_stream_combiner_new (gchar *name); + +#endif /* __GST_STREAMCOMBINER_H__ */ diff --git a/gst/encoding/gststreamsplitter.c b/gst/encoding/gststreamsplitter.c new file mode 100644 index 0000000000..a2fa589f36 --- /dev/null +++ b/gst/encoding/gststreamsplitter.c @@ -0,0 +1,431 @@ +/* GStreamer Stream Splitter + * Copyright (C) 2010 Edward Hervey + * (C) 2009 Nokia Corporation + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "gststreamsplitter.h" + +static GstStaticPadTemplate src_template = +GST_STATIC_PAD_TEMPLATE ("src_%d", GST_PAD_SRC, GST_PAD_REQUEST, + GST_STATIC_CAPS_ANY); + +static GstStaticPadTemplate sink_template = GST_STATIC_PAD_TEMPLATE ("sink", + GST_PAD_SINK, + GST_PAD_ALWAYS, + GST_STATIC_CAPS_ANY); + +GST_DEBUG_CATEGORY_STATIC (gst_stream_splitter_debug); +#define GST_CAT_DEFAULT gst_stream_splitter_debug + +G_DEFINE_TYPE (GstStreamSplitter, gst_stream_splitter, GST_TYPE_ELEMENT); + +#define STREAMS_LOCK(obj) (g_mutex_lock(obj->lock)) +#define STREAMS_UNLOCK(obj) (g_mutex_unlock(obj->lock)) + +static void gst_stream_splitter_dispose (GObject * object); + +static GstPad *gst_stream_splitter_request_new_pad (GstElement * element, + GstPadTemplate * templ, const gchar * name); +static void gst_stream_splitter_release_pad (GstElement * element, + GstPad * pad); + +static void +gst_stream_splitter_class_init (GstStreamSplitterClass * klass) +{ + GObjectClass *gobject_klass; + GstElementClass *gstelement_klass; + + gobject_klass = (GObjectClass *) klass; + gstelement_klass = (GstElementClass *) klass; + + gobject_klass->dispose = gst_stream_splitter_dispose; + + GST_DEBUG_CATEGORY_INIT (gst_stream_splitter_debug, "streamsplitter", 0, + "Stream Splitter"); + + gst_element_class_add_pad_template (gstelement_klass, + gst_static_pad_template_get (&src_template)); + gst_element_class_add_pad_template (gstelement_klass, + gst_static_pad_template_get (&sink_template)); + + gstelement_klass->request_new_pad = + GST_DEBUG_FUNCPTR (gst_stream_splitter_request_new_pad); + gstelement_klass->release_pad = + GST_DEBUG_FUNCPTR (gst_stream_splitter_release_pad); + + gst_element_class_set_details_simple (gstelement_klass, + "streamsplitter", "Generic", + "Splits streams based on their media type", + "Edward Hervey "); +} + +static void +gst_stream_splitter_dispose (GObject * object) +{ + GstStreamSplitter *stream_splitter = (GstStreamSplitter *) object; + + if (stream_splitter->lock) { + g_mutex_free (stream_splitter->lock); + stream_splitter->lock = NULL; + } + + G_OBJECT_CLASS (gst_stream_splitter_parent_class)->dispose (object); +} + +static GstFlowReturn +gst_stream_splitter_chain (GstPad * pad, GstBuffer * buf) +{ + GstStreamSplitter *stream_splitter = + (GstStreamSplitter *) GST_PAD_PARENT (pad); + GstFlowReturn res; + GstPad *srcpad = NULL; + + STREAMS_LOCK (stream_splitter); + if (stream_splitter->current) + srcpad = gst_object_ref (stream_splitter->current); + STREAMS_UNLOCK (stream_splitter); + + if (G_UNLIKELY (srcpad == NULL)) + goto nopad; + + if (G_UNLIKELY (stream_splitter->pending_events)) { + GList *tmp; + GST_DEBUG_OBJECT (srcpad, "Pushing out pending events"); + + for (tmp = stream_splitter->pending_events; tmp; tmp = tmp->next) { + GstEvent *event = (GstEvent *) tmp->data; + gst_pad_push_event (srcpad, event); + } + g_list_free (stream_splitter->pending_events); + stream_splitter->pending_events = NULL; + } + + /* Forward to currently activated stream */ + res = gst_pad_push (srcpad, buf); + gst_object_unref (srcpad); + + return res; + +nopad: + GST_WARNING_OBJECT (stream_splitter, "No output pad was configured"); + return GST_FLOW_ERROR; +} + +static gboolean +gst_stream_splitter_sink_event (GstPad * pad, GstEvent * event) +{ + GstStreamSplitter *stream_splitter = + (GstStreamSplitter *) GST_PAD_PARENT (pad); + gboolean res = TRUE; + gboolean toall = FALSE; + gboolean store = FALSE; + gboolean eos = FALSE; + gboolean flushpending = FALSE; + + /* FLUSH_START/STOP : forward to all + * EOS : transform to CUSTOM_REAL_EOS and forward to all + * INBAND events : store to send in chain function to selected chain + * OUT_OF_BAND events : send to all + */ + + GST_DEBUG_OBJECT (stream_splitter, "Got event %s", + GST_EVENT_TYPE_NAME (event)); + + switch (GST_EVENT_TYPE (event)) { + case GST_EVENT_FLUSH_STOP: + flushpending = TRUE; + toall = TRUE; + break; + case GST_EVENT_FLUSH_START: + toall = TRUE; + break; + case GST_EVENT_EOS: + /* Replace with our custom eos event */ + gst_event_unref (event); + event = + gst_event_new_custom (GST_EVENT_CUSTOM_DOWNSTREAM, + gst_structure_empty_new ("stream-switching-eos")); + toall = TRUE; + eos = TRUE; + break; + default: + if (GST_EVENT_TYPE (event) & GST_EVENT_TYPE_SERIALIZED) + store = TRUE; + } + + if (flushpending) { + GList *tmp; + for (tmp = stream_splitter->pending_events; tmp; tmp = tmp->next) + gst_event_unref ((GstEvent *) tmp->data); + g_list_free (stream_splitter->pending_events); + stream_splitter->pending_events = NULL; + } + + if (store) { + stream_splitter->pending_events = + g_list_append (stream_splitter->pending_events, event); + } else if (toall || eos) { + GList *tmp; + guint32 cookie; + + /* Send to all pads */ + STREAMS_LOCK (stream_splitter); + resync: + if (G_UNLIKELY (stream_splitter->srcpads == NULL)) { + STREAMS_UNLOCK (stream_splitter); + /* No source pads */ + gst_event_unref (event); + res = FALSE; + goto beach; + } + tmp = stream_splitter->srcpads; + cookie = stream_splitter->cookie; + while (tmp) { + GstPad *srcpad = (GstPad *) tmp->data; + STREAMS_UNLOCK (stream_splitter); + /* In case of EOS, we first push out the real one to flush out + * each streams (but which will be discarded in the streamcombiner) + * before our custom one (which will be converted back to and EOS + * in the streamcombiner) */ + if (eos) + gst_pad_push_event (srcpad, gst_event_new_eos ()); + gst_event_ref (event); + res = gst_pad_push_event (srcpad, event); + STREAMS_LOCK (stream_splitter); + if (G_UNLIKELY (cookie != stream_splitter->cookie)) + goto resync; + tmp = tmp->next; + } + STREAMS_UNLOCK (stream_splitter); + gst_event_unref (event); + } else { + GstPad *pad; + + /* Only send to current pad */ + + STREAMS_LOCK (stream_splitter); + pad = stream_splitter->current; + STREAMS_UNLOCK (stream_splitter); + if (pad) + res = gst_pad_push_event (pad, event); + else { + gst_event_unref (event); + res = FALSE; + } + } + +beach: + return res; +} + +static GstCaps * +gst_stream_splitter_sink_getcaps (GstPad * pad) +{ + GstStreamSplitter *stream_splitter = + (GstStreamSplitter *) GST_PAD_PARENT (pad); + guint32 cookie; + GList *tmp; + GstCaps *res = NULL; + + /* Return the combination of all downstream caps */ + + STREAMS_LOCK (stream_splitter); + +resync: + if (G_UNLIKELY (stream_splitter->srcpads == NULL)) { + res = gst_caps_new_any (); + goto beach; + } + + res = NULL; + cookie = stream_splitter->cookie; + tmp = stream_splitter->srcpads; + + while (tmp) { + GstPad *srcpad = (GstPad *) tmp->data; + + STREAMS_UNLOCK (stream_splitter); + if (res) + gst_caps_merge (res, gst_pad_peer_get_caps_reffed (srcpad)); + else + res = gst_pad_peer_get_caps (srcpad); + STREAMS_LOCK (stream_splitter); + + if (G_UNLIKELY (cookie != stream_splitter->cookie)) { + if (res) + gst_caps_unref (res); + goto resync; + } + tmp = tmp->next; + } + +beach: + STREAMS_UNLOCK (stream_splitter); + return res; +} + +static gboolean +gst_stream_splitter_sink_setcaps (GstPad * pad, GstCaps * caps) +{ + GstStreamSplitter *stream_splitter = + (GstStreamSplitter *) GST_PAD_PARENT (pad); + guint32 cookie; + GList *tmp; + gboolean res; + + GST_DEBUG_OBJECT (stream_splitter, "caps %" GST_PTR_FORMAT, caps); + + /* Try on all pads, choose the one that succeeds as the current stream */ + STREAMS_LOCK (stream_splitter); + +resync: + if (G_UNLIKELY (stream_splitter->srcpads == NULL)) { + res = FALSE; + goto beach; + } + + res = FALSE; + tmp = stream_splitter->srcpads; + cookie = stream_splitter->cookie; + + while (tmp) { + GstPad *srcpad = (GstPad *) tmp->data; + GstCaps *peercaps; + + STREAMS_UNLOCK (stream_splitter); + peercaps = gst_pad_peer_get_caps_reffed (srcpad); + if (peercaps) { + res = gst_caps_can_intersect (caps, peercaps); + gst_caps_unref (peercaps); + } + STREAMS_LOCK (stream_splitter); + + if (G_UNLIKELY (cookie != stream_splitter->cookie)) + goto resync; + + if (res) { + /* FIXME : we need to switch properly */ + GST_DEBUG_OBJECT (srcpad, "Setting caps on this pad was succesfull"); + stream_splitter->current = srcpad; + goto beach; + } + tmp = tmp->next; + } + +beach: + STREAMS_UNLOCK (stream_splitter); + return res; +} + +static gboolean +gst_stream_splitter_src_event (GstPad * pad, GstEvent * event) +{ + GstStreamSplitter *stream_splitter = + (GstStreamSplitter *) GST_PAD_PARENT (pad); + + GST_DEBUG_OBJECT (pad, "%s", GST_EVENT_TYPE_NAME (event)); + + /* Forward upstream as is */ + return gst_pad_push_event (stream_splitter->sinkpad, event); +} + +static gboolean +gst_stream_splitter_src_query (GstPad * pad, GstQuery * query) +{ + GstStreamSplitter *stream_splitter = + (GstStreamSplitter *) GST_PAD_PARENT (pad); + + GST_DEBUG_OBJECT (pad, "%s", GST_QUERY_TYPE_NAME (query)); + + /* Forward upstream as is */ + return gst_pad_peer_query (stream_splitter->sinkpad, query); +} + +static void +gst_stream_splitter_init (GstStreamSplitter * stream_splitter) +{ + stream_splitter->sinkpad = + gst_pad_new_from_static_template (&sink_template, "sink"); + /* FIXME : No buffer alloc for the time being, it will resort to the fallback */ + /* gst_pad_set_bufferalloc_function (stream_splitter->sinkpad, */ + /* gst_stream_splitter_buffer_alloc); */ + gst_pad_set_chain_function (stream_splitter->sinkpad, + gst_stream_splitter_chain); + gst_pad_set_event_function (stream_splitter->sinkpad, + gst_stream_splitter_sink_event); + gst_pad_set_getcaps_function (stream_splitter->sinkpad, + gst_stream_splitter_sink_getcaps); + gst_pad_set_setcaps_function (stream_splitter->sinkpad, + gst_stream_splitter_sink_setcaps); + gst_element_add_pad (GST_ELEMENT (stream_splitter), stream_splitter->sinkpad); + + stream_splitter->lock = g_mutex_new (); +} + +static GstPad * +gst_stream_splitter_request_new_pad (GstElement * element, + GstPadTemplate * templ, const gchar * name) +{ + GstStreamSplitter *stream_splitter = (GstStreamSplitter *) element; + GstPad *srcpad; + + srcpad = gst_pad_new_from_static_template (&src_template, name); + gst_pad_set_event_function (srcpad, gst_stream_splitter_src_event); + gst_pad_set_query_function (srcpad, gst_stream_splitter_src_query); + + STREAMS_LOCK (stream_splitter); + stream_splitter->srcpads = g_list_append (stream_splitter->srcpads, srcpad); + gst_pad_set_active (srcpad, TRUE); + gst_element_add_pad (element, srcpad); + stream_splitter->cookie++; + STREAMS_UNLOCK (stream_splitter); + + return srcpad; +} + +static void +gst_stream_splitter_release_pad (GstElement * element, GstPad * pad) +{ + GstStreamSplitter *stream_splitter = (GstStreamSplitter *) element; + GList *tmp; + + STREAMS_LOCK (stream_splitter); + tmp = g_list_find (stream_splitter->srcpads, pad); + if (tmp) { + GstPad *pad = (GstPad *) tmp->data; + + stream_splitter->srcpads = + g_list_delete_link (stream_splitter->srcpads, tmp); + stream_splitter->cookie++; + + if (pad == stream_splitter->current) { + /* Deactivate current flow */ + GST_DEBUG_OBJECT (element, "Removed pad was the current one"); + stream_splitter->current = NULL; + } + + gst_element_remove_pad (element, pad); + } + STREAMS_UNLOCK (stream_splitter); + + return; +} diff --git a/gst/encoding/gststreamsplitter.h b/gst/encoding/gststreamsplitter.h new file mode 100644 index 0000000000..b503c00fc9 --- /dev/null +++ b/gst/encoding/gststreamsplitter.h @@ -0,0 +1,62 @@ +/* GStreamer Stream Splitter + * Copyright (C) 2010 Edward Hervey + * (C) 2009 Nokia Corporation + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef __GST_STREAMSPLITTER_H__ +#define __GST_STREAMSPLITTER_H__ + +#include + +#define GST_TYPE_STREAM_SPLITTER (gst_stream_splitter_get_type()) +#define GST_STREAM_SPLITTER(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_STREAM_SPLITTER,GstStreamSplitter)) +#define GST_STREAM_SPLITTER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_STREAM_SPLITTER,GstStreamSplitterClass)) +#define GST_IS_STREAM_SPLITTER(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_STREAM_SPLITTER)) +#define GST_IS_STREAM_SPLITTER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_STREAM_SPLITTER)) + +typedef struct _GstStreamSplitter GstStreamSplitter; +typedef struct _GstStreamSplitterClass GstStreamSplitterClass; + +struct _GstStreamSplitter { + GstElement parent; + + GstPad *sinkpad; + + /* lock protects: + * * the current pad + * * the list of srcpads + */ + GMutex *lock; + /* Currently activated srcpad */ + GstPad *current; + GList *srcpads; + guint32 cookie; + + /* List of pending in-band events */ + GList *pending_events; +}; + +struct _GstStreamSplitterClass { + GstElementClass parent; +}; + +GType gst_stream_splitter_get_type(void); + +GstElement *gst_stream_splitter_new (gchar *name); + +#endif /* __GST_STREAMSPLITTER_H__ */ diff --git a/tests/check/Makefile.am b/tests/check/Makefile.am index 59ba7403f8..03387af51f 100644 --- a/tests/check/Makefile.am +++ b/tests/check/Makefile.am @@ -106,6 +106,7 @@ check_PROGRAMS = \ elements/audiotestsrc \ elements/decodebin \ elements/decodebin2 \ + elements/encodebin \ elements/ffmpegcolorspace \ elements/gdpdepay \ elements/gdppay \ @@ -298,6 +299,9 @@ elements_playbin2_CFLAGS = $(GST_BASE_CFLAGS) $(AM_CFLAGS) elements_decodebin_LDADD = $(GST_BASE_LIBS) $(LDADD) elements_decodebin_CFLAGS = $(GST_BASE_CFLAGS) $(AM_CFLAGS) +elements_encodebin_LDADD = $(top_builddir)/gst-libs/gst/pbutils/libgstpbutils-@GST_MAJORMINOR@.la $(GST_BASE_LIBS) $(LDADD) +elements_encodebin_CFLAGS = $(GST_PLUGINS_BASE_CFLAGS) $(GST_BASE_CFLAGS) $(AM_CFLAGS) + elements_decodebin2_LDADD = $(GST_BASE_LIBS) $(LDADD) elements_decodebin2_CFLAGS = $(GST_BASE_CFLAGS) $(AM_CFLAGS) diff --git a/tests/check/elements/.gitignore b/tests/check/elements/.gitignore index 3e11d9e015..20bd96e23f 100644 --- a/tests/check/elements/.gitignore +++ b/tests/check/elements/.gitignore @@ -9,6 +9,7 @@ audioresample audiotestsrc decodebin decodebin2 +encodebin gdpdepay gdppay gnomevfssink diff --git a/tests/check/elements/encodebin.c b/tests/check/elements/encodebin.c new file mode 100644 index 0000000000..b325694009 --- /dev/null +++ b/tests/check/elements/encodebin.c @@ -0,0 +1,742 @@ +/* GStreamer unit test for gstprofile + * + * Copyright (C) <2009> Edward Hervey + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include + +/* Helper functions to create profiles */ + +static GstEncodingProfile * +create_ogg_vorbis_profile (guint presence, gchar * preset) +{ + GstEncodingContainerProfile *cprof; + GstCaps *ogg, *vorbis; + + ogg = gst_caps_new_simple ("application/ogg", NULL); + cprof = + gst_encoding_container_profile_new ((gchar *) "myprofile", NULL, ogg, + NULL); + gst_caps_unref (ogg); + + vorbis = gst_caps_new_simple ("audio/x-vorbis", NULL); + fail_unless (gst_encoding_container_profile_add_profile (cprof, + (GstEncodingProfile *) gst_encoding_audio_profile_new (vorbis, preset, + NULL, presence))); + gst_caps_unref (vorbis); + + return (GstEncodingProfile *) cprof; +} + +static GstEncodingProfile * +create_ogg_theora_vorbis_profile (guint theorapresence, guint vorbispresence) +{ + GstEncodingContainerProfile *prof; + GstCaps *ogg, *vorbis, *theora; + + ogg = gst_caps_new_simple ("application/ogg", NULL); + prof = + gst_encoding_container_profile_new ((gchar *) "myprofile", NULL, ogg, + NULL); + gst_caps_unref (ogg); + + vorbis = gst_caps_new_simple ("audio/x-vorbis", NULL); + fail_unless (gst_encoding_container_profile_add_profile (prof, + (GstEncodingProfile *) gst_encoding_audio_profile_new (vorbis, NULL, + NULL, vorbispresence))); + gst_caps_unref (vorbis); + + theora = gst_caps_new_simple ("video/x-theora", NULL); + fail_unless (gst_encoding_container_profile_add_profile (prof, + (GstEncodingProfile *) gst_encoding_video_profile_new (theora, NULL, + NULL, theorapresence))); + gst_caps_unref (theora); + + return (GstEncodingProfile *) prof; +} + +GST_START_TEST (test_encodebin_states) +{ + GstElement *ebin; + GstEncodingProfile *prof, *prof2; + GstCaps *ogg; + GstPad *srcpad; + GstPad *target; + + /* Create an encodebin and check that it correctly changes states + * according to whether a profile is set or not */ + + ebin = gst_element_factory_make ("encodebin", NULL); + + /* Check if the source pad was properly created */ + srcpad = gst_element_get_static_pad (ebin, "src"); + fail_unless (srcpad != NULL); + + /* At this point, the ghostpad has *NO* target */ + target = gst_ghost_pad_get_target (GST_GHOST_PAD (srcpad)); + fail_unless (target == NULL); + g_object_unref (srcpad); + + /* No profile, + * switching to READY should succeed, + * but switching to PAUSED should fail + */ + fail_unless_equals_int (gst_element_set_state (ebin, GST_STATE_READY), + GST_STATE_CHANGE_SUCCESS); + fail_unless_equals_int (gst_element_set_state (ebin, GST_STATE_PAUSED), + GST_STATE_CHANGE_FAILURE); + + /* Set a profile on encodebin... */ + ogg = gst_caps_new_simple ("application/ogg", NULL); + prof = (GstEncodingProfile *) gst_encoding_container_profile_new ((gchar *) + "myprofile", NULL, ogg, NULL); + gst_caps_unref (ogg); + + g_object_set (ebin, "profile", prof, NULL); + + /* ... and check the profile has been properly set */ + g_object_get (ebin, "profile", &prof2, NULL); + + fail_unless (gst_encoding_profile_is_equal (prof, prof2)); + + gst_encoding_profile_unref (prof); + gst_encoding_profile_unref (prof2); + + /* Make sure we can go to PAUSED */ + fail_unless_equals_int (gst_element_set_state (ebin, GST_STATE_PAUSED), + GST_STATE_CHANGE_SUCCESS); + + /* At this point, the source pad *HAS* a target */ + srcpad = gst_element_get_static_pad (ebin, "src"); + fail_unless (srcpad != NULL); + target = gst_ghost_pad_get_target (GST_GHOST_PAD (srcpad)); + fail_unless (target != NULL); + g_object_unref (target); + g_object_unref (srcpad); + + + /* Set back to NULL */ + fail_unless_equals_int (gst_element_set_state (ebin, GST_STATE_NULL), + GST_STATE_CHANGE_SUCCESS); + + gst_object_unref (ebin); +}; + +GST_END_TEST; + +GST_START_TEST (test_encodebin_sink_pads_static) +{ + GstElement *ebin; + GstEncodingProfile *prof; + GstPad *srcpad, *sinkpad; + + /* Create an encodebin and check that it properly creates the sink pads + * for a single-stream profile with fixed presence */ + + ebin = gst_element_factory_make ("encodebin", NULL); + + /* streamprofile that has a forced presence of 1 */ + prof = create_ogg_vorbis_profile (1, NULL); + + g_object_set (ebin, "profile", prof, NULL); + + gst_encoding_profile_unref (prof); + + fail_unless_equals_int (gst_element_set_state (ebin, GST_STATE_PAUSED), + GST_STATE_CHANGE_SUCCESS); + + /* Check if the source pad was properly created */ + srcpad = gst_element_get_static_pad (ebin, "src"); + fail_unless (srcpad != NULL); + g_object_unref (srcpad); + + /* Check if the audio sink pad was properly created */ + sinkpad = gst_element_get_static_pad (ebin, "audio_0"); + fail_unless (sinkpad != NULL); + g_object_unref (sinkpad); + + /* Set back to NULL */ + fail_unless_equals_int (gst_element_set_state (ebin, GST_STATE_NULL), + GST_STATE_CHANGE_SUCCESS); + + gst_object_unref (ebin); +}; + +GST_END_TEST; + +GST_START_TEST (test_encodebin_sink_pads_nopreset_static) +{ + GstElement *ebin; + GstEncodingProfile *prof; + + /* Create an encodebin with a bogus preset and check it fails switching states */ + + ebin = gst_element_factory_make ("encodebin", NULL); + + /* streamprofile that has a forced presence of 1 */ + prof = create_ogg_vorbis_profile (1, (gchar *) "nowaythispresetexists"); + + g_object_set (ebin, "profile", prof, NULL); + + gst_encoding_profile_unref (prof); + + /* It will go to READY... */ + fail_unless_equals_int (gst_element_set_state (ebin, GST_STATE_READY), + GST_STATE_CHANGE_SUCCESS); + /* ... but to not PAUSED */ + fail_unless_equals_int (gst_element_set_state (ebin, GST_STATE_PAUSED), + GST_STATE_CHANGE_FAILURE); + + gst_element_set_state (ebin, GST_STATE_NULL); + + gst_object_unref (ebin); +}; + +GST_END_TEST; + +GST_START_TEST (test_encodebin_sink_pads_dynamic) +{ + GstElement *ebin; + GstEncodingProfile *prof; + GstPad *srcpad, *sinkpad; + GstCaps *sinkcaps; + + /* Create an encodebin and check that it properly creates the sink pads + * for a single-stream profile with a unfixed presence */ + + ebin = gst_element_factory_make ("encodebin", NULL); + + /* streamprofile that has non-forced presence */ + prof = create_ogg_vorbis_profile (0, NULL); + + g_object_set (ebin, "profile", prof, NULL); + + gst_encoding_profile_unref (prof); + + /* Check if the source pad was properly created */ + srcpad = gst_element_get_static_pad (ebin, "src"); + fail_unless (srcpad != NULL); + g_object_unref (srcpad); + + /* Check if the audio sink pad can be requested */ + sinkpad = gst_element_get_request_pad (ebin, "audio_0"); + fail_unless (sinkpad != NULL); + gst_element_release_request_pad (ebin, sinkpad); + sinkpad = NULL; + + /* Check again with the 'request-pad' signal */ + sinkcaps = gst_caps_new_simple ("audio/x-raw-int", NULL); + g_signal_emit_by_name (ebin, "request-pad", sinkcaps, &sinkpad); + gst_caps_unref (sinkcaps); + fail_unless (sinkpad != NULL); + gst_element_release_request_pad (ebin, sinkpad); + + fail_unless_equals_int (gst_element_set_state (ebin, GST_STATE_PAUSED), + GST_STATE_CHANGE_SUCCESS); + + /* Set back to NULL */ + fail_unless_equals_int (gst_element_set_state (ebin, GST_STATE_NULL), + GST_STATE_CHANGE_SUCCESS); + + gst_object_unref (ebin); +}; + +GST_END_TEST; + +GST_START_TEST (test_encodebin_sink_pads_multiple_static) +{ + GstElement *ebin; + GstEncodingProfile *prof; + GstPad *srcpad, *sinkpadvorbis, *sinkpadtheora; + + /* Create an encodebin and check that it properly creates the sink pads */ + + ebin = gst_element_factory_make ("encodebin", NULL); + + /* First try is with a streamprofile that has a forced presence of 1 */ + prof = create_ogg_theora_vorbis_profile (1, 1); + + g_object_set (ebin, "profile", prof, NULL); + + gst_encoding_profile_unref (prof); + + fail_unless_equals_int (gst_element_set_state (ebin, GST_STATE_PAUSED), + GST_STATE_CHANGE_SUCCESS); + + /* Check if the source pad was properly created */ + srcpad = gst_element_get_static_pad (ebin, "src"); + fail_unless (srcpad != NULL); + g_object_unref (srcpad); + + /* Check if the audio sink pad was properly created */ + sinkpadvorbis = gst_element_get_static_pad (ebin, "audio_0"); + fail_unless (sinkpadvorbis != NULL); + g_object_unref (sinkpadvorbis); + + /* Check if the video sink pad was properly created */ + sinkpadtheora = gst_element_get_static_pad (ebin, "video_1"); + fail_unless (sinkpadtheora != NULL); + g_object_unref (sinkpadtheora); + + /* Set back to NULL */ + fail_unless_equals_int (gst_element_set_state (ebin, GST_STATE_NULL), + GST_STATE_CHANGE_SUCCESS); + + gst_object_unref (ebin); +}; + +GST_END_TEST; + +GST_START_TEST (test_encodebin_sink_pads_multiple_dynamic) +{ + GstElement *ebin; + GstEncodingProfile *prof; + GstPad *srcpad, *sinkpadvorbis, *sinkpadtheora; + + /* Create an encodebin and check that it properly creates the sink pads + * for a multiple-stream with unfixed presence */ + + ebin = gst_element_factory_make ("encodebin", NULL); + + /* multi-stream profile that has non-forced presence */ + prof = create_ogg_theora_vorbis_profile (0, 0); + + g_object_set (ebin, "profile", prof, NULL); + + gst_encoding_profile_unref (prof); + + /* Check if the source pad was properly created */ + srcpad = gst_element_get_static_pad (ebin, "src"); + fail_unless (srcpad != NULL); + g_object_unref (srcpad); + + /* Check if the audio sink pad was properly created */ + sinkpadvorbis = gst_element_get_request_pad (ebin, "audio_0"); + fail_unless (sinkpadvorbis != NULL); + g_object_unref (sinkpadvorbis); + + /* Check if the video sink pad was properly created */ + sinkpadtheora = gst_element_get_request_pad (ebin, "video_1"); + fail_unless (sinkpadtheora != NULL); + g_object_unref (sinkpadtheora); + + fail_unless_equals_int (gst_element_set_state (ebin, GST_STATE_PAUSED), + GST_STATE_CHANGE_SUCCESS); + + /* Set back to NULL */ + fail_unless_equals_int (gst_element_set_state (ebin, GST_STATE_NULL), + GST_STATE_CHANGE_SUCCESS); + + gst_object_unref (ebin); +}; + +GST_END_TEST; + +GST_START_TEST (test_encodebin_sink_pads_dynamic_encoder) +{ + GstElement *ebin; + GstEncodingProfile *prof; + GstPad *srcpad, *sinkpad = NULL; + GstCaps *vorbiscaps; + + /* Create an encodebin and check that it properly creates the sink pads + * for a single-stream profile with a unfixed presence */ + + ebin = gst_element_factory_make ("encodebin", NULL); + + /* streamprofile that has non-forced presence */ + prof = create_ogg_vorbis_profile (0, NULL); + + g_object_set (ebin, "profile", prof, NULL); + + gst_encoding_profile_unref (prof); + + /* Check if the source pad was properly created */ + srcpad = gst_element_get_static_pad (ebin, "src"); + fail_unless (srcpad != NULL); + g_object_unref (srcpad); + + /* Check if the audio sink pad was properly created */ + vorbiscaps = gst_caps_from_string ("audio/x-vorbis,channels=2,rate=44100"); + g_signal_emit_by_name (ebin, "request-pad", vorbiscaps, &sinkpad); + gst_caps_unref (vorbiscaps); + fail_unless (sinkpad != NULL); + gst_element_release_request_pad (ebin, sinkpad); + + fail_unless_equals_int (gst_element_set_state (ebin, GST_STATE_PAUSED), + GST_STATE_CHANGE_SUCCESS); + + /* Set back to NULL */ + fail_unless_equals_int (gst_element_set_state (ebin, GST_STATE_NULL), + GST_STATE_CHANGE_SUCCESS); + + gst_object_unref (ebin); +}; + +GST_END_TEST; + +GST_START_TEST (test_encodebin_render_audio_static) +{ + GstElement *ebin, *pipeline, *audiotestsrc, *fakesink; + GstEncodingProfile *prof; + GstBus *bus; + gboolean done = FALSE; + + /* Create an encodebin and render 5s of vorbis/ogg */ + + pipeline = gst_pipeline_new ("encodebin-pipeline"); + bus = gst_pipeline_get_bus ((GstPipeline *) pipeline); + audiotestsrc = gst_element_factory_make ("audiotestsrc", NULL); + g_object_set (audiotestsrc, "num-buffers", 10, NULL); + fakesink = gst_element_factory_make ("fakesink", NULL); + + ebin = gst_element_factory_make ("encodebin", NULL); + + prof = create_ogg_vorbis_profile (1, NULL); + g_object_set (ebin, "profile", prof, NULL); + gst_encoding_profile_unref (prof); + + gst_bin_add_many ((GstBin *) pipeline, audiotestsrc, ebin, fakesink, NULL); + + fail_unless (gst_element_link_many (audiotestsrc, ebin, fakesink, NULL)); + + fail_unless_equals_int (gst_element_set_state (pipeline, GST_STATE_PLAYING), + GST_STATE_CHANGE_ASYNC); + + while (!done) { + GstMessage *msg; + + /* poll the bus until we get EOS without any errors */ + msg = gst_bus_timed_pop (bus, GST_SECOND / 10); + if (msg) { + switch (GST_MESSAGE_TYPE (msg)) { + case GST_MESSAGE_ERROR: + fail ("GST_MESSAGE_ERROR"); + break; + case GST_MESSAGE_EOS: + done = TRUE; + break; + default: + break; + } + gst_message_unref (msg); + } + } + + /* Set back to NULL */ + fail_unless_equals_int (gst_element_set_state (pipeline, GST_STATE_NULL), + GST_STATE_CHANGE_SUCCESS); + + g_object_unref (bus); + + gst_object_unref (pipeline); +} + +GST_END_TEST; + +GST_START_TEST (test_encodebin_render_audio_dynamic) +{ + GstElement *ebin, *pipeline, *audiotestsrc, *fakesink; + GstEncodingProfile *prof; + GstBus *bus; + GstPad *sinkpad, *srcpad; + gboolean done = FALSE; + + /* Create an encodebin and render 5s of vorbis/ogg */ + + pipeline = gst_pipeline_new ("encodebin-pipeline"); + bus = gst_pipeline_get_bus ((GstPipeline *) pipeline); + audiotestsrc = gst_element_factory_make ("audiotestsrc", NULL); + g_object_set (audiotestsrc, "num-buffers", 10, NULL); + fakesink = gst_element_factory_make ("fakesink", NULL); + + ebin = gst_element_factory_make ("encodebin", NULL); + + prof = create_ogg_vorbis_profile (0, NULL); + g_object_set (ebin, "profile", prof, NULL); + gst_encoding_profile_unref (prof); + + gst_bin_add_many ((GstBin *) pipeline, audiotestsrc, ebin, fakesink, NULL); + + srcpad = gst_element_get_static_pad (audiotestsrc, "src"); + fail_unless (srcpad != NULL); + + sinkpad = gst_element_get_request_pad (ebin, "audio_0"); + fail_unless (sinkpad != NULL); + + fail_unless_equals_int (gst_pad_link (srcpad, sinkpad), GST_PAD_LINK_OK); + + g_object_unref (srcpad); + g_object_unref (sinkpad); + + fail_unless (gst_element_link (ebin, fakesink)); + + fail_unless_equals_int (gst_element_set_state (pipeline, GST_STATE_PLAYING), + GST_STATE_CHANGE_ASYNC); + + while (!done) { + GstMessage *msg; + + /* poll the bus until we get EOS without any errors */ + msg = gst_bus_timed_pop (bus, GST_SECOND / 10); + if (msg) { + switch (GST_MESSAGE_TYPE (msg)) { + case GST_MESSAGE_ERROR: + fail ("GST_MESSAGE_ERROR"); + break; + case GST_MESSAGE_EOS: + done = TRUE; + break; + default: + break; + } + gst_message_unref (msg); + } + } + + /* Set back to NULL */ + fail_unless_equals_int (gst_element_set_state (pipeline, GST_STATE_NULL), + GST_STATE_CHANGE_SUCCESS); + + g_object_unref (bus); + + gst_object_unref (pipeline); +} + +GST_END_TEST; + +GST_START_TEST (test_encodebin_render_audio_video_static) +{ + GstElement *ebin, *pipeline, *audiotestsrc, *videotestsrc, *fakesink; + GstEncodingProfile *prof; + GstBus *bus; + gboolean done = FALSE; + + /* Create an encodebin and render 5s of vorbis/ogg */ + + pipeline = gst_pipeline_new ("encodebin-pipeline"); + bus = gst_pipeline_get_bus ((GstPipeline *) pipeline); + audiotestsrc = gst_element_factory_make ("audiotestsrc", NULL); + g_object_set (audiotestsrc, "num-buffers", 10, NULL); + videotestsrc = gst_element_factory_make ("videotestsrc", NULL); + g_object_set (videotestsrc, "num-buffers", 5, NULL); + fakesink = gst_element_factory_make ("fakesink", NULL); + + ebin = gst_element_factory_make ("encodebin", NULL); + + prof = create_ogg_theora_vorbis_profile (1, 1); + g_object_set (ebin, "profile", prof, NULL); + gst_encoding_profile_unref (prof); + + gst_bin_add_many ((GstBin *) pipeline, audiotestsrc, videotestsrc, ebin, + fakesink, NULL); + + fail_unless (gst_element_link (videotestsrc, ebin)); + fail_unless (gst_element_link_many (audiotestsrc, ebin, fakesink, NULL)); + + fail_unless_equals_int (gst_element_set_state (pipeline, GST_STATE_PLAYING), + GST_STATE_CHANGE_ASYNC); + + while (!done) { + GstMessage *msg; + + /* poll the bus until we get EOS without any errors */ + msg = gst_bus_timed_pop (bus, GST_SECOND / 10); + if (msg) { + switch (GST_MESSAGE_TYPE (msg)) { + case GST_MESSAGE_ERROR: + fail ("GST_MESSAGE_ERROR"); + break; + case GST_MESSAGE_EOS: + done = TRUE; + break; + default: + break; + } + gst_message_unref (msg); + } + } + + /* Set back to NULL */ + fail_unless_equals_int (gst_element_set_state (pipeline, GST_STATE_NULL), + GST_STATE_CHANGE_SUCCESS); + + g_object_unref (bus); + + gst_object_unref (pipeline); +} + +GST_END_TEST; + +GST_START_TEST (test_encodebin_render_audio_video_dynamic) +{ + GstElement *ebin, *pipeline, *audiotestsrc, *videotestsrc, *fakesink; + GstEncodingProfile *prof; + GstBus *bus; + gboolean done = FALSE; + GstPad *sinkpad, *srcpad; + + /* Create an encodebin and render 5s of vorbis/ogg */ + + pipeline = gst_pipeline_new ("encodebin-pipeline"); + bus = gst_pipeline_get_bus ((GstPipeline *) pipeline); + audiotestsrc = gst_element_factory_make ("audiotestsrc", NULL); + g_object_set (audiotestsrc, "num-buffers", 10, NULL); + videotestsrc = gst_element_factory_make ("videotestsrc", NULL); + g_object_set (videotestsrc, "num-buffers", 5, NULL); + fakesink = gst_element_factory_make ("fakesink", NULL); + + ebin = gst_element_factory_make ("encodebin", NULL); + + prof = create_ogg_theora_vorbis_profile (0, 0); + g_object_set (ebin, "profile", prof, NULL); + gst_encoding_profile_unref (prof); + + gst_bin_add_many ((GstBin *) pipeline, audiotestsrc, videotestsrc, ebin, + fakesink, NULL); + + fail_unless (gst_element_link (ebin, fakesink)); + + srcpad = gst_element_get_static_pad (audiotestsrc, "src"); + sinkpad = gst_element_get_request_pad (ebin, "audio_0"); + fail_unless (srcpad != NULL); + fail_unless (sinkpad != NULL); + fail_unless_equals_int (gst_pad_link (srcpad, sinkpad), GST_PAD_LINK_OK); + g_object_unref (srcpad); + g_object_unref (sinkpad); + + srcpad = gst_element_get_static_pad (videotestsrc, "src"); + sinkpad = gst_element_get_request_pad (ebin, "video_1"); + fail_unless_equals_int (gst_pad_link (srcpad, sinkpad), GST_PAD_LINK_OK); + g_object_unref (srcpad); + g_object_unref (sinkpad); + + fail_unless_equals_int (gst_element_set_state (pipeline, GST_STATE_PLAYING), + GST_STATE_CHANGE_ASYNC); + + while (!done) { + GstMessage *msg; + + /* poll the bus until we get EOS without any errors */ + msg = gst_bus_timed_pop (bus, GST_SECOND / 10); + if (msg) { + switch (GST_MESSAGE_TYPE (msg)) { + case GST_MESSAGE_ERROR: + fail ("GST_MESSAGE_ERROR"); + break; + case GST_MESSAGE_EOS: + done = TRUE; + break; + default: + break; + } + gst_message_unref (msg); + } + } + + /* Set back to NULL */ + fail_unless_equals_int (gst_element_set_state (pipeline, GST_STATE_NULL), + GST_STATE_CHANGE_SUCCESS); + + g_object_unref (bus); + + gst_object_unref (pipeline); +} + +GST_END_TEST; + +GST_START_TEST (test_encodebin_impossible_element_combination) +{ + GstElement *ebin; + GstEncodingProfile *prof; + GstCaps *ogg, *x264; + + ebin = gst_element_factory_make ("x264enc", NULL); + if (ebin == NULL) { + GST_DEBUG ("No available h264 encoder, skipping test"); + return; + } + gst_object_unref (ebin); + + /* Make sure that impossible combinations of encoders and muxer + * properly fail. In this case we try putting h264 in ogg. + * + * To properly test we abort early, we use a presence of zero for the + * h264 stream profile. */ + + ebin = gst_element_factory_make ("encodebin", NULL); + + ogg = gst_caps_new_simple ("application/ogg", NULL); + prof = (GstEncodingProfile *) gst_encoding_container_profile_new ((gchar *) + "myprofile", NULL, ogg, NULL); + gst_caps_unref (ogg); + + x264 = gst_caps_new_simple ("video/x-h264", NULL); + fail_unless (gst_encoding_container_profile_add_profile + (GST_ENCODING_CONTAINER_PROFILE (prof), + (GstEncodingProfile *) gst_encoding_video_profile_new (x264, NULL, + NULL, 0))); + gst_caps_unref (x264); + + g_object_set (ebin, "profile", prof, NULL); + gst_encoding_profile_unref (prof); + + /* It will go to READY... */ + fail_unless_equals_int (gst_element_set_state (ebin, GST_STATE_READY), + GST_STATE_CHANGE_SUCCESS); + /* ... but to not PAUSED */ + fail_unless_equals_int (gst_element_set_state (ebin, GST_STATE_PAUSED), + GST_STATE_CHANGE_FAILURE); + + gst_element_set_state (ebin, GST_STATE_NULL); + + gst_object_unref (ebin); +}; + +GST_END_TEST; + + +static Suite * +encodebin_suite (void) +{ + Suite *s = suite_create ("encodebin element"); + TCase *tc_chain = tcase_create ("general"); + + suite_add_tcase (s, tc_chain); + tcase_add_test (tc_chain, test_encodebin_states); + tcase_add_test (tc_chain, test_encodebin_sink_pads_static); + tcase_add_test (tc_chain, test_encodebin_sink_pads_nopreset_static); + tcase_add_test (tc_chain, test_encodebin_sink_pads_dynamic); + tcase_add_test (tc_chain, test_encodebin_sink_pads_multiple_static); + tcase_add_test (tc_chain, test_encodebin_sink_pads_multiple_dynamic); + tcase_add_test (tc_chain, test_encodebin_sink_pads_dynamic_encoder); + tcase_add_test (tc_chain, test_encodebin_render_audio_static); + tcase_add_test (tc_chain, test_encodebin_render_audio_dynamic); + tcase_add_test (tc_chain, test_encodebin_render_audio_video_static); + tcase_add_test (tc_chain, test_encodebin_render_audio_video_dynamic); + tcase_add_test (tc_chain, test_encodebin_impossible_element_combination); + + return s; +} + +GST_CHECK_MAIN (encodebin); From a5994446b31f011fdc29ef7aff570c7001661891 Mon Sep 17 00:00:00 2001 From: Edward Hervey Date: Mon, 13 Sep 2010 10:08:47 +0200 Subject: [PATCH 030/254] examples: encoding example Along with gstcapslist --- configure.ac | 1 + tests/examples/Makefile.am | 4 +- tests/examples/encoding/.gitignore | 1 + tests/examples/encoding/Makefile.am | 11 + tests/examples/encoding/encoding.c | 512 ++++++++++++++++++++++++++ tests/examples/encoding/gstcapslist.c | 286 ++++++++++++++ tests/examples/encoding/gstcapslist.h | 35 ++ 7 files changed, 848 insertions(+), 2 deletions(-) create mode 100644 tests/examples/encoding/.gitignore create mode 100644 tests/examples/encoding/Makefile.am create mode 100644 tests/examples/encoding/encoding.c create mode 100644 tests/examples/encoding/gstcapslist.c create mode 100644 tests/examples/encoding/gstcapslist.h diff --git a/configure.ac b/configure.ac index 64f877cf65..ff219a989f 100644 --- a/configure.ac +++ b/configure.ac @@ -995,6 +995,7 @@ tests/check/Makefile tests/examples/Makefile tests/examples/app/Makefile tests/examples/dynamic/Makefile +tests/examples/encoding/Makefile tests/examples/gio/Makefile tests/examples/overlay/Makefile tests/examples/seek/Makefile diff --git a/tests/examples/Makefile.am b/tests/examples/Makefile.am index 841338093f..48c38a55c4 100644 --- a/tests/examples/Makefile.am +++ b/tests/examples/Makefile.am @@ -8,8 +8,8 @@ if USE_GIO GIO_SUBDIRS = gio endif -SUBDIRS = app dynamic $(FT2_SUBDIRS) $(GIO_SUBDIRS) overlay playrec volume v4l +SUBDIRS = app dynamic $(FT2_SUBDIRS) $(GIO_SUBDIRS) overlay playrec volume v4l encoding -DIST_SUBDIRS = app dynamic gio overlay seek snapshot playrec volume v4l +DIST_SUBDIRS = app dynamic gio overlay seek snapshot playrec volume v4l encoding include $(top_srcdir)/common/parallel-subdirs.mak diff --git a/tests/examples/encoding/.gitignore b/tests/examples/encoding/.gitignore new file mode 100644 index 0000000000..c684c2e50a --- /dev/null +++ b/tests/examples/encoding/.gitignore @@ -0,0 +1 @@ +encoding diff --git a/tests/examples/encoding/Makefile.am b/tests/examples/encoding/Makefile.am new file mode 100644 index 0000000000..3e95e8aca3 --- /dev/null +++ b/tests/examples/encoding/Makefile.am @@ -0,0 +1,11 @@ +examples = encoding + +encoding_SOURCES = gstcapslist.c encoding.c +EXTRA_DIST = gstcapslist.h + +noinst_PROGRAMS = $(examples) + +LDADD = $(top_builddir)/gst-libs/gst/pbutils/libgstpbutils-@GST_MAJORMINOR@.la\ + -lgstpbutils-@GST_MAJORMINOR@ + $(GST_LIBS) +AM_CFLAGS = -I$(top_builddir)/gst-libs $(GST_PLUGINS_BASE_CFLAGS) $(GST_BASE_CFLAGS) $(GST_CFLAGS) diff --git a/tests/examples/encoding/encoding.c b/tests/examples/encoding/encoding.c new file mode 100644 index 0000000000..c668148f8b --- /dev/null +++ b/tests/examples/encoding/encoding.c @@ -0,0 +1,512 @@ +/* Example application for using GstProfile and encodebin + * Copyright (C) 2009 Edward Hervey + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include +#include +#include +#include +#include "gstcapslist.h" + +static gboolean silent = FALSE; + +static void +list_codecs (void) +{ + GstCaps *l; + GstCaps *caps; + guint i, len; + + caps = gst_caps_new_empty (); + + g_print ("Available container formats:\n"); + l = gst_caps_list_container_formats (GST_RANK_NONE); + len = gst_caps_get_size (l); + for (i = 0; i < len; i++) { + GstStructure *st = gst_caps_steal_structure (l, 0); + gchar *tmpstr, *desc; + + gst_caps_append_structure (caps, st); + + tmpstr = gst_caps_to_string (caps); + desc = gst_pb_utils_get_codec_description (caps); + g_print (" %s - %s\n", desc, tmpstr); + g_free (tmpstr); + if (desc) + g_free (desc); + gst_caps_remove_structure (caps, 0); + } + g_print ("\n"); + gst_caps_unref (l); + + g_print ("Available video codecs:\n"); + l = gst_caps_list_video_encoding_formats (GST_RANK_NONE); + len = gst_caps_get_size (l); + for (i = 0; i < len; i++) { + GstStructure *st = gst_caps_steal_structure (l, 0); + gchar *tmpstr, *desc; + + gst_caps_append_structure (caps, st); + + tmpstr = gst_caps_to_string (caps); + desc = gst_pb_utils_get_codec_description (caps); + g_print (" %s - %s\n", desc, tmpstr); + g_free (tmpstr); + if (desc) + g_free (desc); + gst_caps_remove_structure (caps, 0); + } + g_print ("\n"); + gst_caps_unref (l); + + g_print ("Available audio codecs:\n"); + l = gst_caps_list_audio_encoding_formats (GST_RANK_NONE); + len = gst_caps_get_size (l); + for (i = 0; i < len; i++) { + GstStructure *st = gst_caps_steal_structure (l, 0); + gchar *tmpstr, *desc; + + gst_caps_append_structure (caps, st); + + tmpstr = gst_caps_to_string (caps); + desc = gst_pb_utils_get_codec_description (caps); + g_print (" %s - %s\n", desc, tmpstr); + g_free (tmpstr); + if (desc) + g_free (desc); + gst_caps_remove_structure (caps, 0); + } + g_print ("\n"); + gst_caps_unref (l); + + gst_caps_unref (caps); +} + +static gchar * +generate_filename (const GstCaps * container, const GstCaps * vcodec, + const GstCaps * acodec) +{ + gchar *a, *b, *c; + gchar *res = NULL; + guint i; + + a = gst_pb_utils_get_codec_description (container); + b = gst_pb_utils_get_codec_description (vcodec); + c = gst_pb_utils_get_codec_description (acodec); + + if (!a) + a = g_strdup_printf ("%.10s", + g_uri_escape_string (gst_caps_to_string (container), NULL, FALSE)); + if (!b) + b = g_strdup_printf ("%.10s", + g_uri_escape_string (gst_caps_to_string (vcodec), NULL, FALSE)); + if (!c) + c = g_strdup_printf ("%.10s", + g_uri_escape_string (gst_caps_to_string (acodec), NULL, FALSE)); + + for (i = 0; i < 256 && res == NULL; i++) { + res = g_strdup_printf ("%s-%s-%s-%d.file", a, b, c, i); + if (g_file_test (res, G_FILE_TEST_EXISTS)) { + g_free (res); + res = NULL; + } + } + /* Make sure file doesn't already exist */ + + g_free (a); + g_free (b); + g_free (c); + + return res; +} + +static GstEncodingProfile * +create_profile (GstCaps * cf, GstCaps * vf, GstCaps * af) +{ + GstEncodingContainerProfile *cprof = NULL; + + cprof = + gst_encoding_container_profile_new ((gchar *) "test-application-profile", + NULL, cf, NULL); + + if (vf) + gst_encoding_container_profile_add_profile (cprof, + (GstEncodingProfile *) gst_encoding_video_profile_new (vf, + NULL, NULL, 0)); + if (af) + gst_encoding_container_profile_add_profile (cprof, (GstEncodingProfile *) + gst_encoding_audio_profile_new (af, NULL, NULL, 0)); + + /* Let's print out some info */ + if (!silent) { + gchar *desc = gst_pb_utils_get_codec_description (cf); + gchar *cd = gst_caps_to_string (cf); + g_print ("Encoding parameters\n"); + g_print (" Container format : %s (%s)\n", desc, cd); + g_free (desc); + g_free (cd); + if (vf) { + desc = gst_pb_utils_get_codec_description (vf); + cd = gst_caps_to_string (vf); + g_print (" Video format : %s (%s)\n", desc, cd); + g_free (desc); + g_free (cd); + } + if (af) { + desc = gst_pb_utils_get_codec_description (af); + cd = gst_caps_to_string (af); + g_print (" Audio format : %s (%s)\n", desc, cd); + g_free (desc); + g_free (cd); + } + } + + return (GstEncodingProfile *) cprof; +} + +static GstEncodingProfile * +create_profile_from_string (gchar * format, gchar * vformat, gchar * aformat) +{ + GstEncodingProfile *prof = NULL; + GstCaps *cf = NULL, *vf = NULL, *af = NULL; + + if (format) + cf = gst_caps_from_string (format); + if (vformat) + vf = gst_caps_from_string (vformat); + if (aformat) + af = gst_caps_from_string (aformat); + + if (G_UNLIKELY ((vformat && (vf == NULL)) || (aformat && (af == NULL)))) + goto beach; + + prof = create_profile (cf, vf, af); + +beach: + if (cf) + gst_caps_unref (cf); + if (vf) + gst_caps_unref (vf); + if (af) + gst_caps_unref (af); + + return prof; +} + +static void +pad_added_cb (GstElement * uridecodebin, GstPad * pad, GstElement * encodebin) +{ + GstPad *sinkpad; + + sinkpad = gst_element_get_compatible_pad (encodebin, pad, NULL); + + if (sinkpad == NULL) { + GstCaps *caps; + + /* Ask encodebin for a compatible pad */ + caps = gst_pad_get_caps (pad); + g_signal_emit_by_name (encodebin, "request-pad", caps, &sinkpad); + if (caps) + gst_caps_unref (caps); + } + if (sinkpad == NULL) { + g_print ("Couldn't get an encoding channel for pad %s:%s\n", + GST_DEBUG_PAD_NAME (pad)); + return; + } + + if (G_UNLIKELY (gst_pad_link (pad, sinkpad) != GST_PAD_LINK_OK)) { + g_print ("Couldn't link pads\n"); + } + + return; +} + +static gboolean +autoplug_continue_cb (GstElement * uridecodebin, GstPad * somepad, + GstCaps * caps, GstElement * encodebin) +{ + GstPad *sinkpad; + + g_signal_emit_by_name (encodebin, "request-pad", caps, &sinkpad); + + if (sinkpad == NULL) + return TRUE; + + return FALSE; +} + +static void +bus_message_cb (GstBus * bus, GstMessage * message, GMainLoop * mainloop) +{ + switch (GST_MESSAGE_TYPE (message)) { + case GST_MESSAGE_ERROR: + g_print ("ERROR\n"); + gst_bus_set_flushing (bus, TRUE); + g_main_loop_quit (mainloop); + break; + case GST_MESSAGE_EOS: + g_print ("Done\n"); + g_main_loop_quit (mainloop); + break; + default: + break; + } +} + +static void +transcode_file (gchar * uri, gchar * outputuri, GstEncodingProfile * prof) +{ + GstElement *pipeline; + GstElement *src; + GstElement *ebin; + GstElement *sink; + GstBus *bus; + GstCaps *profilecaps, *rescaps; + GMainLoop *mainloop; + + g_print (" Input URI : %s\n", uri); + g_print (" Output URI : %s\n", outputuri); + + sink = gst_element_make_from_uri (GST_URI_SINK, outputuri, "sink"); + if (G_UNLIKELY (sink == NULL)) { + g_print ("Can't create output sink, most likely invalid output URI !\n"); + return; + } + + src = gst_element_factory_make ("uridecodebin", NULL); + if (G_UNLIKELY (src == NULL)) { + g_print ("Can't create uridecodebin for input URI, aborting!\n"); + return; + } + + /* Figure out the streams that can be passed as-is to encodebin */ + g_object_get (src, "caps", &rescaps, NULL); + rescaps = gst_caps_copy (rescaps); + profilecaps = gst_encoding_profile_get_output_caps (prof); + gst_caps_append (rescaps, profilecaps); + + /* Set properties */ + g_object_set (src, "uri", uri, "caps", rescaps, NULL); + + ebin = gst_element_factory_make ("encodebin", NULL); + g_object_set (ebin, "profile", prof, NULL); + + g_signal_connect (src, "autoplug-continue", G_CALLBACK (autoplug_continue_cb), + ebin); + g_signal_connect (src, "pad-added", G_CALLBACK (pad_added_cb), ebin); + + pipeline = gst_pipeline_new ("encoding-pipeline"); + + gst_bin_add_many (GST_BIN (pipeline), src, ebin, sink, NULL); + + gst_element_link (ebin, sink); + + mainloop = g_main_loop_new (NULL, FALSE); + + bus = gst_pipeline_get_bus ((GstPipeline *) pipeline); + gst_bus_add_signal_watch (bus); + g_signal_connect (bus, "message", G_CALLBACK (bus_message_cb), mainloop); + + if (gst_element_set_state (pipeline, + GST_STATE_PLAYING) == GST_STATE_CHANGE_FAILURE) { + g_print ("Failed to start the encoding\n"); + return; + } + + g_main_loop_run (mainloop); + + gst_element_set_state (pipeline, GST_STATE_NULL); + gst_object_unref (pipeline); +} + +static gchar * +ensure_uri (gchar * location) +{ + gchar *res; + gchar *path; + + if (gst_uri_is_valid (location)) + return g_strdup (location); + + if (!g_path_is_absolute (location)) { + gchar *cur_dir; + cur_dir = g_get_current_dir (); + path = g_build_filename (cur_dir, location, NULL); + g_free (cur_dir); + } else + path = g_strdup (location); + + res = g_filename_to_uri (path, NULL, NULL); + g_free (path); + + return res; +} + +int +main (int argc, char **argv) +{ + GError *err = NULL; + gchar *outputuri = NULL; + gchar *format = NULL; + gchar *aformat = NULL; + gchar *vformat = NULL; + gboolean allmissing = FALSE; + gboolean listcodecs = FALSE; + GOptionEntry options[] = { + {"silent", 's', 0, G_OPTION_ARG_NONE, &silent, + "Don't output the information structure", NULL}, + {"outputuri", 'o', 0, G_OPTION_ARG_STRING, &outputuri, + "URI to encode to", "URI (://)"}, + {"format", 'f', 0, G_OPTION_ARG_STRING, &format, + "Container format", ""}, + {"vformat", 'v', 0, G_OPTION_ARG_STRING, &vformat, + "Video format", ""}, + {"aformat", 'a', 0, G_OPTION_ARG_STRING, &aformat, + "Audio format", ""}, + {"allmissing", 'm', 0, G_OPTION_ARG_NONE, &allmissing, + "encode to all matching format/codec that aren't specified", NULL}, + {"list-codecs", 'l', 0, G_OPTION_ARG_NONE, &listcodecs, + "list all available codecs and container formats", NULL}, + {NULL} + }; + GOptionContext *ctx; + GstEncodingProfile *prof; + gchar *inputuri; + + if (!g_thread_supported ()) + g_thread_init (NULL); + + ctx = g_option_context_new ("- encode URIs with GstProfile and encodebin"); + g_option_context_add_main_entries (ctx, options, NULL); + g_option_context_add_group (ctx, gst_init_get_option_group ()); + + if (!g_option_context_parse (ctx, &argc, &argv, &err)) { + g_print ("Error initializing: %s\n", err->message); + exit (1); + } + + if (listcodecs) { + list_codecs (); + g_option_context_free (ctx); + exit (0); + } + + if (outputuri == NULL || argc != 2) { + g_print ("%s", g_option_context_get_help (ctx, TRUE, NULL)); + g_option_context_free (ctx); + exit (-1); + } + + g_option_context_free (ctx); + + /* Fixup outputuri to be a URI */ + inputuri = ensure_uri (argv[1]); + outputuri = ensure_uri (outputuri); + + if (allmissing) { + GList *muxers; + GstCaps *formats = NULL; + GstCaps *vformats = NULL; + GstCaps *aformats = NULL; + guint f, v, a, flen, vlen, alen; + + if (!format) + formats = gst_caps_list_container_formats (GST_RANK_NONE); + else + formats = gst_caps_from_string (format); + + if (!vformat) + vformats = gst_caps_list_video_encoding_formats (GST_RANK_NONE); + else + vformats = gst_caps_from_string (vformat); + + if (!aformat) + aformats = gst_caps_list_audio_encoding_formats (GST_RANK_NONE); + else + aformats = gst_caps_from_string (aformat); + muxers = + gst_element_factory_list_get_elements (GST_ELEMENT_FACTORY_TYPE_MUXER, + GST_RANK_NONE); + + flen = gst_caps_get_size (formats); + + for (f = 0; f < flen; f++) { + GstCaps *container = + gst_caps_new_full (gst_caps_steal_structure (formats, 0), NULL); + GstCaps *compatv = + gst_caps_list_compatible_codecs (container, vformats, muxers); + GstCaps *compata = + gst_caps_list_compatible_codecs (container, aformats, muxers); + + vlen = gst_caps_get_size (compatv); + alen = gst_caps_get_size (compata); + + + for (v = 0; v < vlen; v++) { + GstCaps *vcodec = + gst_caps_new_full (gst_structure_copy (gst_caps_get_structure + (compatv, v)), NULL); + for (a = 0; a < alen; a++) { + GstCaps *acodec = + gst_caps_new_full (gst_structure_copy (gst_caps_get_structure + (compata, a)), NULL); + + prof = + create_profile ((GstCaps *) container, (GstCaps *) vcodec, + (GstCaps *) acodec); + if (G_UNLIKELY (prof == NULL)) { + g_print ("Wrong arguments\n"); + break; + } + outputuri = + ensure_uri (generate_filename (container, vcodec, acodec)); + transcode_file (inputuri, outputuri, prof); + gst_encoding_profile_unref (prof); + + gst_caps_unref (acodec); + } + gst_caps_unref (vcodec); + } + gst_caps_unref (container); + } + + } else { + + /* Create the profile */ + prof = create_profile_from_string (format, vformat, aformat); + if (G_UNLIKELY (prof == NULL)) { + g_print ("Encoding arguments are not valid !\n"); + return 1; + } + + /* Trancode file */ + transcode_file (inputuri, outputuri, prof); + + /* cleanup */ + gst_encoding_profile_unref (prof); + + } + return 0; +} diff --git a/tests/examples/encoding/gstcapslist.c b/tests/examples/encoding/gstcapslist.c new file mode 100644 index 0000000000..4908e438c5 --- /dev/null +++ b/tests/examples/encoding/gstcapslist.c @@ -0,0 +1,286 @@ +/* GStreamer + * Copyright (C) <2010> Edward Hervey + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include "gstcapslist.h" + +/* + * Caps listing convenience functions + */ + +static gboolean +remove_range_foreach (GQuark field_id, const GValue * value, GstStructure * st) +{ + GType ftype = G_VALUE_TYPE (value); + const gchar *fname; + + if (ftype == GST_TYPE_INT_RANGE || ftype == GST_TYPE_DOUBLE_RANGE || + ftype == GST_TYPE_FRACTION_RANGE) { + gst_structure_remove_field (st, g_quark_to_string (field_id)); + return FALSE; + } + + fname = g_quark_to_string (field_id); + + /* if (strstr (fname, "framerate") || strstr (fname, "pixel-aspect-ratio") || */ + /* strstr (fname, "rate")) { */ + /* gst_structure_remove_field (st, g_quark_to_string (field_id)); */ + /* return FALSE; */ + /* } */ + + return TRUE; +} + +static void +clear_caps (GstCaps * caps, GstCaps * rescaps) +{ + GstCaps *res; + GstStructure *st; + guint i; + + res = gst_caps_make_writable (caps); + + GST_DEBUG ("incoming caps %" GST_PTR_FORMAT, res); + + /* Remove width/height/framerate/depth/width fields */ + for (i = gst_caps_get_size (res); i; i--) { + st = gst_caps_get_structure (res, i - 1); + + /* Remove range fields */ + while (!gst_structure_foreach (st, + (GstStructureForeachFunc) remove_range_foreach, st)); + } + + GST_DEBUG ("stripped %" GST_PTR_FORMAT, res); + + /* And append to list without duplicates */ + while ((st = gst_caps_steal_structure (res, 0))) { + /* Skip fake codecs/containers */ + if (gst_structure_has_name (st, "audio/x-raw-int") || + gst_structure_has_name (st, "audio/x-raw-float") || + gst_structure_has_name (st, "video/x-raw-yuv") || + gst_structure_has_name (st, "video/x-raw-rgb") || + gst_structure_has_name (st, "unknown/unknown")) { + gst_structure_free (st); + continue; + } + + gst_caps_append_structure (rescaps, st); + } + + gst_caps_unref (res); +} + +static GstCaps * +get_all_caps (GList * elements, GstPadDirection direction) +{ + GstCaps *res = NULL, *res2; + GList *tmp; + + res = gst_caps_new_empty (); + + for (tmp = elements; tmp; tmp = tmp->next) { + GstElementFactory *factory = (GstElementFactory *) tmp->data; + const GList *templates; + GList *walk; + + templates = gst_element_factory_get_static_pad_templates (factory); + for (walk = (GList *) templates; walk; walk = g_list_next (walk)) { + GstStaticPadTemplate *templ = walk->data; + if (templ->direction == direction) + clear_caps (gst_static_caps_get (&templ->static_caps), res); + } + } + + res2 = gst_caps_normalize (res); + gst_caps_unref (res); + return res2; +} + +/** + * gst_caps_list_container_formats: + * @minrank: The minimum #GstRank + * + * Returns a #GstCaps corresponding to all the container formats + * one can mux to on this system. + * + * Returns: A #GstCaps. Unref with %gst_caps_unref when done with it. + */ +GstCaps * +gst_caps_list_container_formats (GstRank minrank) +{ + GstCaps *res; + GList *muxers; + + muxers = + gst_element_factory_list_get_elements (GST_ELEMENT_FACTORY_TYPE_MUXER, + minrank); + res = get_all_caps (muxers, GST_PAD_SRC); + gst_plugin_feature_list_free (muxers); + + return res; +} + +static GstCaps * +gst_caps_list_encoding_formats (GstRank minrank) +{ + GstCaps *res; + GList *encoders; + + encoders = + gst_element_factory_list_get_elements (GST_ELEMENT_FACTORY_TYPE_ENCODER, + minrank); + res = get_all_caps (encoders, GST_PAD_SRC); + gst_plugin_feature_list_free (encoders); + + return res; +} + +/** + * gst_caps_list_video_encoding_formats: + * @minrank: The minimum #GstRank + * + * Returns a #GstCaps corresponding to all the video or image formats one + * can encode to on this system. + * + * Returns: A #GstCaps. Unref with %gst_caps_unref when done with it. + */ +GstCaps * +gst_caps_list_video_encoding_formats (GstRank minrank) +{ + GstCaps *res; + GList *encoders; + + encoders = + gst_element_factory_list_get_elements + (GST_ELEMENT_FACTORY_TYPE_VIDEO_ENCODER, minrank); + res = get_all_caps (encoders, GST_PAD_SRC); + gst_plugin_feature_list_free (encoders); + + return res; +} + + +/** + * gst_caps_list_audio_encoding_formats: + * @minrank: The minimum #GstRank + * + * Returns a #GstCaps corresponding to all the audio formats one + * can encode to on this system. + * + * Returns: A #GstCaps. Unref with %gst_caps_unref when done with it. + */ +GstCaps * +gst_caps_list_audio_encoding_formats (GstRank minrank) +{ + GstCaps *res; + GList *encoders; + + encoders = + gst_element_factory_list_get_elements + (GST_ELEMENT_FACTORY_TYPE_AUDIO_ENCODER, minrank); + res = get_all_caps (encoders, GST_PAD_SRC); + gst_plugin_feature_list_free (encoders); + + return res; +} + +/** + * gst_caps_list_compatible_codecs: + * @containerformat: A #GstCaps corresponding to a container format + * @codecformats: An optional #GstCaps of codec formats + * @muxers: An optional #GList of muxer #GstElementFactory. + * + * Returns an array of #GstCaps corresponding to the audio/video/text formats + * one can encode to and that can be muxed in the provided @containerformat. + * + * If specified, only the #GstCaps contained in @codecformats will be checked + * against, else all compatible audio/video formats will be returned. + * + * If specified, only the #GstElementFactory contained in @muxers will be checked, + * else all available muxers on the system will be checked. + * + * Returns: A #GstCaps containing all compatible formats. Unref with %gst_caps_unref + * when done. + */ +GstCaps * +gst_caps_list_compatible_codecs (const GstCaps * containerformat, + GstCaps * codecformats, GList * muxers) +{ + const GList *templates; + GstElementFactory *factory; + GList *walk; + GstCaps *res = NULL; + GstCaps *tmpcaps; + GList *tmp; + gboolean hadmuxers = (muxers != NULL); + gboolean hadcodecs = (codecformats != NULL); + + GST_DEBUG ("containerformat: %" GST_PTR_FORMAT, containerformat); + GST_DEBUG ("codecformats: %" GST_PTR_FORMAT, codecformats); + + if (!hadmuxers) + muxers = + gst_element_factory_list_get_elements (GST_ELEMENT_FACTORY_TYPE_MUXER, + GST_RANK_NONE); + if (!hadcodecs) + codecformats = gst_caps_list_encoding_formats (GST_RANK_NONE); + + /* Get the highest rank muxer matching containerformat */ + tmp = + gst_element_factory_list_filter (muxers, containerformat, GST_PAD_SRC, + TRUE); + if (G_UNLIKELY (tmp == NULL)) + goto beach; + + factory = (GstElementFactory *) tmp->data; + + GST_DEBUG ("Trying with factory %s", + gst_element_factory_get_longname (factory)); + + /* Match all muxer sink pad templates against the available codec formats */ + templates = gst_element_factory_get_static_pad_templates (factory); + gst_plugin_feature_list_free (tmp); + + tmpcaps = gst_caps_new_empty (); + + for (walk = (GList *) templates; walk; walk = walk->next) { + GstStaticPadTemplate *templ = walk->data; + + if (templ->direction == GST_PAD_SINK) { + GstCaps *templ_caps; + + templ_caps = gst_static_caps_get (&templ->static_caps); + gst_caps_append (tmpcaps, gst_caps_copy (templ_caps)); + } + } + + res = gst_caps_intersect (tmpcaps, codecformats); + gst_caps_unref (tmpcaps); + +beach: + if (!hadmuxers) + gst_plugin_feature_list_free (muxers); + if (!hadcodecs) + gst_caps_unref (codecformats); + + tmpcaps = gst_caps_normalize (res); + gst_caps_unref (res); + + return tmpcaps; +} diff --git a/tests/examples/encoding/gstcapslist.h b/tests/examples/encoding/gstcapslist.h new file mode 100644 index 0000000000..fa0ed83bfe --- /dev/null +++ b/tests/examples/encoding/gstcapslist.h @@ -0,0 +1,35 @@ +/* GStreamer + * Copyright (C) <2010> Edward Hervey + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include + +GstCaps *gst_caps_list_compatible_codecs (const GstCaps *containerformat, + GstCaps *codecformats, + GList *muxers); + +GstCaps *gst_caps_list_compatible_containers (GstCaps *mediaformat, + GList *containerformats); + + +GstCaps *gst_caps_list_container_formats (GstRank minrank); + +GstCaps *gst_caps_list_video_encoding_formats (GstRank minrank); + +GstCaps *gst_caps_list_audio_encoding_formats (GstRank minrank); + From 1c2c9c10b52122fd112023850e3ec2ee5bd35dc2 Mon Sep 17 00:00:00 2001 From: Wim Taymans Date: Wed, 15 Dec 2010 12:58:47 +0100 Subject: [PATCH 031/254] basedepay: add support for buffer lists in the depayloader Add support for buffer lists in the depayloader. --- gst-libs/gst/rtp/gstbasertpdepayload.c | 129 ++++++++++++++++++------- gst-libs/gst/rtp/gstbasertpdepayload.h | 2 + 2 files changed, 98 insertions(+), 33 deletions(-) diff --git a/gst-libs/gst/rtp/gstbasertpdepayload.c b/gst-libs/gst/rtp/gstbasertpdepayload.c index 6c9723ab5c..583754fda4 100644 --- a/gst-libs/gst/rtp/gstbasertpdepayload.c +++ b/gst-libs/gst/rtp/gstbasertpdepayload.c @@ -496,30 +496,58 @@ create_segment_event (GstBaseRTPDepayload * filter, gboolean update, return event; } -static GstFlowReturn -gst_base_rtp_depayload_push_full (GstBaseRTPDepayload * filter, - gboolean do_ts, guint32 rtptime, GstBuffer * out_buf) +typedef struct { - GstFlowReturn ret; - GstCaps *srccaps; + GstBaseRTPDepayload *depayload; GstBaseRTPDepayloadClass *bclass; + GstCaps *caps; + gboolean do_ts; + gboolean rtptime; +} HeaderData; + +static GstBufferListItem +set_headers (GstBuffer ** buffer, guint group, guint idx, HeaderData * data) +{ + GstBaseRTPDepayload *depayload = data->depayload; + + *buffer = gst_buffer_make_metadata_writable (*buffer); + gst_buffer_set_caps (*buffer, data->caps); + + /* set the timestamp if we must and can */ + if (data->bclass->set_gst_timestamp && data->do_ts) + data->bclass->set_gst_timestamp (depayload, data->rtptime, *buffer); + + if (G_UNLIKELY (depayload->priv->discont)) { + GST_LOG_OBJECT (depayload, "Marking DISCONT on output buffer"); + GST_BUFFER_FLAG_SET (*buffer, GST_BUFFER_FLAG_DISCONT); + depayload->priv->discont = FALSE; + } + + return GST_BUFFER_LIST_SKIP_GROUP; +} + +static GstFlowReturn +gst_base_rtp_depayload_prepare_push (GstBaseRTPDepayload * filter, + gboolean do_ts, guint32 rtptime, gboolean is_list, gpointer obj) +{ GstBaseRTPDepayloadPrivate *priv; + HeaderData data; priv = filter->priv; - /* almost certainly required */ - out_buf = gst_buffer_make_metadata_writable (out_buf); + data.depayload = filter; + data.caps = GST_PAD_CAPS (filter->srcpad); + data.rtptime = rtptime; + data.do_ts = do_ts; + data.bclass = GST_BASE_RTP_DEPAYLOAD_GET_CLASS (filter); - /* set the caps if any */ - srccaps = GST_PAD_CAPS (filter->srcpad); - if (G_LIKELY (srccaps)) - gst_buffer_set_caps (out_buf, srccaps); - - bclass = GST_BASE_RTP_DEPAYLOAD_GET_CLASS (filter); - - /* set the timestamp if we must and can */ - if (bclass->set_gst_timestamp && do_ts) - bclass->set_gst_timestamp (filter, rtptime, out_buf); + if (is_list) { + gst_buffer_list_foreach (GST_BUFFER_LIST_CAST (obj), + (GstBufferListFunc) set_headers, &data); + } else { + GstBuffer *buf = GST_BUFFER_CAST (obj); + set_headers (&buf, 0, 0, &data); + } /* if this is the first buffer send a NEWSEGMENT */ if (G_UNLIKELY (filter->need_newsegment)) { @@ -533,20 +561,7 @@ gst_base_rtp_depayload_push_full (GstBaseRTPDepayload * filter, GST_DEBUG_OBJECT (filter, "Pushed newsegment event on this first buffer"); } - if (G_UNLIKELY (priv->discont)) { - GST_LOG_OBJECT (filter, "Marking DISCONT on output buffer"); - GST_BUFFER_FLAG_SET (out_buf, GST_BUFFER_FLAG_DISCONT); - priv->discont = FALSE; - } - - /* push it */ - GST_LOG_OBJECT (filter, "Pushing buffer size %d, timestamp %" GST_TIME_FORMAT, - GST_BUFFER_SIZE (out_buf), - GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (out_buf))); - - ret = gst_pad_push (filter->srcpad, out_buf); - - return ret; + return GST_FLOW_OK; } /** @@ -569,7 +584,18 @@ GstFlowReturn gst_base_rtp_depayload_push_ts (GstBaseRTPDepayload * filter, guint32 timestamp, GstBuffer * out_buf) { - return gst_base_rtp_depayload_push_full (filter, TRUE, timestamp, out_buf); + GstFlowReturn res; + + res = + gst_base_rtp_depayload_prepare_push (filter, TRUE, timestamp, FALSE, + out_buf); + + if (G_LIKELY (res == GST_FLOW_OK)) + res = gst_pad_push (filter->srcpad, out_buf); + else + gst_buffer_unref (out_buf); + + return res; } /** @@ -589,7 +615,44 @@ gst_base_rtp_depayload_push_ts (GstBaseRTPDepayload * filter, guint32 timestamp, GstFlowReturn gst_base_rtp_depayload_push (GstBaseRTPDepayload * filter, GstBuffer * out_buf) { - return gst_base_rtp_depayload_push_full (filter, FALSE, 0, out_buf); + GstFlowReturn res; + + res = gst_base_rtp_depayload_prepare_push (filter, FALSE, 0, FALSE, out_buf); + + if (G_LIKELY (res == GST_FLOW_OK)) + res = gst_pad_push (filter->srcpad, out_buf); + else + gst_buffer_unref (out_buf); + + return res; +} + +/** + * gst_base_rtp_depayload_push_list: + * @filter: a #GstBaseRTPDepayload + * @out_list: a #GstBufferList + * + * Push @out_list to the peer of @filter. This function takes ownership of + * @out_list. + * + * Returns: a #GstFlowReturn. + * + * Since: 0.10.32 + */ +GstFlowReturn +gst_base_rtp_depayload_push_list (GstBaseRTPDepayload * filter, + GstBufferList * out_list) +{ + GstFlowReturn res; + + res = gst_base_rtp_depayload_prepare_push (filter, TRUE, 0, TRUE, out_list); + + if (G_LIKELY (res == GST_FLOW_OK)) + res = gst_pad_push_list (filter->srcpad, out_list); + else + gst_buffer_list_unref (out_list); + + return res; } /* convert the PacketLost event form a jitterbuffer to a segment update. diff --git a/gst-libs/gst/rtp/gstbasertpdepayload.h b/gst-libs/gst/rtp/gstbasertpdepayload.h index d20ed91489..4ba2fc4ed0 100644 --- a/gst-libs/gst/rtp/gstbasertpdepayload.h +++ b/gst-libs/gst/rtp/gstbasertpdepayload.h @@ -128,6 +128,8 @@ GType gst_base_rtp_depayload_get_type (void); GstFlowReturn gst_base_rtp_depayload_push (GstBaseRTPDepayload *filter, GstBuffer *out_buf); GstFlowReturn gst_base_rtp_depayload_push_ts (GstBaseRTPDepayload *filter, guint32 timestamp, GstBuffer *out_buf); +GstFlowReturn gst_base_rtp_depayload_push_list (GstBaseRTPDepayload *filter, GstBufferList *out_list); + G_END_DECLS From 708b38904f7241f7f7da8efbb773e87f6701f477 Mon Sep 17 00:00:00 2001 From: Stefan Kost Date: Wed, 15 Dec 2010 14:55:34 +0200 Subject: [PATCH 032/254] Automatic update of common submodule From 20742ae to 169462a --- common | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common b/common index 20742aee03..169462a62f 160000 --- a/common +++ b/common @@ -1 +1 @@ -Subproject commit 20742aee033cc7c4aa9a817df005d15d5fa6ba85 +Subproject commit 169462a62f8b3cb91d721092af13530a3f72a462 From 34ea5bdd062fe09cc9071e065b21bb142545ef99 Mon Sep 17 00:00:00 2001 From: Wim Taymans Date: Wed, 15 Dec 2010 16:30:55 +0100 Subject: [PATCH 033/254] rtpbuffer: relax arrangement for RTP bufferlists Don't assume there are exactly 2 buffers but allow cases where the header and payload are in 1 buffer or where the payload is in more buffers. --- gst-libs/gst/rtp/gstrtpbuffer.c | 44 +++++++++++++++++++-------------- 1 file changed, 25 insertions(+), 19 deletions(-) diff --git a/gst-libs/gst/rtp/gstrtpbuffer.c b/gst-libs/gst/rtp/gstrtpbuffer.c index 1cf608b1a0..8f94d3f5d4 100644 --- a/gst-libs/gst/rtp/gstrtpbuffer.c +++ b/gst-libs/gst/rtp/gstrtpbuffer.c @@ -453,33 +453,20 @@ gst_rtp_buffer_list_validate (GstBufferList * list) guint8 *packet_payload; guint payload_size; guint packet_size; + guint j, n_buffers; - /* each group should consists of 2 buffers: one containing the RTP header - * and the other one the payload, FIXME, relax the requirement of only one - * payload buffer. */ - if (gst_buffer_list_iterator_n_buffers (it) != 2) + /* each group should consists of at least 1 buffer: The first buffer always + * contains the complete RTP header. Next buffers contain the payload */ + n_buffers = gst_buffer_list_iterator_n_buffers (it); + if (n_buffers < 1) goto invalid_list; - /* get the RTP header */ + /* get the RTP header (and if n_buffers == 1 also the payload) */ rtpbuf = gst_buffer_list_iterator_next (it); packet_header = GST_BUFFER_DATA (rtpbuf); if (packet_header == NULL) goto invalid_list; - /* get the payload */ - paybuf = gst_buffer_list_iterator_next (it); - packet_payload = GST_BUFFER_DATA (paybuf); - if (packet_payload == NULL) { - goto invalid_list; - } - payload_size = GST_BUFFER_SIZE (paybuf); - if (payload_size == 0) { - goto invalid_list; - } - - /* the size of the RTP packet within the current group */ - packet_size = GST_BUFFER_SIZE (rtpbuf) + payload_size; - /* check the sequence number */ if (G_UNLIKELY (i == 0)) { prev_seqnum = g_ntohs (GST_RTP_HEADER_SEQ (packet_header)); @@ -489,6 +476,25 @@ gst_rtp_buffer_list_validate (GstBufferList * list) goto invalid_list; } + packet_size = GST_BUFFER_SIZE (rtpbuf); + packet_payload = NULL; + payload_size = 0; + + /* get the payload buffers */ + for (j = 1; j < n_buffers; j++) { + /* get the payload */ + paybuf = gst_buffer_list_iterator_next (it); + + if ((packet_payload = GST_BUFFER_DATA (paybuf)) == NULL) + goto invalid_list; + + if ((payload_size = GST_BUFFER_SIZE (paybuf)) == 0) + goto invalid_list; + + /* the size of the RTP packet within the current group */ + packet_size += payload_size; + } + /* validate packet */ if (!validate_data (packet_header, packet_size, packet_payload, payload_size)) { From fa5d713045931ef52d708831393484eab9ad387b Mon Sep 17 00:00:00 2001 From: Wim Taymans Date: Wed, 15 Dec 2010 16:35:43 +0100 Subject: [PATCH 034/254] win32: update defs file --- win32/common/libgstrtp.def | 1 + 1 file changed, 1 insertion(+) diff --git a/win32/common/libgstrtp.def b/win32/common/libgstrtp.def index bfa8c98d49..41c9660c93 100644 --- a/win32/common/libgstrtp.def +++ b/win32/common/libgstrtp.def @@ -10,6 +10,7 @@ EXPORTS gst_base_rtp_audio_payload_set_samplebits_options gst_base_rtp_depayload_get_type gst_base_rtp_depayload_push + gst_base_rtp_depayload_push_list gst_base_rtp_depayload_push_ts gst_basertppayload_get_type gst_basertppayload_is_filled From dd699397c20fac4b227bef94b59757f47b22bcc1 Mon Sep 17 00:00:00 2001 From: Andy Wingo Date: Wed, 15 Dec 2010 17:51:36 +0100 Subject: [PATCH 035/254] add gst_rtsp_url_decode_path_components * gst-libs/gst/rtsp/gstrtspurl.h: * gst-libs/gst/rtsp/gstrtspurl.c (gst_rtsp_url_decode_path_components): New public function, returns a strv of uri-decoded path components. * tests/check/Makefile.am: * tests/check/libs/rtsp.c: Add tests. --- gst-libs/gst/rtsp/gstrtspurl.c | 73 ++++++++++++++++ gst-libs/gst/rtsp/gstrtspurl.h | 2 + tests/check/Makefile.am | 8 ++ tests/check/libs/rtsp.c | 150 +++++++++++++++++++++++++++++++++ 4 files changed, 233 insertions(+) create mode 100644 tests/check/libs/rtsp.c diff --git a/gst-libs/gst/rtsp/gstrtspurl.c b/gst-libs/gst/rtsp/gstrtspurl.c index 0a71091cf7..6973e09c38 100644 --- a/gst-libs/gst/rtsp/gstrtspurl.c +++ b/gst-libs/gst/rtsp/gstrtspurl.c @@ -341,3 +341,76 @@ gst_rtsp_url_get_request_uri (const GstRTSPUrl * url) return uri; } + +static int +hex_to_int (gchar c) +{ + if (c >= '0' && c <= '9') + return c - '0'; + else if (c >= 'a' && c <= 'f') + return c - 'a' + 10; + else if (c >= 'A' && c <= 'F') + return c - 'A' + 10; + else + return -1; +} + +static void +unescape_path_component (gchar * comp) +{ + guint len = strlen (comp); + guint i; + + for (i = 0; i + 2 < len; i++) + if (comp[i] == '%') { + int a, b; + + a = hex_to_int (comp[i + 1]); + b = hex_to_int (comp[i + 2]); + + /* The a||b check is to ensure that the byte is not '\0' */ + if (a >= 0 && b >= 0 && (a || b)) { + comp[i] = (gchar) (a * 16 + b); + memmove (comp + i + 1, comp + i + 3, len - i - 3); + len -= 2; + comp[len] = '\0'; + } + } +} + +/** + * gst_rtsp_url_decode_path_components: + * @url: a #GstRTSPUrl + * + * Splits the path of @url on '/' boundaries, decoding the resulting components, + * + * The decoding performed by this routine is "URI decoding", as defined in RFC + * 3986, commonly known as percent-decoding. For example, a string "foo%2fbar" + * will decode to "foo/bar" -- the %2f being replaced by the corresponding byte + * with hex value 0x2f. Note that there is no guarantee that the resulting byte + * sequence is valid in any given encoding. As a special case, %00 is not + * unescaped to NUL, as that would prematurely terminate the string. + * + * Also note that since paths usually start with a slash, the first component + * will usually be the empty string. + * + * Returns: a string vector. g_strfreev() after usage. + * + * Since: 0.10.32 + */ +gchar ** +gst_rtsp_url_decode_path_components (const GstRTSPUrl * url) +{ + gchar **ret; + guint i; + + g_return_val_if_fail (url != NULL, NULL); + g_return_val_if_fail (url->abspath != NULL, NULL); + + ret = g_strsplit (url->abspath, "/", -1); + + for (i = 0; ret[i]; i++) + unescape_path_component (ret[i]); + + return ret; +} diff --git a/gst-libs/gst/rtsp/gstrtspurl.h b/gst-libs/gst/rtsp/gstrtspurl.h index db9620ec7a..b34ee870fc 100644 --- a/gst-libs/gst/rtsp/gstrtspurl.h +++ b/gst-libs/gst/rtsp/gstrtspurl.h @@ -92,6 +92,8 @@ GstRTSPResult gst_rtsp_url_parse (const gchar *urlstr, GstRTSPUrl GstRTSPUrl* gst_rtsp_url_copy (const GstRTSPUrl *url); void gst_rtsp_url_free (GstRTSPUrl *url); gchar* gst_rtsp_url_get_request_uri (const GstRTSPUrl *url); +gchar** gst_rtsp_url_decode_path_components + (const GstRTSPUrl *url); GstRTSPResult gst_rtsp_url_set_port (GstRTSPUrl *url, guint16 port); GstRTSPResult gst_rtsp_url_get_port (const GstRTSPUrl *url, guint16 *port); diff --git a/tests/check/Makefile.am b/tests/check/Makefile.am index 03387af51f..31c9be1b4d 100644 --- a/tests/check/Makefile.am +++ b/tests/check/Makefile.am @@ -130,6 +130,7 @@ check_PROGRAMS = \ libs/pbutils \ libs/profile \ libs/rtp \ + libs/rtsp \ libs/tag \ libs/video \ $(check_orc) \ @@ -224,6 +225,13 @@ libs_rtp_LDADD = \ $(top_builddir)/gst-libs/gst/rtp/libgstrtp-@GST_MAJORMINOR@.la \ $(GST_BASE_LIBS) $(LDADD) +libs_rtsp_CFLAGS = \ + $(GST_PLUGINS_BASE_CFLAGS) \ + $(AM_CFLAGS) +libs_rtsp_LDADD = \ + $(top_builddir)/gst-libs/gst/rtsp/libgstrtsp-@GST_MAJORMINOR@.la \ + $(GST_BASE_LIBS) $(LDADD) + libs_tag_CFLAGS = \ $(GST_PLUGINS_BASE_CFLAGS) \ $(GST_BASE_CFLAGS) \ diff --git a/tests/check/libs/rtsp.c b/tests/check/libs/rtsp.c new file mode 100644 index 0000000000..fa26eead7a --- /dev/null +++ b/tests/check/libs/rtsp.c @@ -0,0 +1,150 @@ +/* GStreamer unit tests for the RTSP support library + * + * Copyright (C) 2010 Andy Wingo + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include + +#include +#include + +GST_START_TEST (test_rtsp_url_basic) +{ + GstRTSPUrl *url = NULL; + GstRTSPResult res; + + res = gst_rtsp_url_parse ("rtsp://localhost/foo/bar", &url); + fail_unless (res == GST_RTSP_OK); + fail_unless (url != NULL); + fail_unless (url->transports & GST_RTSP_LOWER_TRANS_TCP); + fail_unless (url->transports & GST_RTSP_LOWER_TRANS_UDP); + fail_unless (url->transports & GST_RTSP_LOWER_TRANS_UDP_MCAST); + fail_unless (url->family == GST_RTSP_FAM_INET); + fail_unless (!url->user); + fail_unless (!url->passwd); + fail_unless (!strcmp (url->host, "localhost")); + /* fail_unless (url->port == GST_RTSP_DEFAULT_PORT); */ + fail_unless (!strcmp (url->abspath, "/foo/bar")); + fail_unless (!url->query); + + gst_rtsp_url_free (url); +} + +GST_END_TEST; + +GST_START_TEST (test_rtsp_url_components_1) +{ + GstRTSPUrl *url = NULL; + GstRTSPResult res; + gchar **comps = NULL; + + res = gst_rtsp_url_parse ("rtsp://localhost/foo/bar", &url); + fail_unless (res == GST_RTSP_OK); + fail_unless (url != NULL); + + comps = gst_rtsp_url_decode_path_components (url); + fail_unless (comps != NULL); + fail_unless (g_strv_length (comps) == 3); + fail_unless (!strcmp (comps[0], "")); + fail_unless (!strcmp (comps[1], "foo")); + fail_unless (!strcmp (comps[2], "bar")); + + gst_rtsp_url_free (url); +} + +GST_END_TEST; + +GST_START_TEST (test_rtsp_url_components_2) +{ + GstRTSPUrl *url = NULL; + GstRTSPResult res; + gchar **comps = NULL; + + res = gst_rtsp_url_parse ("rtsp://localhost/foo%2Fbar/qux%20baz", &url); + fail_unless (res == GST_RTSP_OK); + fail_unless (url != NULL); + + comps = gst_rtsp_url_decode_path_components (url); + fail_unless (comps != NULL); + fail_unless (g_strv_length (comps) == 3); + fail_unless (!strcmp (comps[0], "")); + fail_unless (!strcmp (comps[1], "foo/bar")); + fail_unless (!strcmp (comps[2], "qux baz")); + + gst_rtsp_url_free (url); +} + +GST_END_TEST; + +GST_START_TEST (test_rtsp_url_components_3) +{ + GstRTSPUrl *url = NULL; + GstRTSPResult res; + gchar **comps = NULL; + + res = gst_rtsp_url_parse ("rtsp://localhost/foo%00bar/qux%20baz", &url); + fail_unless (res == GST_RTSP_OK); + fail_unless (url != NULL); + + comps = gst_rtsp_url_decode_path_components (url); + fail_unless (comps != NULL); + fail_unless (g_strv_length (comps) == 3); + fail_unless (!strcmp (comps[0], "")); + fail_unless (!strcmp (comps[1], "foo%00bar")); + fail_unless (!strcmp (comps[2], "qux baz")); + + gst_rtsp_url_free (url); +} + +GST_END_TEST; + +static Suite * +rtsp_suite (void) +{ + Suite *s = suite_create ("rtsp support library"); + TCase *tc_chain = tcase_create ("general"); + + suite_add_tcase (s, tc_chain); + tcase_add_test (tc_chain, test_rtsp_url_basic); + tcase_add_test (tc_chain, test_rtsp_url_components_1); + tcase_add_test (tc_chain, test_rtsp_url_components_2); + tcase_add_test (tc_chain, test_rtsp_url_components_3); + + return s; +} + +int +main (int argc, char **argv) +{ + int nf; + + Suite *s = rtsp_suite (); + SRunner *sr = srunner_create (s); + + gst_check_init (&argc, &argv); + + srunner_run_all (sr, CK_NORMAL); + nf = srunner_ntests_failed (sr); + srunner_free (sr); + + return nf; +} From f0ece95fa34a1a2e3271bc9bc39de7e78d34bd85 Mon Sep 17 00:00:00 2001 From: Stefan Kost Date: Wed, 15 Dec 2010 23:47:29 +0200 Subject: [PATCH 036/254] win32: update the def file with the new rtsp api --- win32/common/libgstrtsp.def | 1 + 1 file changed, 1 insertion(+) diff --git a/win32/common/libgstrtsp.def b/win32/common/libgstrtsp.def index 1b904cb697..5327c5b8cf 100644 --- a/win32/common/libgstrtsp.def +++ b/win32/common/libgstrtsp.def @@ -93,6 +93,7 @@ EXPORTS gst_rtsp_transport_new gst_rtsp_transport_parse gst_rtsp_url_copy + gst_rtsp_url_decode_path_components gst_rtsp_url_free gst_rtsp_url_get_port gst_rtsp_url_get_request_uri From 32f28f476e2e950fc528bb37ca9fb541b83039b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= Date: Thu, 16 Dec 2010 10:11:43 +0100 Subject: [PATCH 037/254] videoscale: Change classification to Filter/Converter/Video/Scaler --- gst/videoscale/gstvideoscale.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gst/videoscale/gstvideoscale.c b/gst/videoscale/gstvideoscale.c index b0f8f436b8..af5ea8db5f 100644 --- a/gst/videoscale/gstvideoscale.c +++ b/gst/videoscale/gstvideoscale.c @@ -219,7 +219,7 @@ gst_video_scale_base_init (gpointer g_class) GstElementClass *element_class = GST_ELEMENT_CLASS (g_class); gst_element_class_set_details_simple (element_class, - "Video scaler", "Filter/Effect/Video", + "Video scaler", "Filter/Converter/Video/Scaler", "Resizes video", "Wim Taymans "); gst_element_class_add_pad_template (element_class, From 270bac8158be27d843d00c94dd7873723417e069 Mon Sep 17 00:00:00 2001 From: Vincent Penquerc'h Date: Thu, 16 Dec 2010 10:26:43 +0000 Subject: [PATCH 038/254] timeoverlay: add missing break https://bugzilla.gnome.org/show_bug.cgi?id=637377 --- ext/pango/gsttextoverlay.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/ext/pango/gsttextoverlay.c b/ext/pango/gsttextoverlay.c index 0dd8a102d1..fa9cf8fd07 100644 --- a/ext/pango/gsttextoverlay.c +++ b/ext/pango/gsttextoverlay.c @@ -848,10 +848,9 @@ gst_text_overlay_set_property (GObject * object, guint prop_id, overlay->wait_text = g_value_get_boolean (value); break; case PROP_AUTO_ADJUST_SIZE: - { overlay->auto_adjust_size = g_value_get_boolean (value); overlay->need_render = TRUE; - } + break; case PROP_VERTICAL_RENDER: overlay->use_vertical_render = g_value_get_boolean (value); gst_text_overlay_update_render_mode (overlay); From b4cd3329a96b934c227b76c6dec955190a4dc3d8 Mon Sep 17 00:00:00 2001 From: Leo Singer Date: Thu, 16 Dec 2010 20:09:58 -0800 Subject: [PATCH 039/254] Revert "Revert "audioresample: Add GAP flag support"" This reverts commit 35c76b3409dde7f2dcc8232388a47a1b99b661a7. Conflicts: gst/audioresample/gstaudioresample.c gst/audioresample/gstaudioresample.h --- gst/audioresample/gstaudioresample.c | 202 +++++++++++++++----- gst/audioresample/gstaudioresample.h | 3 + gst/audioresample/resample.c | 6 + gst/audioresample/speex_resampler.h | 6 + gst/audioresample/speex_resampler_wrapper.h | 7 + 5 files changed, 172 insertions(+), 52 deletions(-) diff --git a/gst/audioresample/gstaudioresample.c b/gst/audioresample/gstaudioresample.c index 42597e45c8..a1da42f34d 100644 --- a/gst/audioresample/gstaudioresample.c +++ b/gst/audioresample/gstaudioresample.c @@ -224,6 +224,7 @@ gst_audio_resample_init (GstAudioResample * resample, resample->quality = SPEEX_RESAMPLER_QUALITY_DEFAULT; + gst_base_transform_set_gap_aware (trans, TRUE); gst_pad_set_query_function (trans->srcpad, gst_audio_resample_query); gst_pad_set_query_type_function (trans->srcpad, gst_audio_resample_query_type); @@ -237,6 +238,8 @@ gst_audio_resample_start (GstBaseTransform * base) resample->need_discont = TRUE; + resample->count_gap = 0; + resample->count_nongap = 0; resample->t0 = GST_CLOCK_TIME_NONE; resample->in_offset0 = GST_BUFFER_OFFSET_NONE; resample->out_offset0 = GST_BUFFER_OFFSET_NONE; @@ -386,8 +389,6 @@ gst_audio_resample_init_state (GstAudioResample * resample, gint width, return NULL; } - funcs->skip_zeros (ret); - return ret; } @@ -781,18 +782,48 @@ gst_audio_resample_workspace_realloc (guint8 ** workspace, guint * size, return *workspace; } +/* Push history_len zeros into the filter, but discard the output. */ static void -gst_audio_resample_push_drain (GstAudioResample * resample) +gst_audio_resample_dump_drain (GstAudioResample * resample, guint history_len) +{ + gint outsize; + guint in_len, in_processed; + guint out_len, out_processed; + guint num, den; + void *buf; + + g_assert (resample->state != NULL); + + resample->funcs->get_ratio (resample->state, &num, &den); + + in_len = in_processed = history_len; + out_processed = out_len = + gst_util_uint64_scale_int_ceil (history_len, den, num); + outsize = out_len * resample->channels * (resample->funcs->width / 8); + + if (out_len == 0) + return; + + buf = g_malloc (outsize); + resample->funcs->process (resample->state, NULL, &in_processed, buf, + &out_processed); + g_free (buf); + + g_assert (in_len == in_processed); +} + +static void +gst_audio_resample_push_drain (GstAudioResample * resample, guint history_len) { GstBuffer *outbuf; GstFlowReturn res; gint outsize; - guint history_len, out_len, out_processed; + guint in_len, in_processed; + guint out_len, out_processed; gint err; guint num, den; - if (!resample->state) - return; + g_assert (resample->state != NULL); /* Don't drain samples if we were reset. */ if (!GST_CLOCK_TIME_IS_VALID (resample->t0)) @@ -800,11 +831,14 @@ gst_audio_resample_push_drain (GstAudioResample * resample) resample->funcs->get_ratio (resample->state, &num, &den); - history_len = resample->funcs->get_input_latency (resample->state); + in_len = in_processed = history_len; out_len = out_processed = gst_util_uint64_scale_int_ceil (history_len, den, num); outsize = out_len * resample->channels * (resample->width / 8); + if (out_len == 0) + return; + res = gst_pad_alloc_buffer_and_set_caps (GST_BASE_TRANSFORM_SRC_PAD (resample), GST_BUFFER_OFFSET_NONE, outsize, @@ -825,7 +859,7 @@ gst_audio_resample_push_drain (GstAudioResample * resample) } /* process */ - err = resample->funcs->process (resample->state, NULL, &history_len, + err = resample->funcs->process (resample->state, NULL, &in_processed, resample->tmp_out, &out_processed); /* convert output format */ @@ -833,7 +867,7 @@ gst_audio_resample_push_drain (GstAudioResample * resample) GST_BUFFER_DATA (outbuf), out_processed, TRUE); } else { /* don't need to convert data format; process */ - err = resample->funcs->process (resample->state, NULL, &history_len, + err = resample->funcs->process (resample->state, NULL, &in_processed, GST_BUFFER_DATA (outbuf), &out_processed); } @@ -848,12 +882,6 @@ gst_audio_resample_push_drain (GstAudioResample * resample) return; } - if (G_UNLIKELY (out_processed == 0)) { - GST_WARNING_OBJECT (resample, "Failed to get drain, dropping buffer"); - gst_buffer_unref (outbuf); - return; - } - /* time */ if (GST_CLOCK_TIME_IS_VALID (resample->t0)) { GST_BUFFER_TIMESTAMP (outbuf) = resample->t0 + @@ -876,7 +904,13 @@ gst_audio_resample_push_drain (GstAudioResample * resample) } /* move along */ resample->samples_out += out_processed; - resample->samples_in += 0; + resample->samples_in += history_len; + + if (G_UNLIKELY (out_processed == 0 && in_len * den > num)) { + GST_WARNING_OBJECT (resample, "Failed to get drain, dropping buffer"); + gst_buffer_unref (outbuf); + return; + } GST_BUFFER_SIZE (outbuf) = out_processed * resample->channels * (resample->width / 8); @@ -906,6 +940,11 @@ gst_audio_resample_event (GstBaseTransform * base, GstEvent * event) switch (GST_EVENT_TYPE (event)) { case GST_EVENT_FLUSH_STOP: gst_audio_resample_reset_state (resample); + if (resample->state) + resample->count_gap = resample->funcs->get_filt_len (resample->state); + else + resample->count_gap = 0; + resample->count_nongap = 0; resample->t0 = GST_CLOCK_TIME_NONE; resample->in_offset0 = GST_BUFFER_OFFSET_NONE; resample->out_offset0 = GST_BUFFER_OFFSET_NONE; @@ -914,8 +953,14 @@ gst_audio_resample_event (GstBaseTransform * base, GstEvent * event) resample->need_discont = TRUE; break; case GST_EVENT_NEWSEGMENT: - gst_audio_resample_push_drain (resample); + if (resample->state) + gst_audio_resample_push_drain (resample, resample->count_nongap); gst_audio_resample_reset_state (resample); + if (resample->state) + resample->count_gap = resample->funcs->get_filt_len (resample->state); + else + resample->count_gap = 0; + resample->count_nongap = 0; resample->t0 = GST_CLOCK_TIME_NONE; resample->in_offset0 = GST_BUFFER_OFFSET_NONE; resample->out_offset0 = GST_BUFFER_OFFSET_NONE; @@ -924,7 +969,8 @@ gst_audio_resample_event (GstBaseTransform * base, GstEvent * event) resample->need_discont = TRUE; break; case GST_EVENT_EOS: - gst_audio_resample_push_drain (resample); + if (resample->state) + gst_audio_resample_push_drain (resample, resample->count_nongap); gst_audio_resample_reset_state (resample); break; default: @@ -939,6 +985,9 @@ gst_audio_resample_check_discont (GstAudioResample * resample, GstBuffer * buf) { guint64 offset; guint64 delta; + guint filt_len = resample->funcs->get_filt_len (resample->state); + guint64 delay = + gst_util_uint64_scale_round (filt_len, GST_SECOND, 2 * resample->inrate); /* is the incoming buffer a discontinuity? */ if (G_UNLIKELY (GST_BUFFER_IS_DISCONT (buf))) @@ -952,7 +1001,7 @@ gst_audio_resample_check_discont (GstAudioResample * resample, GstBuffer * buf) /* convert the inbound timestamp to an offset. */ offset = gst_util_uint64_scale_int_round (GST_BUFFER_TIMESTAMP (buf) - - resample->t0, resample->inrate, GST_SECOND); + resample->t0 - delay, resample->inrate, GST_SECOND); /* many elements generate imperfect streams due to rounding errors, so we * permit a small error (up to one sample) without triggering a filter @@ -977,7 +1026,7 @@ gst_audio_resample_process (GstAudioResample * resample, GstBuffer * inbuf, { guint32 in_len, in_processed; guint32 out_len, out_processed; - gint err; + guint filt_len = resample->funcs->get_filt_len (resample->state); in_len = GST_BUFFER_SIZE (inbuf) / resample->channels; out_len = GST_BUFFER_SIZE (outbuf) / resample->channels; @@ -988,47 +1037,92 @@ gst_audio_resample_process (GstAudioResample * resample, GstBuffer * inbuf, in_processed = in_len; out_processed = out_len; - if (resample->funcs->width != resample->width) { - /* need to convert data format for processing; ensure we have enough - * workspace available */ - if (!gst_audio_resample_workspace_realloc (&resample->tmp_in, - &resample->tmp_in_size, in_len * resample->channels * - (resample->funcs->width / 8)) || - !gst_audio_resample_workspace_realloc (&resample->tmp_out, - &resample->tmp_out_size, out_len * resample->channels * - (resample->funcs->width / 8))) { - GST_ERROR_OBJECT (resample, "failed to allocate workspace"); - return GST_FLOW_ERROR; + if (GST_BUFFER_FLAG_IS_SET (inbuf, GST_BUFFER_FLAG_GAP)) { + resample->count_nongap = 0; + if (resample->count_gap < filt_len) { + guint zeros_to_push; + if (in_len >= filt_len - resample->count_gap) + zeros_to_push = filt_len - resample->count_gap; + else + zeros_to_push = in_len; + + gst_audio_resample_push_drain (resample, zeros_to_push); + in_len -= zeros_to_push; + resample->count_gap += zeros_to_push; } - /* convert input */ - gst_audio_resample_convert_buffer (resample, GST_BUFFER_DATA (inbuf), - resample->tmp_in, in_len, FALSE); + { + guint num, den; + resample->funcs->get_ratio (resample->state, &num, &den); + out_processed = + gst_util_uint64_scale_int_ceil (resample->samples_in + in_len, den, + num) - resample->samples_out; - /* process */ - err = resample->funcs->process (resample->state, - resample->tmp_in, &in_processed, resample->tmp_out, &out_processed); + memset (GST_BUFFER_DATA (outbuf), 0, GST_BUFFER_SIZE (outbuf)); + GST_BUFFER_FLAG_SET (outbuf, GST_BUFFER_FLAG_GAP); + resample->count_gap += in_len; + in_processed = in_len; + } + } else { /* not a gap */ - /* convert output */ - gst_audio_resample_convert_buffer (resample, resample->tmp_out, - GST_BUFFER_DATA (outbuf), out_processed, TRUE); - } else { - /* no format conversion required; process */ - err = resample->funcs->process (resample->state, - GST_BUFFER_DATA (inbuf), &in_processed, - GST_BUFFER_DATA (outbuf), &out_processed); + gint err; + + if (resample->count_gap > filt_len) { + /* push in enough zeros to restore the filter to the right offset */ + guint num, den; + resample->funcs->get_ratio (resample->state, &num, &den); + gst_audio_resample_dump_drain (resample, + (resample->count_gap - filt_len) % num); + } + resample->count_gap = 0; + if (resample->count_nongap < filt_len) { + resample->count_nongap += in_len; + if (resample->count_nongap > filt_len) + resample->count_nongap = filt_len; + } + + if (resample->funcs->width != resample->width) { + /* need to convert data format for processing; ensure we have enough + * workspace available */ + if (!gst_audio_resample_workspace_realloc (&resample->tmp_in, + &resample->tmp_in_size, in_len * resample->channels * + (resample->funcs->width / 8)) || + !gst_audio_resample_workspace_realloc (&resample->tmp_out, + &resample->tmp_out_size, out_len * resample->channels * + (resample->funcs->width / 8))) { + GST_ERROR_OBJECT (resample, "failed to allocate workspace"); + return GST_FLOW_ERROR; + } + + /* convert input */ + gst_audio_resample_convert_buffer (resample, GST_BUFFER_DATA (inbuf), + resample->tmp_in, in_len, FALSE); + + /* process */ + err = resample->funcs->process (resample->state, + resample->tmp_in, &in_processed, resample->tmp_out, &out_processed); + + /* convert output */ + gst_audio_resample_convert_buffer (resample, resample->tmp_out, + GST_BUFFER_DATA (outbuf), out_processed, TRUE); + } else { + /* no format conversion required; process */ + err = resample->funcs->process (resample->state, + GST_BUFFER_DATA (inbuf), &in_processed, + GST_BUFFER_DATA (outbuf), &out_processed); + } + + if (G_UNLIKELY (err != RESAMPLER_ERR_SUCCESS)) { + GST_ERROR_OBJECT (resample, "Failed to convert data: %s", + resample->funcs->strerror (err)); + return GST_FLOW_ERROR; + } } /* If we wrote more than allocated something is really wrong now and we * should better abort immediately */ g_assert (out_len >= out_processed); - if (G_UNLIKELY (err != RESAMPLER_ERR_SUCCESS)) { - GST_ERROR_OBJECT (resample, "Failed to convert data: %s", - resample->funcs->strerror (err)); - return GST_FLOW_ERROR; - } - if (G_UNLIKELY (in_len != in_processed)) { GST_WARNING_OBJECT (resample, "converted %d of %d input samples", in_processed, in_len); @@ -1115,13 +1209,17 @@ gst_audio_resample_transform (GstBaseTransform * base, GstBuffer * inbuf, /* handle discontinuity */ if (G_UNLIKELY (resample->need_discont)) { + guint filt_len = resample->funcs->get_filt_len (resample->state); + guint64 delay = gst_util_uint64_scale_round (filt_len, GST_SECOND, + 2 * resample->inrate); + resample->count_gap = resample->funcs->get_filt_len (resample->state); /* reset */ resample->samples_in = 0; resample->samples_out = 0; GST_DEBUG_OBJECT (resample, "found discontinuity; resyncing"); /* resync the timestamp and offset counters if possible */ if (GST_BUFFER_TIMESTAMP_IS_VALID (inbuf)) { - resample->t0 = GST_BUFFER_TIMESTAMP (inbuf); + resample->t0 = GST_BUFFER_TIMESTAMP (inbuf) - delay; } else { GST_DEBUG_OBJECT (resample, "... but new timestamp is invalid"); resample->t0 = GST_CLOCK_TIME_NONE; diff --git a/gst/audioresample/gstaudioresample.h b/gst/audioresample/gstaudioresample.h index b0733365b1..fdf3e06f05 100644 --- a/gst/audioresample/gstaudioresample.h +++ b/gst/audioresample/gstaudioresample.h @@ -63,6 +63,9 @@ struct _GstAudioResample { guint64 out_offset0; guint64 samples_in; guint64 samples_out; + + guint count_gap; + guint count_nongap; gint channels; gint inrate; diff --git a/gst/audioresample/resample.c b/gst/audioresample/resample.c index 2cfd5442e3..7d42f0e0fd 100644 --- a/gst/audioresample/resample.c +++ b/gst/audioresample/resample.c @@ -1310,6 +1310,12 @@ speex_resampler_get_output_latency (SpeexResamplerState * st) (st->num_rate >> 1)) / st->num_rate; } +EXPORT int +speex_resampler_get_filt_len (SpeexResamplerState * st) +{ + return st->filt_len; +} + EXPORT int speex_resampler_skip_zeros (SpeexResamplerState * st) { diff --git a/gst/audioresample/speex_resampler.h b/gst/audioresample/speex_resampler.h index 9dc02806a6..894b380f80 100644 --- a/gst/audioresample/speex_resampler.h +++ b/gst/audioresample/speex_resampler.h @@ -73,6 +73,7 @@ #define speex_resampler_get_output_stride CAT_PREFIX(RANDOM_PREFIX,_resampler_get_output_stride) #define speex_resampler_get_input_latency CAT_PREFIX(RANDOM_PREFIX,_resampler_get_input_latency) #define speex_resampler_get_output_latency CAT_PREFIX(RANDOM_PREFIX,_resampler_get_output_latency) +#define speex_resampler_get_filt_len CAT_PREFIX(RANDOM_PREFIX,_resampler_get_filt_len) #define speex_resampler_skip_zeros CAT_PREFIX(RANDOM_PREFIX,_resampler_skip_zeros) #define speex_resampler_reset_mem CAT_PREFIX(RANDOM_PREFIX,_resampler_reset_mem) #define speex_resampler_strerror CAT_PREFIX(RANDOM_PREFIX,_resampler_strerror) @@ -333,6 +334,11 @@ int speex_resampler_get_input_latency(SpeexResamplerState *st); */ int speex_resampler_get_output_latency(SpeexResamplerState *st); +/** Get the length of the filter in input samples. + * @param st Resampler state + */ +int speex_resampler_get_filt_len(SpeexResamplerState *st); + /** Make sure that the first samples to go out of the resamplers don't have * leading zeros. This is only useful before starting to use a newly created * resampler. It is recommended to use that when resampling an audio file, as diff --git a/gst/audioresample/speex_resampler_wrapper.h b/gst/audioresample/speex_resampler_wrapper.h index 36d444f879..08a82bc105 100644 --- a/gst/audioresample/speex_resampler_wrapper.h +++ b/gst/audioresample/speex_resampler_wrapper.h @@ -52,6 +52,7 @@ typedef struct { void (*get_ratio) (SpeexResamplerState * st, guint32 * ratio_num, guint32 * ratio_den); int (*get_input_latency) (SpeexResamplerState * st); + int (*get_filt_len) (SpeexResamplerState * st); int (*set_quality) (SpeexResamplerState * st, gint quality); int (*reset_mem) (SpeexResamplerState * st); int (*skip_zeros) (SpeexResamplerState * st); @@ -71,6 +72,7 @@ void resample_float_resampler_get_rate (SpeexResamplerState * st, void resample_float_resampler_get_ratio (SpeexResamplerState * st, guint32 * ratio_num, guint32 * ratio_den); int resample_float_resampler_get_input_latency (SpeexResamplerState * st); +int resample_float_resampler_get_filt_len (SpeexResamplerState * st); int resample_float_resampler_set_quality (SpeexResamplerState * st, gint quality); int resample_float_resampler_reset_mem (SpeexResamplerState * st); int resample_float_resampler_skip_zeros (SpeexResamplerState * st); @@ -85,6 +87,7 @@ static const SpeexResampleFuncs float_funcs = resample_float_resampler_get_rate, resample_float_resampler_get_ratio, resample_float_resampler_get_input_latency, + resample_float_resampler_get_filt_len, resample_float_resampler_set_quality, resample_float_resampler_reset_mem, resample_float_resampler_skip_zeros, @@ -104,6 +107,7 @@ void resample_double_resampler_get_rate (SpeexResamplerState * st, void resample_double_resampler_get_ratio (SpeexResamplerState * st, guint32 * ratio_num, guint32 * ratio_den); int resample_double_resampler_get_input_latency (SpeexResamplerState * st); +int resample_double_resampler_get_filt_len (SpeexResamplerState * st); int resample_double_resampler_set_quality (SpeexResamplerState * st, gint quality); int resample_double_resampler_reset_mem (SpeexResamplerState * st); int resample_double_resampler_skip_zeros (SpeexResamplerState * st); @@ -118,6 +122,7 @@ static const SpeexResampleFuncs double_funcs = resample_double_resampler_get_rate, resample_double_resampler_get_ratio, resample_double_resampler_get_input_latency, + resample_double_resampler_get_filt_len, resample_double_resampler_set_quality, resample_double_resampler_reset_mem, resample_double_resampler_skip_zeros, @@ -137,6 +142,7 @@ void resample_int_resampler_get_rate (SpeexResamplerState * st, void resample_int_resampler_get_ratio (SpeexResamplerState * st, guint32 * ratio_num, guint32 * ratio_den); int resample_int_resampler_get_input_latency (SpeexResamplerState * st); +int resample_int_resampler_get_filt_len (SpeexResamplerState * st); int resample_int_resampler_set_quality (SpeexResamplerState * st, gint quality); int resample_int_resampler_reset_mem (SpeexResamplerState * st); int resample_int_resampler_skip_zeros (SpeexResamplerState * st); @@ -151,6 +157,7 @@ static const SpeexResampleFuncs int_funcs = resample_int_resampler_get_rate, resample_int_resampler_get_ratio, resample_int_resampler_get_input_latency, + resample_int_resampler_get_filt_len, resample_int_resampler_set_quality, resample_int_resampler_reset_mem, resample_int_resampler_skip_zeros, From 87f242273700bfb4ea183056749c73dd9f372e8a Mon Sep 17 00:00:00 2001 From: Leo Singer Date: Thu, 16 Dec 2010 20:30:24 -0800 Subject: [PATCH 040/254] audioresample: initial filter transient discarded; unit tests passing --- gst/audioresample/gstaudioresample.c | 35 ++++++++++++++-------------- 1 file changed, 17 insertions(+), 18 deletions(-) diff --git a/gst/audioresample/gstaudioresample.c b/gst/audioresample/gstaudioresample.c index a1da42f34d..d1b557336a 100644 --- a/gst/audioresample/gstaudioresample.c +++ b/gst/audioresample/gstaudioresample.c @@ -389,6 +389,8 @@ gst_audio_resample_init_state (GstAudioResample * resample, gint width, return NULL; } + funcs->skip_zeros (ret); + return ret; } @@ -941,9 +943,8 @@ gst_audio_resample_event (GstBaseTransform * base, GstEvent * event) case GST_EVENT_FLUSH_STOP: gst_audio_resample_reset_state (resample); if (resample->state) - resample->count_gap = resample->funcs->get_filt_len (resample->state); - else - resample->count_gap = 0; + resample->funcs->skip_zeros (resample->state); + resample->count_gap = 0; resample->count_nongap = 0; resample->t0 = GST_CLOCK_TIME_NONE; resample->in_offset0 = GST_BUFFER_OFFSET_NONE; @@ -957,9 +958,8 @@ gst_audio_resample_event (GstBaseTransform * base, GstEvent * event) gst_audio_resample_push_drain (resample, resample->count_nongap); gst_audio_resample_reset_state (resample); if (resample->state) - resample->count_gap = resample->funcs->get_filt_len (resample->state); - else - resample->count_gap = 0; + resample->funcs->skip_zeros (resample->state); + resample->count_gap = 0; resample->count_nongap = 0; resample->t0 = GST_CLOCK_TIME_NONE; resample->in_offset0 = GST_BUFFER_OFFSET_NONE; @@ -985,9 +985,6 @@ gst_audio_resample_check_discont (GstAudioResample * resample, GstBuffer * buf) { guint64 offset; guint64 delta; - guint filt_len = resample->funcs->get_filt_len (resample->state); - guint64 delay = - gst_util_uint64_scale_round (filt_len, GST_SECOND, 2 * resample->inrate); /* is the incoming buffer a discontinuity? */ if (G_UNLIKELY (GST_BUFFER_IS_DISCONT (buf))) @@ -1001,7 +998,7 @@ gst_audio_resample_check_discont (GstAudioResample * resample, GstBuffer * buf) /* convert the inbound timestamp to an offset. */ offset = gst_util_uint64_scale_int_round (GST_BUFFER_TIMESTAMP (buf) - - resample->t0 - delay, resample->inrate, GST_SECOND); + resample->t0, resample->inrate, GST_SECOND); /* many elements generate imperfect streams due to rounding errors, so we * permit a small error (up to one sample) without triggering a filter @@ -1054,9 +1051,12 @@ gst_audio_resample_process (GstAudioResample * resample, GstBuffer * inbuf, { guint num, den; resample->funcs->get_ratio (resample->state, &num, &den); - out_processed = - gst_util_uint64_scale_int_ceil (resample->samples_in + in_len, den, - num) - resample->samples_out; + if (resample->samples_in + in_len >= filt_len / 2) + out_processed = + gst_util_uint64_scale_int_ceil (resample->samples_in + in_len - + filt_len / 2, den, num) - resample->samples_out; + else + out_processed = 0; memset (GST_BUFFER_DATA (outbuf), 0, GST_BUFFER_SIZE (outbuf)); GST_BUFFER_FLAG_SET (outbuf, GST_BUFFER_FLAG_GAP); @@ -1209,17 +1209,16 @@ gst_audio_resample_transform (GstBaseTransform * base, GstBuffer * inbuf, /* handle discontinuity */ if (G_UNLIKELY (resample->need_discont)) { - guint filt_len = resample->funcs->get_filt_len (resample->state); - guint64 delay = gst_util_uint64_scale_round (filt_len, GST_SECOND, - 2 * resample->inrate); - resample->count_gap = resample->funcs->get_filt_len (resample->state); + resample->funcs->skip_zeros (resample->state); + resample->count_gap = 0; + resample->count_nongap = 0; /* reset */ resample->samples_in = 0; resample->samples_out = 0; GST_DEBUG_OBJECT (resample, "found discontinuity; resyncing"); /* resync the timestamp and offset counters if possible */ if (GST_BUFFER_TIMESTAMP_IS_VALID (inbuf)) { - resample->t0 = GST_BUFFER_TIMESTAMP (inbuf) - delay; + resample->t0 = GST_BUFFER_TIMESTAMP (inbuf); } else { GST_DEBUG_OBJECT (resample, "... but new timestamp is invalid"); resample->t0 = GST_CLOCK_TIME_NONE; From 6832b38527fe7af96029a88d5f579eae10c51ba9 Mon Sep 17 00:00:00 2001 From: Leo Singer Date: Thu, 16 Dec 2010 20:32:07 -0800 Subject: [PATCH 041/254] audioresample: replaced void* with gpointer --- gst/audioresample/gstaudioresample.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gst/audioresample/gstaudioresample.c b/gst/audioresample/gstaudioresample.c index d1b557336a..05f6075f78 100644 --- a/gst/audioresample/gstaudioresample.c +++ b/gst/audioresample/gstaudioresample.c @@ -792,7 +792,7 @@ gst_audio_resample_dump_drain (GstAudioResample * resample, guint history_len) guint in_len, in_processed; guint out_len, out_processed; guint num, den; - void *buf; + gpointer buf; g_assert (resample->state != NULL); From aac8b216787083030dd41fe434e11d21c197bda4 Mon Sep 17 00:00:00 2001 From: Leo Singer Date: Thu, 16 Dec 2010 20:34:13 -0800 Subject: [PATCH 042/254] audioresample: renamed count_gap, count_nongap to more descriptive num_gap_samples, num_nongap_samples --- gst/audioresample/gstaudioresample.c | 46 ++++++++++++++-------------- gst/audioresample/gstaudioresample.h | 4 +-- 2 files changed, 25 insertions(+), 25 deletions(-) diff --git a/gst/audioresample/gstaudioresample.c b/gst/audioresample/gstaudioresample.c index 05f6075f78..8d0bddf223 100644 --- a/gst/audioresample/gstaudioresample.c +++ b/gst/audioresample/gstaudioresample.c @@ -238,8 +238,8 @@ gst_audio_resample_start (GstBaseTransform * base) resample->need_discont = TRUE; - resample->count_gap = 0; - resample->count_nongap = 0; + resample->num_gap_samples = 0; + resample->num_nongap_samples = 0; resample->t0 = GST_CLOCK_TIME_NONE; resample->in_offset0 = GST_BUFFER_OFFSET_NONE; resample->out_offset0 = GST_BUFFER_OFFSET_NONE; @@ -944,8 +944,8 @@ gst_audio_resample_event (GstBaseTransform * base, GstEvent * event) gst_audio_resample_reset_state (resample); if (resample->state) resample->funcs->skip_zeros (resample->state); - resample->count_gap = 0; - resample->count_nongap = 0; + resample->num_gap_samples = 0; + resample->num_nongap_samples = 0; resample->t0 = GST_CLOCK_TIME_NONE; resample->in_offset0 = GST_BUFFER_OFFSET_NONE; resample->out_offset0 = GST_BUFFER_OFFSET_NONE; @@ -955,12 +955,12 @@ gst_audio_resample_event (GstBaseTransform * base, GstEvent * event) break; case GST_EVENT_NEWSEGMENT: if (resample->state) - gst_audio_resample_push_drain (resample, resample->count_nongap); + gst_audio_resample_push_drain (resample, resample->num_nongap_samples); gst_audio_resample_reset_state (resample); if (resample->state) resample->funcs->skip_zeros (resample->state); - resample->count_gap = 0; - resample->count_nongap = 0; + resample->num_gap_samples = 0; + resample->num_nongap_samples = 0; resample->t0 = GST_CLOCK_TIME_NONE; resample->in_offset0 = GST_BUFFER_OFFSET_NONE; resample->out_offset0 = GST_BUFFER_OFFSET_NONE; @@ -970,7 +970,7 @@ gst_audio_resample_event (GstBaseTransform * base, GstEvent * event) break; case GST_EVENT_EOS: if (resample->state) - gst_audio_resample_push_drain (resample, resample->count_nongap); + gst_audio_resample_push_drain (resample, resample->num_nongap_samples); gst_audio_resample_reset_state (resample); break; default: @@ -1035,17 +1035,17 @@ gst_audio_resample_process (GstAudioResample * resample, GstBuffer * inbuf, out_processed = out_len; if (GST_BUFFER_FLAG_IS_SET (inbuf, GST_BUFFER_FLAG_GAP)) { - resample->count_nongap = 0; - if (resample->count_gap < filt_len) { + resample->num_nongap_samples = 0; + if (resample->num_gap_samples < filt_len) { guint zeros_to_push; - if (in_len >= filt_len - resample->count_gap) - zeros_to_push = filt_len - resample->count_gap; + if (in_len >= filt_len - resample->num_gap_samples) + zeros_to_push = filt_len - resample->num_gap_samples; else zeros_to_push = in_len; gst_audio_resample_push_drain (resample, zeros_to_push); in_len -= zeros_to_push; - resample->count_gap += zeros_to_push; + resample->num_gap_samples += zeros_to_push; } { @@ -1060,25 +1060,25 @@ gst_audio_resample_process (GstAudioResample * resample, GstBuffer * inbuf, memset (GST_BUFFER_DATA (outbuf), 0, GST_BUFFER_SIZE (outbuf)); GST_BUFFER_FLAG_SET (outbuf, GST_BUFFER_FLAG_GAP); - resample->count_gap += in_len; + resample->num_gap_samples += in_len; in_processed = in_len; } } else { /* not a gap */ gint err; - if (resample->count_gap > filt_len) { + if (resample->num_gap_samples > filt_len) { /* push in enough zeros to restore the filter to the right offset */ guint num, den; resample->funcs->get_ratio (resample->state, &num, &den); gst_audio_resample_dump_drain (resample, - (resample->count_gap - filt_len) % num); + (resample->num_gap_samples - filt_len) % num); } - resample->count_gap = 0; - if (resample->count_nongap < filt_len) { - resample->count_nongap += in_len; - if (resample->count_nongap > filt_len) - resample->count_nongap = filt_len; + resample->num_gap_samples = 0; + if (resample->num_nongap_samples < filt_len) { + resample->num_nongap_samples += in_len; + if (resample->num_nongap_samples > filt_len) + resample->num_nongap_samples = filt_len; } if (resample->funcs->width != resample->width) { @@ -1210,8 +1210,8 @@ gst_audio_resample_transform (GstBaseTransform * base, GstBuffer * inbuf, /* handle discontinuity */ if (G_UNLIKELY (resample->need_discont)) { resample->funcs->skip_zeros (resample->state); - resample->count_gap = 0; - resample->count_nongap = 0; + resample->num_gap_samples = 0; + resample->num_nongap_samples = 0; /* reset */ resample->samples_in = 0; resample->samples_out = 0; diff --git a/gst/audioresample/gstaudioresample.h b/gst/audioresample/gstaudioresample.h index fdf3e06f05..8ffe4d53e2 100644 --- a/gst/audioresample/gstaudioresample.h +++ b/gst/audioresample/gstaudioresample.h @@ -64,8 +64,8 @@ struct _GstAudioResample { guint64 samples_in; guint64 samples_out; - guint count_gap; - guint count_nongap; + guint num_gap_samples; + guint num_nongap_samples; gint channels; gint inrate; From d6d2aa44ab5c1cb1a0b83d07d3acf56a312d61a1 Mon Sep 17 00:00:00 2001 From: Leo Singer Date: Thu, 16 Dec 2010 20:38:31 -0800 Subject: [PATCH 043/254] audioresample: push half a history length, instead of a full history length, at end-of-stream so that output segment and input segment have same duration --- gst/audioresample/gstaudioresample.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/gst/audioresample/gstaudioresample.c b/gst/audioresample/gstaudioresample.c index 8d0bddf223..a9222a6457 100644 --- a/gst/audioresample/gstaudioresample.c +++ b/gst/audioresample/gstaudioresample.c @@ -954,8 +954,10 @@ gst_audio_resample_event (GstBaseTransform * base, GstEvent * event) resample->need_discont = TRUE; break; case GST_EVENT_NEWSEGMENT: - if (resample->state) - gst_audio_resample_push_drain (resample, resample->num_nongap_samples); + if (resample->state) { + guint latency = resample->funcs->get_input_latency (resample->state); + gst_audio_resample_push_drain (resample, latency); + } gst_audio_resample_reset_state (resample); if (resample->state) resample->funcs->skip_zeros (resample->state); @@ -969,8 +971,10 @@ gst_audio_resample_event (GstBaseTransform * base, GstEvent * event) resample->need_discont = TRUE; break; case GST_EVENT_EOS: - if (resample->state) - gst_audio_resample_push_drain (resample, resample->num_nongap_samples); + if (resample->state) { + guint latency = resample->funcs->get_input_latency (resample->state); + gst_audio_resample_push_drain (resample, latency); + } gst_audio_resample_reset_state (resample); break; default: From 25a154be5f971e86b37c6d4130176d4583625a6d Mon Sep 17 00:00:00 2001 From: Leo Singer Date: Thu, 16 Dec 2010 20:40:33 -0800 Subject: [PATCH 044/254] audioresample: changed num_gap_samples, num_nongap_samples from guint32 to guint64 so that gaps of greater than or equal to 2^32 samples do not cause integer overflow --- gst/audioresample/gstaudioresample.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gst/audioresample/gstaudioresample.h b/gst/audioresample/gstaudioresample.h index 8ffe4d53e2..f5f746482d 100644 --- a/gst/audioresample/gstaudioresample.h +++ b/gst/audioresample/gstaudioresample.h @@ -64,8 +64,8 @@ struct _GstAudioResample { guint64 samples_in; guint64 samples_out; - guint num_gap_samples; - guint num_nongap_samples; + guint64 num_gap_samples; + guint64 num_nongap_samples; gint channels; gint inrate; From 5bfe1baab393d2a0b16329abda1bd1a7f38d4aec Mon Sep 17 00:00:00 2001 From: Leo Singer Date: Fri, 17 Dec 2010 00:49:26 -0800 Subject: [PATCH 045/254] audioresample: corrected buffer duration calculation to account for nonzero initial timestamp Since we calculate timestamps by: timestamp = t0 + (out samples) / (out rate) and durations by: duration = ((out samples) + (processed samples)) / (out rate) - timestamp if t0 is nonzero, this would simplify to duration = t0 + (processed samples) / (out rate). This duration is too large by the amount t0. We should have done: duration = t0 + ((out samples) + (processed samples)) / (out rate) - timestamp so that duration = (processed samples) / (out rate). --- gst/audioresample/gstaudioresample.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gst/audioresample/gstaudioresample.c b/gst/audioresample/gstaudioresample.c index a9222a6457..90967c2671 100644 --- a/gst/audioresample/gstaudioresample.c +++ b/gst/audioresample/gstaudioresample.c @@ -889,7 +889,7 @@ gst_audio_resample_push_drain (GstAudioResample * resample, guint history_len) GST_BUFFER_TIMESTAMP (outbuf) = resample->t0 + gst_util_uint64_scale_int_round (resample->samples_out, GST_SECOND, resample->outrate); - GST_BUFFER_DURATION (outbuf) = + GST_BUFFER_DURATION (outbuf) = resample->t0 + gst_util_uint64_scale_int_round (resample->samples_out + out_processed, GST_SECOND, resample->outrate) - GST_BUFFER_TIMESTAMP (outbuf); } else { @@ -1137,7 +1137,7 @@ gst_audio_resample_process (GstAudioResample * resample, GstBuffer * inbuf, GST_BUFFER_TIMESTAMP (outbuf) = resample->t0 + gst_util_uint64_scale_int_round (resample->samples_out, GST_SECOND, resample->outrate); - GST_BUFFER_DURATION (outbuf) = + GST_BUFFER_DURATION (outbuf) = resample->t0 + gst_util_uint64_scale_int_round (resample->samples_out + out_processed, GST_SECOND, resample->outrate) - GST_BUFFER_TIMESTAMP (outbuf); } else { From aa07af41f30cab25bb8b4bc6faa5d9b958306058 Mon Sep 17 00:00:00 2001 From: Rob Clark Date: Fri, 17 Dec 2010 19:06:27 -0600 Subject: [PATCH 046/254] fix compile errors on macosx with i686-apple-darwin10-gcc-4.2.1: encoding-profile.h:134: warning: type qualifiers ignored on function return type encoding-profile.c:240: warning: type qualifiers ignored on function return type gstencodebin.c: In function 'next_unused_stream_profile': gstencodebin.c:454: warning: format '%d' expects type 'int', but argument 8 has type 'GType' gstencodebin.c:464: warning: format '%d' expects type 'int', but argument 8 has type 'GType' --- gst-libs/gst/pbutils/encoding-profile.c | 2 +- gst-libs/gst/pbutils/encoding-profile.h | 2 +- gst/encoding/gstencodebin.c | 6 ++++-- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/gst-libs/gst/pbutils/encoding-profile.c b/gst-libs/gst/pbutils/encoding-profile.c index 8c364c8878..03be1317c5 100644 --- a/gst-libs/gst/pbutils/encoding-profile.c +++ b/gst-libs/gst/pbutils/encoding-profile.c @@ -235,7 +235,7 @@ gst_encoding_profile_get_preset (GstEncodingProfile * profile) * Returns: The number of time the profile is used in its parent * container profile. If 0, it is not a mandatory stream */ -const guint +guint gst_encoding_profile_get_presence (GstEncodingProfile * profile) { return profile->presence; diff --git a/gst-libs/gst/pbutils/encoding-profile.h b/gst-libs/gst/pbutils/encoding-profile.h index 3c6f3c3d37..f455a607ce 100644 --- a/gst-libs/gst/pbutils/encoding-profile.h +++ b/gst-libs/gst/pbutils/encoding-profile.h @@ -131,7 +131,7 @@ const gchar * gst_encoding_profile_get_name(GstEncodingProfile *profile); const gchar * gst_encoding_profile_get_description(GstEncodingProfile *profile); const GstCaps * gst_encoding_profile_get_format(GstEncodingProfile *profile); const gchar * gst_encoding_profile_get_preset(GstEncodingProfile *profile); -const guint gst_encoding_profile_get_presence(GstEncodingProfile *profile); +guint gst_encoding_profile_get_presence(GstEncodingProfile *profile); const GstCaps * gst_encoding_profile_get_restriction(GstEncodingProfile *profile); void gst_encoding_profile_set_name(GstEncodingProfile *profile, const gchar *name); diff --git a/gst/encoding/gstencodebin.c b/gst/encoding/gstencodebin.c index 3ba5a403dd..4a126202b1 100644 --- a/gst/encoding/gstencodebin.c +++ b/gst/encoding/gstencodebin.c @@ -451,7 +451,8 @@ stream_profile_used_count (GstEncodeBin * ebin, GstEncodingProfile * sprof) static inline GstEncodingProfile * next_unused_stream_profile (GstEncodeBin * ebin, GType ptype, GstCaps * caps) { - GST_DEBUG_OBJECT (ebin, "ptype:%d, caps:%" GST_PTR_FORMAT, ptype, caps); + GST_DEBUG_OBJECT (ebin, "ptype:%s, caps:%" GST_PTR_FORMAT, + g_type_name (ptype), caps); if (G_UNLIKELY (ptype == G_TYPE_NONE && caps != NULL)) { /* Identify the profile type based on raw caps */ @@ -461,7 +462,8 @@ next_unused_stream_profile (GstEncodeBin * ebin, GType ptype, GstCaps * caps) ptype = GST_TYPE_ENCODING_AUDIO_PROFILE; /* else if (gst_caps_can_intersect (ebin->raw_text_caps, caps)) */ /* ptype = GST_TYPE_ENCODING_TEXT_PROFILE; */ - GST_DEBUG_OBJECT (ebin, "Detected profile type as being %d", ptype); + GST_DEBUG_OBJECT (ebin, "Detected profile type as being %s", + g_type_name (ptype)); } if (GST_IS_ENCODING_CONTAINER_PROFILE (ebin->profile)) { From 22aa87e98fd931840a3a1e45e1d0a6a23564e214 Mon Sep 17 00:00:00 2001 From: Vincent Penquerc'h Date: Fri, 17 Dec 2010 14:16:18 +0000 Subject: [PATCH 047/254] ogg: implement packet duration query for kate streams https://bugzilla.gnome.org/show_bug.cgi?id=637519 --- ext/ogg/gstoggdemux.c | 7 ++++++- ext/ogg/gstoggstream.c | 28 +++++++++++++++++++++++++++- 2 files changed, 33 insertions(+), 2 deletions(-) diff --git a/ext/ogg/gstoggdemux.c b/ext/ogg/gstoggdemux.c index df470f9b1e..8da7288e7f 100644 --- a/ext/ogg/gstoggdemux.c +++ b/ext/ogg/gstoggdemux.c @@ -540,7 +540,12 @@ gst_ogg_demux_chain_peer (GstOggPad * pad, ogg_packet * packet, } else if (pad->map.is_sparse) { out_timestamp = gst_ogg_stream_granule_to_time (&pad->map, pad->current_granule); - out_duration = GST_CLOCK_TIME_NONE; + if (duration == GST_CLOCK_TIME_NONE) { + out_duration = GST_CLOCK_TIME_NONE; + } else { + out_duration = gst_util_uint64_scale (duration, + GST_SECOND * pad->map.granulerate_d, pad->map.granulerate_n); + } } else { out_timestamp = gst_ogg_stream_granule_to_time (&pad->map, pad->current_granule - duration); diff --git a/ext/ogg/gstoggstream.c b/ext/ogg/gstoggstream.c index eeaf4b9b50..f8ba6c09f7 100644 --- a/ext/ogg/gstoggstream.c +++ b/ext/ogg/gstoggstream.c @@ -1732,6 +1732,32 @@ setup_kate_mapper (GstOggStream * pad, ogg_packet * packet) return TRUE; } +static gint64 +packet_duration_kate (GstOggStream * pad, ogg_packet * packet) +{ + gint64 duration; + + if (packet->bytes < 1) + return 0; + + switch (packet->packet[0]) { + case 0x00: /* text data */ + if (packet->bytes < 1 + 8 * 2) { + duration = 0; + } else { + duration = GST_READ_UINT64_LE (packet->packet + 1 + 8); + if (duration < 0) + duration = 0; + } + break; + default: + duration = GST_CLOCK_TIME_NONE; + break; + } + + return duration; +} + /* *INDENT-OFF* */ /* indent hates our freedoms */ @@ -1875,7 +1901,7 @@ const GstOggMap mappers[] = { granule_to_granulepos_default, NULL, is_header_count, - NULL, + packet_duration_kate, NULL, NULL }, From c23c706dce96554eef20062554403fc7aac65b02 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= Date: Sat, 18 Dec 2010 20:47:00 +0100 Subject: [PATCH 048/254] examples: Fix encodebin example CFLAGS and LDFLAGS Previously it would only succeed to link if a new enough libgstpbutils-0.10 was installed in the default library search path. --- tests/examples/encoding/Makefile.am | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/tests/examples/encoding/Makefile.am b/tests/examples/encoding/Makefile.am index 3e95e8aca3..2bcc902878 100644 --- a/tests/examples/encoding/Makefile.am +++ b/tests/examples/encoding/Makefile.am @@ -5,7 +5,8 @@ EXTRA_DIST = gstcapslist.h noinst_PROGRAMS = $(examples) -LDADD = $(top_builddir)/gst-libs/gst/pbutils/libgstpbutils-@GST_MAJORMINOR@.la\ - -lgstpbutils-@GST_MAJORMINOR@ +LDADD = $(top_builddir)/gst-libs/gst/pbutils/libgstpbutils-@GST_MAJORMINOR@.la \ $(GST_LIBS) -AM_CFLAGS = -I$(top_builddir)/gst-libs $(GST_PLUGINS_BASE_CFLAGS) $(GST_BASE_CFLAGS) $(GST_CFLAGS) +AM_CFLAGS = -I$(top_builddir)/gst-libs \ + $(GST_PLUGINS_BASE_CFLAGS) \ + $(GST_CFLAGS) From 3e35df72b6209db88749d56633ebe6049da217eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= Date: Sun, 19 Dec 2010 09:53:08 +0100 Subject: [PATCH 049/254] rtsp: Fix memory leaks in the gst_rtsp_url_decode_path_components() unit tests --- tests/check/libs/rtsp.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/check/libs/rtsp.c b/tests/check/libs/rtsp.c index fa26eead7a..377f277bf3 100644 --- a/tests/check/libs/rtsp.c +++ b/tests/check/libs/rtsp.c @@ -68,6 +68,7 @@ GST_START_TEST (test_rtsp_url_components_1) fail_unless (!strcmp (comps[1], "foo")); fail_unless (!strcmp (comps[2], "bar")); + g_strfreev (comps); gst_rtsp_url_free (url); } @@ -90,6 +91,7 @@ GST_START_TEST (test_rtsp_url_components_2) fail_unless (!strcmp (comps[1], "foo/bar")); fail_unless (!strcmp (comps[2], "qux baz")); + g_strfreev (comps); gst_rtsp_url_free (url); } @@ -112,6 +114,7 @@ GST_START_TEST (test_rtsp_url_components_3) fail_unless (!strcmp (comps[1], "foo%00bar")); fail_unless (!strcmp (comps[2], "qux baz")); + g_strfreev (comps); gst_rtsp_url_free (url); } From 2c84beebb253fee89e3bd76dd0d97c7eeadbc97d Mon Sep 17 00:00:00 2001 From: Edward Hervey Date: Sun, 19 Dec 2010 13:22:23 +0100 Subject: [PATCH 050/254] gst-discoverer: show global tags by default --- tools/gst-discoverer.c | 25 ++++++++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/tools/gst-discoverer.c b/tools/gst-discoverer.c index bff1b7945e..2182c0f0c9 100644 --- a/tools/gst-discoverer.c +++ b/tools/gst-discoverer.c @@ -204,9 +204,6 @@ print_stream_info (GstDiscovererStreamInfo * info, void *depth) desc = gst_stream_video_information_to_string (info, GPOINTER_TO_INT (depth) + 1); - } - - if (desc) { g_print ("%s", desc); g_free (desc); } @@ -240,13 +237,35 @@ print_topology (GstDiscovererStreamInfo * info, gint depth) } } +static gboolean +print_tag_each (GQuark field_id, const GValue * value, gpointer user_data) +{ + gint tab = GPOINTER_TO_INT (user_data); + gchar *ser; + + ser = gst_value_serialize (value); + + g_print ("%*s%s: %s\n", tab, " ", + gst_tag_get_nick (g_quark_to_string (field_id)), ser); + g_free (ser); + + return TRUE; +} + static void print_properties (GstDiscovererInfo * info, gint tab) { + const GstTagList *tags; + g_print ("%*sDuration: %" GST_TIME_FORMAT "\n", tab + 1, " ", GST_TIME_ARGS (gst_discoverer_info_get_duration (info))); g_print ("%*sSeekable: %s\n", tab + 1, " ", (gst_discoverer_info_get_seekable (info) ? "yes" : "no")); + if ((tags = gst_discoverer_info_get_tags (info))) { + g_print ("%*sTags: \n", tab + 1, " "); + gst_structure_foreach ((const GstStructure *) tags, print_tag_each, + GINT_TO_POINTER (tab + 5)); + } } static void From 76afffd55fae600f91d93614a815c2cbbf856661 Mon Sep 17 00:00:00 2001 From: Edward Hervey Date: Sun, 19 Dec 2010 13:41:22 +0100 Subject: [PATCH 051/254] gstdiscoverer: Don't leak tags --- gst-libs/gst/pbutils/gstdiscoverer.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/gst-libs/gst/pbutils/gstdiscoverer.c b/gst-libs/gst/pbutils/gstdiscoverer.c index 8955136e8d..cdeb913c47 100644 --- a/gst-libs/gst/pbutils/gstdiscoverer.c +++ b/gst-libs/gst/pbutils/gstdiscoverer.c @@ -385,12 +385,15 @@ static gboolean _event_probe (GstPad * pad, GstEvent * event, PrivateStream * ps) { if (GST_EVENT_TYPE (event) == GST_EVENT_TAG) { - GstTagList *tl = NULL; + GstTagList *tl = NULL, *tmp; gst_event_parse_tag (event, &tl); GST_DEBUG_OBJECT (pad, "tags %" GST_PTR_FORMAT, tl); DISCO_LOCK (ps->dc); - ps->tags = gst_tag_list_merge (ps->tags, tl, GST_TAG_MERGE_APPEND); + tmp = gst_tag_list_merge (ps->tags, tl, GST_TAG_MERGE_APPEND); + if (ps->tags) + gst_tag_list_free (ps->tags); + ps->tags = tmp; DISCO_UNLOCK (ps->dc); } @@ -919,8 +922,8 @@ discoverer_collect (GstDiscoverer * dc) gst_caps_get_structure (dc->priv->current_info->stream_info->caps, 0); if (g_str_has_prefix (gst_structure_get_name (st), "image/")) - ((GstDiscovererVideoInfo *) dc->priv->current_info->stream_info)-> - is_image = TRUE; + ((GstDiscovererVideoInfo *) dc->priv->current_info-> + stream_info)->is_image = TRUE; } } @@ -1003,15 +1006,18 @@ handle_message (GstDiscoverer * dc, GstMessage * msg) case GST_MESSAGE_TAG: { - GstTagList *tl; + GstTagList *tl, *tmp; gst_message_parse_tag (msg, &tl); GST_DEBUG ("Got tags %" GST_PTR_FORMAT, tl); /* Merge with current tags */ - dc->priv->current_info->tags = + tmp = gst_tag_list_merge (dc->priv->current_info->tags, tl, GST_TAG_MERGE_APPEND); gst_tag_list_free (tl); + if (dc->priv->current_info->tags) + gst_tag_list_free (dc->priv->current_info->tags); + dc->priv->current_info->tags = tmp; } break; From 60f75d00510b8660ef36e6a87b55181e6db20a30 Mon Sep 17 00:00:00 2001 From: Edward Hervey Date: Mon, 20 Dec 2010 17:46:48 +0100 Subject: [PATCH 052/254] Automatic update of common submodule From 169462a to 46445ad --- common | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common b/common index 169462a62f..46445ad50f 160000 --- a/common +++ b/common @@ -1 +1 @@ -Subproject commit 169462a62f8b3cb91d721092af13530a3f72a462 +Subproject commit 46445ad50f184d2640dd205361e0446e9121ba5f From e187dacc35310354da820324c38a36193daefa70 Mon Sep 17 00:00:00 2001 From: Edward Hervey Date: Fri, 17 Dec 2010 16:10:53 +0100 Subject: [PATCH 053/254] docs: Update for videoscale class changes --- docs/plugins/inspect/plugin-videoscale.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/plugins/inspect/plugin-videoscale.xml b/docs/plugins/inspect/plugin-videoscale.xml index ce92c33f6b..63a0f753f8 100644 --- a/docs/plugins/inspect/plugin-videoscale.xml +++ b/docs/plugins/inspect/plugin-videoscale.xml @@ -12,7 +12,7 @@ videoscale Video scaler - Filter/Effect/Video + Filter/Converter/Video/Scaler Resizes video Wim Taymans <wim.taymans@chello.be> From d20b84f1d250ab5f25744645d0341cf952ca6eab Mon Sep 17 00:00:00 2001 From: Edward Hervey Date: Tue, 21 Dec 2010 13:07:27 +0100 Subject: [PATCH 054/254] encodebin: Fix usage of non-container profiles --- gst/encoding/gstencodebin.c | 149 ++++++++++++++++++++---------------- 1 file changed, 84 insertions(+), 65 deletions(-) diff --git a/gst/encoding/gstencodebin.c b/gst/encoding/gstencodebin.c index 4a126202b1..002ab16ccc 100644 --- a/gst/encoding/gstencodebin.c +++ b/gst/encoding/gstencodebin.c @@ -88,6 +88,7 @@ struct _GstEncodeBin GList *streams; /* List of StreamGroup, not sorted */ GstElement *muxer; + /* Ghostpad with changing target */ GstPad *srcpad; /* TRUE if in PAUSED/PLAYING */ @@ -148,16 +149,16 @@ struct _StreamGroup #define DEFAULT_AUDIO_JITTER_TOLERANCE 20 * GST_MSECOND #define DEFAULT_AVOID_REENCODING FALSE -#define DEFAULT_RAW_CAPS \ - "video/x-raw-yuv; " \ - "video/x-raw-rgb; " \ - "video/x-raw-gray; " \ - "audio/x-raw-int; " \ - "audio/x-raw-float; " \ - "text/plain; " \ - "text/x-pango-markup; " \ - "video/x-dvd-subpicture; " \ - "subpicture/x-pgs" +#define DEFAULT_RAW_CAPS \ + "video/x-raw-yuv; " \ + "video/x-raw-rgb; " \ + "video/x-raw-gray; " \ + "audio/x-raw-int; " \ + "audio/x-raw-float; " \ + "text/plain; " \ + "text/x-pango-markup; " \ + "video/x-dvd-subpicture; " \ + "subpicture/x-pgs" /* Properties */ enum @@ -835,7 +836,7 @@ _create_stream_group (GstEncodeBin * ebin, GstEncodingProfile * sprof, const gchar * sinkpadname, GstCaps * sinkcaps) { StreamGroup *sgroup = NULL; - GstPad *sinkpad, *srcpad, *muxerpad; + GstPad *sinkpad, *srcpad, *muxerpad = NULL; /* Element we will link to the encoder */ GstElement *last = NULL; GList *tmp, *tosync = NULL; @@ -871,12 +872,14 @@ _create_stream_group (GstEncodeBin * ebin, GstEncodingProfile * sprof, if (G_UNLIKELY (sgroup->encoder == NULL)) goto no_encoder; - /* Muxer - * We first figure out if the muxer has a sinkpad compatible with the selected - * profile */ - muxerpad = get_compatible_muxer_sink_pad (ebin, NULL, format); - if (G_UNLIKELY (muxerpad == NULL)) - goto no_muxer_pad; + /* Muxer. + * If we are handling a container profile, figure out if the muxer has a + * sinkpad compatible with the selected profile */ + if (ebin->muxer) { + 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 @@ -888,11 +891,15 @@ _create_stream_group (GstEncodeBin * ebin, GstEncodingProfile * sprof, gst_bin_add (GST_BIN (ebin), sgroup->outqueue); tosync = g_list_append (tosync, sgroup->outqueue); srcpad = gst_element_get_static_pad (sgroup->outqueue, "src"); - if (G_UNLIKELY (fast_pad_link (srcpad, muxerpad) != GST_PAD_LINK_OK)) { - goto muxer_link_failure; + if (muxerpad) { + if (G_UNLIKELY (fast_pad_link (srcpad, muxerpad) != GST_PAD_LINK_OK)) { + goto muxer_link_failure; + } + gst_object_unref (muxerpad); + } else { + gst_ghost_pad_set_target (GST_GHOST_PAD (ebin->srcpad), srcpad); } gst_object_unref (srcpad); - gst_object_unref (muxerpad); /* Output capsfilter * This will receive the format caps from the streamprofile */ @@ -1264,12 +1271,6 @@ _get_muxer (GstEncodeBin * ebin) format = gst_encoding_profile_get_format (ebin->profile); preset = gst_encoding_profile_get_preset (ebin->profile); - if (format == NULL) { - GST_DEBUG ("Container-less profile, using identity"); - muxer = gst_element_factory_make ("identity", NULL); - goto beach; - } - GST_DEBUG ("Getting list of muxers for format %" GST_PTR_FORMAT, format); muxers = @@ -1327,42 +1328,47 @@ create_elements_and_pads (GstEncodeBin * ebin) GST_DEBUG ("Current profile : %s", gst_encoding_profile_get_name (ebin->profile)); - /* 1. Get the compatible muxer */ - muxer = _get_muxer (ebin); - if (G_UNLIKELY (muxer == NULL)) - goto no_muxer; + if (GST_IS_ENCODING_CONTAINER_PROFILE (ebin->profile)) { + /* 1. Get the compatible muxer */ + muxer = _get_muxer (ebin); + if (G_UNLIKELY (muxer == NULL)) + goto no_muxer; - /* Record the muxer */ - ebin->muxer = muxer; - gst_bin_add ((GstBin *) ebin, muxer); + /* Record the muxer */ + ebin->muxer = muxer; + gst_bin_add ((GstBin *) ebin, muxer); - /* 2. Ghost the muxer source pad */ + /* 2. Ghost the muxer source pad */ - /* FIXME : We should figure out if it's a static/request/dyamic pad, - * but for the time being let's assume it's a static pad :) */ - muxerpad = gst_element_get_static_pad (muxer, "src"); - if (G_UNLIKELY (muxerpad == NULL)) - goto no_muxer_pad; + /* FIXME : We should figure out if it's a static/request/dyamic pad, + * but for the time being let's assume it's a static pad :) */ + muxerpad = gst_element_get_static_pad (muxer, "src"); + if (G_UNLIKELY (muxerpad == NULL)) + goto no_muxer_pad; - if (!gst_ghost_pad_set_target (GST_GHOST_PAD (ebin->srcpad), muxerpad)) - goto no_muxer_ghost_pad; + if (!gst_ghost_pad_set_target (GST_GHOST_PAD (ebin->srcpad), muxerpad)) + goto no_muxer_ghost_pad; - gst_object_unref (muxerpad); + gst_object_unref (muxerpad); + /* 3. Activate fixed presence streams */ + profiles = + gst_encoding_container_profile_get_profiles + (GST_ENCODING_CONTAINER_PROFILE (ebin->profile)); + for (tmp = profiles; tmp; tmp = tmp->next) { + sprof = (GstEncodingProfile *) tmp->data; - /* 3. Activate fixed presence streams */ - profiles = - gst_encoding_container_profile_get_profiles - (GST_ENCODING_CONTAINER_PROFILE (ebin->profile)); - for (tmp = profiles; tmp; tmp = tmp->next) { - sprof = (GstEncodingProfile *) tmp->data; + GST_DEBUG ("Trying stream profile with presence %d", + gst_encoding_profile_get_presence (sprof)); - GST_DEBUG ("Trying stream profile with presence %d", - gst_encoding_profile_get_presence (sprof)); - - if (gst_encoding_profile_get_presence (sprof) != 0) { - if (G_UNLIKELY (_create_stream_group (ebin, sprof, NULL, NULL) == NULL)) - goto stream_error; + if (gst_encoding_profile_get_presence (sprof) != 0) { + if (G_UNLIKELY (_create_stream_group (ebin, sprof, NULL, NULL) == NULL)) + goto stream_error; + } } + } else { + if (G_UNLIKELY (_create_stream_group (ebin, ebin->profile, NULL, + NULL) == NULL)) + goto stream_error; } return ret; @@ -1394,10 +1400,8 @@ no_muxer_ghost_pad: stream_error: { GST_WARNING ("Could not create Streams"); - gst_element_remove_pad ((GstElement *) ebin, ebin->srcpad); gst_bin_remove (GST_BIN (ebin), muxer); ebin->muxer = NULL; - ebin->srcpad = NULL; return FALSE; } } @@ -1434,15 +1438,17 @@ stream_group_free (GstEncodeBin * ebin, StreamGroup * sgroup) GST_DEBUG_OBJECT (ebin, "Freeing StreamGroup %p", sgroup); - /* outqueue - Muxer */ - tmppad = gst_element_get_static_pad (sgroup->outqueue, "src"); - pad = gst_pad_get_peer (tmppad); + if (ebin->muxer) { + /* outqueue - Muxer */ + tmppad = gst_element_get_static_pad (sgroup->outqueue, "src"); + pad = gst_pad_get_peer (tmppad); - /* Remove muxer request sink pad */ - gst_pad_unlink (tmppad, pad); - gst_element_release_request_pad (ebin->muxer, pad); - gst_object_unref (tmppad); - gst_object_unref (pad); + /* Remove muxer request sink pad */ + gst_pad_unlink (tmppad, pad); + gst_element_release_request_pad (ebin->muxer, pad); + gst_object_unref (tmppad); + gst_object_unref (pad); + } if (sgroup->outqueue) gst_element_set_state (sgroup->outqueue, GST_STATE_NULL); @@ -1538,6 +1544,15 @@ gst_encode_bin_tear_down_profile (GstEncodeBin * ebin) while (ebin->streams) stream_group_remove (ebin, (StreamGroup *) ebin->streams->data); + /* Set ghostpad target to NULL */ + gst_ghost_pad_set_target (GST_GHOST_PAD (ebin->srcpad), NULL); + + /* Remove muxer if present */ + if (ebin->muxer) { + gst_bin_remove (GST_BIN (ebin), ebin->muxer); + ebin->muxer = NULL; + } + /* free/clear profile */ gst_encoding_profile_unref (ebin->profile); ebin->profile = NULL; @@ -1550,7 +1565,9 @@ gst_encode_bin_setup_profile (GstEncodeBin * ebin, GstEncodingProfile * profile) g_return_val_if_fail (ebin->profile == NULL, FALSE); - GST_DEBUG ("Setting up profile %s", gst_encoding_profile_get_name (profile)); + GST_DEBUG ("Setting up profile %s (type:%s)", + gst_encoding_profile_get_name (profile), + gst_encoding_profile_get_type_nick (profile)); ebin->profile = profile; gst_mini_object_ref ((GstMiniObject *) ebin->profile); @@ -1566,6 +1583,8 @@ gst_encode_bin_setup_profile (GstEncodeBin * ebin, GstEncodingProfile * profile) static gboolean gst_encode_bin_set_profile (GstEncodeBin * ebin, GstEncodingProfile * profile) { + g_return_val_if_fail (GST_IS_ENCODING_PROFILE (profile), FALSE); + GST_DEBUG_OBJECT (ebin, "profile : %s", gst_encoding_profile_get_name (profile)); From c6bc271e7ea4362bff2bd754e5396456649891fb Mon Sep 17 00:00:00 2001 From: Edward Hervey Date: Tue, 21 Dec 2010 13:08:15 +0100 Subject: [PATCH 055/254] encoding-profile: Add guard against profiles without format --- gst-libs/gst/pbutils/encoding-profile.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/gst-libs/gst/pbutils/encoding-profile.c b/gst-libs/gst/pbutils/encoding-profile.c index 03be1317c5..f981f7e8d1 100644 --- a/gst-libs/gst/pbutils/encoding-profile.c +++ b/gst-libs/gst/pbutils/encoding-profile.c @@ -673,6 +673,8 @@ GstEncodingContainerProfile * gst_encoding_container_profile_new (const gchar * name, const gchar * description, GstCaps * format, const gchar * preset) { + g_return_val_if_fail (GST_IS_CAPS (format), NULL); + return (GstEncodingContainerProfile *) common_creation (GST_TYPE_ENCODING_CONTAINER_PROFILE, format, preset, name, description, NULL, 0); From 949595a7a3bdb3d111b5755b7693d44526986d5d Mon Sep 17 00:00:00 2001 From: Edward Hervey Date: Tue, 21 Dec 2010 13:09:34 +0100 Subject: [PATCH 056/254] tests: Update container-less profile checks --- tests/check/elements/encodebin.c | 84 ++++++++++++++++++++++++++++++++ tests/check/libs/profile.c | 46 ----------------- 2 files changed, 84 insertions(+), 46 deletions(-) diff --git a/tests/check/elements/encodebin.c b/tests/check/elements/encodebin.c index b325694009..424b89d87e 100644 --- a/tests/check/elements/encodebin.c +++ b/tests/check/elements/encodebin.c @@ -75,6 +75,21 @@ create_ogg_theora_vorbis_profile (guint theorapresence, guint vorbispresence) return (GstEncodingProfile *) prof; } +static GstEncodingProfile * +create_vorbis_only_profile (void) +{ + GstEncodingProfile *prof; + GstCaps *vorbis; + + vorbis = gst_caps_new_simple ("audio/x-vorbis", NULL); + prof = + (GstEncodingProfile *) gst_encoding_audio_profile_new (vorbis, NULL, NULL, + 0); + gst_caps_unref (vorbis); + + return prof; +} + GST_START_TEST (test_encodebin_states) { GstElement *ebin; @@ -454,6 +469,74 @@ GST_START_TEST (test_encodebin_render_audio_static) GST_END_TEST; +GST_START_TEST (test_encodebin_render_audio_only_static) +{ + GstElement *ebin, *pipeline, *audiotestsrc, *fakesink; + GstEncodingProfile *prof; + GstBus *bus; + gboolean done = FALSE; + GstPad *sinkpad; + GstCaps *sinkcaps; + + /* Create an encodebin and render 5s of vorbis only */ + + pipeline = gst_pipeline_new ("encodebin-pipeline"); + bus = gst_pipeline_get_bus ((GstPipeline *) pipeline); + audiotestsrc = gst_element_factory_make ("audiotestsrc", NULL); + g_object_set (audiotestsrc, "num-buffers", 10, NULL); + fakesink = gst_element_factory_make ("fakesink", NULL); + + ebin = gst_element_factory_make ("encodebin", NULL); + + prof = create_vorbis_only_profile (); + g_object_set (ebin, "profile", prof, NULL); + gst_encoding_profile_unref (prof); + + gst_bin_add_many ((GstBin *) pipeline, audiotestsrc, ebin, fakesink, NULL); + + fail_unless (gst_element_link_many (audiotestsrc, ebin, fakesink, NULL)); + + /* Requesting a new pad should fail */ + fail_if (gst_element_get_request_pad (ebin, "audio_0") != NULL); + sinkcaps = gst_caps_new_simple ("audio/x-raw-int", NULL); + g_signal_emit_by_name (ebin, "request-pad", sinkcaps, &sinkpad); + gst_caps_unref (sinkcaps); + fail_if (sinkpad != NULL); + + fail_unless_equals_int (gst_element_set_state (pipeline, GST_STATE_PLAYING), + GST_STATE_CHANGE_ASYNC); + + while (!done) { + GstMessage *msg; + + /* poll the bus until we get EOS without any errors */ + msg = gst_bus_timed_pop (bus, GST_SECOND / 10); + if (msg) { + switch (GST_MESSAGE_TYPE (msg)) { + case GST_MESSAGE_ERROR: + fail ("GST_MESSAGE_ERROR"); + break; + case GST_MESSAGE_EOS: + done = TRUE; + break; + default: + break; + } + gst_message_unref (msg); + } + } + + /* Set back to NULL */ + fail_unless_equals_int (gst_element_set_state (pipeline, GST_STATE_NULL), + GST_STATE_CHANGE_SUCCESS); + + g_object_unref (bus); + + gst_object_unref (pipeline); +} + +GST_END_TEST; + GST_START_TEST (test_encodebin_render_audio_dynamic) { GstElement *ebin, *pipeline, *audiotestsrc, *fakesink; @@ -731,6 +814,7 @@ encodebin_suite (void) tcase_add_test (tc_chain, test_encodebin_sink_pads_multiple_dynamic); tcase_add_test (tc_chain, test_encodebin_sink_pads_dynamic_encoder); tcase_add_test (tc_chain, test_encodebin_render_audio_static); + tcase_add_test (tc_chain, test_encodebin_render_audio_only_static); tcase_add_test (tc_chain, test_encodebin_render_audio_dynamic); tcase_add_test (tc_chain, test_encodebin_render_audio_video_static); tcase_add_test (tc_chain, test_encodebin_render_audio_video_dynamic); diff --git a/tests/check/libs/profile.c b/tests/check/libs/profile.c index a5640a646a..ed974c89eb 100644 --- a/tests/check/libs/profile.c +++ b/tests/check/libs/profile.c @@ -132,51 +132,6 @@ GST_START_TEST (test_profile_output_caps) GST_END_TEST; -GST_START_TEST (test_containerless_profile) -{ - GstEncodingProfile *encprof; - GstEncodingAudioProfile *audioprof; - GstCaps *container = NULL, *vorbis; - GstCaps *test1, *test2; - - vorbis = gst_caps_new_simple ("audio/x-vorbis", NULL); - - GST_DEBUG ("Creating container profile without any caps"); - encprof = (GstEncodingProfile *) gst_encoding_container_profile_new ((gchar *) - "container-vorbis", "dumb-profile", container, (gchar *) "dumb-preset"); - CHECK_PROFILE (encprof, "container-vorbis", "dumb-profile", NULL, - "dumb-preset", 0, 0); - - GST_DEBUG ("Creating audio profile"); - audioprof = gst_encoding_audio_profile_new (vorbis, (gchar *) "HQ", NULL, 0); - CHECK_PROFILE ((GstEncodingProfile *) audioprof, NULL, NULL, vorbis, "HQ", 0, - 0); - - GST_DEBUG ("Adding audio profile to container"); - /* We can add one stream profile to container-less profiles.. */ - fail_unless (gst_encoding_container_profile_add_profile ( - (GstEncodingContainerProfile *) encprof, - (GstEncodingProfile *) audioprof)); - GST_DEBUG ("Adding audio profile to container a second time (should fail)"); - /* .. but not two */ - fail_if (gst_encoding_container_profile_add_profile ( - (GstEncodingContainerProfile *) encprof, - (GstEncodingProfile *) audioprof)); - - GST_DEBUG ("Checking caps"); - /* Test caps */ - test1 = gst_caps_from_string ("audio/x-vorbis"); - test2 = gst_encoding_profile_get_output_caps (encprof); - fail_unless (gst_caps_is_equal (test1, test2)); - gst_caps_unref (test1); - gst_caps_unref (test2); - - gst_encoding_profile_unref (encprof); - gst_caps_unref (vorbis); -} - -GST_END_TEST; - static GstEncodingTarget * create_saveload_target (void) { @@ -440,7 +395,6 @@ profile_suite (void) tcase_add_test (tc_chain, test_profile_creation); tcase_add_test (tc_chain, test_profile_output_caps); - tcase_add_test (tc_chain, test_containerless_profile); if (can_write) { tcase_add_test (tc_chain, test_loading_profile); tcase_add_test (tc_chain, test_saving_profile); From bc633345038a78de2a40639e95e88a143908f464 Mon Sep 17 00:00:00 2001 From: Wim Taymans Date: Mon, 20 Dec 2010 18:28:14 +0100 Subject: [PATCH 057/254] rtppayload: copy applied rate to segment Use set_segment_full to copy all segment values to the segment structure. --- gst-libs/gst/rtp/gstbasertppayload.c | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/gst-libs/gst/rtp/gstbasertppayload.c b/gst-libs/gst/rtp/gstbasertppayload.c index e9c98811e7..ed52e7f933 100644 --- a/gst-libs/gst/rtp/gstbasertppayload.c +++ b/gst-libs/gst/rtp/gstbasertppayload.c @@ -402,15 +402,25 @@ gst_basertppayload_event (GstPad * pad, GstEvent * event) case GST_EVENT_NEWSEGMENT: { gboolean update; - gdouble rate; + gdouble rate, arate; GstFormat fmt; gint64 start, stop, position; + GstSegment *segment; - gst_event_parse_new_segment (event, &update, &rate, &fmt, &start, &stop, - &position); - gst_segment_set_newsegment (&basertppayload->segment, update, rate, fmt, - start, stop, position); + segment = &basertppayload->segment; + gst_event_parse_new_segment_full (event, &update, &rate, &arate, &fmt, + &start, &stop, &position); + gst_segment_set_newsegment_full (segment, update, rate, arate, fmt, start, + stop, position); + + GST_DEBUG_OBJECT (basertppayload, + "configured NEWSEGMENT update %d, rate %lf, applied rate %lf, " + "format %d, " + "%" G_GINT64_FORMAT " -- %" G_GINT64_FORMAT ", time %" + G_GINT64_FORMAT ", accum %" G_GINT64_FORMAT, update, rate, arate, + segment->format, segment->start, segment->stop, segment->time, + segment->accum); /* fallthrough */ } default: From d51ff7e4eb339027b55bc3fac55c3f77725cba69 Mon Sep 17 00:00:00 2001 From: Wim Taymans Date: Mon, 20 Dec 2010 18:29:15 +0100 Subject: [PATCH 058/254] basertppay: use RTP base time when invalid timestamps When we have an invalid running-time (because we clipped, for example) use the RTP base time for timestamping instead of generating wrong RTP timestamps. --- gst-libs/gst/rtp/gstbasertppayload.c | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/gst-libs/gst/rtp/gstbasertppayload.c b/gst-libs/gst/rtp/gstbasertppayload.c index ed52e7f933..a389185589 100644 --- a/gst-libs/gst/rtp/gstbasertppayload.c +++ b/gst-libs/gst/rtp/gstbasertppayload.c @@ -787,12 +787,16 @@ gst_basertppayload_prepare_push (GstBaseRTPPayload * payload, rtime = gst_segment_to_running_time (&payload->segment, GST_FORMAT_TIME, data.timestamp); - GST_LOG_OBJECT (payload, - "Using running_time %" GST_TIME_FORMAT " for RTP timestamp", - GST_TIME_ARGS (rtime)); - - rtime = gst_util_uint64_scale_int (rtime, payload->clock_rate, GST_SECOND); - + if (rtime == -1) { + GST_LOG_OBJECT (payload, "Clipped timestamp, using base RTP timestamp"); + rtime = 0; + } else { + GST_LOG_OBJECT (payload, + "Using running_time %" GST_TIME_FORMAT " for RTP timestamp", + GST_TIME_ARGS (rtime)); + rtime = + gst_util_uint64_scale_int (rtime, payload->clock_rate, GST_SECOND); + } /* add running_time in clock-rate units to the base timestamp */ data.rtptime = payload->ts_base + rtime; } else { @@ -820,8 +824,8 @@ gst_basertppayload_prepare_push (GstBaseRTPPayload * payload, GST_BUFFER_SIZE (GST_BUFFER (obj)), payload->seqnum, data.rtptime, GST_TIME_ARGS (data.timestamp)); - if (g_atomic_int_compare_and_exchange (&payload->priv-> - notified_first_timestamp, 1, 0)) { + if (g_atomic_int_compare_and_exchange (&payload-> + priv->notified_first_timestamp, 1, 0)) { g_object_notify (G_OBJECT (payload), "timestamp"); g_object_notify (G_OBJECT (payload), "seqnum"); } From 8945ce0958f54b4704c7e1dabc0a537b05ca3890 Mon Sep 17 00:00:00 2001 From: Wim Taymans Date: Tue, 21 Dec 2010 10:41:27 +0100 Subject: [PATCH 059/254] seek: don't pause for live buffering messages --- tests/examples/seek/seek.c | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/examples/seek/seek.c b/tests/examples/seek/seek.c index 5f0e1e5e1b..d1957385d3 100644 --- a/tests/examples/seek/seek.c +++ b/tests/examples/seek/seek.c @@ -2402,6 +2402,7 @@ msg_buffering (GstBus * bus, GstMessage * message, GstPipeline * data) do_download_buffering (percent); break; case GST_BUFFERING_LIVE: + is_live = TRUE; case GST_BUFFERING_TIMESHIFT: case GST_BUFFERING_STREAM: do_stream_buffering (percent); From eac243bc01100c73c4d8b3ec62464a4533fc9469 Mon Sep 17 00:00:00 2001 From: Wim Taymans Date: Tue, 21 Dec 2010 13:19:38 +0100 Subject: [PATCH 060/254] vorbisdec: avoid using invalid timestamps --- ext/vorbis/gstvorbisdec.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ext/vorbis/gstvorbisdec.c b/ext/vorbis/gstvorbisdec.c index efd0ba0557..e607ce1d92 100644 --- a/ext/vorbis/gstvorbisdec.c +++ b/ext/vorbis/gstvorbisdec.c @@ -827,7 +827,7 @@ vorbis_do_timestamps (GstVorbisDec * vd, GstBuffer * buf, gboolean reverse, GstClockTime timestamp, GstClockTime duration) { /* interpolate reverse */ - if (vd->last_timestamp != -1 && reverse) + if (vd->last_timestamp != -1 && duration != -1 && reverse) vd->last_timestamp -= duration; /* take buffer timestamp, use interpolated timestamp otherwise */ @@ -837,7 +837,7 @@ vorbis_do_timestamps (GstVorbisDec * vd, GstBuffer * buf, gboolean reverse, timestamp = vd->last_timestamp; /* interpolate forwards */ - if (vd->last_timestamp != -1 && !reverse) + if (vd->last_timestamp != -1 && duration != -1 && !reverse) vd->last_timestamp += duration; GST_BUFFER_TIMESTAMP (buf) = timestamp; From 1dafd7136d4f365d9ff91b4d18a62e072481a704 Mon Sep 17 00:00:00 2001 From: Wim Taymans Date: Tue, 21 Dec 2010 13:37:41 +0100 Subject: [PATCH 061/254] vorbisdec: keep timestamps when no decoded output Keep track of the timestamps even when we didn't generate decodable output. --- ext/vorbis/gstvorbisdec.c | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/ext/vorbis/gstvorbisdec.c b/ext/vorbis/gstvorbisdec.c index e607ce1d92..33f4184d57 100644 --- a/ext/vorbis/gstvorbisdec.c +++ b/ext/vorbis/gstvorbisdec.c @@ -840,8 +840,15 @@ vorbis_do_timestamps (GstVorbisDec * vd, GstBuffer * buf, gboolean reverse, if (vd->last_timestamp != -1 && duration != -1 && !reverse) vd->last_timestamp += duration; - GST_BUFFER_TIMESTAMP (buf) = timestamp; - GST_BUFFER_DURATION (buf) = duration; + GST_LOG_OBJECT (vd, + "keeping timestamp %" GST_TIME_FORMAT " ts %" GST_TIME_FORMAT " dur %" + GST_TIME_FORMAT, GST_TIME_ARGS (vd->last_timestamp), + GST_TIME_ARGS (timestamp), GST_TIME_ARGS (duration)); + + if (buf) { + GST_BUFFER_TIMESTAMP (buf) = timestamp; + GST_BUFFER_DURATION (buf) = duration; + } } static GstFlowReturn @@ -850,7 +857,7 @@ vorbis_handle_data_packet (GstVorbisDec * vd, ogg_packet * packet, { vorbis_sample_t **pcm; guint sample_count; - GstBuffer *out; + GstBuffer *out = NULL; GstFlowReturn result; gint size; @@ -910,6 +917,10 @@ vorbis_handle_data_packet (GstVorbisDec * vd, ogg_packet * packet, result = vorbis_dec_push_reverse (vd, out); done: + if (out == NULL) { + /* no output, still keep track of timestamps */ + vorbis_do_timestamps (vd, NULL, FALSE, timestamp, duration); + } vorbis_synthesis_read (&vd->vd, sample_count); return result; From 9e787a0211c4220c80e62a4f4a2de4e2c457a2a0 Mon Sep 17 00:00:00 2001 From: Wim Taymans Date: Tue, 21 Dec 2010 15:02:18 +0100 Subject: [PATCH 062/254] rtpdepayloade: add support for getting events Add support for intercepting sink events in the depayloader by adding a new vmethod. --- gst-libs/gst/rtp/gstbasertpdepayload.c | 25 +++++++++++++++++++++---- gst-libs/gst/rtp/gstbasertpdepayload.h | 6 +++++- 2 files changed, 26 insertions(+), 5 deletions(-) diff --git a/gst-libs/gst/rtp/gstbasertpdepayload.c b/gst-libs/gst/rtp/gstbasertpdepayload.c index 583754fda4..d1d39916d6 100644 --- a/gst-libs/gst/rtp/gstbasertpdepayload.c +++ b/gst-libs/gst/rtp/gstbasertpdepayload.c @@ -97,6 +97,8 @@ static void gst_base_rtp_depayload_set_gst_timestamp (GstBaseRTPDepayload * filter, guint32 rtptime, GstBuffer * buf); static gboolean gst_base_rtp_depayload_packet_lost (GstBaseRTPDepayload * filter, GstEvent * event); +static gboolean gst_base_rtp_depayload_handle_event (GstBaseRTPDepayload * + filter, GstEvent * event); GST_BOILERPLATE (GstBaseRTPDepayload, gst_base_rtp_depayload, GstElement, GST_TYPE_ELEMENT); @@ -142,6 +144,7 @@ gst_base_rtp_depayload_class_init (GstBaseRTPDepayloadClass * klass) klass->set_gst_timestamp = gst_base_rtp_depayload_set_gst_timestamp; klass->packet_lost = gst_base_rtp_depayload_packet_lost; + klass->handle_event = gst_base_rtp_depayload_handle_event; GST_DEBUG_CATEGORY_INIT (basertpdepayload_debug, "basertpdepayload", 0, "Base class for RTP Depayloaders"); @@ -407,14 +410,12 @@ no_process: } static gboolean -gst_base_rtp_depayload_handle_sink_event (GstPad * pad, GstEvent * event) +gst_base_rtp_depayload_handle_event (GstBaseRTPDepayload * filter, + GstEvent * event) { - GstBaseRTPDepayload *filter; gboolean res = TRUE; gboolean forward = TRUE; - filter = GST_BASE_RTP_DEPAYLOAD (GST_OBJECT_PARENT (pad)); - switch (GST_EVENT_TYPE (event)) { case GST_EVENT_FLUSH_STOP: gst_segment_init (&filter->segment, GST_FORMAT_UNDEFINED); @@ -474,6 +475,22 @@ gst_base_rtp_depayload_handle_sink_event (GstPad * pad, GstEvent * event) return res; } +static gboolean +gst_base_rtp_depayload_handle_sink_event (GstPad * pad, GstEvent * event) +{ + gboolean res = FALSE; + GstBaseRTPDepayload *filter; + GstBaseRTPDepayloadClass *bclass; + + filter = GST_BASE_RTP_DEPAYLOAD (GST_OBJECT_PARENT (pad)); + + bclass = GST_BASE_RTP_DEPAYLOAD_GET_CLASS (filter); + if (bclass->handle_event) + res = bclass->handle_event (filter, event); + + return res; +} + static GstEvent * create_segment_event (GstBaseRTPDepayload * filter, gboolean update, GstClockTime position) diff --git a/gst-libs/gst/rtp/gstbasertpdepayload.h b/gst-libs/gst/rtp/gstbasertpdepayload.h index 4ba2fc4ed0..bdd56a3816 100644 --- a/gst-libs/gst/rtp/gstbasertpdepayload.h +++ b/gst-libs/gst/rtp/gstbasertpdepayload.h @@ -119,8 +119,12 @@ struct _GstBaseRTPDepayloadClass * The default implementation of this message pushes a segment update. */ gboolean (*packet_lost) (GstBaseRTPDepayload *filter, GstEvent *event); + /* the default implementation does the default actions for events but + * implementation can override. */ + gboolean (*handle_event) (GstBaseRTPDepayload * filter, GstEvent * event); + /*< private >*/ - gpointer _gst_reserved[GST_PADDING-1]; + gpointer _gst_reserved[GST_PADDING-2]; }; GType gst_base_rtp_depayload_get_type (void); From 6ffabccf04a7025822252a895b4111af6af6ac0e Mon Sep 17 00:00:00 2001 From: Wim Taymans Date: Tue, 21 Dec 2010 15:11:10 +0100 Subject: [PATCH 063/254] depay: update some docs --- gst-libs/gst/rtp/gstbasertpdepayload.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/gst-libs/gst/rtp/gstbasertpdepayload.h b/gst-libs/gst/rtp/gstbasertpdepayload.h index bdd56a3816..000c1167ff 100644 --- a/gst-libs/gst/rtp/gstbasertpdepayload.h +++ b/gst-libs/gst/rtp/gstbasertpdepayload.h @@ -120,7 +120,8 @@ struct _GstBaseRTPDepayloadClass gboolean (*packet_lost) (GstBaseRTPDepayload *filter, GstEvent *event); /* the default implementation does the default actions for events but - * implementation can override. */ + * implementation can override. + * Since: 0.10.32 */ gboolean (*handle_event) (GstBaseRTPDepayload * filter, GstEvent * event); /*< private >*/ From 4b3e1403a1ac83cc5cc2a19c009bfd1149f0f496 Mon Sep 17 00:00:00 2001 From: Edward Hervey Date: Tue, 21 Dec 2010 16:33:50 +0100 Subject: [PATCH 064/254] encoding-target: Ensure target names and categories are valid --- gst-libs/gst/pbutils/encoding-target.c | 57 +++++++++++++++++++ tests/check/libs/profile.c | 78 ++++++++++++++++++++++++++ 2 files changed, 135 insertions(+) diff --git a/gst-libs/gst/pbutils/encoding-target.c b/gst-libs/gst/pbutils/encoding-target.c index 19065e8fe7..b62895c1f2 100644 --- a/gst-libs/gst/pbutils/encoding-target.c +++ b/gst-libs/gst/pbutils/encoding-target.c @@ -19,6 +19,7 @@ */ #include +#include #include "encoding-target.h" /* @@ -150,6 +151,40 @@ gst_encoding_target_get_profiles (GstEncodingTarget * target) return target->profiles; } +static inline gboolean +validate_name (const gchar * name) +{ + guint i, len; + + len = strlen (name); + if (len == 0) + return FALSE; + + /* First character can only be a lower case ASCII character */ + if (!g_ascii_isalpha (name[0]) || !g_ascii_islower (name[0])) + return FALSE; + + /* All following characters can only by: + * either a lower case ASCII character + * or an hyphen + * or a numeric */ + for (i = 1; i < len; i++) { + /* if uppercase ASCII letter, return */ + if (g_ascii_isupper (name[i])) + return FALSE; + /* if a digit, continue */ + if (g_ascii_isdigit (name[i])) + continue; + /* if an hyphen, continue */ + if (name[i] == '-') + continue; + /* remaining should only be ascii letters */ + if (!g_ascii_isalpha (name[i])) + return FALSE; + } + + return TRUE; +} /** * gst_encoding_target_new: @@ -160,6 +195,10 @@ gst_encoding_target_get_profiles (GstEncodingTarget * target) * * Creates a new #GstEncodingTarget. * + * The name and category can only consist of lowercase ASCII letters for the + * first character, followed by either lowercase ASCII letters, digits or + * hyphens ('-'). + * * Since: 0.10.32 * * Returns: The newly created #GstEncodingTarget or %NULL if there was an @@ -176,6 +215,12 @@ gst_encoding_target_new (const gchar * name, const gchar * category, g_return_val_if_fail (category != NULL, NULL); g_return_val_if_fail (description != NULL, NULL); + /* Validate name */ + if (!validate_name (name)) + goto invalid_name; + if (!validate_name (category)) + goto invalid_category; + res = (GstEncodingTarget *) gst_mini_object_new (GST_TYPE_ENCODING_TARGET); res->name = g_strdup (name); res->category = g_strdup (category); @@ -190,6 +235,18 @@ gst_encoding_target_new (const gchar * name, const gchar * category, } return res; + +invalid_name: + { + GST_ERROR ("Invalid name for encoding category : '%s'", name); + return NULL; + } + +invalid_category: + { + GST_ERROR ("Invalid category for encoding category : '%s'", category); + return NULL; + } } /** diff --git a/tests/check/libs/profile.c b/tests/check/libs/profile.c index ed974c89eb..0018b0bd22 100644 --- a/tests/check/libs/profile.c +++ b/tests/check/libs/profile.c @@ -132,6 +132,83 @@ GST_START_TEST (test_profile_output_caps) GST_END_TEST; + +GST_START_TEST (test_target_naming) +{ + GstEncodingTarget *target; + + /* NULL values */ + ASSERT_CRITICAL (target = gst_encoding_target_new (NULL, NULL, NULL, NULL)); + fail_if (target != NULL); + ASSERT_CRITICAL (target = + gst_encoding_target_new ("donkey", NULL, NULL, NULL)); + fail_if (target != NULL); + ASSERT_CRITICAL (target = + gst_encoding_target_new (NULL, "donkey", NULL, NULL)); + fail_if (target != NULL); + ASSERT_CRITICAL (target = + gst_encoding_target_new (NULL, NULL, "donkey", NULL)); + fail_if (target != NULL); + + /* Name and Category validation */ + + /* empty non-NULL strings */ + fail_if (gst_encoding_target_new ("", "valid", "description", NULL) != NULL); + fail_if (gst_encoding_target_new ("valid", "", "description", NULL) != NULL); + + /* don't start with a lower case ASCII character */ + fail_if (gst_encoding_target_new ("A", "valid", "description", NULL) != NULL); + fail_if (gst_encoding_target_new ("3", "valid", "description", NULL) != NULL); + fail_if (gst_encoding_target_new ("-", "valid", "description", NULL) != NULL); + fail_if (gst_encoding_target_new ("!", "valid", "description", NULL) != NULL); + fail_if (gst_encoding_target_new (" ", "valid", "description", NULL) != NULL); + fail_if (gst_encoding_target_new ("valid", "A", "description", NULL) != NULL); + fail_if (gst_encoding_target_new ("valid", "3", "description", NULL) != NULL); + fail_if (gst_encoding_target_new ("valid", "-", "description", NULL) != NULL); + fail_if (gst_encoding_target_new ("valid", "!", "description", NULL) != NULL); + fail_if (gst_encoding_target_new ("valid", " ", "description", NULL) != NULL); + + /* Starting with anything else is valid */ + target = gst_encoding_target_new ("a", "valid", "description", NULL); + fail_if (target == NULL); + gst_encoding_target_unref (target); + target = gst_encoding_target_new ("z", "valid", "description", NULL); + fail_if (target == NULL); + gst_encoding_target_unref (target); + target = gst_encoding_target_new ("valid", "a", "description", NULL); + fail_if (target == NULL); + gst_encoding_target_unref (target); + target = gst_encoding_target_new ("valid", "z", "description", NULL); + fail_if (target == NULL); + gst_encoding_target_unref (target); + + /* only inner valid characters are lower-case ASCII letters *OR* digits *OR* hyphens */ + fail_if (gst_encoding_target_new ("aA", "valid", "description", + NULL) != NULL); + fail_if (gst_encoding_target_new ("a!", "valid", "description", + NULL) != NULL); + fail_if (gst_encoding_target_new ("space donkeys", "valid", "description", + NULL) != NULL); + fail_if (gst_encoding_target_new ("howaboutùnicode", "valid", "description", + NULL) != NULL); + fail_if (gst_encoding_target_new ("valid", "aA", "description", + NULL) != NULL); + fail_if (gst_encoding_target_new ("valid", "a!", "description", + NULL) != NULL); + + target = + gst_encoding_target_new ("donkey-4-ever", "valid", "description", NULL); + fail_if (target == NULL); + gst_encoding_target_unref (target); + target = + gst_encoding_target_new ("valid", "donkey-4-ever", "description", NULL); + fail_if (target == NULL); + gst_encoding_target_unref (target); + +} + +GST_END_TEST; + static GstEncodingTarget * create_saveload_target (void) { @@ -395,6 +472,7 @@ profile_suite (void) tcase_add_test (tc_chain, test_profile_creation); tcase_add_test (tc_chain, test_profile_output_caps); + tcase_add_test (tc_chain, test_target_naming); if (can_write) { tcase_add_test (tc_chain, test_loading_profile); tcase_add_test (tc_chain, test_saving_profile); From f221466099b9193fb737cafc6bde1195aaeec06a Mon Sep 17 00:00:00 2001 From: Vincent Penquerc'h Date: Tue, 21 Dec 2010 10:26:40 +0000 Subject: [PATCH 065/254] playbin2: delay stream-changed messages https://bugzilla.gnome.org/show_bug.cgi?id=637586 --- gst/playback/gstplaybin2.c | 76 ++++++++++++++++++++++++++++++++++++-- 1 file changed, 73 insertions(+), 3 deletions(-) diff --git a/gst/playback/gstplaybin2.c b/gst/playback/gstplaybin2.c index 75f19ab987..154ffd296a 100644 --- a/gst/playback/gstplaybin2.c +++ b/gst/playback/gstplaybin2.c @@ -264,6 +264,8 @@ struct _GstSourceSelect GstPad *sinkpad; /* the sinkpad of the sink when the selector * is linked */ + GstEvent *sinkpad_delayed_event; + gulong sinkpad_data_probe; }; #define GST_SOURCE_GROUP_GET_LOCK(group) (((GstSourceGroup*)(group))->lock) @@ -1056,6 +1058,8 @@ gst_play_bin_class_init (GstPlayBinClass * klass) static void init_group (GstPlayBin * playbin, GstSourceGroup * group) { + int n; + /* store the array for the different channels */ group->video_channels = g_ptr_array_new (); group->audio_channels = g_ptr_array_new (); @@ -1089,11 +1093,27 @@ init_group (GstPlayBin * playbin, GstSourceGroup * group) group->selector[4].media_list[0] = "video/"; group->selector[4].type = GST_PLAY_SINK_TYPE_VIDEO; group->selector[4].channels = group->video_channels; + + for (n = 0; n < GST_PLAY_SINK_TYPE_LAST; n++) { + GstSourceSelect *select = &group->selector[n]; + select->sinkpad_delayed_event = NULL; + select->sinkpad_data_probe = 0; + } } static void free_group (GstPlayBin * playbin, GstSourceGroup * group) { + int n; + + for (n = 0; n < GST_PLAY_SINK_TYPE_LAST; n++) { + GstSourceSelect *select = &group->selector[n]; + if (select->sinkpad && select->sinkpad_data_probe) + gst_pad_remove_data_probe (select->sinkpad, select->sinkpad_data_probe); + if (select->sinkpad_delayed_event) + gst_event_unref (select->sinkpad_delayed_event); + } + g_free (group->uri); g_free (group->suburi); g_ptr_array_free (group->video_channels, TRUE); @@ -2301,6 +2321,39 @@ selector_blocked (GstPad * pad, gboolean blocked, gpointer user_data) GST_DEBUG_OBJECT (pad, "blocked callback, blocked: %d", blocked); } +/* this callback sends a delayed event once the pad becomes unblocked */ +static gboolean +stream_changed_data_probe (GstPad * pad, GstMiniObject * object, gpointer data) +{ + GstSourceSelect *select = (GstSourceSelect *) data; + GstEvent *e; + + /* we need do this just once, so cleanup first */ + gst_pad_remove_data_probe (pad, select->sinkpad_data_probe); + select->sinkpad_data_probe = 0; + e = select->sinkpad_delayed_event; + select->sinkpad_delayed_event = NULL; + + /* really, this should not happen */ + if (!e) { + GST_WARNING ("Data probed called, but no delayed event"); + return TRUE; + } + + if (GST_IS_EVENT (object) + && GST_EVENT_TYPE (GST_EVENT_CAST (object)) == GST_EVENT_NEWSEGMENT) { + /* push the event first, then send the delayed one */ + gst_event_ref (GST_EVENT_CAST (object)); + gst_pad_send_event (pad, GST_EVENT_CAST (object)); + gst_pad_send_event (pad, e); + return FALSE; + } else { + /* send delayed event, then allow the caller to go on */ + gst_pad_send_event (pad, e); + return TRUE; + } +} + /* helper function to lookup stuff in lists */ static gboolean array_has_value (const gchar * values[], const gchar * value) @@ -2742,8 +2795,25 @@ no_more_pads_cb (GstElement * decodebin, GstSourceGroup * group) group->stream_changed_pending = g_list_prepend (group->stream_changed_pending, GUINT_TO_POINTER (seqnum)); + + /* remove any data probe we might have, and replace */ + if (select->sinkpad_delayed_event) + gst_event_unref (select->sinkpad_delayed_event); + select->sinkpad_delayed_event = event; + if (select->sinkpad_data_probe) + gst_pad_remove_data_probe (select->sinkpad, + select->sinkpad_data_probe); + + /* we go to the trouble of setting a probe on the pad to send + the playbin2-stream-changed event as sending it here might + find that the pad is blocked, so we'd block here, and the + pad might not be linked yet. Additionally, sending it here + apparently would be on the wrong thread */ + select->sinkpad_data_probe = + gst_pad_add_data_probe (select->sinkpad, + (GCallback) stream_changed_data_probe, (gpointer) select); + g_mutex_unlock (group->stream_changed_pending_lock); - gst_pad_send_event (select->sinkpad, event); gst_message_unref (msg); } @@ -2870,8 +2940,8 @@ autoplug_continue_cb (GstElement * element, GstPad * pad, GstCaps * caps, GstPad *text_sinkpad = NULL; text_sink = - (group->playbin->text_sink) ? gst_object_ref (group->playbin-> - text_sink) : NULL; + (group->playbin->text_sink) ? gst_object_ref (group-> + playbin->text_sink) : NULL; if (text_sink) text_sinkpad = gst_element_get_static_pad (text_sink, "sink"); From 9f6bcdd5ee629ebe73c3a85d819e0863785cea13 Mon Sep 17 00:00:00 2001 From: Edward Hervey Date: Tue, 21 Dec 2010 18:51:29 +0100 Subject: [PATCH 066/254] pbutils: More gtk-doc annotations --- gst-libs/gst/pbutils/encoding-target.c | 29 +++++---- gst-libs/gst/pbutils/gstdiscoverer-types.c | 70 ++++++++++++---------- gst-libs/gst/pbutils/gstdiscoverer.c | 8 ++- gst-libs/gst/pbutils/install-plugins.c | 4 +- gst-libs/gst/pbutils/missing-plugins.c | 10 ++-- 5 files changed, 69 insertions(+), 52 deletions(-) diff --git a/gst-libs/gst/pbutils/encoding-target.c b/gst-libs/gst/pbutils/encoding-target.c index b62895c1f2..cc8cac3b3b 100644 --- a/gst-libs/gst/pbutils/encoding-target.c +++ b/gst-libs/gst/pbutils/encoding-target.c @@ -101,7 +101,7 @@ gst_encoding_target_class_init (GstMiniObjectClass * klass) * * Since: 0.10.32 * - * Returns: The name of the @target. + * Returns: (transfer none): The name of the @target. */ const gchar * gst_encoding_target_get_name (GstEncodingTarget * target) @@ -115,7 +115,7 @@ gst_encoding_target_get_name (GstEncodingTarget * target) * * Since: 0.10.32 * - * Returns: The category of the @target. + * Returns: (transfer none): The category of the @target. */ const gchar * gst_encoding_target_get_category (GstEncodingTarget * target) @@ -129,7 +129,7 @@ gst_encoding_target_get_category (GstEncodingTarget * target) * * Since: 0.10.32 * - * Returns: The description of the @target. + * Returns: (transfer none): The description of the @target. */ const gchar * gst_encoding_target_get_description (GstEncodingTarget * target) @@ -143,7 +143,8 @@ gst_encoding_target_get_description (GstEncodingTarget * target) * * Since: 0.10.32 * - * Returns: A list of #GstEncodingProfile(s) this @target handles. + * Returns: (transfer none) (element-type Gst.EncodingProfile): A list of + * #GstEncodingProfile(s) this @target handles. */ const GList * gst_encoding_target_get_profiles (GstEncodingTarget * target) @@ -189,9 +190,12 @@ validate_name (const gchar * name) /** * gst_encoding_target_new: * @name: The name of the target. - * @category: The name of the category to which this @target belongs. - * @description: A description of #GstEncodingTarget in the current locale. - * @profiles: A #GList of #GstEncodingProfile. + * @category: (transfer none): The name of the category to which this @target + * belongs. + * @description: (transfer none): A description of #GstEncodingTarget in the + * current locale. + * @profiles: (transfer none) (element-type Gst.EncodingProfile): A #GList of + * #GstEncodingProfile. * * Creates a new #GstEncodingTarget. * @@ -201,8 +205,8 @@ validate_name (const gchar * name) * * Since: 0.10.32 * - * Returns: The newly created #GstEncodingTarget or %NULL if there was an - * error. + * Returns: (transfer full): The newly created #GstEncodingTarget or %NULL if + * there was an error. */ GstEncodingTarget * @@ -252,7 +256,7 @@ invalid_category: /** * gst_encoding_target_add_profile: * @target: the #GstEncodingTarget to add a profile to - * @profile: the #GstEncodingProfile to add + * @profile: (transfer full): the #GstEncodingProfile to add * * Adds the given @profile to the @target. * @@ -642,7 +646,8 @@ empty_name: * * Since: 0.10.32 * - * Returns: The #GstEncodingTarget contained in the file, else %NULL + * Returns: (transfer full): The #GstEncodingTarget contained in the file, else + * %NULL */ GstEncodingTarget * @@ -677,7 +682,7 @@ beach: * * Since: 0.10.32 * - * Returns: The #GstEncodingTarget if available, else %NULL + * Returns: (transfer full): The #GstEncodingTarget if available, else %NULL. */ GstEncodingTarget * diff --git a/gst-libs/gst/pbutils/gstdiscoverer-types.c b/gst-libs/gst/pbutils/gstdiscoverer-types.c index 2a5839b07b..3cf3562e46 100644 --- a/gst-libs/gst/pbutils/gstdiscoverer-types.c +++ b/gst-libs/gst/pbutils/gstdiscoverer-types.c @@ -382,8 +382,9 @@ gst_discoverer_stream_info_list_free (GList * infos) * Finds the #GstDiscovererStreamInfo contained in @info that match the * given @streamtype. * - * Returns: A #GList of matching #GstDiscovererStreamInfo. The caller should - * free it with #gst_discoverer_stream_info_list_free. + * Returns: (transfer full) (element-type Gst.DiscovererStreamInfo): A #GList of + * matching #GstDiscovererStreamInfo. The caller should free it with + * gst_discoverer_stream_info_list_free(). * * Since: 0.10.31 */ @@ -408,8 +409,9 @@ gst_discoverer_info_get_streams (GstDiscovererInfo * info, GType streamtype) * * Finds all the #GstDiscovererAudioInfo contained in @info * - * Returns: A #GList of matching #GstDiscovererStreamInfo. The caller should - * free it with #gst_discoverer_stream_info_list_free. + * Returns: (transfer full) (element-type Gst.DiscovererStreamInfo): A #GList of + * matching #GstDiscovererStreamInfo. The caller should free it with + * gst_discoverer_stream_info_list_free(). * * Since: 0.10.31 */ @@ -425,8 +427,9 @@ gst_discoverer_info_get_audio_streams (GstDiscovererInfo * info) * * Finds all the #GstDiscovererVideoInfo contained in @info * - * Returns: A #GList of matching #GstDiscovererStreamInfo. The caller should - * free it with #gst_discoverer_stream_info_list_free. + * Returns: (transfer full) (element-type Gst.DiscovererStreamInfo): A #GList of + * matching #GstDiscovererStreamInfo. The caller should free it with + * gst_discoverer_stream_info_list_free(). * * Since: 0.10.31 */ @@ -442,8 +445,9 @@ gst_discoverer_info_get_video_streams (GstDiscovererInfo * info) * * Finds all the #GstDiscovererContainerInfo contained in @info * - * Returns: A #GList of matching #GstDiscovererStreamInfo. The caller should - * free it with #gst_discoverer_stream_info_list_free. + * Returns: (transfer full) (element-type Gst.DiscovererStreamInfo): A #GList of + * matching #GstDiscovererStreamInfo. The caller should free it with + * gst_discoverer_stream_info_list_free(). * * Since: 0.10.31 */ @@ -493,8 +497,9 @@ gst_discoverer_stream_info_get_stream_type_nick (GstDiscovererStreamInfo * info) * gst_discoverer_stream_info_get_previous: * @info: a #GstDiscovererStreamInfo * - * Returns: the previous #GstDiscovererStreamInfo in a chain. %NULL for starting - * points. Unref with #gst_discoverer_stream_info_unref after usage. + * Returns: (transfer full): the previous #GstDiscovererStreamInfo in a chain. + * %NULL for starting points. Unref with #gst_discoverer_stream_info_unref + * after usage. * * Since: 0.10.31 */ @@ -512,7 +517,8 @@ gst_discoverer_stream_info_get_previous (GstDiscovererStreamInfo * info) * gst_discoverer_stream_info_get_next: * @info: a #GstDiscovererStreamInfo * - * Returns: the next #GstDiscovererStreamInfo in a chain. %NULL for final streams. + * Returns: (transfer full): the next #GstDiscovererStreamInfo in a chain. %NULL + * for final streams. * Unref with #gst_discoverer_stream_info_unref after usage. * * Since: 0.10.31 @@ -532,7 +538,8 @@ gst_discoverer_stream_info_get_next (GstDiscovererStreamInfo * info) * gst_discoverer_stream_info_get_caps: * @info: a #GstDiscovererStreamInfo * - * Returns: the #GstCaps of the stream. Unref with #gst_caps_unref after usage. + * Returns: (transfer full): the #GstCaps of the stream. Unref with + * #gst_caps_unref after usage. * * Since: 0.10.31 */ @@ -550,8 +557,8 @@ gst_discoverer_stream_info_get_caps (GstDiscovererStreamInfo * info) * gst_discoverer_stream_info_get_tags: * @info: a #GstDiscovererStreamInfo * - * Returns: the tags contained in this stream. If you wish to use the tags after - * the life-time of @info you will need to copy them. + * Returns: (transfer none): the tags contained in this stream. If you wish to + * use the tags after the life-time of @info you will need to copy them. * * Since: 0.10.31 */ @@ -568,9 +575,9 @@ gst_discoverer_stream_info_get_tags (GstDiscovererStreamInfo * info) * gst_discoverer_stream_info_get_misc: * @info: a #GstDiscovererStreamInfo * - * Returns: additional information regarding the stream (for example codec version, - * profile, etc..). If you wish to use the #GstStructure after the life-time of - * @info you will need to copy it. + * Returns: (transfer none): additional information regarding the stream (for + * example codec version, profile, etc..). If you wish to use the #GstStructure + * after the life-time of @info you will need to copy it. * * Since: 0.10.31 */ @@ -588,8 +595,9 @@ gst_discoverer_stream_info_get_misc (GstDiscovererStreamInfo * info) * gst_discoverer_container_info_get_streams: * @info: a #GstDiscovererStreamInfo * - * Returns: the list of #GstDiscovererStreamInfo this container stream offers. - * Free with #gst_discoverer_stream_info_list_free after usage. + * Returns: (transfer full) (element-type Gst.DiscovererStreamInfo): the list of + * #GstDiscovererStreamInfo this container stream offers. + * Free with gst_discoverer_stream_info_list_free() after usage. * * Since: 0.10.31 */ @@ -822,8 +830,8 @@ gst_discoverer_video_info_is_image (const GstDiscovererVideoInfo * info) * gst_discoverer_info_get_uri: * @info: a #GstDiscovererInfo * - * Returns: the URI to which this information corresponds to. Copy it if you - * wish to use it after the life-time of @info. + * Returns: (transfer none): the URI to which this information corresponds to. + * Copy it if you wish to use it after the life-time of @info. * * Since: 0.10.31 */ @@ -845,9 +853,10 @@ DISCOVERER_INFO_ACCESSOR_CODE (result, GstDiscovererResult, GST_DISCOVERER_OK); * gst_discoverer_info_get_stream_info: * @info: a #GstDiscovererInfo * - * Returns: the structure (or topology) of the URI as a #GstDiscovererStreamInfo. + * Returns: (transfer full): the structure (or topology) of the URI as a + * #GstDiscovererStreamInfo. * This structure can be traversed to see the original hierarchy. Unref with - * #gst_discoverer_stream_info_unref after usage. + * gst_discoverer_stream_info_unref() after usage. * * Since: 0.10.31 */ @@ -866,8 +875,9 @@ gst_discoverer_info_get_stream_info (GstDiscovererInfo * info) * gst_discoverer_info_get_stream_list: * @info: a #GstDiscovererInfo * - * Returns: the list of all streams contained in the #info. Free after usage - * with #gst_discoverer_stream_info_list_free. + * Returns: (transfer full) (element-type Gst.DiscovererStreamInfo): the list of + * all streams contained in the #info. Free after usage + * with gst_discoverer_stream_info_list_free(). * * Since: 0.10.31 */ @@ -912,9 +922,9 @@ DISCOVERER_INFO_ACCESSOR_CODE (seekable, gboolean, FALSE); * gst_discoverer_info_get_misc: * @info: a #GstDiscovererInfo * - * Returns: Miscellaneous information stored as a #GstStructure (for example: - * information about missing plugins). If you wish to use the #GstStructure - * after the life-time of @info, you will need to copy it. + * Returns: (transfer none): Miscellaneous information stored as a #GstStructure + * (for example: information about missing plugins). If you wish to use the + * #GstStructure after the life-time of @info, you will need to copy it. * * Since: 0.10.31 */ @@ -925,8 +935,8 @@ DISCOVERER_INFO_ACCESSOR_CODE (misc, const GstStructure *, NULL); * gst_discoverer_info_get_tags: * @info: a #GstDiscovererInfo * - * Returns: all tags contained in the %URI. If you wish to use the tags after - * the life-time of @info, you will need to copy them. + * Returns: (transfer none): all tags contained in the %URI. If you wish to use + * the tags after the life-time of @info, you will need to copy them. * * Since: 0.10.31 */ diff --git a/gst-libs/gst/pbutils/gstdiscoverer.c b/gst-libs/gst/pbutils/gstdiscoverer.c index cdeb913c47..fa5b742e5d 100644 --- a/gst-libs/gst/pbutils/gstdiscoverer.c +++ b/gst-libs/gst/pbutils/gstdiscoverer.c @@ -1346,9 +1346,11 @@ gst_discoverer_discover_uri_async (GstDiscoverer * discoverer, * * Synchronously discovers the given @uri. * - * A copy of @uri will be done internally, the caller can safely g_free() afterwards. + * A copy of @uri will be done internally, the caller can safely g_free() + * afterwards. * - * Returns: see #GstDiscovererInfo. The caller must unref this structure after use. + * Returns: (transfer full): the result of the scanning. Can be %NULL iif an + * error occured. * * Since: 0.10.31 */ @@ -1400,7 +1402,7 @@ gst_discoverer_discover_uri (GstDiscoverer * discoverer, const gchar * uri, * * Creates a new #GstDiscoverer with the provided timeout. * - * Returns: The new #GstDiscoverer. Free with gst_object_unref() when done. + * Returns: (transfer full): The new #GstDiscoverer. * If an error happened when creating the discoverer, @err will be set * accordingly and %NULL will be returned. If @err is set, the caller must * free it when no longer needed using g_error_free(). diff --git a/gst-libs/gst/pbutils/install-plugins.c b/gst-libs/gst/pbutils/install-plugins.c index 60a426357a..9b5f45e1df 100644 --- a/gst-libs/gst/pbutils/install-plugins.c +++ b/gst-libs/gst/pbutils/install-plugins.c @@ -608,8 +608,8 @@ gst_install_plugins_installer_exited (GPid pid, gint status, gpointer data) * gst_install_plugins_async: * @details: NULL-terminated array of installer string details (see below) * @ctx: a #GstInstallPluginsContext, or NULL - * @func: the function to call when the installer program returns - * @user_data: the user data to pass to @func when called, or NULL + * @func: (scope async): the function to call when the installer program returns + * @user_data: (closure): the user data to pass to @func when called, or NULL * * Requests plugin installation without blocking. Once the plugins have been * installed or installation has failed, @func will be called with the result diff --git a/gst-libs/gst/pbutils/missing-plugins.c b/gst-libs/gst/pbutils/missing-plugins.c index ca82ce5c8b..1b6d44bb20 100644 --- a/gst-libs/gst/pbutils/missing-plugins.c +++ b/gst-libs/gst/pbutils/missing-plugins.c @@ -166,7 +166,7 @@ copy_and_clean_caps (const GstCaps * caps) * that a source element for a particular URI protocol is missing. This * function is mainly for use in plugins. * - * Returns: a new #GstMessage, or NULL on error + * Returns: (transfer full): a new #GstMessage, or NULL on error */ GstMessage * gst_missing_uri_source_message_new (GstElement * element, @@ -199,7 +199,7 @@ gst_missing_uri_source_message_new (GstElement * element, * that a sink element for a particular URI protocol is missing. This * function is mainly for use in plugins. * - * Returns: a new #GstMessage, or NULL on error + * Returns: (transfer full): a new #GstMessage, or NULL on error */ GstMessage * gst_missing_uri_sink_message_new (GstElement * element, const gchar * protocol) @@ -231,7 +231,7 @@ gst_missing_uri_sink_message_new (GstElement * element, const gchar * protocol) * that a certain required element is missing. This function is mainly for * use in plugins. * - * Returns: a new #GstMessage, or NULL on error + * Returns: (transfer full): a new #GstMessage, or NULL on error */ GstMessage * gst_missing_element_message_new (GstElement * element, @@ -263,7 +263,7 @@ gst_missing_element_message_new (GstElement * element, * that a decoder element for a particular set of (fixed) caps is missing. * This function is mainly for use in plugins. * - * Returns: a new #GstMessage, or NULL on error + * Returns: (transfer full): a new #GstMessage, or NULL on error */ GstMessage * gst_missing_decoder_message_new (GstElement * element, @@ -303,7 +303,7 @@ gst_missing_decoder_message_new (GstElement * element, * that an encoder element for a particular set of (fixed) caps is missing. * This function is mainly for use in plugins. * - * Returns: a new #GstMessage, or NULL on error + * Returns: (transfer full): a new #GstMessage, or NULL on error */ GstMessage * gst_missing_encoder_message_new (GstElement * element, From b11303319cd7fe184eaadaf65016f343accb0729 Mon Sep 17 00:00:00 2001 From: Alessandro Decina Date: Wed, 22 Dec 2010 13:56:12 +0100 Subject: [PATCH 067/254] encodebin: minor fix in error handling. Don't call gst_bin_remove (bin, ). --- gst/encoding/gstencodebin.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/gst/encoding/gstencodebin.c b/gst/encoding/gstencodebin.c index 002ab16ccc..b6e2dc4c8a 100644 --- a/gst/encoding/gstencodebin.c +++ b/gst/encoding/gstencodebin.c @@ -1320,7 +1320,7 @@ static gboolean create_elements_and_pads (GstEncodeBin * ebin) { gboolean ret = TRUE; - GstElement *muxer; + GstElement *muxer = NULL; GstPad *muxerpad; const GList *tmp, *profiles; GstEncodingProfile *sprof; @@ -1400,7 +1400,8 @@ no_muxer_ghost_pad: stream_error: { GST_WARNING ("Could not create Streams"); - gst_bin_remove (GST_BIN (ebin), muxer); + if (muxer) + gst_bin_remove (GST_BIN (ebin), muxer); ebin->muxer = NULL; return FALSE; } From 17777f25960ef48cad4400c881002a4d1d1ac4ee Mon Sep 17 00:00:00 2001 From: Thiago Santos Date: Wed, 22 Dec 2010 10:32:03 -0300 Subject: [PATCH 068/254] tag: exif: Fix unitialized data warning Fixes a valgrind warning on jifmux tests on -bad caused by unitialized bytes. Fixes #637758 --- gst-libs/gst/tag/gstexiftag.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gst-libs/gst/tag/gstexiftag.c b/gst-libs/gst/tag/gstexiftag.c index e72bf3a3a6..cc39acd1e3 100644 --- a/gst-libs/gst/tag/gstexiftag.c +++ b/gst-libs/gst/tag/gstexiftag.c @@ -752,7 +752,7 @@ static void write_exif_undefined_tag (GstExifWriter * writer, guint16 tag, const guint8 * data, gint size) { - guint32 offset; + guint32 offset = 0; if (size > 4) { /* we only use the data offset here, later we add up the @@ -773,7 +773,7 @@ static void write_exif_ascii_tag (GstExifWriter * writer, guint16 tag, const gchar * str) { gint size; - guint32 offset; + guint32 offset = 0; size = strlen (str) + 1; From ad22e8bc10d91af41f809417d16fb241e7752d36 Mon Sep 17 00:00:00 2001 From: Edward Hervey Date: Wed, 22 Dec 2010 18:19:48 +0100 Subject: [PATCH 069/254] encoding-target: Fix typo --- gst-libs/gst/pbutils/encoding-target.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gst-libs/gst/pbutils/encoding-target.c b/gst-libs/gst/pbutils/encoding-target.c index cc8cac3b3b..a5a7b3d55b 100644 --- a/gst-libs/gst/pbutils/encoding-target.c +++ b/gst-libs/gst/pbutils/encoding-target.c @@ -242,13 +242,13 @@ gst_encoding_target_new (const gchar * name, const gchar * category, invalid_name: { - GST_ERROR ("Invalid name for encoding category : '%s'", name); + GST_ERROR ("Invalid name for encoding target : '%s'", name); return NULL; } invalid_category: { - GST_ERROR ("Invalid category for encoding category : '%s'", category); + GST_ERROR ("Invalid name for encoding category : '%s'", category); return NULL; } } From c76a6ef8ea47f2517c641da6f117df4feb1afe14 Mon Sep 17 00:00:00 2001 From: Edward Hervey Date: Wed, 22 Dec 2010 18:12:14 +0100 Subject: [PATCH 070/254] encodebin: Also use "Formatter"s for container formats --- gst/encoding/gstencodebin.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/gst/encoding/gstencodebin.c b/gst/encoding/gstencodebin.c index b6e2dc4c8a..105d841f08 100644 --- a/gst/encoding/gstencodebin.c +++ b/gst/encoding/gstencodebin.c @@ -325,13 +325,20 @@ 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 = + 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, GST_RANK_MARGINAL); + encode_bin->parsers = gst_element_factory_list_get_elements (GST_ELEMENT_FACTORY_TYPE_PARSER, GST_RANK_MARGINAL); From e443ae6000ddfd4d469c6614914fd700396558b1 Mon Sep 17 00:00:00 2001 From: Vincent Penquerc'h Date: Wed, 22 Dec 2010 19:06:56 +0000 Subject: [PATCH 071/254] oggdemux: Don't use gst_pad_alloc_buffer() allocate buffers using gst_buffer_new_and_alloc() instead of gst_pad_alloc_buffer_and_set_caps(), as the first one will cause the pad to block, and we don't want that since that will prevent subsequent pads from being fed if a block occurs at start, when all pads must be fed for playback to start. This fixes autoplugging of the tiger element and other things. https://bugzilla.gnome.org/show_bug.cgi?id=637822 --- ext/ogg/gstoggdemux.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/ext/ogg/gstoggdemux.c b/ext/ogg/gstoggdemux.c index 8da7288e7f..89707832e9 100644 --- a/ext/ogg/gstoggdemux.c +++ b/ext/ogg/gstoggdemux.c @@ -567,10 +567,9 @@ gst_ogg_demux_chain_peer (GstOggPad * pad, ogg_packet * packet, goto empty_packet; } - ret = - gst_pad_alloc_buffer_and_set_caps (GST_PAD_CAST (pad), - GST_BUFFER_OFFSET_NONE, packet->bytes - offset - trim, - GST_PAD_CAPS (pad), &buf); + buf = gst_buffer_new_and_alloc (packet->bytes - offset - trim); + gst_buffer_set_caps (buf, GST_PAD_CAPS (pad)); + ret = GST_FLOW_OK; /* combine flows */ cret = gst_ogg_demux_combine_flows (ogg, pad, ret); From 0c4820914cc03d0031301cad117c3326146d1c31 Mon Sep 17 00:00:00 2001 From: David Schleef Date: Wed, 22 Dec 2010 15:29:56 -0800 Subject: [PATCH 072/254] oggstream: Fix parsing of theora size --- ext/ogg/gstoggstream.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ext/ogg/gstoggstream.c b/ext/ogg/gstoggstream.c index f8ba6c09f7..783364a20c 100644 --- a/ext/ogg/gstoggstream.c +++ b/ext/ogg/gstoggstream.c @@ -343,8 +343,8 @@ setup_theora_mapper (GstOggStream * pad, ogg_packet * packet) guint8 *data = packet->packet; guint w, h, par_d, par_n; - w = GST_READ_UINT24_BE (data + 14) & 0xFFFFF0; - h = GST_READ_UINT24_BE (data + 17) & 0xFFFFF0; + w = GST_READ_UINT24_BE (data + 14) & 0xFFFFFF; + h = GST_READ_UINT24_BE (data + 17) & 0xFFFFFF; pad->granulerate_n = GST_READ_UINT32_BE (data + 22); pad->granulerate_d = GST_READ_UINT32_BE (data + 26); From dd135119d929ce60c2a2594b51cd3db0e47a6b73 Mon Sep 17 00:00:00 2001 From: Vincent Penquerc'h Date: Thu, 23 Dec 2010 17:18:17 +0000 Subject: [PATCH 073/254] oggdemux: set headers on caps This will allow switching from one stream to another without having to send the headers for the new stream again. https://bugzilla.gnome.org/show_bug.cgi?id=637927 --- ext/ogg/gstoggdemux.c | 49 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/ext/ogg/gstoggdemux.c b/ext/ogg/gstoggdemux.c index 89707832e9..c04481d9a4 100644 --- a/ext/ogg/gstoggdemux.c +++ b/ext/ogg/gstoggdemux.c @@ -122,6 +122,9 @@ static GstFlowReturn gst_ogg_demux_combine_flows (GstOggDemux * ogg, GstOggPad * pad, GstFlowReturn ret); static void gst_ogg_demux_sync_streams (GstOggDemux * ogg); +GstCaps *gst_ogg_demux_set_header_on_caps (GstOggDemux * ogg, + GstCaps * caps, GList * headers); + GType gst_ogg_pad_get_type (void); G_DEFINE_TYPE (GstOggPad, gst_ogg_pad, GST_TYPE_PAD); @@ -1710,6 +1713,47 @@ gst_ogg_demux_deactivate_current_chain (GstOggDemux * ogg) return TRUE; } +GstCaps * +gst_ogg_demux_set_header_on_caps (GstOggDemux * ogg, GstCaps * caps, + GList * headers) +{ + GstStructure *structure; + GValue array = { 0 }; + + GST_LOG_OBJECT (ogg, "caps: %" GST_PTR_FORMAT, caps); + + if (G_UNLIKELY (!caps)) + return NULL; + if (G_UNLIKELY (!headers)) + return NULL; + + caps = gst_caps_make_writable (caps); + structure = gst_caps_get_structure (caps, 0); + + g_value_init (&array, GST_TYPE_ARRAY); + + while (headers) { + GValue value = { 0 }; + GstBuffer *buffer; + ogg_packet *op = headers->data; + g_assert (op); + buffer = gst_buffer_new_and_alloc (op->bytes); + memcpy (GST_BUFFER_DATA (buffer), op->packet, op->bytes); + GST_BUFFER_FLAG_SET (buffer, GST_BUFFER_FLAG_IN_CAPS); + g_value_init (&value, GST_TYPE_BUFFER); + gst_value_take_buffer (&value, buffer); + gst_value_array_append_value (&array, &value); + g_value_unset (&value); + headers = headers->next; + } + + gst_structure_set_value (structure, "streamheader", &array); + g_value_unset (&array); + GST_LOG_OBJECT (ogg, "here are the newly set caps: %" GST_PTR_FORMAT, caps); + + return caps; +} + static gboolean gst_ogg_demux_activate_chain (GstOggDemux * ogg, GstOggChain * chain, GstEvent * event) @@ -1795,6 +1839,11 @@ gst_ogg_demux_activate_chain (GstOggDemux * ogg, GstOggChain * chain, pad->map.taglist = NULL; } + /* Set headers on caps */ + pad->map.caps = + gst_ogg_demux_set_header_on_caps (ogg, pad->map.caps, pad->map.headers); + gst_pad_set_caps (GST_PAD_CAST (pad), pad->map.caps); + GST_DEBUG_OBJECT (ogg, "pushing headers"); /* push headers */ for (walk = pad->map.headers; walk; walk = g_list_next (walk)) { From 802cf04d06274c48c5ca8115dde0d6bf98bb308c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim-Philipp=20M=C3=BCller?= Date: Sun, 26 Dec 2010 17:29:38 +0000 Subject: [PATCH 074/254] pbutils: add description for DVB subtitle caps --- gst-libs/gst/pbutils/descriptions.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/gst-libs/gst/pbutils/descriptions.c b/gst-libs/gst/pbutils/descriptions.c index ca99344243..cd67a6bd88 100644 --- a/gst-libs/gst/pbutils/descriptions.c +++ b/gst-libs/gst/pbutils/descriptions.c @@ -161,6 +161,7 @@ static const FormatInfo formats[] = { {"video/x-compressed-yuv", N_("CYUV Lossless"), 0}, {"video/x-dirac", "Dirac", 0}, {"video/x-dnxhd", "Digital Nonlinear Extensible High Definition (DNxHD)", 0}, + /* FIXME 0.11: rename to subpicture/x-dvd or so */ {"video/x-dvd-subpicture", "DVD subpicture", 0}, {"video/x-ffv", N_("FFMpeg v1"), 0}, {"video/x-flash-screen", "Flash Screen Video", 0}, @@ -235,6 +236,7 @@ static const FormatInfo formats[] = { {"application/x-subtitle-tmplayer", N_("TMPlayer subtitle format"), 0}, {"application/x-kate", "Kate", 0}, {"subtitle/x-kate", N_("Kate subtitle format"), 0}, + {"subpicture/x-dvb", "DVB subtitles", 0}, /* add variant field to typefinder? { "application/x-subtitle", N_("subtitle"), 0}, */ /* non-audio/video/container formats */ From 85cafac6af27a3f46cd7ffcce1ff503810cafc11 Mon Sep 17 00:00:00 2001 From: Vincent Penquerc'h Date: Sat, 25 Dec 2010 15:22:42 +0000 Subject: [PATCH 075/254] oggstream: implement tag extraction for Kate streams This will mainly allow Totem to know the language of those streams, so the subtitle selection menu gets properly filled out. https://bugzilla.gnome.org/show_bug.cgi?id=638005 --- ext/ogg/gstoggstream.c | 53 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 52 insertions(+), 1 deletion(-) diff --git a/ext/ogg/gstoggstream.c b/ext/ogg/gstoggstream.c index 783364a20c..c9e2cc5841 100644 --- a/ext/ogg/gstoggstream.c +++ b/ext/ogg/gstoggstream.c @@ -1758,6 +1758,57 @@ packet_duration_kate (GstOggStream * pad, ogg_packet * packet) return duration; } +static void +extract_tags_kate (GstOggStream * pad, ogg_packet * packet) +{ + GstTagList *list = NULL; + + if (packet->bytes <= 0) + return; + + switch (packet->packet[0]) { + case 0x80:{ + const gchar *canonical; + char language[16]; + + if (packet->bytes < 64) { + GST_WARNING ("Kate ID header packet is less than 64 bytes, ignored"); + break; + } + + /* the language tag is 16 bytes at offset 32, ensure NUL terminator */ + memcpy (language, packet->packet + 32, 16); + language[15] = 0; + + /* language is an ISO 639-1 code or RFC 3066 language code, we + * truncate to ISO 639-1 */ + g_strdelimit (language, NULL, '\0'); + canonical = gst_tag_get_language_code_iso_639_1 (language); + if (canonical) { + list = gst_tag_list_new_full (GST_TAG_LANGUAGE_CODE, canonical, NULL); + } else { + GST_WARNING ("Unknown or invalid language code %s, ignored", language); + } + break; + } + case 0x81: + tag_list_from_vorbiscomment_packet (packet, + (const guint8 *) "\201kate\0\0\0\0", 9, &list); + break; + default: + break; + } + + if (list) { + if (pad->taglist) { + /* ensure the comment packet cannot override the category/language + from the identification header */ + gst_tag_list_insert (pad->taglist, list, GST_TAG_MERGE_KEEP_ALL); + } else + pad->taglist = list; + } +} + /* *INDENT-OFF* */ /* indent hates our freedoms */ @@ -1903,7 +1954,7 @@ const GstOggMap mappers[] = { is_header_count, packet_duration_kate, NULL, - NULL + extract_tags_kate }, { "BBCD\0", 5, 13, From c665034742f8f4e5e702ac61e8d26ed6d64f242f Mon Sep 17 00:00:00 2001 From: Wim Taymans Date: Tue, 28 Dec 2010 11:41:49 +0100 Subject: [PATCH 076/254] basedepay: fix refcounting issue Make sure that when _make_writable() returns a new buffer, we actually push that one instead of the old one. --- gst-libs/gst/rtp/gstbasertpdepayload.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/gst-libs/gst/rtp/gstbasertpdepayload.c b/gst-libs/gst/rtp/gstbasertpdepayload.c index d1d39916d6..fdc861d205 100644 --- a/gst-libs/gst/rtp/gstbasertpdepayload.c +++ b/gst-libs/gst/rtp/gstbasertpdepayload.c @@ -559,11 +559,11 @@ gst_base_rtp_depayload_prepare_push (GstBaseRTPDepayload * filter, data.bclass = GST_BASE_RTP_DEPAYLOAD_GET_CLASS (filter); if (is_list) { - gst_buffer_list_foreach (GST_BUFFER_LIST_CAST (obj), - (GstBufferListFunc) set_headers, &data); + GstBufferList **blist = obj; + gst_buffer_list_foreach (*blist, (GstBufferListFunc) set_headers, &data); } else { - GstBuffer *buf = GST_BUFFER_CAST (obj); - set_headers (&buf, 0, 0, &data); + GstBuffer **buf = obj; + set_headers (buf, 0, 0, &data); } /* if this is the first buffer send a NEWSEGMENT */ @@ -605,7 +605,7 @@ gst_base_rtp_depayload_push_ts (GstBaseRTPDepayload * filter, guint32 timestamp, res = gst_base_rtp_depayload_prepare_push (filter, TRUE, timestamp, FALSE, - out_buf); + &out_buf); if (G_LIKELY (res == GST_FLOW_OK)) res = gst_pad_push (filter->srcpad, out_buf); @@ -634,7 +634,7 @@ gst_base_rtp_depayload_push (GstBaseRTPDepayload * filter, GstBuffer * out_buf) { GstFlowReturn res; - res = gst_base_rtp_depayload_prepare_push (filter, FALSE, 0, FALSE, out_buf); + res = gst_base_rtp_depayload_prepare_push (filter, FALSE, 0, FALSE, &out_buf); if (G_LIKELY (res == GST_FLOW_OK)) res = gst_pad_push (filter->srcpad, out_buf); @@ -662,7 +662,7 @@ gst_base_rtp_depayload_push_list (GstBaseRTPDepayload * filter, { GstFlowReturn res; - res = gst_base_rtp_depayload_prepare_push (filter, TRUE, 0, TRUE, out_list); + res = gst_base_rtp_depayload_prepare_push (filter, TRUE, 0, TRUE, &out_list); if (G_LIKELY (res == GST_FLOW_OK)) res = gst_pad_push_list (filter->srcpad, out_list); From 68e64770a0878d07287f4c62da65f15c108a66dd Mon Sep 17 00:00:00 2001 From: Wim Taymans Date: Tue, 28 Dec 2010 19:39:18 +0100 Subject: [PATCH 077/254] oggdemux: handle pads that are not added yet Don't try to stream data on pads that are not added yet. This happens while we discover the different streams. --- ext/ogg/gstoggdemux.c | 23 +++++++---------------- 1 file changed, 7 insertions(+), 16 deletions(-) diff --git a/ext/ogg/gstoggdemux.c b/ext/ogg/gstoggdemux.c index c04481d9a4..18ecc550b6 100644 --- a/ext/ogg/gstoggdemux.c +++ b/ext/ogg/gstoggdemux.c @@ -452,6 +452,8 @@ gst_ogg_demux_chain_peer (GstOggPad * pad, ogg_packet * packet, guint64 out_offset, out_offset_end; gboolean delta_unit = FALSE; + cret = GST_FLOW_OK; + GST_DEBUG_OBJECT (ogg, "%p streaming to peer serial %08lx", pad, pad->map.serialno); @@ -467,7 +469,6 @@ gst_ogg_demux_chain_peer (GstOggPad * pad, ogg_packet * packet, if ((data[0] & 1) || (data[0] & 3 && pad->map.is_ogm_text)) { /* We don't push header packets for OGM */ - cret = gst_ogg_demux_combine_flows (ogg, pad, GST_FLOW_OK); goto done; } @@ -488,7 +489,6 @@ gst_ogg_demux_chain_peer (GstOggPad * pad, ogg_packet * packet, packet->b_o_s || (packet->bytes >= 5 && memcmp (packet->packet, "OVP80", 5) == 0)) { /* We don't push header packets for VP8 */ - cret = gst_ogg_demux_combine_flows (ogg, pad, GST_FLOW_OK); goto done; } offset = 0; @@ -570,14 +570,11 @@ gst_ogg_demux_chain_peer (GstOggPad * pad, ogg_packet * packet, goto empty_packet; } + if (!pad->added) + goto not_added; + buf = gst_buffer_new_and_alloc (packet->bytes - offset - trim); gst_buffer_set_caps (buf, GST_PAD_CAPS (pad)); - ret = GST_FLOW_OK; - - /* combine flows */ - cret = gst_ogg_demux_combine_flows (ogg, pad, ret); - if (ret != GST_FLOW_OK) - goto no_buffer; /* set delta flag for OGM content */ if (delta_unit) @@ -658,23 +655,17 @@ done: empty_packet: { GST_DEBUG_OBJECT (ogg, "Skipping empty packet"); - cret = gst_ogg_demux_combine_flows (ogg, pad, GST_FLOW_OK); goto done; } no_timestamp: { GST_DEBUG_OBJECT (ogg, "skipping packet: no valid granule found yet"); - cret = gst_ogg_demux_combine_flows (ogg, pad, GST_FLOW_OK); goto done; } - -no_buffer: +not_added: { - GST_DEBUG_OBJECT (ogg, - "%p could not get buffer from peer %08lx, %d (%s), combined %d (%s)", - pad, pad->map.serialno, ret, gst_flow_get_name (ret), - cret, gst_flow_get_name (cret)); + GST_DEBUG_OBJECT (ogg, "pad not added yet"); goto done; } } From 60ff7c0eb475f80e8a0e767f432a55485aba0d75 Mon Sep 17 00:00:00 2001 From: Havard Graff Date: Thu, 25 Nov 2010 17:01:04 +0100 Subject: [PATCH 078/254] baseaudiosink: protect against ringbuffer disappearing while in a query Observed a case where the sink went to null-state during the query, hence the ringbuffer-pointer was NULL, causing a crash. Moving the ringbuffer-check code until after the query, and hold the lock during the check and while using the spec-values. It should not matter to the query wether the ringbuffer is present or not, and it actually gets a time bit more time to get the ringbuffer set up in this case! Fixes #635231 --- gst-libs/gst/audio/gstbaseaudiosink.c | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/gst-libs/gst/audio/gstbaseaudiosink.c b/gst-libs/gst/audio/gstbaseaudiosink.c index 8e7760bfa1..b7167b2e7f 100644 --- a/gst-libs/gst/audio/gstbaseaudiosink.c +++ b/gst-libs/gst/audio/gstbaseaudiosink.c @@ -417,13 +417,6 @@ gst_base_audio_sink_query (GstElement * element, GstQuery * query) GST_DEBUG_OBJECT (basesink, "latency query"); - if (!basesink->ringbuffer || !basesink->ringbuffer->spec.rate) { - GST_DEBUG_OBJECT (basesink, - "we are not yet negotiated, can't report latency yet"); - res = FALSE; - goto done; - } - /* ask parent first, it will do an upstream query for us. */ if ((res = gst_base_sink_query_latency (GST_BASE_SINK_CAST (basesink), &live, @@ -434,6 +427,15 @@ gst_base_audio_sink_query (GstElement * element, GstQuery * query) if (live && us_live) { GstRingBufferSpec *spec; + GST_OBJECT_LOCK (basesink); + if (!basesink->ringbuffer || !basesink->ringbuffer->spec.rate) { + GST_OBJECT_UNLOCK (basesink); + + GST_DEBUG_OBJECT (basesink, + "we are not yet negotiated, can't report latency yet"); + res = FALSE; + goto done; + } spec = &basesink->ringbuffer->spec; basesink->priv->us_latency = min_l; @@ -441,6 +443,7 @@ gst_base_audio_sink_query (GstElement * element, GstQuery * query) min_latency = gst_util_uint64_scale_int (spec->seglatency * spec->segsize, GST_SECOND, spec->rate * spec->bytes_per_sample); + GST_OBJECT_UNLOCK (basesink); /* we cannot go lower than the buffer size and the min peer latency */ min_latency = min_latency + min_l; From a5533c21d9fce686038d976052326795552852f5 Mon Sep 17 00:00:00 2001 From: Vincent Penquerc'h Date: Tue, 28 Dec 2010 17:39:58 +0000 Subject: [PATCH 079/254] oggstream: fix interpretation of Theora granule position The offset part of the granpos is not a sign of the newer encoding. Use the version number instead. This fixes the criticals thrown by theoraparse, and (at last) the remaining part of #553244. --- ext/ogg/gstoggstream.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/ext/ogg/gstoggstream.c b/ext/ogg/gstoggstream.c index c9e2cc5841..b3bcd29387 100644 --- a/ext/ogg/gstoggstream.c +++ b/ext/ogg/gstoggstream.c @@ -342,6 +342,11 @@ setup_theora_mapper (GstOggStream * pad, ogg_packet * packet) { guint8 *data = packet->packet; guint w, h, par_d, par_n; + guint8 vmaj, vmin, vrev; + + vmaj = data[7]; + vmin = data[8]; + vrev = data[9]; w = GST_READ_UINT24_BE (data + 14) & 0xFFFFFF; h = GST_READ_UINT24_BE (data + 17) & 0xFFFFFF; @@ -371,6 +376,12 @@ setup_theora_mapper (GstOggStream * pad, ogg_packet * packet) return FALSE; } + /* The interpretation of the granule position has changed with 3.2.1. + The granule is now made from the number of frames encoded, rather than + the index of the frame being encoded - so three is a difference of 1. */ + pad->theora_has_zero_keyoffset = + ((vmaj << 16) | (vmin << 8) | vrev) < 0x030201; + pad->caps = gst_caps_new_simple ("video/x-theora", NULL); if (w > 0 && h > 0) { @@ -398,9 +409,6 @@ granulepos_to_granule_theora (GstOggStream * pad, gint64 granulepos) if (pad->granuleshift != 0) { keyindex = granulepos >> pad->granuleshift; keyoffset = granulepos - (keyindex << pad->granuleshift); - if (keyoffset == 0) { - pad->theora_has_zero_keyoffset = TRUE; - } if (pad->theora_has_zero_keyoffset) { keyoffset++; } From 542256fd55da92d5a72c57fbe5cceb4f8a49df88 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim-Philipp=20M=C3=BCller?= Date: Wed, 29 Dec 2010 11:51:42 +0000 Subject: [PATCH 080/254] ogg: fix typo in comment --- ext/ogg/gstoggstream.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ext/ogg/gstoggstream.c b/ext/ogg/gstoggstream.c index b3bcd29387..572f9ca9f5 100644 --- a/ext/ogg/gstoggstream.c +++ b/ext/ogg/gstoggstream.c @@ -378,7 +378,7 @@ setup_theora_mapper (GstOggStream * pad, ogg_packet * packet) /* The interpretation of the granule position has changed with 3.2.1. The granule is now made from the number of frames encoded, rather than - the index of the frame being encoded - so three is a difference of 1. */ + the index of the frame being encoded - so there is a difference of 1. */ pad->theora_has_zero_keyoffset = ((vmaj << 16) | (vmin << 8) | vrev) < 0x030201; From c41a4d0df48ab3a6f04b3d5750d456fe0c6484a2 Mon Sep 17 00:00:00 2001 From: Andoni Morales Alastruey Date: Wed, 13 Oct 2010 17:09:13 +0200 Subject: [PATCH 081/254] multifdsink: add first and last buffer's timestamp to the stats --- gst/tcp/gstmultifdsink.c | 20 +++++++++++++++++++- gst/tcp/gstmultifdsink.h | 2 ++ 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/gst/tcp/gstmultifdsink.c b/gst/tcp/gstmultifdsink.c index dcc1879b12..f72bfff4dd 100644 --- a/gst/tcp/gstmultifdsink.c +++ b/gst/tcp/gstmultifdsink.c @@ -846,6 +846,8 @@ gst_multi_fd_sink_add_full (GstMultiFdSink * sink, int fd, client->bytes_sent = 0; client->dropped_buffers = 0; client->avg_queue_size = 0; + client->first_buffer_ts = GST_CLOCK_TIME_NONE; + client->last_buffer_ts = GST_CLOCK_TIME_NONE; client->new_connection = TRUE; client->burst_min_unit = min_unit; client->burst_min_value = min_value; @@ -1036,6 +1038,8 @@ restart: * guint64 : time the client is/was connected (in nanoseconds) * guint64 : last activity time (in nanoseconds, since Epoch) * guint64 : buffers dropped due to recovery + * guint64 : timestamp of the first buffer sent (in nanoseconds) + * guint64 : timestamp of the last buffer sent (in nanoseconds) */ GValueArray * gst_multi_fd_sink_get_stats (GstMultiFdSink * sink, int fd) @@ -1054,7 +1058,7 @@ gst_multi_fd_sink_get_stats (GstMultiFdSink * sink, int fd) GValue value = { 0 }; guint64 interval; - result = g_value_array_new (5); + result = g_value_array_new (7); g_value_init (&value, G_TYPE_UINT64); g_value_set_uint64 (&value, client->bytes_sent); @@ -1088,6 +1092,14 @@ gst_multi_fd_sink_get_stats (GstMultiFdSink * sink, int fd) g_value_init (&value, G_TYPE_UINT64); g_value_set_uint64 (&value, client->dropped_buffers); result = g_value_array_append (result, &value); + g_value_unset (&value); + g_value_init (&value, G_TYPE_UINT64); + g_value_set_uint64 (&value, client->first_buffer_ts); + result = g_value_array_append (result, &value); + g_value_unset (&value); + g_value_init (&value, G_TYPE_UINT64); + g_value_set_uint64 (&value, client->last_buffer_ts); + result = g_value_array_append (result, &value); } noclient: @@ -2065,6 +2077,12 @@ gst_multi_fd_sink_handle_client_write (GstMultiFdSink * sink, buf = g_array_index (sink->bufqueue, GstBuffer *, client->bufpos); client->bufpos--; + /* update stats */ + if (client->first_buffer_ts == GST_CLOCK_TIME_NONE) + client->first_buffer_ts = GST_BUFFER_TIMESTAMP (buf); + client->last_buffer_ts = GST_BUFFER_TIMESTAMP (buf); + + /* decrease flushcount */ if (client->flushcount != -1) client->flushcount--; diff --git a/gst/tcp/gstmultifdsink.h b/gst/tcp/gstmultifdsink.h index d2d9ce4e5b..0ee7888527 100644 --- a/gst/tcp/gstmultifdsink.h +++ b/gst/tcp/gstmultifdsink.h @@ -176,6 +176,8 @@ typedef struct { guint64 last_activity_time; guint64 dropped_buffers; guint64 avg_queue_size; + guint64 first_buffer_ts; + guint64 last_buffer_ts; } GstTCPClient; #define CLIENTS_LOCK_INIT(fdsink) (g_static_rec_mutex_init(&fdsink->clientslock)) From b1696cf21d5400095a4371c351f485c30f7cbd3a Mon Sep 17 00:00:00 2001 From: Wim Taymans Date: Wed, 29 Dec 2010 12:53:36 +0100 Subject: [PATCH 082/254] multifdsink: only keep last valid timestamp Fixes #634397 --- gst/tcp/gstmultifdsink.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/gst/tcp/gstmultifdsink.c b/gst/tcp/gstmultifdsink.c index f72bfff4dd..4072eefb87 100644 --- a/gst/tcp/gstmultifdsink.c +++ b/gst/tcp/gstmultifdsink.c @@ -2052,6 +2052,7 @@ gst_multi_fd_sink_handle_client_write (GstMultiFdSink * sink, } else { /* client can pick a buffer from the global queue */ GstBuffer *buf; + GstClockTime timestamp; /* for new connections, we need to find a good spot in the * bufqueue to start streaming from */ @@ -2078,10 +2079,11 @@ gst_multi_fd_sink_handle_client_write (GstMultiFdSink * sink, client->bufpos--; /* update stats */ + timestamp = GST_BUFFER_TIMESTAMP (buf); if (client->first_buffer_ts == GST_CLOCK_TIME_NONE) - client->first_buffer_ts = GST_BUFFER_TIMESTAMP (buf); - client->last_buffer_ts = GST_BUFFER_TIMESTAMP (buf); - + client->first_buffer_ts = timestamp; + if (timestamp != -1) + client->last_buffer_ts = timestamp; /* decrease flushcount */ if (client->flushcount != -1) From bb786dfb5cc480b0329876b123e468a26031cf71 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim-Philipp=20M=C3=BCller?= Date: Wed, 29 Dec 2010 22:36:41 +0000 Subject: [PATCH 083/254] typefinding: assume EBML files without doctype are matroska https://bugzilla.gnome.org/show_bug.cgi?id=638019 --- gst/typefind/gsttypefindfunctions.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/gst/typefind/gsttypefindfunctions.c b/gst/typefind/gsttypefindfunctions.c index 5944c70ff1..640f769dd8 100644 --- a/gst/typefind/gsttypefindfunctions.c +++ b/gst/typefind/gsttypefindfunctions.c @@ -3184,6 +3184,10 @@ ebml_check_header (GstTypeFind * tf, const gchar * doctype, int doctype_len) if (!data) return FALSE; + /* only check doctype if asked to do so */ + if (doctype == NULL || doctype_len == 0) + return TRUE; + /* the header must contain the doctype. For now, we don't parse the * whole header but simply check for the availability of that array * of characters inside the header. Not fully fool-proof, but good @@ -3204,6 +3208,8 @@ matroska_type_find (GstTypeFind * tf, gpointer ununsed) { if (ebml_check_header (tf, "matroska", 8)) gst_type_find_suggest (tf, GST_TYPE_FIND_MAXIMUM, MATROSKA_CAPS); + else if (ebml_check_header (tf, NULL, 0)) + gst_type_find_suggest (tf, GST_TYPE_FIND_LIKELY, MATROSKA_CAPS); } /*** video/webm ***/ From 678753b32514950e76d2d0b85ea707154560fa18 Mon Sep 17 00:00:00 2001 From: Wim Taymans Date: Thu, 30 Dec 2010 18:08:05 +0100 Subject: [PATCH 084/254] baseaudiopay: fix timestamps on buffer lists Fix the outgoing timestamps and RTP timestamps on outgoing buffers when using buffer lists. --- gst-libs/gst/rtp/gstbasertpaudiopayload.c | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/gst-libs/gst/rtp/gstbasertpaudiopayload.c b/gst-libs/gst/rtp/gstbasertpaudiopayload.c index 512455a69d..d8ba21bf3f 100644 --- a/gst-libs/gst/rtp/gstbasertpaudiopayload.c +++ b/gst-libs/gst/rtp/gstbasertpaudiopayload.c @@ -482,12 +482,11 @@ gst_base_rtp_audio_payload_push (GstBaseRTPAudioPayload * baseaudiopayload, static GstFlowReturn gst_base_rtp_audio_payload_push_buffer (GstBaseRTPAudioPayload * - baseaudiopayload, GstBuffer * buffer) + baseaudiopayload, GstBuffer * buffer, GstClockTime timestamp) { GstBaseRTPPayload *basepayload; GstBaseRTPAudioPayloadPrivate *priv; GstBuffer *outbuf; - GstClockTime timestamp; guint8 *payload; guint payload_len; GstFlowReturn ret; @@ -496,7 +495,6 @@ gst_base_rtp_audio_payload_push_buffer (GstBaseRTPAudioPayload * basepayload = GST_BASE_RTP_PAYLOAD (baseaudiopayload); payload_len = GST_BUFFER_SIZE (buffer); - timestamp = GST_BUFFER_TIMESTAMP (buffer); GST_DEBUG_OBJECT (baseaudiopayload, "Pushing %d bytes ts %" GST_TIME_FORMAT, payload_len, GST_TIME_ARGS (timestamp)); @@ -607,7 +605,9 @@ gst_base_rtp_audio_payload_flush (GstBaseRTPAudioPayload * baseaudiopayload, * anything. */ buffer = gst_adapter_take_buffer (adapter, payload_len); - ret = gst_base_rtp_audio_payload_push_buffer (baseaudiopayload, buffer); + ret = + gst_base_rtp_audio_payload_push_buffer (baseaudiopayload, buffer, + timestamp); } else { /* create buffer to hold the payload */ outbuf = gst_rtp_buffer_new_allocate (payload_len, 0, 0); @@ -814,23 +814,22 @@ gst_base_rtp_audio_payload_handle_buffer (GstBaseRTPPayload * guint align; guint size; gboolean discont; + GstClockTime timestamp; ret = GST_FLOW_OK; payload = GST_BASE_RTP_AUDIO_PAYLOAD_CAST (basepayload); priv = payload->priv; + timestamp = GST_BUFFER_TIMESTAMP (buffer); discont = GST_BUFFER_IS_DISCONT (buffer); if (discont) { - GstClockTime timestamp; GST_DEBUG_OBJECT (payload, "Got DISCONT"); /* flush everything out of the adapter, mark DISCONT */ ret = gst_base_rtp_audio_payload_flush (payload, -1, -1); priv->discont = TRUE; - timestamp = GST_BUFFER_TIMESTAMP (buffer); - /* get the distance between the timestamp gap and produce the same gap in * the RTP timestamps */ if (priv->last_timestamp != -1 && timestamp != -1) { @@ -878,7 +877,7 @@ gst_base_rtp_audio_payload_handle_buffer (GstBaseRTPPayload * /* If buffer fits on an RTP packet, let's just push it through * this will check against max_ptime and max_mtu */ GST_DEBUG_OBJECT (payload, "Fast packet push"); - ret = gst_base_rtp_audio_payload_push_buffer (payload, buffer); + ret = gst_base_rtp_audio_payload_push_buffer (payload, buffer, timestamp); } else { /* push the buffer in the adapter */ gst_adapter_push (priv->adapter, buffer); From 84f95ae2829cb3ea7e023e6512b2736a7bd76068 Mon Sep 17 00:00:00 2001 From: Stefan Kost Date: Tue, 29 Jan 2008 07:38:31 +0000 Subject: [PATCH 085/254] Replace the switch plugin with the selector plugin. Add output-selector as the opposite of input-selector (was switc... Original commit message from CVS: * configure.ac: * docs/plugins/Makefile.am: * docs/plugins/gst-plugins-bad-plugins-docs.sgml: * docs/plugins/gst-plugins-bad-plugins-sections.txt: * docs/plugins/gst-plugins-bad-plugins.args: * docs/plugins/gst-plugins-bad-plugins.hierarchy: * docs/plugins/gst-plugins-bad-plugins.interfaces: * docs/plugins/gst-plugins-bad-plugins.signals: * docs/plugins/inspect/plugin-metadata.xml: * docs/plugins/inspect/plugin-selector.xml: * docs/plugins/inspect/plugin-soundtouch.xml: * docs/plugins/inspect/plugin-switch.xml: * gst/selector/.cvsignore: * gst/selector/Makefile.am: * gst/selector/gstinputselector.c: * gst/selector/gstinputselector.h: * gst/selector/gstoutputselector.c: * gst/selector/gstoutputselector.h: * gst/selector/gstselector-marshal.list: * gst/selector/gstselector.c: * gst/selector/selector.vcproj: * gst/switch/.cvsignore: * gst/switch/Makefile.am: * gst/switch/gstswitch-marshal.list: * gst/switch/gstswitch.c: * gst/switch/gstswitch.h: * gst/switch/switch.vcproj: * tests/icles/.cvsignore: * tests/icles/Makefile.am: * tests/icles/output-selector-test.c: Replace the switch plugin with the selector plugin. Add output- selector as the opposite of input-selectoo (was switch). Add a test for output-selector. Add docs for the elements. The vcproj needs update. Fixes #500142. --- tests/icles/output-selector-test.c | 149 +++++++++++++++++++++++++++++ 1 file changed, 149 insertions(+) create mode 100755 tests/icles/output-selector-test.c diff --git a/tests/icles/output-selector-test.c b/tests/icles/output-selector-test.c new file mode 100755 index 0000000000..304295cdb3 --- /dev/null +++ b/tests/icles/output-selector-test.c @@ -0,0 +1,149 @@ +#include + +//[.. my_bus_callback goes here ..] + +static GMainLoop *loop; + +static gboolean +my_bus_callback (GstBus * bus, GstMessage * message, gpointer data) +{ + g_print ("Got %s message\n", GST_MESSAGE_TYPE_NAME (message)); + + switch (GST_MESSAGE_TYPE (message)) { + case GST_MESSAGE_ERROR:{ + GError *err; + gchar *debug; + + gst_message_parse_error (message, &err, &debug); + g_print ("Error: %s\n", err->message); + g_error_free (err); + g_free (debug); + + g_main_loop_quit (loop); + break; + } + case GST_MESSAGE_EOS: + /* end-of-stream */ + g_main_loop_quit (loop); + break; + default: + /* unhandled message */ + break; + } + /* we want to be notified again the next time there is a message + * on the bus, so returning TRUE (FALSE means we want to stop watching + * for messages on the bus and our callback should not be called again) + */ + return TRUE; +} + +static gboolean +switch_cb (gpointer user_data) +{ + + GstElement *sel = GST_ELEMENT (user_data); + gchar *old_pad_name, *new_pad_name; + + g_object_get (G_OBJECT (sel), "active-pad", &old_pad_name, NULL); + + if (g_str_equal (old_pad_name, "src0")) + new_pad_name = "src1"; + else + new_pad_name = "src0"; + + g_object_set (G_OBJECT (sel), "active-pad", new_pad_name, NULL); + + g_print ("switched from %s to %s\n", old_pad_name, new_pad_name); + g_free (old_pad_name); + + return TRUE; + +} + +gint +main (gint argc, gchar * argv[]) +{ + GstElement *pipeline, *src, *toverlay, *osel, *sink1, *sink2, *convert; + GstPad *osel_src1, *osel_src2, *sinkpad; + GstBus *bus; + + /* init GStreamer */ + gst_init (&argc, &argv); + loop = g_main_loop_new (NULL, FALSE); + + /* create elements */ + pipeline = gst_element_factory_make ("pipeline", "pipeline"); + src = gst_element_factory_make ("videotestsrc", "src"); + toverlay = gst_element_factory_make ("timeoverlay", "timeoverlay"); + osel = gst_element_factory_make ("output-selector", "osel"); + convert = gst_element_factory_make ("ffmpegcolorspace", "convert"); + sink1 = gst_element_factory_make ("xvimagesink", "sink1"); + sink2 = gst_element_factory_make ("ximagesink", "sink2"); + + if (!pipeline || !src || !toverlay || !osel || !convert || !sink1 || !sink2) { + g_print ("missing element\n"); + return -1; + } + + /* add them to bin */ + gst_bin_add_many (GST_BIN (pipeline), src, toverlay, osel, convert, sink1, + sink2, NULL); + + /* set properties */ + g_object_set (G_OBJECT (src), "is-live", TRUE, NULL); + g_object_set (G_OBJECT (src), "do-timestamp", TRUE, NULL); + g_object_set (G_OBJECT (src), "num-buffers", 500, NULL); + g_object_set (G_OBJECT (sink1), "sync", FALSE, NULL); + g_object_set (G_OBJECT (sink2), "sync", FALSE, NULL); + g_object_set (G_OBJECT (osel), "resend-latest", TRUE, NULL); + + /* link src ! timeoverlay ! osel */ + if (!gst_element_link_many (src, toverlay, osel, NULL)) { + g_print ("linking failed\n"); + return -1; + } + + /* link output 1 */ + sinkpad = gst_element_get_static_pad (sink1, "sink"); + osel_src1 = gst_element_get_request_pad (osel, "src%d"); + if (gst_pad_link (osel_src1, sinkpad) != GST_PAD_LINK_OK) { + g_print ("linking output 1 failed\n"); + return -1; + } + gst_object_unref (sinkpad); + + /* link output 2 */ + sinkpad = gst_element_get_static_pad (convert, "sink"); + osel_src2 = gst_element_get_request_pad (osel, "src%d"); + if (gst_pad_link (osel_src2, sinkpad) != GST_PAD_LINK_OK) { + g_print ("linking output 2 failed\n"); + return -1; + } + gst_object_unref (sinkpad); + + if (!gst_element_link (convert, sink2)) { + g_print ("linking output 2 failed\n"); + return -1; + } + + /* add switch callback */ + g_timeout_add (1000, switch_cb, osel); + + /* change to playing */ + bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline)); + gst_bus_add_watch (bus, my_bus_callback, loop); + gst_object_unref (bus); + + gst_element_set_state (pipeline, GST_STATE_PLAYING); + + /* now run */ + g_main_loop_run (loop); + + /* also clean up */ + gst_element_set_state (pipeline, GST_STATE_NULL); + gst_element_release_request_pad (osel, osel_src1); + gst_element_release_request_pad (osel, osel_src2); + gst_object_unref (GST_OBJECT (pipeline)); + + return 0; +} From db777f1767f77a3c01df12b2bd4c36b5ecfc9da6 Mon Sep 17 00:00:00 2001 From: Stefan Kost Date: Thu, 7 Feb 2008 13:48:20 +0000 Subject: [PATCH 086/254] tests/icles/output-selector-test.c: Add a fixme comment. Original commit message from CVS: * gst/multifile/gstmultifilesink.c: Add a fixme comment. * gst/selector/gstoutputselector.c: Fix same leak as in input-selector. * tests/icles/output-selector-test.c: Improve the test. --- tests/icles/output-selector-test.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/icles/output-selector-test.c b/tests/icles/output-selector-test.c index 304295cdb3..b158b68ed4 100755 --- a/tests/icles/output-selector-test.c +++ b/tests/icles/output-selector-test.c @@ -93,8 +93,8 @@ main (gint argc, gchar * argv[]) g_object_set (G_OBJECT (src), "is-live", TRUE, NULL); g_object_set (G_OBJECT (src), "do-timestamp", TRUE, NULL); g_object_set (G_OBJECT (src), "num-buffers", 500, NULL); - g_object_set (G_OBJECT (sink1), "sync", FALSE, NULL); - g_object_set (G_OBJECT (sink2), "sync", FALSE, NULL); + g_object_set (G_OBJECT (sink1), "sync", FALSE, "async", FALSE, NULL); + g_object_set (G_OBJECT (sink2), "sync", FALSE, "async", FALSE, NULL); g_object_set (G_OBJECT (osel), "resend-latest", TRUE, NULL); /* link src ! timeoverlay ! osel */ From 4253fc77c66b32b2aa885b62d59eb7a061d85b73 Mon Sep 17 00:00:00 2001 From: Stefan Kost Date: Thu, 19 Jun 2008 13:18:24 +0000 Subject: [PATCH 087/254] tests: Use BOILERPLATE macro and update output-selector test to the latest api changes. Original commit message from CVS: * gst/selector/gstoutputselector.c: * tests/icles/output-selector-test.c: Use BOILERPLATE macro and update test to the latest api changes. --- tests/icles/output-selector-test.c | 32 ++++++++++++++++++------------ 1 file changed, 19 insertions(+), 13 deletions(-) diff --git a/tests/icles/output-selector-test.c b/tests/icles/output-selector-test.c index b158b68ed4..1d54b34a2b 100755 --- a/tests/icles/output-selector-test.c +++ b/tests/icles/output-selector-test.c @@ -1,9 +1,14 @@ #include -//[.. my_bus_callback goes here ..] +#define SWITCH_TIMEOUT 1000 +#define NUM_VIDEO_BUFFERS 500 static GMainLoop *loop; +/* Output selector src pads */ +static GstPad *osel_src1 = NULL; +static GstPad *osel_src2 = NULL; + static gboolean my_bus_callback (GstBus * bus, GstMessage * message, gpointer data) { @@ -40,21 +45,22 @@ my_bus_callback (GstBus * bus, GstMessage * message, gpointer data) static gboolean switch_cb (gpointer user_data) { - GstElement *sel = GST_ELEMENT (user_data); - gchar *old_pad_name, *new_pad_name; + GstPad *old_pad, *new_pad = NULL; - g_object_get (G_OBJECT (sel), "active-pad", &old_pad_name, NULL); + g_object_get (G_OBJECT (sel), "active-pad", &old_pad, NULL); - if (g_str_equal (old_pad_name, "src0")) - new_pad_name = "src1"; + if (old_pad == osel_src1) + new_pad = osel_src2; else - new_pad_name = "src0"; + new_pad = osel_src1; - g_object_set (G_OBJECT (sel), "active-pad", new_pad_name, NULL); + g_object_set (G_OBJECT (sel), "active-pad", new_pad, NULL); - g_print ("switched from %s to %s\n", old_pad_name, new_pad_name); - g_free (old_pad_name); + g_print ("switched from %s:%s to %s:%s\n", GST_DEBUG_PAD_NAME (old_pad), + GST_DEBUG_PAD_NAME (new_pad)); + + gst_object_unref (old_pad); return TRUE; @@ -64,7 +70,7 @@ gint main (gint argc, gchar * argv[]) { GstElement *pipeline, *src, *toverlay, *osel, *sink1, *sink2, *convert; - GstPad *osel_src1, *osel_src2, *sinkpad; + GstPad *sinkpad; GstBus *bus; /* init GStreamer */ @@ -92,7 +98,7 @@ main (gint argc, gchar * argv[]) /* set properties */ g_object_set (G_OBJECT (src), "is-live", TRUE, NULL); g_object_set (G_OBJECT (src), "do-timestamp", TRUE, NULL); - g_object_set (G_OBJECT (src), "num-buffers", 500, NULL); + g_object_set (G_OBJECT (src), "num-buffers", NUM_VIDEO_BUFFERS, NULL); g_object_set (G_OBJECT (sink1), "sync", FALSE, "async", FALSE, NULL); g_object_set (G_OBJECT (sink2), "sync", FALSE, "async", FALSE, NULL); g_object_set (G_OBJECT (osel), "resend-latest", TRUE, NULL); @@ -127,7 +133,7 @@ main (gint argc, gchar * argv[]) } /* add switch callback */ - g_timeout_add (1000, switch_cb, osel); + g_timeout_add (SWITCH_TIMEOUT, switch_cb, osel); /* change to playing */ bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline)); From 526ee4b5337afe3422b82d3598d0a1c683c33e05 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= Date: Tue, 24 Feb 2009 16:33:51 +0100 Subject: [PATCH 088/254] tests: move examples directory to tests/examples as in every other GStreamer module --- tests/icles/input-selector-test.c | 162 ++++++++++++++++++++++++++++++ 1 file changed, 162 insertions(+) create mode 100644 tests/icles/input-selector-test.c diff --git a/tests/icles/input-selector-test.c b/tests/icles/input-selector-test.c new file mode 100644 index 0000000000..4742c03376 --- /dev/null +++ b/tests/icles/input-selector-test.c @@ -0,0 +1,162 @@ +/* GStreamer + * Copyright (C) 2003 Julien Moutte + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif +#include +#include + + +#include + +static GMainLoop *loop = NULL; + +static gboolean +my_bus_callback (GstBus * bus, GstMessage * message, gpointer data) +{ + g_print ("Got %s message\n", GST_MESSAGE_TYPE_NAME (message)); + + switch (GST_MESSAGE_TYPE (message)) { + case GST_MESSAGE_ERROR:{ + GError *err; + gchar *debug; + + gst_message_parse_error (message, &err, &debug); + g_print ("Error: %s\n", err->message); + g_error_free (err); + g_free (debug); + + g_main_loop_quit (loop); + break; + } + case GST_MESSAGE_EOS: + /* end-of-stream */ + g_main_loop_quit (loop); + break; + default: + /* unhandled message */ + break; + } + + /* we want to be notified again the next time there is a message + * on the bus, so returning TRUE (FALSE means we want to stop watching + * for messages on the bus and our callback should not be called again) + */ + return TRUE; +} + + + +static gboolean +switch_timer (GstElement * video_switch) +{ + gint nb_sources; + GstPad *active_pad, *new_pad; + gchar *active_name; + + g_message ("switching"); + g_object_get (G_OBJECT (video_switch), "n-pads", &nb_sources, NULL); + g_object_get (G_OBJECT (video_switch), "active-pad", &active_pad, NULL); + + active_name = gst_pad_get_name (active_pad); + if (strcmp (active_name, "sink0") == 0) { + new_pad = gst_element_get_static_pad (video_switch, "sink1"); + } else { + new_pad = gst_element_get_static_pad (video_switch, "sink0"); + } + g_object_set (G_OBJECT (video_switch), "active-pad", new_pad, NULL); + g_free (active_name); + gst_object_unref (new_pad); + + g_message ("current number of sources : %d, active source %s", + nb_sources, gst_pad_get_name (active_pad)); + + return (GST_STATE (GST_ELEMENT (video_switch)) == GST_STATE_PLAYING); +} + +static void +last_message_received (GObject * segment) +{ + gchar *last_message; + + g_object_get (segment, "last_message", &last_message, NULL); + g_print ("last-message: %s\n", last_message); + g_free (last_message); +} + +int +main (int argc, char *argv[]) +{ + GstElement *pipeline, *src1, *src2, *video_switch, *video_sink, *segment; + GstElement *sink1_sync, *sink2_sync, *capsfilter; + GstBus *bus; + + /* Initing GStreamer library */ + gst_init (&argc, &argv); + + loop = g_main_loop_new (NULL, FALSE); + + pipeline = gst_pipeline_new ("pipeline"); + src1 = gst_element_factory_make ("videotestsrc", "src1"); + g_object_set (G_OBJECT (src1), "pattern", 0, NULL); + src2 = gst_element_factory_make ("videotestsrc", "src2"); + g_object_set (G_OBJECT (src2), "pattern", 1, NULL); + capsfilter = gst_element_factory_make ("capsfilter", "caps0"); + g_object_set (G_OBJECT (capsfilter), "caps", + gst_caps_from_string ("video/x-raw-rgb,width=640,height=480"), NULL); + video_switch = gst_element_factory_make ("input-selector", "video_switch"); + segment = gst_element_factory_make ("identity", "identity-segment"); + g_object_set (G_OBJECT (segment), "silent", TRUE, NULL); + g_signal_connect (G_OBJECT (segment), "notify::last-message", + G_CALLBACK (last_message_received), segment); + g_object_set (G_OBJECT (segment), "single-segment", TRUE, NULL); + video_sink = gst_element_factory_make ("ximagesink", "video_sink"); + g_object_set (G_OBJECT (video_sink), "sync", FALSE, NULL); + sink1_sync = gst_element_factory_make ("identity", "sink0_sync"); + g_object_set (G_OBJECT (sink1_sync), "sync", TRUE, NULL); + sink2_sync = gst_element_factory_make ("identity", "sink1_sync"); + g_object_set (G_OBJECT (sink2_sync), "sync", TRUE, NULL); + gst_bin_add_many (GST_BIN (pipeline), src1, src2, segment, video_switch, + video_sink, sink1_sync, sink2_sync, capsfilter, NULL); + gst_element_link (src1, sink1_sync); + gst_element_link (sink1_sync, video_switch); + gst_element_link (src2, capsfilter); + gst_element_link (capsfilter, sink2_sync); + gst_element_link (sink2_sync, video_switch); + gst_element_link (video_switch, segment); + gst_element_link (segment, /*scaler); + gst_element_link (scaler, */ video_sink); + + bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline)); + gst_bus_add_watch (bus, my_bus_callback, NULL); + gst_object_unref (bus); + gst_element_set_state (GST_ELEMENT (pipeline), GST_STATE_PLAYING); + + g_timeout_add (200, (GSourceFunc) switch_timer, video_switch); + + g_main_loop_run (loop); + + gst_element_set_state (GST_ELEMENT (pipeline), GST_STATE_READY); + + /* unref */ + gst_object_unref (GST_OBJECT (pipeline)); + + exit (0); +} From 3b6eb6e32b7f942178c358a289483aea406769a8 Mon Sep 17 00:00:00 2001 From: Michael Smith Date: Tue, 27 Oct 2009 11:51:05 -0700 Subject: [PATCH 089/254] tests: Remove executable bits from non-executable files. --- tests/icles/output-selector-test.c | 0 1 file changed, 0 insertions(+), 0 deletions(-) mode change 100755 => 100644 tests/icles/output-selector-test.c diff --git a/tests/icles/output-selector-test.c b/tests/icles/output-selector-test.c old mode 100755 new mode 100644 From 52bdb195b2a1b2c5a208a690060579888ba6b5c0 Mon Sep 17 00:00:00 2001 From: Stefan Kost Date: Wed, 24 Nov 2010 12:22:01 +0200 Subject: [PATCH 090/254] output-selector-test: don't hardcode videosinks and use more colorspace conv. Use autovideosink instead of hardcoded sinks. Use an additional colorspace converter between videotestsrc and timeoverlay. --- tests/icles/output-selector-test.c | 46 +++++++++++++++++++++--------- 1 file changed, 32 insertions(+), 14 deletions(-) diff --git a/tests/icles/output-selector-test.c b/tests/icles/output-selector-test.c index 1d54b34a2b..24ad2835dc 100644 --- a/tests/icles/output-selector-test.c +++ b/tests/icles/output-selector-test.c @@ -66,10 +66,16 @@ switch_cb (gpointer user_data) } +static void +on_bin_element_added (GstBin * bin, GstElement * element, gpointer user_data) +{ + g_object_set (G_OBJECT (element), "sync", FALSE, "async", FALSE, NULL); +} + gint main (gint argc, gchar * argv[]) { - GstElement *pipeline, *src, *toverlay, *osel, *sink1, *sink2, *convert; + GstElement *pipeline, *src, *toverlay, *osel, *sink1, *sink2, *c1, *c2, *c0; GstPad *sinkpad; GstBus *bus; @@ -80,54 +86,66 @@ main (gint argc, gchar * argv[]) /* create elements */ pipeline = gst_element_factory_make ("pipeline", "pipeline"); src = gst_element_factory_make ("videotestsrc", "src"); + c0 = gst_element_factory_make ("ffmpegcolorspace", NULL); toverlay = gst_element_factory_make ("timeoverlay", "timeoverlay"); osel = gst_element_factory_make ("output-selector", "osel"); - convert = gst_element_factory_make ("ffmpegcolorspace", "convert"); - sink1 = gst_element_factory_make ("xvimagesink", "sink1"); - sink2 = gst_element_factory_make ("ximagesink", "sink2"); + c1 = gst_element_factory_make ("ffmpegcolorspace", NULL); + c2 = gst_element_factory_make ("ffmpegcolorspace", NULL); + sink1 = gst_element_factory_make ("autovideosink", "sink1"); + sink2 = gst_element_factory_make ("autovideosink", "sink2"); - if (!pipeline || !src || !toverlay || !osel || !convert || !sink1 || !sink2) { + if (!pipeline || !src || !c0 || !toverlay || !osel || !c1 || !c2 || !sink1 || + !sink2) { g_print ("missing element\n"); return -1; } /* add them to bin */ - gst_bin_add_many (GST_BIN (pipeline), src, toverlay, osel, convert, sink1, + gst_bin_add_many (GST_BIN (pipeline), src, c0, toverlay, osel, c1, sink1, c2, sink2, NULL); /* set properties */ g_object_set (G_OBJECT (src), "is-live", TRUE, NULL); g_object_set (G_OBJECT (src), "do-timestamp", TRUE, NULL); g_object_set (G_OBJECT (src), "num-buffers", NUM_VIDEO_BUFFERS, NULL); - g_object_set (G_OBJECT (sink1), "sync", FALSE, "async", FALSE, NULL); - g_object_set (G_OBJECT (sink2), "sync", FALSE, "async", FALSE, NULL); g_object_set (G_OBJECT (osel), "resend-latest", TRUE, NULL); + /* handle deferred properties */ + g_signal_connect (G_OBJECT (sink1), "element-added", + G_CALLBACK (on_bin_element_added), NULL); + g_signal_connect (G_OBJECT (sink2), "element-added", + G_CALLBACK (on_bin_element_added), NULL); + /* link src ! timeoverlay ! osel */ - if (!gst_element_link_many (src, toverlay, osel, NULL)) { + if (!gst_element_link_many (src, c0, toverlay, osel, NULL)) { g_print ("linking failed\n"); return -1; } /* link output 1 */ - sinkpad = gst_element_get_static_pad (sink1, "sink"); + sinkpad = gst_element_get_static_pad (c1, "sink"); osel_src1 = gst_element_get_request_pad (osel, "src%d"); if (gst_pad_link (osel_src1, sinkpad) != GST_PAD_LINK_OK) { + g_print ("linking output 1 converter failed\n"); + return -1; + } + gst_object_unref (sinkpad); + + if (!gst_element_link (c1, sink1)) { g_print ("linking output 1 failed\n"); return -1; } - gst_object_unref (sinkpad); /* link output 2 */ - sinkpad = gst_element_get_static_pad (convert, "sink"); + sinkpad = gst_element_get_static_pad (c2, "sink"); osel_src2 = gst_element_get_request_pad (osel, "src%d"); if (gst_pad_link (osel_src2, sinkpad) != GST_PAD_LINK_OK) { - g_print ("linking output 2 failed\n"); + g_print ("linking output 2 converter failed\n"); return -1; } gst_object_unref (sinkpad); - if (!gst_element_link (convert, sink2)) { + if (!gst_element_link (c2, sink2)) { g_print ("linking output 2 failed\n"); return -1; } From cfe8ffdf6eed21acb5e477701df42f3b66847e43 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim-Philipp=20M=C3=BCller?= Date: Fri, 31 Dec 2010 01:24:50 +0000 Subject: [PATCH 091/254] tests: add input-selector-test and output-selector-test Moved from gst-plugins-bad into -base, becasue it uses videotestsrc and other elements from -base, so it can't be in core. --- tests/icles/.gitignore | 2 ++ tests/icles/Makefile.am | 12 ++++++++++++ 2 files changed, 14 insertions(+) diff --git a/tests/icles/.gitignore b/tests/icles/.gitignore index 72ace7370c..bd175b1a8b 100644 --- a/tests/icles/.gitignore +++ b/tests/icles/.gitignore @@ -1,4 +1,6 @@ audio-trickplay +input-selector-test +output-selector-test playbin-text position-formats stress-playbin diff --git a/tests/icles/Makefile.am b/tests/icles/Makefile.am index 8fbdb92713..d7a3236b90 100644 --- a/tests/icles/Makefile.am +++ b/tests/icles/Makefile.am @@ -26,6 +26,18 @@ test_xoverlay_LDADD = $(GST_LIBS) $(X_LIBS) $(LIBM) $(GTK_LIBS) \ $(top_builddir)/gst-libs/gst/interfaces/libgstinterfaces-$(GST_MAJORMINOR).la endif +output_selector_test_SOURCES = output-selector-test.c +output_selector_test_CFLAGS = $(GST_PLUGINS_BASE_CFLAGS) $(GST_CFLAGS) +output_selector_test_LDADD = $(GST_LIBS) +output_selector_test_LDFLAGS = $(GST_PLUGIN_LDFLAGS) + +input_selector_test_SOURCES = input-selector-test.c +input_selector_test_CFLAGS = $(GST_PLUGINS_BASE_CFLAGS) $(GST_CFLAGS) +input_selector_test_LDADD = $(GST_LIBS) +input_selector_test_LDFLAGS = $(GST_PLUGIN_LDFLAGS) + +X_TESTS += output-selector-test input-selector-test + else X_TESTS = endif From dcd422271661ee57b926d1004c95ec193a11a742 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim-Philipp=20M=C3=BCller?= Date: Fri, 31 Dec 2010 12:14:22 +0000 Subject: [PATCH 092/254] playbin2: use input-selector from core instead of internal copy --- configure.ac | 2 +- gst/playback/Makefile.am | 2 - gst/playback/gstinputselector.c | 1459 ----------------------------- gst/playback/gstinputselector.h | 84 -- gst/playback/gstplay-marshal.list | 2 - gst/playback/gstplaybin2.c | 10 +- 6 files changed, 3 insertions(+), 1556 deletions(-) delete mode 100644 gst/playback/gstinputselector.c delete mode 100644 gst/playback/gstinputselector.h diff --git a/configure.ac b/configure.ac index ff219a989f..e575024942 100644 --- a/configure.ac +++ b/configure.ac @@ -60,7 +60,7 @@ AC_LIBTOOL_WIN32_DLL AM_PROG_LIBTOOL dnl *** required versions of GStreamer stuff *** -GST_REQ=0.10.31 +GST_REQ=0.10.31.1 dnl *** autotools stuff **** diff --git a/gst/playback/Makefile.am b/gst/playback/Makefile.am index 01b3d206dc..6e7130e4ce 100644 --- a/gst/playback/Makefile.am +++ b/gst/playback/Makefile.am @@ -17,7 +17,6 @@ libgstplaybin_la_SOURCES = \ gstplaysink.c \ gstplaybasebin.c \ gstplay-enum.c \ - gstinputselector.c \ gststreaminfo.c \ gststreamselector.c \ gstsubtitleoverlay.c \ @@ -56,7 +55,6 @@ noinst_HEADERS = \ gstplaybasebin.h \ gstplaysink.h \ gststreaminfo.h \ - gstinputselector.h \ gstplay-enum.h \ gststreamselector.h \ gstrawcaps.h \ diff --git a/gst/playback/gstinputselector.c b/gst/playback/gstinputselector.c deleted file mode 100644 index d561d95731..0000000000 --- a/gst/playback/gstinputselector.c +++ /dev/null @@ -1,1459 +0,0 @@ -/* GStreamer - * Copyright (C) 2003 Julien Moutte - * Copyright (C) 2005 Ronald S. Bultje - * Copyright (C) 2005 Jan Schmidt - * Copyright (C) 2007 Wim Taymans - * Copyright (C) 2007 Andy Wingo - * Copyright (C) 2008 Nokia Corporation. (contact ) - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -/** - * SECTION:element-input-selector - * @see_also: #GstOutputSelector - * - * Direct one out of N input streams to the output pad. - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include - -#include "gstinputselector.h" -#include "gstplay-marshal.h" - -GST_DEBUG_CATEGORY_STATIC (input_selector_debug); -#define GST_CAT_DEFAULT input_selector_debug - -static GstStaticPadTemplate gst_input_selector_sink_factory = -GST_STATIC_PAD_TEMPLATE ("sink%d", - GST_PAD_SINK, - GST_PAD_REQUEST, - GST_STATIC_CAPS_ANY); - -static GstStaticPadTemplate gst_input_selector_src_factory = -GST_STATIC_PAD_TEMPLATE ("src", - GST_PAD_SRC, - GST_PAD_ALWAYS, - GST_STATIC_CAPS_ANY); - -enum -{ - PROP_0, - PROP_N_PADS, - PROP_ACTIVE_PAD, - PROP_SELECT_ALL, - PROP_LAST -}; - -#define DEFAULT_PAD_ALWAYS_OK TRUE - -enum -{ - PROP_PAD_0, - PROP_PAD_RUNNING_TIME, - PROP_PAD_TAGS, - PROP_PAD_ACTIVE, - PROP_PAD_ALWAYS_OK, - PROP_PAD_LAST -}; - -enum -{ - /* methods */ - SIGNAL_BLOCK, - SIGNAL_SWITCH, - LAST_SIGNAL -}; -static guint gst_input_selector_signals[LAST_SIGNAL] = { 0 }; - -static inline gboolean gst_input_selector_is_active_sinkpad (GstInputSelector * - sel, GstPad * pad); -static GstPad *gst_input_selector_activate_sinkpad (GstInputSelector * sel, - GstPad * pad); -static GstPad *gst_input_selector_get_linked_pad (GstPad * pad, - gboolean strict); -static gboolean gst_input_selector_check_eos (GstElement * selector); - -#define GST_TYPE_SELECTOR_PAD \ - (gst_selector_pad_get_type()) -#define GST_SELECTOR_PAD(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_SELECTOR_PAD, GstSelectorPad)) -#define GST_SELECTOR_PAD_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_SELECTOR_PAD, GstSelectorPadClass)) -#define GST_IS_SELECTOR_PAD(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_SELECTOR_PAD)) -#define GST_IS_SELECTOR_PAD_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_SELECTOR_PAD)) -#define GST_SELECTOR_PAD_CAST(obj) \ - ((GstSelectorPad *)(obj)) - -typedef struct _GstSelectorPad GstSelectorPad; -typedef struct _GstSelectorPadClass GstSelectorPadClass; - -struct _GstSelectorPad -{ - GstPad parent; - - gboolean active; /* when buffer have passed the pad */ - gboolean eos; /* when EOS has been received */ - gboolean discont; /* after switching we create a discont */ - gboolean always_ok; - GstSegment segment; /* the current segment on the pad */ - GstTagList *tags; /* last tags received on the pad */ - - gboolean segment_pending; -}; - -struct _GstSelectorPadClass -{ - GstPadClass parent; -}; - -static void gst_selector_pad_class_init (GstSelectorPadClass * klass); -static void gst_selector_pad_init (GstSelectorPad * pad); -static void gst_selector_pad_finalize (GObject * object); -static void gst_selector_pad_get_property (GObject * object, - guint prop_id, GValue * value, GParamSpec * pspec); -static void gst_selector_pad_set_property (GObject * object, - guint prop_id, const GValue * value, GParamSpec * pspec); - -static GstPadClass *selector_pad_parent_class = NULL; - -static gint64 gst_selector_pad_get_running_time (GstSelectorPad * pad); -static void gst_selector_pad_reset (GstSelectorPad * pad); -static gboolean gst_selector_pad_event (GstPad * pad, GstEvent * event); -static GstCaps *gst_selector_pad_getcaps (GstPad * pad); -static gboolean gst_selector_pad_acceptcaps (GstPad * pad, GstCaps * caps); -static GstIterator *gst_selector_pad_iterate_linked_pads (GstPad * pad); -static GstFlowReturn gst_selector_pad_chain (GstPad * pad, GstBuffer * buf); -static GstFlowReturn gst_selector_pad_bufferalloc (GstPad * pad, - guint64 offset, guint size, GstCaps * caps, GstBuffer ** buf); - -static GType -gst_selector_pad_get_type (void) -{ - static GType selector_pad_type = 0; - - if (!selector_pad_type) { - static const GTypeInfo selector_pad_info = { - sizeof (GstSelectorPadClass), - NULL, - NULL, - (GClassInitFunc) gst_selector_pad_class_init, - NULL, - NULL, - sizeof (GstSelectorPad), - 0, - (GInstanceInitFunc) gst_selector_pad_init, - }; - - selector_pad_type = - g_type_register_static (GST_TYPE_PAD, "GstPlaybin2SelectorPad", - &selector_pad_info, 0); - } - return selector_pad_type; -} - -static void -gst_selector_pad_class_init (GstSelectorPadClass * klass) -{ - GObjectClass *gobject_class; - - gobject_class = (GObjectClass *) klass; - - selector_pad_parent_class = g_type_class_peek_parent (klass); - - gobject_class->finalize = gst_selector_pad_finalize; - - gobject_class->get_property = gst_selector_pad_get_property; - gobject_class->set_property = gst_selector_pad_set_property; - - g_object_class_install_property (gobject_class, PROP_PAD_RUNNING_TIME, - g_param_spec_int64 ("running-time", "Running time", - "Running time of stream on pad", 0, G_MAXINT64, 0, - G_PARAM_READABLE | G_PARAM_STATIC_STRINGS)); - g_object_class_install_property (gobject_class, PROP_PAD_TAGS, - g_param_spec_boxed ("tags", "Tags", - "The currently active tags on the pad", GST_TYPE_TAG_LIST, - G_PARAM_READABLE | G_PARAM_STATIC_STRINGS)); - g_object_class_install_property (gobject_class, PROP_PAD_ACTIVE, - g_param_spec_boolean ("active", "Active", - "If the pad is currently active", FALSE, - G_PARAM_READABLE | G_PARAM_STATIC_STRINGS)); - g_object_class_install_property (gobject_class, PROP_PAD_ALWAYS_OK, - g_param_spec_boolean ("always-ok", "Always OK", - "Make an inactive pad return OK instead of NOT_LINKED", - DEFAULT_PAD_ALWAYS_OK, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); -} - -static void -gst_selector_pad_init (GstSelectorPad * pad) -{ - pad->always_ok = DEFAULT_PAD_ALWAYS_OK; - gst_selector_pad_reset (pad); -} - -static void -gst_selector_pad_finalize (GObject * object) -{ - GstSelectorPad *pad; - - pad = GST_SELECTOR_PAD_CAST (object); - - if (pad->tags) - gst_tag_list_free (pad->tags); - - G_OBJECT_CLASS (selector_pad_parent_class)->finalize (object); -} - -static void -gst_selector_pad_set_property (GObject * object, guint prop_id, - const GValue * value, GParamSpec * pspec) -{ - GstSelectorPad *spad = GST_SELECTOR_PAD_CAST (object); - - switch (prop_id) { - case PROP_PAD_ALWAYS_OK: - GST_OBJECT_LOCK (object); - spad->always_ok = g_value_get_boolean (value); - GST_OBJECT_UNLOCK (object); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -gst_selector_pad_get_property (GObject * object, guint prop_id, - GValue * value, GParamSpec * pspec) -{ - GstSelectorPad *spad = GST_SELECTOR_PAD_CAST (object); - - switch (prop_id) { - case PROP_PAD_RUNNING_TIME: - g_value_set_int64 (value, gst_selector_pad_get_running_time (spad)); - break; - case PROP_PAD_TAGS: - GST_OBJECT_LOCK (object); - g_value_set_boxed (value, spad->tags); - GST_OBJECT_UNLOCK (object); - break; - case PROP_PAD_ACTIVE: - { - GstInputSelector *sel; - - sel = GST_INPUT_SELECTOR (gst_pad_get_parent (spad)); - g_value_set_boolean (value, gst_input_selector_is_active_sinkpad (sel, - GST_PAD_CAST (spad))); - gst_object_unref (sel); - break; - } - case PROP_PAD_ALWAYS_OK: - GST_OBJECT_LOCK (object); - g_value_set_boolean (value, spad->always_ok); - GST_OBJECT_UNLOCK (object); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static gint64 -gst_selector_pad_get_running_time (GstSelectorPad * pad) -{ - gint64 ret = 0; - - GST_OBJECT_LOCK (pad); - if (pad->active) { - gint64 last_stop = pad->segment.last_stop; - - if (last_stop >= 0) - ret = gst_segment_to_running_time (&pad->segment, GST_FORMAT_TIME, - last_stop); - } - GST_OBJECT_UNLOCK (pad); - - GST_DEBUG_OBJECT (pad, "running time: %" GST_TIME_FORMAT, - GST_TIME_ARGS (ret)); - - return ret; -} - -static void -gst_selector_pad_reset (GstSelectorPad * pad) -{ - GST_OBJECT_LOCK (pad); - pad->active = FALSE; - pad->eos = FALSE; - pad->segment_pending = FALSE; - pad->discont = FALSE; - gst_segment_init (&pad->segment, GST_FORMAT_UNDEFINED); - GST_OBJECT_UNLOCK (pad); -} - -/* strictly get the linked pad from the sinkpad. If the pad is active we return - * the srcpad else we return NULL */ -static GstIterator * -gst_selector_pad_iterate_linked_pads (GstPad * pad) -{ - GstInputSelector *sel = GST_INPUT_SELECTOR (gst_pad_get_parent (pad)); - GstPad *otherpad; - GstIterator *it; - - otherpad = gst_input_selector_get_linked_pad (pad, TRUE); - it = gst_iterator_new_single (GST_TYPE_PAD, otherpad, - (GstCopyFunction) gst_object_ref, (GFreeFunc) gst_object_unref); - - if (otherpad) - gst_object_unref (otherpad); - gst_object_unref (sel); - - return it; -} - -static gboolean -gst_selector_pad_event (GstPad * pad, GstEvent * event) -{ - gboolean res = TRUE; - gboolean forward = TRUE; - GstInputSelector *sel; - GstSelectorPad *selpad; - GstPad *prev_active_sinkpad; - GstPad *active_sinkpad; - - sel = GST_INPUT_SELECTOR (gst_pad_get_parent (pad)); - selpad = GST_SELECTOR_PAD_CAST (pad); - - GST_INPUT_SELECTOR_LOCK (sel); - prev_active_sinkpad = sel->active_sinkpad; - active_sinkpad = gst_input_selector_activate_sinkpad (sel, pad); - - /* only forward if we are dealing with the active sinkpad or if select_all - * is enabled */ - if (pad != active_sinkpad && !sel->select_all) - forward = FALSE; - GST_INPUT_SELECTOR_UNLOCK (sel); - - if (prev_active_sinkpad != active_sinkpad && pad == active_sinkpad) - g_object_notify (G_OBJECT (sel), "active-pad"); - - switch (GST_EVENT_TYPE (event)) { - case GST_EVENT_FLUSH_START: - /* FIXME, flush out the waiter */ - break; - case GST_EVENT_FLUSH_STOP: - GST_INPUT_SELECTOR_LOCK (sel); - gst_selector_pad_reset (selpad); - sel->pending_close = FALSE; - GST_INPUT_SELECTOR_UNLOCK (sel); - break; - case GST_EVENT_NEWSEGMENT: - { - gboolean update; - GstFormat format; - gdouble rate, arate; - gint64 start, stop, time; - - gst_event_parse_new_segment_full (event, &update, &rate, &arate, &format, - &start, &stop, &time); - - GST_DEBUG_OBJECT (pad, - "configured NEWSEGMENT update %d, rate %lf, applied rate %lf, " - "format %d, " - "%" G_GINT64_FORMAT " -- %" G_GINT64_FORMAT ", time %" - G_GINT64_FORMAT, update, rate, arate, format, start, stop, time); - - GST_INPUT_SELECTOR_LOCK (sel); - GST_OBJECT_LOCK (selpad); - gst_segment_set_newsegment_full (&selpad->segment, update, - rate, arate, format, start, stop, time); - GST_OBJECT_UNLOCK (selpad); - - /* If we aren't forwarding the event (because the pad is not the - * active_sinkpad, and select_all is not set, then set the flag on the - * that says a segment needs sending if/when that pad is activated. - * For all other cases, we send the event immediately, which makes - * sparse streams and other segment updates work correctly downstream. - */ - if (!forward) - selpad->segment_pending = TRUE; - - GST_INPUT_SELECTOR_UNLOCK (sel); - break; - } - case GST_EVENT_TAG: - { - GstTagList *tags, *oldtags, *newtags; - - gst_event_parse_tag (event, &tags); - - GST_OBJECT_LOCK (selpad); - oldtags = selpad->tags; - - newtags = gst_tag_list_merge (oldtags, tags, GST_TAG_MERGE_REPLACE); - selpad->tags = newtags; - if (oldtags) - gst_tag_list_free (oldtags); - GST_DEBUG_OBJECT (pad, "received tags %" GST_PTR_FORMAT, newtags); - GST_OBJECT_UNLOCK (selpad); - - g_object_notify (G_OBJECT (selpad), "tags"); - break; - } - case GST_EVENT_EOS: - selpad->eos = TRUE; - GST_DEBUG_OBJECT (pad, "received EOS"); - /* don't forward eos in select_all mode until all sink pads have eos */ - if (sel->select_all && !gst_input_selector_check_eos (GST_ELEMENT (sel))) { - forward = FALSE; - } - break; - default: - break; - } - if (forward) { - GST_DEBUG_OBJECT (pad, "forwarding event"); - res = gst_pad_push_event (sel->srcpad, event); - } else - gst_event_unref (event); - - gst_object_unref (sel); - - return res; -} - -static GstCaps * -gst_selector_pad_getcaps (GstPad * pad) -{ - GstInputSelector *sel; - GstCaps *caps; - - sel = GST_INPUT_SELECTOR (gst_pad_get_parent (pad)); - - GST_DEBUG_OBJECT (sel, "Getting caps of srcpad peer"); - caps = gst_pad_peer_get_caps_reffed (sel->srcpad); - if (caps == NULL) - caps = gst_caps_new_any (); - - gst_object_unref (sel); - - return caps; -} - -static gboolean -gst_selector_pad_acceptcaps (GstPad * pad, GstCaps * caps) -{ - GstInputSelector *sel; - gboolean res; - - sel = GST_INPUT_SELECTOR (gst_pad_get_parent (pad)); - - GST_DEBUG_OBJECT (sel, "Checking acceptcaps of srcpad peer"); - res = gst_pad_peer_accept_caps (sel->srcpad, caps); - gst_object_unref (sel); - - return res; -} - -static GstFlowReturn -gst_selector_pad_bufferalloc (GstPad * pad, guint64 offset, - guint size, GstCaps * caps, GstBuffer ** buf) -{ - GstInputSelector *sel; - GstFlowReturn result; - GstPad *active_sinkpad; - GstPad *prev_active_sinkpad; - GstSelectorPad *selpad; - - sel = GST_INPUT_SELECTOR (gst_pad_get_parent (pad)); - selpad = GST_SELECTOR_PAD_CAST (pad); - - GST_LOG_OBJECT (pad, "received alloc"); - - GST_INPUT_SELECTOR_LOCK (sel); - prev_active_sinkpad = sel->active_sinkpad; - active_sinkpad = gst_input_selector_activate_sinkpad (sel, pad); - - if (pad != active_sinkpad) - goto not_active; - - GST_INPUT_SELECTOR_UNLOCK (sel); - - if (prev_active_sinkpad != active_sinkpad && pad == active_sinkpad) - g_object_notify (G_OBJECT (sel), "active-pad"); - - result = gst_pad_alloc_buffer (sel->srcpad, offset, size, caps, buf); - -done: - gst_object_unref (sel); - - return result; - - /* ERRORS */ -not_active: - { - GST_INPUT_SELECTOR_UNLOCK (sel); - - /* unselected pad, perform fallback alloc or return unlinked when - * asked */ - GST_OBJECT_LOCK (selpad); - if (selpad->always_ok) { - GST_DEBUG_OBJECT (pad, "Not selected, performing fallback allocation"); - *buf = NULL; - result = GST_FLOW_OK; - } else { - GST_DEBUG_OBJECT (pad, "Not selected, return NOT_LINKED"); - result = GST_FLOW_NOT_LINKED; - } - GST_OBJECT_UNLOCK (selpad); - - goto done; - } -} - -/* must be called with the SELECTOR_LOCK, will block while the pad is blocked - * or return TRUE when flushing */ -static gboolean -gst_input_selector_wait (GstInputSelector * self, GstPad * pad) -{ - while (self->blocked && !self->flushing) { - /* we can be unlocked here when we are shutting down (flushing) or when we - * get unblocked */ - GST_INPUT_SELECTOR_WAIT (self); - } - return self->flushing; -} - -static GstFlowReturn -gst_selector_pad_chain (GstPad * pad, GstBuffer * buf) -{ - GstInputSelector *sel; - GstFlowReturn res; - GstPad *active_sinkpad; - GstPad *prev_active_sinkpad; - GstSelectorPad *selpad; - GstClockTime start_time; - GstSegment *seg; - GstEvent *close_event = NULL, *start_event = NULL; - GstCaps *caps; - - sel = GST_INPUT_SELECTOR (gst_pad_get_parent (pad)); - selpad = GST_SELECTOR_PAD_CAST (pad); - seg = &selpad->segment; - - GST_INPUT_SELECTOR_LOCK (sel); - /* wait or check for flushing */ - if (gst_input_selector_wait (sel, pad)) - goto flushing; - - GST_LOG_OBJECT (pad, "getting active pad"); - - prev_active_sinkpad = sel->active_sinkpad; - active_sinkpad = gst_input_selector_activate_sinkpad (sel, pad); - - /* update the segment on the srcpad */ - start_time = GST_BUFFER_TIMESTAMP (buf); - if (GST_CLOCK_TIME_IS_VALID (start_time)) { - GST_LOG_OBJECT (pad, "received start time %" GST_TIME_FORMAT, - GST_TIME_ARGS (start_time)); - if (GST_BUFFER_DURATION_IS_VALID (buf)) - GST_LOG_OBJECT (pad, "received end time %" GST_TIME_FORMAT, - GST_TIME_ARGS (start_time + GST_BUFFER_DURATION (buf))); - - GST_OBJECT_LOCK (pad); - gst_segment_set_last_stop (seg, seg->format, start_time); - GST_OBJECT_UNLOCK (pad); - } - - /* Ignore buffers from pads except the selected one */ - if (pad != active_sinkpad) - goto ignore; - - if (G_UNLIKELY (sel->pending_close)) { - GstSegment *cseg = &sel->segment; - - GST_DEBUG_OBJECT (sel, - "pushing close NEWSEGMENT update %d, rate %lf, applied rate %lf, " - "format %d, " - "%" G_GINT64_FORMAT " -- %" G_GINT64_FORMAT ", time %" - G_GINT64_FORMAT, TRUE, cseg->rate, cseg->applied_rate, cseg->format, - cseg->start, cseg->stop, cseg->time); - - /* create update segment */ - close_event = gst_event_new_new_segment_full (TRUE, cseg->rate, - cseg->applied_rate, cseg->format, cseg->start, cseg->stop, cseg->time); - - sel->pending_close = FALSE; - } - /* if we have a pending segment, push it out now */ - if (G_UNLIKELY (selpad->segment_pending)) { - GST_DEBUG_OBJECT (pad, - "pushing pending NEWSEGMENT update %d, rate %lf, applied rate %lf, " - "format %d, " - "%" G_GINT64_FORMAT " -- %" G_GINT64_FORMAT ", time %" - G_GINT64_FORMAT, FALSE, seg->rate, seg->applied_rate, seg->format, - seg->start, seg->stop, seg->time); - - start_event = gst_event_new_new_segment_full (FALSE, seg->rate, - seg->applied_rate, seg->format, seg->start, seg->stop, seg->time); - - selpad->segment_pending = FALSE; - } - GST_INPUT_SELECTOR_UNLOCK (sel); - - if (prev_active_sinkpad != active_sinkpad && pad == active_sinkpad) - g_object_notify (G_OBJECT (sel), "active-pad"); - - if (close_event) - gst_pad_push_event (sel->srcpad, close_event); - - if (start_event) - gst_pad_push_event (sel->srcpad, start_event); - - if (selpad->discont) { - buf = gst_buffer_make_metadata_writable (buf); - - GST_DEBUG_OBJECT (pad, "Marking discont buffer %p", buf); - GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_DISCONT); - selpad->discont = FALSE; - } - - /* forward */ - GST_LOG_OBJECT (pad, "Forwarding buffer %p", buf); - - if ((caps = GST_BUFFER_CAPS (buf))) { - if (GST_PAD_CAPS (sel->srcpad) != caps) - gst_pad_set_caps (sel->srcpad, caps); - } - - res = gst_pad_push (sel->srcpad, buf); - -done: - gst_object_unref (sel); - return res; - - /* dropped buffers */ -ignore: - { - GST_DEBUG_OBJECT (pad, "Pad not active, discard buffer %p", buf); - /* when we drop a buffer, we're creating a discont on this pad */ - selpad->discont = TRUE; - GST_INPUT_SELECTOR_UNLOCK (sel); - gst_buffer_unref (buf); - - /* figure out what to return upstream */ - GST_OBJECT_LOCK (selpad); - if (selpad->always_ok) - res = GST_FLOW_OK; - else - res = GST_FLOW_NOT_LINKED; - GST_OBJECT_UNLOCK (selpad); - - goto done; - } -flushing: - { - GST_DEBUG_OBJECT (pad, "We are flushing, discard buffer %p", buf); - GST_INPUT_SELECTOR_UNLOCK (sel); - gst_buffer_unref (buf); - res = GST_FLOW_WRONG_STATE; - goto done; - } -} - -static void gst_input_selector_init (GstInputSelector * sel); -static void gst_input_selector_base_init (GstInputSelectorClass * klass); -static void gst_input_selector_class_init (GstInputSelectorClass * klass); - -static void gst_input_selector_dispose (GObject * object); - -static void gst_input_selector_set_property (GObject * object, - guint prop_id, const GValue * value, GParamSpec * pspec); -static void gst_input_selector_get_property (GObject * object, - guint prop_id, GValue * value, GParamSpec * pspec); - -static GstPad *gst_input_selector_request_new_pad (GstElement * element, - GstPadTemplate * templ, const gchar * unused); -static void gst_input_selector_release_pad (GstElement * element, GstPad * pad); - -static GstStateChangeReturn gst_input_selector_change_state (GstElement * - element, GstStateChange transition); - -static GstCaps *gst_input_selector_getcaps (GstPad * pad); -static gboolean gst_input_selector_event (GstPad * pad, GstEvent * event); -static gboolean gst_input_selector_query (GstPad * pad, GstQuery * query); -static gint64 gst_input_selector_block (GstInputSelector * self); -static void gst_input_selector_switch (GstInputSelector * self, - GstPad * pad, gint64 stop_time, gint64 start_time); - -static GstElementClass *parent_class = NULL; - -GType -gst_input_selector_get_type (void) -{ - static GType input_selector_type = 0; - - if (!input_selector_type) { - static const GTypeInfo input_selector_info = { - sizeof (GstInputSelectorClass), - (GBaseInitFunc) gst_input_selector_base_init, - NULL, - (GClassInitFunc) gst_input_selector_class_init, - NULL, - NULL, - sizeof (GstInputSelector), - 0, - (GInstanceInitFunc) gst_input_selector_init, - }; - input_selector_type = - g_type_register_static (GST_TYPE_ELEMENT, - "GstPlaybin2InputSelector", &input_selector_info, 0); - GST_DEBUG_CATEGORY_INIT (input_selector_debug, - "playbin2-input-selector", 0, "Playbin2 input stream selector element"); - } - - return input_selector_type; -} - -static void -gst_input_selector_base_init (GstInputSelectorClass * klass) -{ - GstElementClass *element_class = GST_ELEMENT_CLASS (klass); - - gst_element_class_set_details_simple (element_class, - "Input selector", "Generic", - "N-to-1 input stream selectoring", - "Julien Moutte , " - "Jan Schmidt , " - "Wim Taymans "); - gst_element_class_add_pad_template (element_class, - gst_static_pad_template_get (&gst_input_selector_sink_factory)); - gst_element_class_add_pad_template (element_class, - gst_static_pad_template_get (&gst_input_selector_src_factory)); -} - -static void -gst_input_selector_class_init (GstInputSelectorClass * klass) -{ - GObjectClass *gobject_class = G_OBJECT_CLASS (klass); - GstElementClass *gstelement_class = GST_ELEMENT_CLASS (klass); - - parent_class = g_type_class_peek_parent (klass); - - /* FIXME: remove after confirming it is safe now */ - g_type_class_ref (gst_selector_pad_get_type ()); - - gobject_class->dispose = gst_input_selector_dispose; - - gobject_class->set_property = gst_input_selector_set_property; - gobject_class->get_property = gst_input_selector_get_property; - - g_object_class_install_property (gobject_class, PROP_N_PADS, - g_param_spec_uint ("n-pads", "Number of Pads", - "The number of sink pads", 0, G_MAXUINT, 0, - G_PARAM_READABLE | G_PARAM_STATIC_STRINGS)); - - g_object_class_install_property (gobject_class, PROP_ACTIVE_PAD, - g_param_spec_object ("active-pad", "Active pad", - "The currently active sink pad", GST_TYPE_PAD, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - - g_object_class_install_property (gobject_class, PROP_SELECT_ALL, - g_param_spec_boolean ("select-all", "Select all mode", - "Forwards data from all input pads", FALSE, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - - /** - * GstInputSelector::block: - * @inputselector: the #GstInputSelector - * - * Block all sink pads in preparation for a switch. Returns the stop time of - * the current switch segment, as a running time, or 0 if there is no current - * active pad or the current active pad never received data. - */ - gst_input_selector_signals[SIGNAL_BLOCK] = - g_signal_new ("block", G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION, - G_STRUCT_OFFSET (GstInputSelectorClass, block), NULL, NULL, - gst_play_marshal_INT64__VOID, G_TYPE_INT64, 0); - /** - * GstInputSelector::switch: - * @inputselector: the #GstInputSelector - * @pad: the pad to switch to - * @stop_time: running time at which to close the previous segment, or -1 - * to use the running time of the previously active sink pad - * @start_time: running time at which to start the new segment, or -1 to - * use the running time of the newly active sink pad - * - * Switch to a new feed. The segment opened by the previously active pad, if - * any, will be closed, and a new segment opened before data flows again. - * - * This signal must be emitted when the element has been blocked via the block signal. - * - * If you have a stream with only one switch element, such as an audio-only - * stream, a stream switch should be performed by first emitting the block - * signal, and then emitting the switch signal with -1 for the stop and start - * time values. - * - * The intention of the @stop_time and @start_time arguments is to allow - * multiple switch elements to switch and maintain stream synchronization. - * When switching a stream with multiple feeds, you will need as many switch - * elements as you have feeds. For example, a feed with audio and video will - * have one switch element between the audio feeds and one for video. - * - * A switch over multiple switch elements should be performed as follows: - * First, emit the block - * signal, collecting the returned values. The maximum running time returned - * by block should then be used as the time at which to close the previous - * segment. - * - * Then, query the running times of the new audio and video pads that you will - * switch to. Naturally, these pads are on separate switch elements. Take the - * minimum running time for those streams and use it for the time at which to - * open the new segment. - * - * If @pad is the same as the current active pad, the element will cancel any - * previous block without adjusting segments. - * - * - * the signal changed from accepting the pad name to the pad object. - * - * - * Since: 0.10.7 - */ - gst_input_selector_signals[SIGNAL_SWITCH] = - g_signal_new ("switch", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (GstInputSelectorClass, switch_), - NULL, NULL, gst_play_marshal_VOID__OBJECT_INT64_INT64, - G_TYPE_NONE, 3, GST_TYPE_PAD, G_TYPE_INT64, G_TYPE_INT64); - - gstelement_class->request_new_pad = gst_input_selector_request_new_pad; - gstelement_class->release_pad = gst_input_selector_release_pad; - gstelement_class->change_state = gst_input_selector_change_state; - - klass->block = GST_DEBUG_FUNCPTR (gst_input_selector_block); - /* note the underscore because switch is a keyword otherwise */ - klass->switch_ = GST_DEBUG_FUNCPTR (gst_input_selector_switch); -} - -static void -gst_input_selector_init (GstInputSelector * sel) -{ - sel->srcpad = gst_pad_new ("src", GST_PAD_SRC); - gst_pad_set_iterate_internal_links_function (sel->srcpad, - GST_DEBUG_FUNCPTR (gst_selector_pad_iterate_linked_pads)); - gst_pad_set_getcaps_function (sel->srcpad, - GST_DEBUG_FUNCPTR (gst_input_selector_getcaps)); - gst_pad_set_query_function (sel->srcpad, - GST_DEBUG_FUNCPTR (gst_input_selector_query)); - gst_pad_set_event_function (sel->srcpad, - GST_DEBUG_FUNCPTR (gst_input_selector_event)); - gst_element_add_pad (GST_ELEMENT (sel), sel->srcpad); - /* sinkpad management */ - sel->active_sinkpad = NULL; - sel->padcount = 0; - gst_segment_init (&sel->segment, GST_FORMAT_UNDEFINED); - - sel->lock = g_mutex_new (); - sel->cond = g_cond_new (); - sel->blocked = FALSE; - - sel->select_all = FALSE; -} - -static void -gst_input_selector_dispose (GObject * object) -{ - GstInputSelector *sel = GST_INPUT_SELECTOR (object); - - if (sel->active_sinkpad) { - gst_object_unref (sel->active_sinkpad); - sel->active_sinkpad = NULL; - } - if (sel->lock) { - g_mutex_free (sel->lock); - sel->lock = NULL; - } - if (sel->cond) { - g_cond_free (sel->cond); - sel->cond = NULL; - } - - G_OBJECT_CLASS (parent_class)->dispose (object); -} - -/* Solve the following equation for B.timestamp, and set that as the segment - * stop: - * B.running_time = (B.timestamp - NS.start) / NS.abs_rate + NS.accum - */ -static gint64 -gst_segment_get_timestamp (GstSegment * segment, gint64 running_time) -{ - if (running_time <= segment->accum) - return segment->start; - else - return (running_time - segment->accum) * segment->abs_rate + segment->start; -} - -static void -gst_segment_set_stop (GstSegment * segment, gint64 running_time) -{ - segment->stop = gst_segment_get_timestamp (segment, running_time); - segment->last_stop = -1; -} - -static void -gst_segment_set_start (GstSegment * segment, gint64 running_time) -{ - gint64 new_start, duration; - - new_start = gst_segment_get_timestamp (segment, running_time); - - /* this is the duration we skipped */ - duration = new_start - segment->start; - /* add the duration to the accumulated segment time */ - segment->accum += duration; - /* move position in the segment */ - segment->time += duration; - segment->start += duration; -} - -/* this function must be called with the SELECTOR_LOCK. It returns TRUE when the - * active pad changed. */ -static gboolean -gst_input_selector_set_active_pad (GstInputSelector * self, - GstPad * pad, gint64 stop_time, gint64 start_time) -{ - GstSelectorPad *old, *new; - GstPad **active_pad_p; - - if (pad == self->active_sinkpad) - return FALSE; - - old = GST_SELECTOR_PAD_CAST (self->active_sinkpad); - new = GST_SELECTOR_PAD_CAST (pad); - - GST_DEBUG_OBJECT (self, "setting active pad to %s:%s", - GST_DEBUG_PAD_NAME (new)); - - if (!GST_CLOCK_TIME_IS_VALID (stop_time) && old) { - /* no stop time given, get the latest running_time on the active pad to - * close and open the new segment */ - stop_time = start_time = gst_selector_pad_get_running_time (old); - GST_DEBUG_OBJECT (self, "using start/stop of %" GST_TIME_FORMAT, - GST_TIME_ARGS (start_time)); - } - - if (old && old->active && !self->pending_close && stop_time >= 0) { - /* schedule a last_stop update if one isn't already scheduled, and a - segment has been pushed before. */ - memcpy (&self->segment, &old->segment, sizeof (self->segment)); - - GST_DEBUG_OBJECT (self, "setting stop_time to %" GST_TIME_FORMAT, - GST_TIME_ARGS (stop_time)); - gst_segment_set_stop (&self->segment, stop_time); - self->pending_close = TRUE; - } - - if (new && new->active && start_time >= 0) { - GST_DEBUG_OBJECT (self, "setting start_time to %" GST_TIME_FORMAT, - GST_TIME_ARGS (start_time)); - /* schedule a new segment push */ - gst_segment_set_start (&new->segment, start_time); - new->segment_pending = TRUE; - } - - active_pad_p = &self->active_sinkpad; - gst_object_replace ((GstObject **) active_pad_p, GST_OBJECT_CAST (pad)); - GST_DEBUG_OBJECT (self, "New active pad is %" GST_PTR_FORMAT, - self->active_sinkpad); - - return TRUE; -} - -static void -gst_input_selector_set_property (GObject * object, guint prop_id, - const GValue * value, GParamSpec * pspec) -{ - GstInputSelector *sel = GST_INPUT_SELECTOR (object); - - switch (prop_id) { - case PROP_ACTIVE_PAD: - { - GstPad *pad; - - pad = g_value_get_object (value); - - GST_INPUT_SELECTOR_LOCK (sel); - gst_input_selector_set_active_pad (sel, pad, - GST_CLOCK_TIME_NONE, GST_CLOCK_TIME_NONE); - GST_INPUT_SELECTOR_UNLOCK (sel); - break; - } - case PROP_SELECT_ALL: - GST_INPUT_SELECTOR_LOCK (object); - sel->select_all = g_value_get_boolean (value); - GST_INPUT_SELECTOR_UNLOCK (object); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -gst_input_selector_get_property (GObject * object, guint prop_id, - GValue * value, GParamSpec * pspec) -{ - GstInputSelector *sel = GST_INPUT_SELECTOR (object); - - switch (prop_id) { - case PROP_N_PADS: - GST_INPUT_SELECTOR_LOCK (object); - g_value_set_uint (value, sel->n_pads); - GST_INPUT_SELECTOR_UNLOCK (object); - break; - case PROP_ACTIVE_PAD: - GST_INPUT_SELECTOR_LOCK (object); - g_value_set_object (value, sel->active_sinkpad); - GST_INPUT_SELECTOR_UNLOCK (object); - break; - case PROP_SELECT_ALL: - GST_INPUT_SELECTOR_LOCK (object); - g_value_set_boolean (value, sel->select_all); - GST_INPUT_SELECTOR_UNLOCK (object); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static GstPad * -gst_input_selector_get_linked_pad (GstPad * pad, gboolean strict) -{ - GstInputSelector *sel; - GstPad *otherpad = NULL; - - sel = GST_INPUT_SELECTOR (gst_pad_get_parent (pad)); - - GST_INPUT_SELECTOR_LOCK (sel); - if (pad == sel->srcpad) - otherpad = sel->active_sinkpad; - else if (pad == sel->active_sinkpad || !strict) - otherpad = sel->srcpad; - if (otherpad) - gst_object_ref (otherpad); - GST_INPUT_SELECTOR_UNLOCK (sel); - - gst_object_unref (sel); - - return otherpad; -} - -static gboolean -gst_input_selector_event (GstPad * pad, GstEvent * event) -{ - gboolean res = FALSE; - GstPad *otherpad; - - otherpad = gst_input_selector_get_linked_pad (pad, TRUE); - - if (otherpad) { - res = gst_pad_push_event (otherpad, event); - - gst_object_unref (otherpad); - } else - gst_event_unref (event); - return res; -} - -/* query on the srcpad. We override this function because by default it will - * only forward the query to one random sinkpad */ -static gboolean -gst_input_selector_query (GstPad * pad, GstQuery * query) -{ - gboolean res = TRUE; - GstInputSelector *sel; - GstPad *otherpad; - - sel = GST_INPUT_SELECTOR (gst_pad_get_parent (pad)); - - otherpad = gst_input_selector_get_linked_pad (pad, TRUE); - - switch (GST_QUERY_TYPE (query)) { - case GST_QUERY_LATENCY: - { - GList *walk; - GstClockTime resmin, resmax; - gboolean reslive; - - resmin = 0; - resmax = -1; - reslive = FALSE; - - /* assume FALSE, we become TRUE if one query succeeds */ - res = FALSE; - - /* perform the query on all sinkpads and combine the results. We take the - * max of min and the min of max for the result latency. */ - GST_INPUT_SELECTOR_LOCK (sel); - for (walk = GST_ELEMENT_CAST (sel)->sinkpads; walk; - walk = g_list_next (walk)) { - GstPad *sinkpad = GST_PAD_CAST (walk->data); - - if (gst_pad_peer_query (sinkpad, query)) { - GstClockTime min, max; - gboolean live; - - /* one query succeeded, we succeed too */ - res = TRUE; - - gst_query_parse_latency (query, &live, &min, &max); - - GST_DEBUG_OBJECT (sinkpad, - "peer latency min %" GST_TIME_FORMAT ", max %" GST_TIME_FORMAT - ", live %d", GST_TIME_ARGS (min), GST_TIME_ARGS (max), live); - - if (live) { - if (min > resmin) - resmin = min; - if (resmax == -1) - resmax = max; - else if (max < resmax) - resmax = max; - if (reslive == FALSE) - reslive = live; - } - } - } - GST_INPUT_SELECTOR_UNLOCK (sel); - if (res) { - gst_query_set_latency (query, reslive, resmin, resmax); - - GST_DEBUG_OBJECT (sel, - "total latency min %" GST_TIME_FORMAT ", max %" GST_TIME_FORMAT - ", live %d", GST_TIME_ARGS (resmin), GST_TIME_ARGS (resmax), - reslive); - } - - break; - } - default: - if (otherpad) - res = gst_pad_peer_query (otherpad, query); - break; - } - if (otherpad) - gst_object_unref (otherpad); - gst_object_unref (sel); - - return res; -} - -static GstCaps * -gst_input_selector_getcaps (GstPad * pad) -{ - GstPad *otherpad; - GstObject *parent; - GstCaps *caps; - - parent = gst_object_get_parent (GST_OBJECT (pad)); - - otherpad = gst_input_selector_get_linked_pad (pad, FALSE); - - if (!otherpad) { - if (GST_INPUT_SELECTOR (parent)->select_all) { - GST_DEBUG_OBJECT (parent, - "Pad %s:%s not linked, returning merge of caps", - GST_DEBUG_PAD_NAME (pad)); - caps = gst_pad_proxy_getcaps (pad); - } else { - GST_DEBUG_OBJECT (parent, - "Pad %s:%s not linked, returning ANY", GST_DEBUG_PAD_NAME (pad)); - caps = gst_caps_new_any (); - } - } else { - GST_DEBUG_OBJECT (parent, - "Pad %s:%s is linked (to %s:%s), returning peer caps", - GST_DEBUG_PAD_NAME (pad), GST_DEBUG_PAD_NAME (otherpad)); - /* if the peer has caps, use those. If the pad is not linked, this function - * returns NULL and we return ANY */ - if (!(caps = gst_pad_peer_get_caps_reffed (otherpad))) - caps = gst_caps_new_any (); - gst_object_unref (otherpad); - } - - gst_object_unref (parent); - return caps; -} - -/* check if the pad is the active sinkpad */ -static gboolean -gst_input_selector_is_active_sinkpad (GstInputSelector * sel, GstPad * pad) -{ - gboolean res; - - GST_INPUT_SELECTOR_LOCK (sel); - res = (pad == sel->active_sinkpad); - GST_INPUT_SELECTOR_UNLOCK (sel); - - return res; -} - -/* Get or create the active sinkpad, must be called with SELECTOR_LOCK */ -static GstPad * -gst_input_selector_activate_sinkpad (GstInputSelector * sel, GstPad * pad) -{ - GstPad *active_sinkpad; - GstSelectorPad *selpad; - - selpad = GST_SELECTOR_PAD_CAST (pad); - - selpad->active = TRUE; - active_sinkpad = sel->active_sinkpad; - if (active_sinkpad == NULL || sel->select_all) { - /* first pad we get activity on becomes the activated pad by default, if we - * select all, we also remember the last used pad. */ - if (sel->active_sinkpad) - gst_object_unref (sel->active_sinkpad); - active_sinkpad = sel->active_sinkpad = gst_object_ref (pad); - GST_DEBUG_OBJECT (sel, "Activating pad %s:%s", GST_DEBUG_PAD_NAME (pad)); - } - - return active_sinkpad; -} - -static GstPad * -gst_input_selector_request_new_pad (GstElement * element, - GstPadTemplate * templ, const gchar * unused) -{ - GstInputSelector *sel; - gchar *name = NULL; - GstPad *sinkpad = NULL; - - g_return_val_if_fail (templ->direction == GST_PAD_SINK, NULL); - - sel = GST_INPUT_SELECTOR (element); - - GST_INPUT_SELECTOR_LOCK (sel); - - GST_LOG_OBJECT (sel, "Creating new pad %d", sel->padcount); - name = g_strdup_printf ("sink%d", sel->padcount++); - sinkpad = g_object_new (GST_TYPE_SELECTOR_PAD, - "name", name, "direction", templ->direction, "template", templ, NULL); - g_free (name); - - sel->n_pads++; - - gst_pad_set_event_function (sinkpad, - GST_DEBUG_FUNCPTR (gst_selector_pad_event)); - gst_pad_set_getcaps_function (sinkpad, - GST_DEBUG_FUNCPTR (gst_selector_pad_getcaps)); - gst_pad_set_acceptcaps_function (sinkpad, - GST_DEBUG_FUNCPTR (gst_selector_pad_acceptcaps)); - gst_pad_set_chain_function (sinkpad, - GST_DEBUG_FUNCPTR (gst_selector_pad_chain)); - gst_pad_set_iterate_internal_links_function (sinkpad, - GST_DEBUG_FUNCPTR (gst_selector_pad_iterate_linked_pads)); - gst_pad_set_bufferalloc_function (sinkpad, - GST_DEBUG_FUNCPTR (gst_selector_pad_bufferalloc)); - - gst_pad_set_active (sinkpad, TRUE); - gst_element_add_pad (GST_ELEMENT (sel), sinkpad); - GST_INPUT_SELECTOR_UNLOCK (sel); - - return sinkpad; -} - -static void -gst_input_selector_release_pad (GstElement * element, GstPad * pad) -{ - GstInputSelector *sel; - - sel = GST_INPUT_SELECTOR (element); - GST_LOG_OBJECT (sel, "Releasing pad %s:%s", GST_DEBUG_PAD_NAME (pad)); - - GST_INPUT_SELECTOR_LOCK (sel); - /* if the pad was the active pad, makes us select a new one */ - if (sel->active_sinkpad == pad) { - GST_DEBUG_OBJECT (sel, "Deactivating pad %s:%s", GST_DEBUG_PAD_NAME (pad)); - gst_object_unref (sel->active_sinkpad); - sel->active_sinkpad = NULL; - } - sel->n_pads--; - - gst_pad_set_active (pad, FALSE); - gst_element_remove_pad (GST_ELEMENT (sel), pad); - GST_INPUT_SELECTOR_UNLOCK (sel); -} - -static void -gst_input_selector_reset (GstInputSelector * sel) -{ - GList *walk; - - GST_INPUT_SELECTOR_LOCK (sel); - /* clear active pad */ - if (sel->active_sinkpad) { - gst_object_unref (sel->active_sinkpad); - sel->active_sinkpad = NULL; - } - /* reset segment */ - gst_segment_init (&sel->segment, GST_FORMAT_UNDEFINED); - sel->pending_close = FALSE; - /* reset each of our sinkpads state */ - for (walk = GST_ELEMENT_CAST (sel)->sinkpads; walk; walk = g_list_next (walk)) { - GstSelectorPad *selpad = GST_SELECTOR_PAD_CAST (walk->data); - - gst_selector_pad_reset (selpad); - - if (selpad->tags) { - gst_tag_list_free (selpad->tags); - selpad->tags = NULL; - } - } - GST_INPUT_SELECTOR_UNLOCK (sel); -} - -static GstStateChangeReturn -gst_input_selector_change_state (GstElement * element, - GstStateChange transition) -{ - GstInputSelector *self = GST_INPUT_SELECTOR (element); - GstStateChangeReturn result; - - switch (transition) { - case GST_STATE_CHANGE_READY_TO_PAUSED: - GST_INPUT_SELECTOR_LOCK (self); - self->blocked = FALSE; - self->flushing = FALSE; - GST_INPUT_SELECTOR_UNLOCK (self); - break; - case GST_STATE_CHANGE_PAUSED_TO_READY: - /* first unlock before we call the parent state change function, which - * tries to acquire the stream lock when going to ready. */ - GST_INPUT_SELECTOR_LOCK (self); - self->blocked = FALSE; - self->flushing = TRUE; - GST_INPUT_SELECTOR_BROADCAST (self); - GST_INPUT_SELECTOR_UNLOCK (self); - break; - default: - break; - } - - result = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition); - - switch (transition) { - case GST_STATE_CHANGE_PAUSED_TO_READY: - gst_input_selector_reset (self); - break; - default: - break; - } - - return result; -} - -static gint64 -gst_input_selector_block (GstInputSelector * self) -{ - gint64 ret = 0; - GstSelectorPad *spad; - - GST_INPUT_SELECTOR_LOCK (self); - - if (self->blocked) - GST_WARNING_OBJECT (self, "switch already blocked"); - - self->blocked = TRUE; - spad = GST_SELECTOR_PAD_CAST (self->active_sinkpad); - - if (spad) - ret = gst_selector_pad_get_running_time (spad); - else - GST_DEBUG_OBJECT (self, "no active pad while blocking"); - - GST_INPUT_SELECTOR_UNLOCK (self); - - return ret; -} - -/* stop_time and start_time are running times */ -static void -gst_input_selector_switch (GstInputSelector * self, GstPad * pad, - gint64 stop_time, gint64 start_time) -{ - gboolean changed; - - g_return_if_fail (self->blocked == TRUE); - - GST_INPUT_SELECTOR_LOCK (self); - changed = - gst_input_selector_set_active_pad (self, pad, stop_time, start_time); - - self->blocked = FALSE; - GST_INPUT_SELECTOR_BROADCAST (self); - GST_INPUT_SELECTOR_UNLOCK (self); - - if (changed) - g_object_notify (G_OBJECT (self), "active-pad"); -} - -static gboolean -gst_input_selector_check_eos (GstElement * selector) -{ - GstIterator *it = gst_element_iterate_sink_pads (selector); - GstIteratorResult ires; - gpointer item; - gboolean done = FALSE, is_eos = FALSE; - GstSelectorPad *pad; - - while (!done) { - ires = gst_iterator_next (it, &item); - switch (ires) { - case GST_ITERATOR_DONE: - GST_INFO_OBJECT (selector, "all sink pads have eos"); - done = TRUE; - is_eos = TRUE; - break; - case GST_ITERATOR_OK: - pad = GST_SELECTOR_PAD_CAST (item); - if (!pad->eos) { - done = TRUE; - } - gst_object_unref (pad); - break; - case GST_ITERATOR_RESYNC: - gst_iterator_resync (it); - break; - default: - done = TRUE; - break; - } - } - gst_iterator_free (it); - - return is_eos; -} diff --git a/gst/playback/gstinputselector.h b/gst/playback/gstinputselector.h deleted file mode 100644 index 58a671d50c..0000000000 --- a/gst/playback/gstinputselector.h +++ /dev/null @@ -1,84 +0,0 @@ -/* GStreamer - * Copyright (C) 2003 Julien Moutte - * Copyright (C) 2005 Ronald S. Bultje - * Copyright (C) 2008 Nokia Corporation. (contact ) - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifndef __GST_INPUT_SELECTOR_H__ -#define __GST_INPUT_SELECTOR_H__ - -#include - -G_BEGIN_DECLS - -#define GST_TYPE_INPUT_SELECTOR \ - (gst_input_selector_get_type()) -#define GST_INPUT_SELECTOR(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_INPUT_SELECTOR, GstInputSelector)) -#define GST_INPUT_SELECTOR_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_INPUT_SELECTOR, GstInputSelectorClass)) -#define GST_IS_INPUT_SELECTOR(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_INPUT_SELECTOR)) -#define GST_IS_INPUT_SELECTOR_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_INPUT_SELECTOR)) - -typedef struct _GstInputSelector GstInputSelector; -typedef struct _GstInputSelectorClass GstInputSelectorClass; - -#define GST_INPUT_SELECTOR_GET_LOCK(sel) (((GstInputSelector*)(sel))->lock) -#define GST_INPUT_SELECTOR_GET_COND(sel) (((GstInputSelector*)(sel))->cond) -#define GST_INPUT_SELECTOR_LOCK(sel) (g_mutex_lock (GST_INPUT_SELECTOR_GET_LOCK(sel))) -#define GST_INPUT_SELECTOR_UNLOCK(sel) (g_mutex_unlock (GST_INPUT_SELECTOR_GET_LOCK(sel))) -#define GST_INPUT_SELECTOR_WAIT(sel) (g_cond_wait (GST_INPUT_SELECTOR_GET_COND(sel), \ - GST_INPUT_SELECTOR_GET_LOCK(sel))) -#define GST_INPUT_SELECTOR_BROADCAST(sel) (g_cond_broadcast (GST_INPUT_SELECTOR_GET_COND(sel))) - -struct _GstInputSelector { - GstElement element; - - GstPad *srcpad; - - GstPad *active_sinkpad; - guint n_pads; - guint padcount; - - GstSegment segment; /* the output segment */ - gboolean pending_close; /* if we should push a close first */ - - GMutex *lock; - GCond *cond; - gboolean blocked; - gboolean flushing; - - /* select all mode, send data from all input pads forward */ - gboolean select_all; -}; - -struct _GstInputSelectorClass { - GstElementClass parent_class; - - gint64 (*block) (GstInputSelector *self); - void (*switch_) (GstInputSelector *self, GstPad *pad, - gint64 stop_time, gint64 start_time); -}; - -GType gst_input_selector_get_type (void); - -G_END_DECLS - -#endif /* __GST_INPUT_SELECTOR_H__ */ diff --git a/gst/playback/gstplay-marshal.list b/gst/playback/gstplay-marshal.list index c07fdce7a2..d7eddf445b 100644 --- a/gst/playback/gstplay-marshal.list +++ b/gst/playback/gstplay-marshal.list @@ -8,5 +8,3 @@ BOXED:OBJECT,BOXED,BOXED BOXED:INT OBJECT:BOXED OBJECT:INT -INT64:VOID -VOID:OBJECT,INT64,INT64 diff --git a/gst/playback/gstplaybin2.c b/gst/playback/gstplaybin2.c index 154ffd296a..aa5aa35364 100644 --- a/gst/playback/gstplaybin2.c +++ b/gst/playback/gstplaybin2.c @@ -230,7 +230,6 @@ #include "gstplay-marshal.h" #include "gstplayback.h" #include "gstplaysink.h" -#include "gstinputselector.h" #include "gstsubtitleoverlay.h" GST_DEBUG_CATEGORY_STATIC (gst_play_bin_debug); @@ -2456,11 +2455,8 @@ pad_added_cb (GstElement * decodebin, GstPad * pad, GstSourceGroup * group) GST_SOURCE_GROUP_LOCK (group); if (select->selector == NULL && playbin->have_selector) { /* no selector, create one */ - GST_DEBUG_OBJECT (playbin, "creating new selector"); - select->selector = g_object_new (GST_TYPE_INPUT_SELECTOR, NULL); - /* the above can't fail, but we keep the error handling around for when - * the selector plugin has moved to -base or -good and we stop using an - * internal copy of input-selector */ + GST_DEBUG_OBJECT (playbin, "creating new input selector"); + select->selector = gst_element_factory_make ("input-selector", NULL); if (select->selector == NULL) { /* post the missing selector message only once */ playbin->have_selector = FALSE; @@ -3621,8 +3617,6 @@ gst_play_bin2_plugin_init (GstPlugin * plugin) { GST_DEBUG_CATEGORY_INIT (gst_play_bin_debug, "playbin2", 0, "play bin"); - g_type_class_ref (gst_input_selector_get_type ()); - return gst_element_register (plugin, "playbin2", GST_RANK_NONE, GST_TYPE_PLAY_BIN); } From 9c9afee1cf7744db3772043ca37b6ee66e0c4519 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim-Philipp=20M=C3=BCller?= Date: Sun, 2 Jan 2011 17:21:54 +0000 Subject: [PATCH 093/254] baseaudiosink: default to enable-last-buffer=FALSE for audio sinks There isn't really any good reason to get the last buffer from an audio sink, so don't make the sink keep it around unnecessarily. --- gst-libs/gst/audio/gstbaseaudiosink.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/gst-libs/gst/audio/gstbaseaudiosink.c b/gst-libs/gst/audio/gstbaseaudiosink.c index b7167b2e7f..54ba77548d 100644 --- a/gst-libs/gst/audio/gstbaseaudiosink.c +++ b/gst-libs/gst/audio/gstbaseaudiosink.c @@ -267,6 +267,7 @@ gst_base_audio_sink_init (GstBaseAudioSink * baseaudiosink, GstBaseAudioSinkClass * g_class) { GstPluginFeature *feature; + GstBaseSink *basesink; baseaudiosink->priv = GST_BASE_AUDIO_SINK_GET_PRIVATE (baseaudiosink); @@ -274,13 +275,16 @@ gst_base_audio_sink_init (GstBaseAudioSink * baseaudiosink, baseaudiosink->latency_time = DEFAULT_LATENCY_TIME; baseaudiosink->provide_clock = DEFAULT_PROVIDE_CLOCK; baseaudiosink->priv->slave_method = DEFAULT_SLAVE_METHOD; + baseaudiosink->priv->drift_tolerance = DEFAULT_DRIFT_TOLERANCE; baseaudiosink->provided_clock = gst_audio_clock_new ("GstAudioSinkClock", (GstAudioClockGetTimeFunc) gst_base_audio_sink_get_time, baseaudiosink); - GST_BASE_SINK (baseaudiosink)->can_activate_push = TRUE; - GST_BASE_SINK (baseaudiosink)->can_activate_pull = DEFAULT_CAN_ACTIVATE_PULL; - baseaudiosink->priv->drift_tolerance = DEFAULT_DRIFT_TOLERANCE; + basesink = GST_BASE_SINK_CAST (baseaudiosink); + basesink->can_activate_push = TRUE; + basesink->can_activate_pull = DEFAULT_CAN_ACTIVATE_PULL; + + gst_base_sink_set_last_buffer_enabled (basesink, FALSE); /* install some custom pad_query functions */ gst_pad_set_query_function (GST_BASE_SINK_PAD (baseaudiosink), From e3451e5ab8baa9eecc282f22a1385f03967a8c5f Mon Sep 17 00:00:00 2001 From: David Schleef Date: Sun, 2 Jan 2011 15:48:47 -0800 Subject: [PATCH 094/254] typefind: Add stream-format to h264 caps --- gst/typefind/gsttypefindfunctions.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/gst/typefind/gsttypefindfunctions.c b/gst/typefind/gsttypefindfunctions.c index 640f769dd8..66a5275d64 100644 --- a/gst/typefind/gsttypefindfunctions.c +++ b/gst/typefind/gsttypefindfunctions.c @@ -2126,7 +2126,8 @@ mpeg4_video_type_find (GstTypeFind * tf, gpointer unused) /*** video/x-h264 H264 elementary video stream ***/ -static GstStaticCaps h264_video_caps = GST_STATIC_CAPS ("video/x-h264"); +static GstStaticCaps h264_video_caps = +GST_STATIC_CAPS ("video/x-h264,stream-format=byte-stream"); #define H264_VIDEO_CAPS gst_static_caps_get(&h264_video_caps) From c05ca085daa643eec846d413f35c16b2f53ed9a1 Mon Sep 17 00:00:00 2001 From: Arun Raghavan Date: Tue, 7 Dec 2010 14:59:46 +0530 Subject: [PATCH 095/254] codec-utils: Minor documentation changes --- gst-libs/gst/pbutils/codec-utils.c | 70 +++++++++++++++++------------- 1 file changed, 39 insertions(+), 31 deletions(-) diff --git a/gst-libs/gst/pbutils/codec-utils.c b/gst-libs/gst/pbutils/codec-utils.c index 112d240fce..f885fe1ff1 100644 --- a/gst-libs/gst/pbutils/codec-utils.c +++ b/gst-libs/gst/pbutils/codec-utils.c @@ -25,9 +25,8 @@ * * * - * Provides numerous codec-specific ulility functions such as functions to - * provide the codec profile and level in human-readable string form from - * header data. + * Provides codec-specific ulility functions such as functions to provide the + * codec profile and level in human-readable string form from header data. * * */ @@ -87,7 +86,7 @@ gst_codec_utils_aac_get_sample_rate_from_index (guint sr_idx) * gst_codec_utils_aac_get_profile: * @audio_config: a pointer to the AudioSpecificConfig as specified in the * Elementary Stream Descriptor (esds) in ISO/IEC 14496-1 (see - * below for a more details). + * gst_codec_utils_aac_get_level() for a more details). * @len: Length of @audio_config in bytes * * Returns the profile of the given AAC stream as a string. The profile is @@ -98,7 +97,7 @@ gst_codec_utils_aac_get_sample_rate_from_index (guint sr_idx) * HE-AAC support has not yet been implemented. * * - * Returns: The profile as a const string and NULL if the profile could not be + * Returns: The profile as a const string and %NULL if the profile could not be * determined. * * Since: 0.10.31 @@ -134,8 +133,7 @@ gst_codec_utils_aac_get_profile (const guint8 * audio_config, guint len) /** * gst_codec_utils_aac_get_level: * @audio_config: a pointer to the AudioSpecificConfig as specified in the - * Elementary Stream Descriptor (esds) in ISO/IEC 14496-1 (see - * below for a more detailed description). + * Elementary Stream Descriptor (esds) in ISO/IEC 14496-1. * @len: Length of @audio_config in bytes * * Determines the level of a stream as defined in ISO/IEC 14496-3. For AAC LC @@ -145,17 +143,25 @@ gst_codec_utils_aac_get_profile (const guint8 * audio_config, guint len) * The @audio_config parameter follows the following format, starting from the * most significant bit of the first byte: * - * Bit 0:4 contains the AudioObjectType - * Bit 5:8 contains the sample frequency index (if this is 0xf, then the next - * 24 bits define the actual sample frequency, and subsequent fields - * are appropriately shifted). - * Bit 9:12 contains the channel configuration + * + * + * Bit 0:4 contains the AudioObjectType + * + * + * Bit 5:8 contains the sample frequency index (if this is 0xf, then the + * next 24 bits define the actual sample frequency, and subsequent + * fields are appropriately shifted). + * + * + * Bit 9:12 contains the channel configuration + * + * * * * HE-AAC support has not yet been implemented. * * - * Returns: The level as a const string and NULL if the level could not be + * Returns: The level as a const string and %NULL if the level could not be * determined. * * Since: 0.10.31 @@ -325,12 +331,12 @@ gst_codec_utils_aac_get_level (const guint8 * audio_config, guint len) * @len: Length of @audio_config in bytes * * Sets the level and profile on @caps if it can be determined from - * @audio_config. See #gst_codec_utils_aac_get_level() and + * @audio_config. See gst_codec_utils_aac_get_level() and * gst_codec_utils_aac_get_profile() for more details on the parameters. * @caps must be audio/mpeg caps with an "mpegversion" field of either 2 or 4. * If mpegversion is 4, the "base-profile" field is also set in @caps. * - * Returns: TRUE if the level and profile could be set, FALSE otherwise. + * Returns: %TRUE if the level and profile could be set, %FALSE otherwise. * * Since: 0.10.31 */ @@ -386,16 +392,18 @@ gst_codec_utils_aac_caps_set_level_and_profile (GstCaps * caps, * as a bitstream here, with bit 0 being the most significant bit of the first * byte. * - * Bit 0:7 - Profile indication - * Bit 8 - constraint_set0_flag - * Bit 9 - constraint_set1_flag - * Bit 10 - constraint_set2_flag - * Bit 11 - constraint_set3_flag - * Bit 12 - constraint_set3_flag - * Bit 13:15 - Reserved - * Bit 16:24 - Level indication + * + * Bit 0:7 - Profile indication + * Bit 8 - constraint_set0_flag + * Bit 9 - constraint_set1_flag + * Bit 10 - constraint_set2_flag + * Bit 11 - constraint_set3_flag + * Bit 12 - constraint_set3_flag + * Bit 13:15 - Reserved + * Bit 16:24 - Level indication + * * - * Returns: The profile as a const string, or NULL if there is an error. + * Returns: The profile as a const string, or %NULL if there is an error. * * Since: 0.10.31 */ @@ -466,9 +474,9 @@ gst_codec_utils_h264_get_profile (const guint8 * sps, guint len) * * Converts the level indication (level_idc) in the stream's * sequence parameter set into a string. The SPS is expected to have the - * same format as for @gst_codec_utils_aac_get_profile(). + * same format as for gst_codec_utils_h264_get_profile(). * - * Returns: The level as a const string, or NULL if there is an error. + * Returns: The level as a const string, or %NULL if there is an error. * * Since: 0.10.31 */ @@ -525,10 +533,10 @@ gst_codec_utils_h264_get_level (const guint8 * sps, guint len) * @len: Length of the data available in @sps. * * Sets the level and profile in @caps if it can be determined from @sps. See - * #gst_codec_utils_h264_get_level() and #gst_codec_utils_h264_get_profile() + * gst_codec_utils_h264_get_level() and gst_codec_utils_h264_get_profile() * for more details on the parameters. * - * Returns: TRUE if the level and profile could be set, FALSE otherwise. + * Returns: %TRUE if the level and profile could be set, %FALSE otherwise. * * Since: 0.10.31 */ @@ -724,11 +732,11 @@ gst_codec_utils_mpeg4video_get_level (const guint8 * vis_obj_seq, guint len) * @len: Length of the data available in @sps. * * Sets the level and profile in @caps if it can be determined from - * @vis_obj_seq. See #gst_codec_utils_mpeg4video_get_level() and - * #gst_codec_utils_mpeg4video_get_profile() for more details on the + * @vis_obj_seq. See gst_codec_utils_mpeg4video_get_level() and + * gst_codec_utils_mpeg4video_get_profile() for more details on the * parameters. * - * Returns: TRUE if the level and profile could be set, FALSE otherwise. + * Returns: %TRUE if the level and profile could be set, %FALSE otherwise. * * Since: 0.10.31 */ From 6ce0d6e78bd0b0331addbdd86f2a1eaf73fa78ad Mon Sep 17 00:00:00 2001 From: Edward Hervey Date: Wed, 5 Jan 2011 12:02:02 +0100 Subject: [PATCH 096/254] video: Fix uninitialized variables reported by macosx gcc --- gst-libs/gst/video/video.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/gst-libs/gst/video/video.c b/gst-libs/gst/video/video.c index 6635125b2e..d9fa50b229 100644 --- a/gst-libs/gst/video/video.c +++ b/gst-libs/gst/video/video.c @@ -566,9 +566,9 @@ gst_video_format_new_caps (GstVideoFormat format, int width, } if (gst_video_format_is_rgb (format)) { GstCaps *caps; - int red_mask; - int blue_mask; - int green_mask; + int red_mask = 0; + int blue_mask = 0; + int green_mask = 0; int alpha_mask; int depth; int bpp; From 0a26cd9fcf9aaa606bf728376ae22dc754b17d6e Mon Sep 17 00:00:00 2001 From: Edward Hervey Date: Wed, 5 Jan 2011 15:31:09 +0100 Subject: [PATCH 097/254] pbutils: Don't forget to include the encoding headers --- gst-libs/gst/pbutils/pbutils.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/gst-libs/gst/pbutils/pbutils.h b/gst-libs/gst/pbutils/pbutils.h index 19b1d1f095..b9277b1382 100644 --- a/gst-libs/gst/pbutils/pbutils.h +++ b/gst-libs/gst/pbutils/pbutils.h @@ -29,6 +29,8 @@ #include #include #include +#include +#include G_BEGIN_DECLS From cdd0a9c8bbae36cfdc4ec19f6bff0677a877694e Mon Sep 17 00:00:00 2001 From: Edward Hervey Date: Wed, 5 Jan 2011 19:30:50 +0100 Subject: [PATCH 098/254] encodebin: Convert to new GstElementClass::request_new_pad_full vmethod --- gst/encoding/gstencodebin.c | 119 +++++++++++++++++------------------- 1 file changed, 56 insertions(+), 63 deletions(-) diff --git a/gst/encoding/gstencodebin.c b/gst/encoding/gstencodebin.c index 105d841f08..cccc71d7d2 100644 --- a/gst/encoding/gstencodebin.c +++ b/gst/encoding/gstencodebin.c @@ -198,7 +198,7 @@ static GstStateChangeReturn gst_encode_bin_change_state (GstElement * element, GstStateChange transition); static GstPad *gst_encode_bin_request_new_pad (GstElement * element, - GstPadTemplate * templ, const gchar * name); + GstPadTemplate * templ, const gchar * name, const GstCaps * caps); static void gst_encode_bin_release_pad (GstElement * element, GstPad * pad); static gboolean @@ -283,7 +283,7 @@ gst_encode_bin_class_init (GstEncodeBinClass * klass) gstelement_klass->change_state = GST_DEBUG_FUNCPTR (gst_encode_bin_change_state); - gstelement_klass->request_new_pad = + gstelement_klass->request_new_pad_full = GST_DEBUG_FUNCPTR (gst_encode_bin_request_new_pad); gstelement_klass->release_pad = GST_DEBUG_FUNCPTR (gst_encode_bin_release_pad); @@ -513,71 +513,22 @@ next_unused_stream_profile (GstEncodeBin * ebin, GType ptype, GstCaps * caps) } static GstPad * -gst_encode_bin_request_new_pad (GstElement * element, - GstPadTemplate * templ, const gchar * name) +request_pad_for_stream (GstEncodeBin * encodebin, GType ptype, + const gchar * name, GstCaps * caps) { - GstEncodeBin *ebin = (GstEncodeBin *) element; - GType ptype; StreamGroup *sgroup; GstEncodingProfile *sprof; - GST_DEBUG_OBJECT (element, "templ:%s, name:%s", templ->name_template, name); - - /* Identify the stream group */ - - if (!strcmp (templ->name_template, "video_%d")) - ptype = GST_TYPE_ENCODING_VIDEO_PROFILE; - else if (!strcmp (templ->name_template, "audio_%d")) - ptype = GST_TYPE_ENCODING_AUDIO_PROFILE; - /* else if (!strcmp (templ->name_template, "text_%d")) */ - /* ptype = GST_TYPE_ENCODING_TEXT_PROFILE; */ - else - ptype = G_TYPE_NONE; - - /* FIXME : Check uniqueness of pad */ - /* FIXME : Check that the requested number is the last one, and if not, - * update the last_pad_id variable so that we don't create a pad with - * the same name/number in the future */ - - /* Find GstEncodingProfile which we need */ - sprof = next_unused_stream_profile (ebin, ptype, NULL); - if (G_UNLIKELY (sprof == NULL)) - goto no_stream_profile; - - sgroup = _create_stream_group (ebin, sprof, name, NULL); - if (G_UNLIKELY (sgroup == NULL)) - goto no_stream_group; - - return sgroup->ghostpad; - -no_stream_profile: - { - GST_WARNING_OBJECT (ebin, "Couldn't find a compatible stream profile"); - return NULL; - } - -no_stream_group: - { - GST_WARNING_OBJECT (ebin, "Couldn't create a StreamGroup"); - return NULL; - } -} - -static GstPad * -gst_encode_bin_request_pad_signal (GstEncodeBin * encodebin, GstCaps * caps) -{ - GstEncodingProfile *sprof; - StreamGroup *sgroup; - - GST_DEBUG_OBJECT (encodebin, "caps:%" GST_PTR_FORMAT, caps); + GST_DEBUG_OBJECT (encodebin, "name:%s caps:%" GST_PTR_FORMAT, name, caps); /* Figure out if we have a unused GstEncodingProfile we can use for * these caps */ - sprof = next_unused_stream_profile (encodebin, G_TYPE_NONE, caps); + sprof = next_unused_stream_profile (encodebin, ptype, caps); + if (G_UNLIKELY (sprof == NULL)) goto no_stream_profile; - sgroup = _create_stream_group (encodebin, sprof, NULL, caps); + sgroup = _create_stream_group (encodebin, sprof, name, caps); if (G_UNLIKELY (sgroup == NULL)) goto no_stream_group; @@ -596,6 +547,47 @@ no_stream_group: } } +static GstPad * +gst_encode_bin_request_new_pad (GstElement * element, + GstPadTemplate * templ, const gchar * name, const GstCaps * caps) +{ + GstEncodeBin *ebin = (GstEncodeBin *) element; + GstPad *res = NULL; + + GST_DEBUG_OBJECT (element, "templ:%s, name:%s", templ->name_template, name); + + /* Identify the stream group */ + if (caps != NULL) { + res = request_pad_for_stream (ebin, G_TYPE_NONE, name, (GstCaps *) caps); + } + + if (res == NULL) { + GType ptype = G_TYPE_NONE; + + if (!strcmp (templ->name_template, "video_%d")) + ptype = GST_TYPE_ENCODING_VIDEO_PROFILE; + else if (!strcmp (templ->name_template, "audio_%d")) + ptype = GST_TYPE_ENCODING_AUDIO_PROFILE; + /* else if (!strcmp (templ->name_template, "text_%d")) */ + /* ptype = GST_TYPE_ENCODING_TEXT_PROFILE; */ + + /* FIXME : Check uniqueness of pad */ + /* FIXME : Check that the requested number is the last one, and if not, + * update the last_pad_id variable so that we don't create a pad with + * the same name/number in the future */ + + res = request_pad_for_stream (ebin, ptype, name, NULL); + } + + return res; +} + +static GstPad * +gst_encode_bin_request_pad_signal (GstEncodeBin * encodebin, GstCaps * caps) +{ + return request_pad_for_stream (encodebin, G_TYPE_NONE, NULL, caps); +} + static inline StreamGroup * find_stream_group_from_pad (GstEncodeBin * ebin, GstPad * pad) { @@ -740,7 +732,7 @@ beach: } static GstPad * -gst_element_request_pad (GstElement * element, GstPadTemplate * templ, +local_element_request_pad (GstElement * element, GstPadTemplate * templ, const gchar * name) { GstPad *newpad = NULL; @@ -780,7 +772,7 @@ gst_element_get_pad_from_template (GstElement * element, GstPadTemplate * templ) break; case GST_PAD_REQUEST: - ret = gst_element_request_pad (element, templ, NULL); + ret = gst_element_request_pad (element, templ, NULL, NULL); break; } @@ -1015,7 +1007,8 @@ _create_stream_group (GstEncodeBin * ebin, GstEncodingProfile * sprof, /* Path 1 : Already-encoded data */ - sinkpad = gst_element_request_pad (sgroup->combiner, NULL, "passthroughsink"); + sinkpad = + local_element_request_pad (sgroup->combiner, NULL, "passthroughsink"); if (G_UNLIKELY (sinkpad == NULL)) goto no_combiner_sinkpad; @@ -1042,7 +1035,7 @@ _create_stream_group (GstEncodeBin * ebin, GstEncodingProfile * sprof, g_object_unref (srcpad); } - srcpad = gst_element_request_pad (sgroup->splitter, NULL, "passthroughsrc"); + srcpad = local_element_request_pad (sgroup->splitter, NULL, "passthroughsrc"); if (G_UNLIKELY (srcpad == NULL)) goto no_splitter_srcpad; @@ -1061,7 +1054,7 @@ _create_stream_group (GstEncodeBin * ebin, GstEncodingProfile * sprof, gst_bin_add ((GstBin *) ebin, sgroup->encoder); tosync = g_list_append (tosync, sgroup->encoder); - sinkpad = gst_element_request_pad (sgroup->combiner, NULL, "encodingsink"); + sinkpad = local_element_request_pad (sgroup->combiner, NULL, "encodingsink"); if (G_UNLIKELY (sinkpad == NULL)) goto no_combiner_sinkpad; srcpad = gst_element_get_static_pad (sgroup->encoder, "src"); @@ -1151,7 +1144,7 @@ _create_stream_group (GstEncodeBin * ebin, GstEncodingProfile * sprof, /* Link to stream splitter */ sinkpad = gst_element_get_static_pad (last, "sink"); - srcpad = gst_element_request_pad (sgroup->splitter, NULL, "encodingsrc"); + srcpad = local_element_request_pad (sgroup->splitter, NULL, "encodingsrc"); if (G_UNLIKELY (srcpad == NULL)) goto no_splitter_srcpad; if (G_UNLIKELY (fast_pad_link (srcpad, sinkpad) != GST_PAD_LINK_OK)) From c8fa8085ba72538109b1e0a7af1ca399443b5e47 Mon Sep 17 00:00:00 2001 From: Edward Hervey Date: Wed, 22 Dec 2010 11:41:41 +0100 Subject: [PATCH 099/254] encoding-target: Add method to get a profile by name API: gst_encoding_target_get_profile --- docs/libs/gst-plugins-base-libs-sections.txt | 1 + gst-libs/gst/pbutils/encoding-profile.c | 10 ++----- gst-libs/gst/pbutils/encoding-target.c | 29 ++++++++++++++++++++ gst-libs/gst/pbutils/encoding-target.h | 2 ++ tests/check/libs/profile.c | 25 +++++++++++++++++ win32/common/libgstpbutils.def | 1 + 6 files changed, 60 insertions(+), 8 deletions(-) diff --git a/docs/libs/gst-plugins-base-libs-sections.txt b/docs/libs/gst-plugins-base-libs-sections.txt index da6134bce0..00e8bd7ead 100644 --- a/docs/libs/gst-plugins-base-libs-sections.txt +++ b/docs/libs/gst-plugins-base-libs-sections.txt @@ -1957,6 +1957,7 @@ gst_encoding_target_get_name gst_encoding_target_get_category gst_encoding_target_get_description gst_encoding_target_get_profiles +gst_encoding_target_get_profile gst_encoding_target_add_profile gst_encoding_target_save gst_encoding_target_save_to diff --git a/gst-libs/gst/pbutils/encoding-profile.c b/gst-libs/gst/pbutils/encoding-profile.c index f981f7e8d1..174bfe6eab 100644 --- a/gst-libs/gst/pbutils/encoding-profile.c +++ b/gst-libs/gst/pbutils/encoding-profile.c @@ -95,20 +95,14 @@ *{ * GstEncodingProfile *prof = NULL; * GstEncodingTarget *target = NULL; - * GList *tmp; * * target = gst_encoding_target_load_from (path); * if (target == NULL) * return NULL; * - * for (tmp = target->profiles; tmp; tmp = tmp->next) { - * GstEncodingProfile *ptmp = (GstEncodingProfile*) tmp->data; + * prof = gst_encoding_target_get_profile (target, profilename); * - * if (!strcmp(gst_encoding_profile_get_name(ptmp), profilename)) { - * prof = ptmp; - * break; - * } - * } + * gst_encoding_target_unref (target); * * return prof; *} diff --git a/gst-libs/gst/pbutils/encoding-target.c b/gst-libs/gst/pbutils/encoding-target.c index a5a7b3d55b..601cdb23c0 100644 --- a/gst-libs/gst/pbutils/encoding-target.c +++ b/gst-libs/gst/pbutils/encoding-target.c @@ -152,6 +152,35 @@ gst_encoding_target_get_profiles (GstEncodingTarget * target) return target->profiles; } +/** + * gst_encoding_target_get_profile: + * @target: a #GstEncodingTarget + * @name: the name of the profile to retrieve + * + * Since: 0.10.32 + * + * Returns: (transfer full): The matching #GstEncodingProfile, or %NULL. + */ +GstEncodingProfile * +gst_encoding_target_get_profile (GstEncodingTarget * target, const gchar * name) +{ + GList *tmp; + + g_return_val_if_fail (GST_IS_ENCODING_TARGET (target), NULL); + g_return_val_if_fail (name != NULL, NULL); + + for (tmp = target->profiles; tmp; tmp = tmp->next) { + GstEncodingProfile *tprof = (GstEncodingProfile *) tmp->data; + + if (!g_strcmp0 (gst_encoding_profile_get_name (tprof), name)) { + gst_encoding_profile_ref (tprof); + return tprof; + } + } + + return NULL; +} + static inline gboolean validate_name (const gchar * name) { diff --git a/gst-libs/gst/pbutils/encoding-target.h b/gst-libs/gst/pbutils/encoding-target.h index c23f526609..0f9d34086c 100644 --- a/gst-libs/gst/pbutils/encoding-target.h +++ b/gst-libs/gst/pbutils/encoding-target.h @@ -85,6 +85,8 @@ const gchar *gst_encoding_target_get_name (GstEncodingTarget *target); const gchar *gst_encoding_target_get_category (GstEncodingTarget *target); const gchar *gst_encoding_target_get_description (GstEncodingTarget *target); const GList *gst_encoding_target_get_profiles (GstEncodingTarget *target); +GstEncodingProfile *gst_encoding_target_get_profile (GstEncodingTarget *target, + const gchar *name); gboolean gst_encoding_target_add_profile (GstEncodingTarget *target, GstEncodingProfile *profile); diff --git a/tests/check/libs/profile.c b/tests/check/libs/profile.c index 0018b0bd22..c9df843ae3 100644 --- a/tests/check/libs/profile.c +++ b/tests/check/libs/profile.c @@ -253,6 +253,30 @@ create_saveload_target (void) return target; } +GST_START_TEST (test_target_profile) +{ + GstEncodingTarget *target; + GstEncodingProfile *prof; + + target = create_saveload_target (); + + /* NULL isn't a valid profile name */ + ASSERT_CRITICAL (gst_encoding_target_get_profile (target, NULL)); + + /* try finding a profile that doesn't exist */ + fail_if (gst_encoding_target_get_profile (target, + "no-really-does-not-exist")); + + /* try finding a profile that exists */ + prof = gst_encoding_target_get_profile (target, "pony"); + fail_if (prof == NULL); + + gst_encoding_profile_unref (prof); + gst_encoding_target_unref (target); +} + +GST_END_TEST; + GST_START_TEST (test_saving_profile) { GstEncodingTarget *orig, *loaded = NULL; @@ -473,6 +497,7 @@ profile_suite (void) tcase_add_test (tc_chain, test_profile_creation); tcase_add_test (tc_chain, test_profile_output_caps); tcase_add_test (tc_chain, test_target_naming); + tcase_add_test (tc_chain, test_target_profile); if (can_write) { tcase_add_test (tc_chain, test_loading_profile); tcase_add_test (tc_chain, test_saving_profile); diff --git a/win32/common/libgstpbutils.def b/win32/common/libgstpbutils.def index 6f43ee4e86..d92c398d65 100644 --- a/win32/common/libgstpbutils.def +++ b/win32/common/libgstpbutils.def @@ -85,6 +85,7 @@ EXPORTS gst_encoding_target_get_category gst_encoding_target_get_description gst_encoding_target_get_name + gst_encoding_target_get_profile gst_encoding_target_get_profiles gst_encoding_target_get_type gst_encoding_target_load From d8f5b6322fc12d91a15eccfce28365cc7942e573 Mon Sep 17 00:00:00 2001 From: Edward Hervey Date: Wed, 22 Dec 2010 18:16:33 +0100 Subject: [PATCH 100/254] encoding-target: Implement save/load feature Fixes #637735 --- configure.ac | 5 + gst-libs/gst/pbutils/encoding-target.c | 187 +++++++++++++++++++++---- gst-libs/gst/pbutils/encoding-target.h | 1 + tests/check/libs/profile.c | 27 ++-- 4 files changed, 182 insertions(+), 38 deletions(-) diff --git a/configure.ac b/configure.ac index e575024942..287cc476f3 100644 --- a/configure.ac +++ b/configure.ac @@ -389,6 +389,11 @@ AG_GST_SET_LEVEL_DEFAULT($GST_GIT) dnl used in examples AG_GST_DEFAULT_ELEMENTS +dnl needed for encoding-target +GST_DATADIR="$GST_PREFIX/share" +AC_DEFINE_UNQUOTED(GST_DATADIR, "$GST_DATADIR", [system wide data directory]) +AC_DEFINE_UNQUOTED(GST_MAJORMINOR, "$GST_MAJORMINOR", [major/minor version]) + dnl behaviour of speex based audio resampler AC_MSG_CHECKING(which audio resample format to use for integer) AC_ARG_WITH([audioresample_format], diff --git a/gst-libs/gst/pbutils/encoding-target.c b/gst-libs/gst/pbutils/encoding-target.c index 601cdb23c0..6565bd911f 100644 --- a/gst-libs/gst/pbutils/encoding-target.c +++ b/gst-libs/gst/pbutils/encoding-target.c @@ -20,6 +20,9 @@ #include #include +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif #include "encoding-target.h" /* @@ -49,6 +52,21 @@ * variableframerate : * */ +/* + * Location of profile files + * + * $GST_DATADIR/gstreamer-GST_MAJORMINOR/encoding-profile + * $HOME/gstreamer-GST_MAJORMINOR/encoding-profile + * + * Naming convention + * $(target.category)/$(target.name).gstprof + * + * Naming restrictions: + * lowercase ASCII letter for the first character + * Same for all other characters + numerics + hyphens + */ + + #define GST_ENCODING_TARGET_HEADER "_gstencodingtarget_" struct _GstEncodingTarget @@ -699,49 +717,132 @@ beach: return res; } +/** + * + * returned list contents must be freed + */ +static GList * +get_matching_filenames (gchar * path, gchar * filename) +{ + GList *res = NULL; + GDir *topdir; + const gchar *subdirname; + + topdir = g_dir_open (path, 0, NULL); + if (G_UNLIKELY (topdir == NULL)) + return NULL; + + while ((subdirname = g_dir_read_name (topdir))) { + gchar *ltmp = g_build_filename (path, subdirname, NULL); + + if (g_file_test (ltmp, G_FILE_TEST_IS_DIR)) { + gchar *tmp = g_build_filename (path, subdirname, filename, NULL); + /* Test to see if we have a file named like that in that directory */ + if (g_file_test (tmp, G_FILE_TEST_EXISTS)) + res = g_list_append (res, tmp); + else + g_free (tmp); + } + g_free (ltmp); + } + + g_dir_close (topdir); + + return res; +} + +static GstEncodingTarget * +gst_encoding_target_subload (gchar * path, const gchar * category, + gchar * lfilename, GError ** error) +{ + GstEncodingTarget *target = NULL; + + if (category) { + gchar *filename; + + filename = g_build_filename (path, category, lfilename, NULL); + target = gst_encoding_target_load_from (filename, error); + g_free (filename); + } else { + GList *tmp, *tries = get_matching_filenames (path, lfilename); + + /* Try to find a file named %s.gstprofile in any subdirectories */ + for (tmp = tries; tmp; tmp = tmp->next) { + target = gst_encoding_target_load_from ((gchar *) tmp->data, NULL); + if (target) + break; + } + g_list_foreach (tries, (GFunc) g_free, NULL); + if (tries) + g_list_free (tries); + } + + return target; +} + /** * gst_encoding_target_load: * @name: the name of the #GstEncodingTarget to load. + * @category: (allow-none): the name of the target category. Can be %NULL * @error: If an error occured, this field will be filled in. * * Searches for the #GstEncodingTarget with the given name, loads it * and returns it. * - * Warning: NOT IMPLEMENTED. + * If the category name is specified only targets from that category will be + * searched for. * * Since: 0.10.32 * * Returns: (transfer full): The #GstEncodingTarget if available, else %NULL. */ - GstEncodingTarget * -gst_encoding_target_load (const gchar * name, GError ** error) +gst_encoding_target_load (const gchar * name, const gchar * category, + GError ** error) { - /* FIXME : IMPLEMENT */ - return NULL; -} + gchar *lfilename, *tldir; + GstEncodingTarget *target = NULL; -/** - * gst_encoding_target_save: - * @target: a #GstEncodingTarget - * @error: If an error occured, this field will be filled in. - * - * Saves the @target to the default location. - * - * Warning: NOT IMPLEMENTED. - * - * Since: 0.10.32 - * - * Returns: %TRUE if the target was correctly saved, else %FALSE. - **/ + g_return_val_if_fail (name != NULL, NULL); -gboolean -gst_encoding_target_save (GstEncodingTarget * target, GError ** error) -{ - g_return_val_if_fail (GST_IS_ENCODING_TARGET (target), FALSE); + if (!validate_name (name)) + goto invalid_name; - /* FIXME : IMPLEMENT */ - return FALSE; + if (category && !validate_name (category)) + goto invalid_category; + + lfilename = g_strdup_printf ("%s.gstprofile", name); + + /* Try from local profiles */ + tldir = + g_build_filename (g_get_home_dir (), ".gstreamer-0.10", + "encoding-profile", NULL); + target = gst_encoding_target_subload (tldir, category, lfilename, error); + g_free (tldir); + + if (target == NULL) { + /* Try from system-wide profiles */ + tldir = + g_build_filename (GST_DATADIR, "gstreamer-" GST_MAJORMINOR, + "encoding-profile", NULL); + target = gst_encoding_target_subload (tldir, category, lfilename, error); + g_free (tldir); + } + + g_free (lfilename); + + return target; + +invalid_name: + { + GST_ERROR ("Invalid name for encoding target : '%s'", name); + return NULL; + } +invalid_category: + { + GST_ERROR ("Invalid name for encoding category : '%s'", category); + return NULL; + } } /** @@ -813,3 +914,39 @@ write_failed: return FALSE; } } + +/** + * gst_encoding_target_save: + * @target: a #GstEncodingTarget + * @error: If an error occured, this field will be filled in. + * + * Saves the @target to the default location. Unless the user has write access + * to the system-wide encoding target directory, it will be saved in a + * user-local directory. + * + * Since: 0.10.32 + * + * Returns: %TRUE if the target was correctly saved, else %FALSE. + **/ + +gboolean +gst_encoding_target_save (GstEncodingTarget * target, GError ** error) +{ + gchar *filename; + gchar *lfilename; + gboolean res; + + g_return_val_if_fail (GST_IS_ENCODING_TARGET (target), FALSE); + g_return_val_if_fail (target->category != NULL, FALSE); + + lfilename = g_strdup_printf ("%s.gstprofile", target->name); + filename = + g_build_filename (g_get_home_dir (), ".gstreamer-0.10", + "encoding-profile", target->category, lfilename, NULL); + g_free (lfilename); + + res = gst_encoding_target_save_to (target, filename, error); + g_free (filename); + + return TRUE; +} diff --git a/gst-libs/gst/pbutils/encoding-target.h b/gst-libs/gst/pbutils/encoding-target.h index 0f9d34086c..fb73654502 100644 --- a/gst-libs/gst/pbutils/encoding-target.h +++ b/gst-libs/gst/pbutils/encoding-target.h @@ -97,6 +97,7 @@ gboolean gst_encoding_target_save_to (GstEncodingTarget *target, const gchar *path, GError **error); GstEncodingTarget *gst_encoding_target_load (const gchar *name, + const gchar *category, GError **error); GstEncodingTarget *gst_encoding_target_load_from (const gchar *path, GError **error); diff --git a/tests/check/libs/profile.c b/tests/check/libs/profile.c index c9df843ae3..fef3406a10 100644 --- a/tests/check/libs/profile.c +++ b/tests/check/libs/profile.c @@ -210,7 +210,7 @@ GST_START_TEST (test_target_naming) GST_END_TEST; static GstEncodingTarget * -create_saveload_target (void) +create_saveload_target (const gchar * targetname) { GstEncodingTarget *target; GstEncodingProfile *profile, *sprof; @@ -218,7 +218,7 @@ create_saveload_target (void) GST_DEBUG ("Creating target"); - target = gst_encoding_target_new ("myponytarget", "herding", + target = gst_encoding_target_new (targetname, "herding", "Plenty of pony glitter profiles", NULL); caps = gst_caps_from_string ("animal/x-pony"); profile = @@ -258,7 +258,7 @@ GST_START_TEST (test_target_profile) GstEncodingTarget *target; GstEncodingProfile *prof; - target = create_saveload_target (); + target = create_saveload_target ("myponytarget"); /* NULL isn't a valid profile name */ ASSERT_CRITICAL (gst_encoding_target_get_profile (target, NULL)); @@ -284,13 +284,13 @@ GST_START_TEST (test_saving_profile) gchar *profile_file_name; /* Create and store a target */ - profile_file_name = g_build_filename (g_get_home_dir (), ".gstreamer-0.10", - "profile", "TestProfile2.profile", NULL); - orig = create_saveload_target (); - GST_DEBUG ("Saving target to '%s'", profile_file_name); - fail_unless (gst_encoding_target_save_to (orig, profile_file_name, NULL)); + orig = create_saveload_target ("myponytarget2"); + GST_DEBUG ("Saving target 'myponytarget2'"); + fail_unless (gst_encoding_target_save (orig, NULL)); /* Check we can load it */ + profile_file_name = g_build_filename (g_get_home_dir (), ".gstreamer-0.10", + "encoding-profile", "herding", "myponytarget2.gstprofile", NULL); GST_DEBUG ("Loading target from '%s'", profile_file_name); loaded = gst_encoding_target_load_from (profile_file_name, NULL); fail_unless (loaded != NULL); @@ -437,11 +437,11 @@ remove_profile_file (void) gchar *profile_file_name; profile_file_name = g_build_filename (g_get_home_dir (), ".gstreamer-0.10", - "profile", "TestProfile.profile", NULL); + "encoding-profile", "herding", "myponytarget.gstprofile", NULL); g_unlink (profile_file_name); g_free (profile_file_name); profile_file_name = g_build_filename (g_get_home_dir (), ".gstreamer-0.10", - "profile", "TestProfile2.profile", NULL); + "encoding-profile", "herding", "myponytarget2.gstprofile", NULL); g_unlink (profile_file_name); g_free (profile_file_name); } @@ -454,10 +454,11 @@ create_profile_file (void) GError *error = NULL; profile_dir = - g_build_filename (g_get_home_dir (), ".gstreamer-0.10", "profile", NULL); + g_build_filename (g_get_home_dir (), ".gstreamer-0.10", + "encoding-profile", "herding", NULL); profile_file_name = - g_build_filename (g_get_home_dir (), ".gstreamer-0.10", "profile", - "TestProfile.profile", NULL); + g_build_filename (g_get_home_dir (), ".gstreamer-0.10", + "encoding-profile", "herding", "myponytarget.gstprofile", NULL); g_mkdir_with_parents (profile_dir, S_IRUSR | S_IWUSR | S_IXUSR); if (!g_file_set_contents (profile_file_name, profile_string, strlen (profile_string), &error)) From deea1eb83f5bd07ff45a44a460dc6af590185fc3 Mon Sep 17 00:00:00 2001 From: Edward Hervey Date: Wed, 22 Dec 2010 18:18:00 +0100 Subject: [PATCH 101/254] encoding-profile: Add convenience method to find a profile API: gst_encoding_profile_find --- docs/libs/gst-plugins-base-libs-sections.txt | 1 + gst-libs/gst/pbutils/Makefile.am | 1 + gst-libs/gst/pbutils/encoding-profile.c | 127 ++++++++++++++++++- gst-libs/gst/pbutils/encoding-profile.h | 5 +- tests/check/libs/profile.c | 84 ++++++++++-- win32/common/libgstpbutils.def | 1 + 6 files changed, 204 insertions(+), 15 deletions(-) diff --git a/docs/libs/gst-plugins-base-libs-sections.txt b/docs/libs/gst-plugins-base-libs-sections.txt index 00e8bd7ead..e42c95675e 100644 --- a/docs/libs/gst-plugins-base-libs-sections.txt +++ b/docs/libs/gst-plugins-base-libs-sections.txt @@ -1913,6 +1913,7 @@ gst_codec_utils_mpeg4video_caps_set_level_and_profile GstEncodingProfile gst_encoding_profile_unref gst_encoding_profile_ref +gst_encoding_profile_find gst_encoding_profile_get_name gst_encoding_profile_get_description gst_encoding_profile_get_format diff --git a/gst-libs/gst/pbutils/Makefile.am b/gst-libs/gst/pbutils/Makefile.am index 73251e1aef..fea84c46d4 100644 --- a/gst-libs/gst/pbutils/Makefile.am +++ b/gst-libs/gst/pbutils/Makefile.am @@ -90,6 +90,7 @@ GstPbutils-@GST_MAJORMINOR@.gir: $(INTROSPECTION_SCANNER) libgstpbutils-@GST_MAJ --pkg gstreamer-0.10 \ --pkg gstreamer-video-@GST_MAJORMINOR@ \ --pkg-export gstreamer-pbutils-@GST_MAJORMINOR@ \ + --add-init-section="gst_init(NULL,NULL);" \ --output $@ \ $(gir_headers) \ $(gir_sources) diff --git a/gst-libs/gst/pbutils/encoding-profile.c b/gst-libs/gst/pbutils/encoding-profile.c index 174bfe6eab..5fa3abb14c 100644 --- a/gst-libs/gst/pbutils/encoding-profile.c +++ b/gst-libs/gst/pbutils/encoding-profile.c @@ -118,6 +118,7 @@ #endif #include "encoding-profile.h" +#include "encoding-target.h" /* GstEncodingProfile API */ @@ -134,12 +135,53 @@ struct _GstEncodingProfile GstCaps *restriction; }; -G_DEFINE_TYPE (GstEncodingProfile, gst_encoding_profile, GST_TYPE_MINI_OBJECT); +static void string_to_profile_transform (const GValue * src_value, + GValue * dest_value); +static gboolean gst_encoding_profile_deserialize_valfunc (GValue * value, + const gchar * s); + +static void gst_encoding_profile_class_init (GstEncodingProfileClass * klass); +static gpointer gst_encoding_profile_parent_class = NULL; static void -gst_encoding_profile_init (GstEncodingProfile * prof) +gst_encoding_profile_class_intern_init (gpointer klass) { - /* Nothing to initialize */ + gst_encoding_profile_parent_class = g_type_class_peek_parent (klass); + gst_encoding_profile_class_init ((GstEncodingProfileClass *) klass); +} + +GType +gst_encoding_profile_get_type (void) +{ + static volatile gsize g_define_type_id__volatile = 0; + + if (g_once_init_enter (&g_define_type_id__volatile)) { + GType g_define_type_id = + g_type_register_static_simple (GST_TYPE_MINI_OBJECT, + g_intern_static_string ("GstEncodingProfile"), + sizeof (GstEncodingProfileClass), + (GClassInitFunc) gst_encoding_profile_class_intern_init, + sizeof (GstEncodingProfile), + NULL, + (GTypeFlags) 0); + static GstValueTable gstvtable = { + G_TYPE_NONE, + (GstValueCompareFunc) NULL, + (GstValueSerializeFunc) NULL, + (GstValueDeserializeFunc) gst_encoding_profile_deserialize_valfunc + }; + + gstvtable.type = g_define_type_id; + + /* Register a STRING=>PROFILE GValueTransformFunc */ + g_value_register_transform_func (G_TYPE_STRING, g_define_type_id, + string_to_profile_transform); + /* Register gst-specific GValue functions */ + gst_value_register (&gstvtable); + + g_once_init_leave (&g_define_type_id__volatile, g_define_type_id); + } + return g_define_type_id__volatile; } static void @@ -828,3 +870,82 @@ gst_encoding_profile_get_type_nick (GstEncodingProfile * profile) return "audio"; return NULL; } + +/** + * gst_encoding_profile_find: + * @targetname: (transfer none): The name of the target + * @profilename: (transfer none): The name of the profile + * @category: (transfer none) (allow-none): The target category. Can be %NULL + * + * Find the #GstEncodingProfile with the specified name and category. + * + * Returns: (transfer full): The matching #GstEncodingProfile or %NULL. + */ +GstEncodingProfile * +gst_encoding_profile_find (const gchar * targetname, const gchar * profilename, + const gchar * category) +{ + GstEncodingProfile *res = NULL; + GstEncodingTarget *target; + + g_return_val_if_fail (targetname != NULL, NULL); + g_return_val_if_fail (profilename != NULL, NULL); + + /* FIXME : how do we handle profiles named the same in several + * categories but of which only one has the required profile ? */ + target = gst_encoding_target_load (targetname, category, NULL); + if (target) { + res = gst_encoding_target_get_profile (target, profilename); + gst_encoding_target_unref (target); + } + + return res; +} + +static GstEncodingProfile * +combo_search (const gchar * pname) +{ + GstEncodingProfile *res; + gchar **split; + + /* Splitup */ + split = g_strsplit (pname, "/", 2); + if (g_strv_length (split) != 2) + return NULL; + + res = gst_encoding_profile_find (split[0], split[1], NULL); + + g_strfreev (split); + + return res; +} + +/* GValue transform function */ +static void +string_to_profile_transform (const GValue * src_value, GValue * dest_value) +{ + const gchar *profilename; + GstEncodingProfile *profile; + + profilename = g_value_get_string (src_value); + + profile = combo_search (profilename); + + if (profile) + gst_value_take_mini_object (dest_value, (GstMiniObject *) profile); +} + +static gboolean +gst_encoding_profile_deserialize_valfunc (GValue * value, const gchar * s) +{ + GstEncodingProfile *profile; + + profile = combo_search (s); + + if (profile) { + gst_value_take_mini_object (value, (GstMiniObject *) profile); + return TRUE; + } + + return FALSE; +} diff --git a/gst-libs/gst/pbutils/encoding-profile.h b/gst-libs/gst/pbutils/encoding-profile.h index f455a607ce..69d3d63436 100644 --- a/gst-libs/gst/pbutils/encoding-profile.h +++ b/gst-libs/gst/pbutils/encoding-profile.h @@ -147,6 +147,10 @@ GstCaps * gst_encoding_profile_get_output_caps (GstEncodingProfile *profile); const gchar *gst_encoding_profile_get_type_nick (GstEncodingProfile *profile); +GstEncodingProfile * gst_encoding_profile_find (const gchar *targetname, + const gchar *profilename, + const gchar *category); + /* GstEncodingContainerProfile API */ gboolean gst_encoding_container_profile_add_profile (GstEncodingContainerProfile *container, GstEncodingProfile *profile); @@ -178,7 +182,6 @@ void gst_encoding_video_profile_set_pass (GstEncodingVideoProfi guint pass); void gst_encoding_video_profile_set_variableframerate (GstEncodingVideoProfile *prof, gboolean variableframerate); - G_END_DECLS #endif /* __GST_PROFILE_H__ */ diff --git a/tests/check/libs/profile.c b/tests/check/libs/profile.c index fef3406a10..adedbba6ed 100644 --- a/tests/check/libs/profile.c +++ b/tests/check/libs/profile.c @@ -325,22 +325,13 @@ GST_START_TEST (test_saving_profile) GST_END_TEST; -GST_START_TEST (test_loading_profile) +static void +test_individual_target (GstEncodingTarget * target) { - GstEncodingTarget *target; - gchar *profile_file_name; GstEncodingProfile *prof; GstCaps *tmpcaps, *tmpcaps2; GstEncodingProfile *sprof1, *sprof2; - profile_file_name = g_build_filename (g_get_home_dir (), ".gstreamer-0.10", - "profile", "TestProfile.profile", NULL); - - GST_DEBUG ("Loading target from '%s'", profile_file_name); - target = gst_encoding_target_load_from (profile_file_name, NULL); - g_free (profile_file_name); - fail_unless (target != NULL); - GST_DEBUG ("Checking the target properties"); /* Check the target */ fail_unless_equals_string (gst_encoding_target_get_name (target), @@ -396,8 +387,79 @@ GST_START_TEST (test_loading_profile) gst_encoding_profile_unref (sprof2); gst_caps_unref (tmpcaps); gst_caps_unref (tmpcaps2); +} +GST_START_TEST (test_loading_profile) +{ + GstEncodingTarget *target; + gchar *profile_file_name; + GstEncodingProfile *profile; + GstCaps *tmpcaps; + GValue strvalue = { 0, }; + GValue miniobjectvalue = { 0, }; + + /* Test loading using short method and all arguments */ + target = gst_encoding_target_load ("myponytarget", "herding", NULL); + fail_unless (target != NULL); + test_individual_target (target); gst_encoding_target_unref (target); + + /* Test loading using short method and no category */ + target = gst_encoding_target_load ("myponytarget", NULL, NULL); + fail_unless (target != NULL); + test_individual_target (target); + gst_encoding_target_unref (target); + + /* Test loading using fully specified path */ + profile_file_name = g_build_filename (g_get_home_dir (), ".gstreamer-0.10", + "encoding-profile", "herding", "myponytarget.gstprofile", NULL); + + GST_DEBUG ("Loading target from '%s'", profile_file_name); + target = gst_encoding_target_load_from (profile_file_name, NULL); + g_free (profile_file_name); + fail_unless (target != NULL); + test_individual_target (target); + gst_encoding_target_unref (target); + + /* Test getting the profiles directly + * First without category */ + profile = gst_encoding_profile_find ("myponytarget", "pony", NULL); + fail_unless (profile != NULL); + tmpcaps = gst_caps_from_string ("animal/x-pony"); + CHECK_PROFILE (profile, "pony", "I don't want a description !", tmpcaps, NULL, + 0, 0); + gst_caps_unref (tmpcaps); + gst_encoding_profile_unref (profile); + + /* Then with a specific category */ + profile = gst_encoding_profile_find ("myponytarget", "pony", "herding"); + fail_unless (profile != NULL); + tmpcaps = gst_caps_from_string ("animal/x-pony"); + CHECK_PROFILE (profile, "pony", "I don't want a description !", tmpcaps, NULL, + 0, 0); + gst_caps_unref (tmpcaps); + gst_encoding_profile_unref (profile); + + /* For my next trick, I will need the assistance of a GValue */ + g_value_init (&strvalue, G_TYPE_STRING); + g_value_init (&miniobjectvalue, GST_TYPE_ENCODING_PROFILE); + g_value_set_static_string (&strvalue, "myponytarget/pony"); + fail_unless (g_value_transform (&strvalue, &miniobjectvalue)); + profile = (GstEncodingProfile *) gst_value_dup_mini_object (&miniobjectvalue); + fail_if (profile == NULL); + g_value_unset (&strvalue); + g_value_unset (&miniobjectvalue); + tmpcaps = gst_caps_from_string ("animal/x-pony"); + CHECK_PROFILE (profile, "pony", "I don't want a description !", tmpcaps, NULL, + 0, 0); + gst_caps_unref (tmpcaps); + gst_encoding_profile_unref (profile); + + /* Let's go crazy for error detection */ + fail_if (gst_encoding_profile_find ("myponytarget", "whales", NULL)); + fail_if (gst_encoding_profile_find ("myponytarget", "whales", "herding")); + fail_if (gst_encoding_profile_find ("myponytarget", "", NULL)); + fail_if (gst_encoding_profile_find ("", "pony", NULL)); } GST_END_TEST; diff --git a/win32/common/libgstpbutils.def b/win32/common/libgstpbutils.def index d92c398d65..333bc68d82 100644 --- a/win32/common/libgstpbutils.def +++ b/win32/common/libgstpbutils.def @@ -65,6 +65,7 @@ EXPORTS gst_encoding_container_profile_get_profiles gst_encoding_container_profile_get_type gst_encoding_container_profile_new + gst_encoding_profile_find gst_encoding_profile_get_description gst_encoding_profile_get_format gst_encoding_profile_get_name From a65faf2f3c687a66f72213d965555c8a4631e2e2 Mon Sep 17 00:00:00 2001 From: Edward Hervey Date: Mon, 3 Jan 2011 13:20:19 +0100 Subject: [PATCH 102/254] encoding-target: Add API for list all categories and targets API: gst_encoding_list_available_categories API: gst_encoding_list_all_targets --- docs/libs/gst-plugins-base-libs-sections.txt | 2 + gst-libs/gst/pbutils/encoding-target.c | 181 +++++++++++++++++++ gst-libs/gst/pbutils/encoding-target.h | 3 + tests/check/libs/profile.c | 47 +++++ win32/common/libgstpbutils.def | 2 + 5 files changed, 235 insertions(+) diff --git a/docs/libs/gst-plugins-base-libs-sections.txt b/docs/libs/gst-plugins-base-libs-sections.txt index e42c95675e..29969fe947 100644 --- a/docs/libs/gst-plugins-base-libs-sections.txt +++ b/docs/libs/gst-plugins-base-libs-sections.txt @@ -1964,6 +1964,8 @@ gst_encoding_target_save gst_encoding_target_save_to gst_encoding_target_load gst_encoding_target_load_from +gst_encoding_list_all_targets +gst_encoding_list_available_categories GST_ENCODING_PROFILE GST_IS_ENCODING_PROFILE diff --git a/gst-libs/gst/pbutils/encoding-target.c b/gst-libs/gst/pbutils/encoding-target.c index 6565bd911f..faee8c308c 100644 --- a/gst-libs/gst/pbutils/encoding-target.c +++ b/gst-libs/gst/pbutils/encoding-target.c @@ -950,3 +950,184 @@ gst_encoding_target_save (GstEncodingTarget * target, GError ** error) return TRUE; } + +static GList * +get_categories (gchar * path) +{ + GList *res = NULL; + GDir *topdir; + const gchar *subdirname; + + topdir = g_dir_open (path, 0, NULL); + if (G_UNLIKELY (topdir == NULL)) + return NULL; + + while ((subdirname = g_dir_read_name (topdir))) { + gchar *ltmp = g_build_filename (path, subdirname, NULL); + + if (g_file_test (ltmp, G_FILE_TEST_IS_DIR)) { + res = g_list_append (res, (gpointer) g_strdup (subdirname)); + } + g_free (ltmp); + } + + g_dir_close (topdir); + + return res; +} + +/** + * gst_encoding_list_available_categories: + * + * Lists all #GstEncodingTarget categories present on disk. + * + * Returns: (transfer full) (element-type gchar*): A list + * of #GstEncodingTarget categories. +*/ +GList * +gst_encoding_list_available_categories (void) +{ + GList *res = NULL; + GList *tmp1, *tmp2; + gchar *topdir; + + /* First try user-local categories */ + topdir = g_build_filename (g_get_home_dir (), ".gstreamer-0.10", + "encoding-profile", NULL); + res = get_categories (topdir); + g_free (topdir); + + /* Extend with system-wide categories */ + topdir = g_build_filename (GST_DATADIR, "gstreamer-" GST_MAJORMINOR, + "encoding-profile", NULL); + tmp1 = get_categories (topdir); + g_free (topdir); + + for (tmp2 = tmp1; tmp2; tmp2 = tmp2->next) { + gchar *name = (gchar *) tmp2->data; + if (!g_list_find_custom (res, name, (GCompareFunc) g_strcmp0)) + res = g_list_append (res, (gpointer) name); + else + g_free (name); + } + g_free (tmp1); + + return res; +} + +static inline GList * +sub_get_all_targets (gchar * subdir) +{ + GList *res = NULL; + const gchar *filename; + GDir *dir; + GstEncodingTarget *target; + + dir = g_dir_open (subdir, 0, NULL); + if (G_UNLIKELY (dir == NULL)) + return NULL; + + while ((filename = g_dir_read_name (dir))) { + gchar *fullname; + + /* Only try files ending with .gstprofile */ + if (!g_str_has_suffix (filename, ".gstprofile")) + continue; + + fullname = g_build_filename (subdir, filename, NULL); + target = gst_encoding_target_load_from (fullname, NULL); + if (target) { + res = g_list_append (res, target); + } else + GST_WARNING ("Failed to get a target from %s", fullname); + g_free (fullname); + } + g_dir_close (dir); + + return res; +} + +static inline GList * +get_all_targets (gchar * topdir, const gchar * categoryname) +{ + GList *res = NULL; + + if (categoryname) { + gchar *subdir = g_build_filename (topdir, categoryname, NULL); + /* Try to open the directory */ + res = sub_get_all_targets (subdir); + g_free (subdir); + } else { + const gchar *subdirname; + GDir *dir = g_dir_open (topdir, 0, NULL); + + if (G_UNLIKELY (dir == NULL)) + return NULL; + + while ((subdirname = g_dir_read_name (dir))) { + gchar *ltmp = g_build_filename (topdir, subdirname, NULL); + + if (g_file_test (ltmp, G_FILE_TEST_IS_DIR)) { + res = g_list_concat (res, sub_get_all_targets (ltmp)); + } + g_free (ltmp); + } + g_dir_close (dir); + } + + return res; +} + +static guint +compare_targets (const GstEncodingTarget * ta, const GstEncodingTarget * tb) +{ + if (!g_strcmp0 (ta->name, tb->name) + && !g_strcmp0 (ta->category, tb->category)) + return -1; + + return 0; +} + +/** + * gst_encoding_list_all_targets: + * @categoryname: (allow-none): The category, for ex: #GST_ENCODING_CATEGORY_DEVICE. + * Can be NULL. + * + * List all available #GstEncodingTarget for the specified category, or all categories + * if @categoryname is NULL. + * + * Returns: (transfer full) (element-type GstEncodingTarget): The list of #GstEncodingTarget + */ +GList * +gst_encoding_list_all_targets (const gchar * categoryname) +{ + GList *res; + GList *tmp1, *tmp2; + gchar *topdir; + + /* Get user-locals */ + topdir = g_build_filename (g_get_home_dir (), ".gstreamer-0.10", + "encoding-profile", NULL); + res = get_all_targets (topdir, categoryname); + g_free (topdir); + + /* Get system-wide */ + topdir = g_build_filename (GST_DATADIR, "gstreamer-" GST_MAJORMINOR, + "encoding-profile", NULL); + tmp1 = get_all_targets (topdir, categoryname); + g_free (topdir); + + /* Merge system-wide targets */ + /* FIXME : We should merge the system-wide profiles into the user-locals + * instead of stopping at identical target names */ + for (tmp2 = tmp1; tmp2; tmp2 = tmp2->next) { + GstEncodingTarget *target = (GstEncodingTarget *) tmp2->data; + if (g_list_find_custom (res, target, (GCompareFunc) compare_targets)) + gst_encoding_target_unref (target); + else + res = g_list_append (res, target); + } + g_list_free (tmp1); + + return res; +} diff --git a/gst-libs/gst/pbutils/encoding-target.h b/gst-libs/gst/pbutils/encoding-target.h index fb73654502..bb5b40921d 100644 --- a/gst-libs/gst/pbutils/encoding-target.h +++ b/gst-libs/gst/pbutils/encoding-target.h @@ -102,6 +102,9 @@ GstEncodingTarget *gst_encoding_target_load (const gchar *name, GstEncodingTarget *gst_encoding_target_load_from (const gchar *path, GError **error); +GList *gst_encoding_list_available_categories (void); +GList *gst_encoding_list_all_targets (const gchar * categoryname); + G_END_DECLS #endif /* __GST_PROFILE_REGISTRY_H__ */ diff --git a/tests/check/libs/profile.c b/tests/check/libs/profile.c index adedbba6ed..deed294cf0 100644 --- a/tests/check/libs/profile.c +++ b/tests/check/libs/profile.c @@ -464,6 +464,52 @@ GST_START_TEST (test_loading_profile) GST_END_TEST; +GST_START_TEST (test_target_list) +{ + GList *categories; + GList *targets; + GList *tmp; + + /* Make sure we get our test category in the available categories */ + categories = gst_encoding_list_available_categories (); + fail_if (categories == NULL); + fail_if (g_list_find_custom (categories, "herding", + (GCompareFunc) g_strcmp0) == NULL); + g_list_foreach (categories, (GFunc) g_free, NULL); + g_list_free (categories); + + /* Try getting all available targets with a specified category */ + targets = gst_encoding_list_all_targets ("herding"); + fail_if (targets == NULL); + for (tmp = targets; tmp; tmp = tmp->next) { + GstEncodingTarget *target = (GstEncodingTarget *) tmp->data; + if (!g_strcmp0 (gst_encoding_target_get_name (target), "myponytarget")) + break; + } + /* If tmp is NULL, it means we iterated the whole list without finding + * our target */ + fail_if (tmp == NULL); + g_list_foreach (targets, (GFunc) gst_mini_object_unref, NULL); + g_list_free (targets); + + /* Try getting all available targets without a specified category */ + targets = gst_encoding_list_all_targets (NULL); + fail_if (targets == NULL); + for (tmp = targets; tmp; tmp = tmp->next) { + GstEncodingTarget *target = (GstEncodingTarget *) tmp->data; + if (!g_strcmp0 (gst_encoding_target_get_name (target), "myponytarget")) + break; + } + /* If tmp is NULL, it means we iterated the whole list without finding + * our target */ + fail_if (tmp == NULL); + g_list_foreach (targets, (GFunc) gst_mini_object_unref, NULL); + g_list_free (targets); +} + +GST_END_TEST; + + static const gchar *profile_string = "\ [_gstencodingtarget_]\n\ name=myponytarget\n\ @@ -564,6 +610,7 @@ profile_suite (void) if (can_write) { tcase_add_test (tc_chain, test_loading_profile); tcase_add_test (tc_chain, test_saving_profile); + tcase_add_test (tc_chain, test_target_list); } tcase_add_unchecked_fixture (tc_chain, test_setup, test_teardown); diff --git a/win32/common/libgstpbutils.def b/win32/common/libgstpbutils.def index 333bc68d82..63c125d8a8 100644 --- a/win32/common/libgstpbutils.def +++ b/win32/common/libgstpbutils.def @@ -65,6 +65,8 @@ EXPORTS gst_encoding_container_profile_get_profiles gst_encoding_container_profile_get_type gst_encoding_container_profile_new + gst_encoding_list_all_targets + gst_encoding_list_available_categories gst_encoding_profile_find gst_encoding_profile_get_description gst_encoding_profile_get_format From 520eb442ce714fba31a94172c370295260d7d9da Mon Sep 17 00:00:00 2001 From: Edward Hervey Date: Mon, 3 Jan 2011 13:21:26 +0100 Subject: [PATCH 103/254] encoding-target: Add more docs regarding categories --- gst-libs/gst/pbutils/encoding-target.c | 15 ++++++++---- gst-libs/gst/pbutils/encoding-target.h | 33 ++++++++++++++++++++++++++ 2 files changed, 44 insertions(+), 4 deletions(-) diff --git a/gst-libs/gst/pbutils/encoding-target.c b/gst-libs/gst/pbutils/encoding-target.c index faee8c308c..0cda8596c2 100644 --- a/gst-libs/gst/pbutils/encoding-target.c +++ b/gst-libs/gst/pbutils/encoding-target.c @@ -133,7 +133,8 @@ gst_encoding_target_get_name (GstEncodingTarget * target) * * Since: 0.10.32 * - * Returns: (transfer none): The category of the @target. + * Returns: (transfer none): The category of the @target. For example: + * #GST_ENCODING_CATEGORY_DEVICE. */ const gchar * gst_encoding_target_get_category (GstEncodingTarget * target) @@ -238,7 +239,7 @@ validate_name (const gchar * name) * gst_encoding_target_new: * @name: The name of the target. * @category: (transfer none): The name of the category to which this @target - * belongs. + * belongs. For example: #GST_ENCODING_CATEGORY_DEVICE. * @description: (transfer none): A description of #GstEncodingTarget in the * current locale. * @profiles: (transfer none) (element-type Gst.EncodingProfile): A #GList of @@ -250,6 +251,10 @@ validate_name (const gchar * name) * first character, followed by either lowercase ASCII letters, digits or * hyphens ('-'). * + * The @category *should* be one of the existing well-defined categories, like + * #GST_ENCODING_CATEGORY_DEVICE, but it *can* be a application or user specific + * category if needed. + * * Since: 0.10.32 * * Returns: (transfer full): The newly created #GstEncodingTarget or %NULL if @@ -305,7 +310,8 @@ invalid_category: * @target: the #GstEncodingTarget to add a profile to * @profile: (transfer full): the #GstEncodingProfile to add * - * Adds the given @profile to the @target. + * Adds the given @profile to the @target. Each added profile must have + * a unique name within the profile. * * The @target will steal a reference to the @profile. If you wish to use * the profile after calling this method, you should increase its reference @@ -783,7 +789,8 @@ gst_encoding_target_subload (gchar * path, const gchar * category, /** * gst_encoding_target_load: * @name: the name of the #GstEncodingTarget to load. - * @category: (allow-none): the name of the target category. Can be %NULL + * @category: (allow-none): the name of the target category, like + * #GST_ENCODING_CATEGORY_DEVICE. Can be %NULL * @error: If an error occured, this field will be filled in. * * Searches for the #GstEncodingTarget with the given name, loads it diff --git a/gst-libs/gst/pbutils/encoding-target.h b/gst-libs/gst/pbutils/encoding-target.h index bb5b40921d..a012011596 100644 --- a/gst-libs/gst/pbutils/encoding-target.h +++ b/gst-libs/gst/pbutils/encoding-target.h @@ -32,9 +32,39 @@ G_BEGIN_DECLS * */ +/** + * GST_ENCODING_CATEGORY_DEVICE: + * #GstEncodingTarget category for device-specific targets. + * The name of the target will usually be the contructor and model of the device, + * and that target will contain #GstEncodingProfiles suitable for that device. + */ #define GST_ENCODING_CATEGORY_DEVICE "device" + +/** + * GST_ENCODING_CATEGORY_ONLINE_SERVICE: + * #GstEncodingTarget category for online-services. + * The name of the target will usually be the name of the online service + * and that target will contain #GstEncodingProfiles suitable for that online + * service. + */ + #define GST_ENCODING_CATEGORY_ONLINE_SERVICE "online-service" + +/** + * GST_ENCODING_CATEGORY_STORAGE_EDITING: + * #GstEncodingTarget category for storage, archiving and editing targets. + * Those targets can be lossless and/or provide very fast random access content. + * The name of the target will usually be the container type or editing target, + * and that target will contain #GstEncodingProfiles suitable for editing or + * storage. + */ #define GST_ENCODING_CATEGORY_STORAGE_EDITING "storage-editing" + +/** + * GST_ENCODING_CATEGORY_CAPTURE: + * #GstEncodingTarget category for recording and capture. + * Targets within this category are optimized for low latency encoding. + */ #define GST_ENCODING_CATEGORY_CAPTURE "capture" /** @@ -42,6 +72,9 @@ G_BEGIN_DECLS * * Collection of #GstEncodingProfile for a specific target or use-case. * + * When being stored/loaded, targets come from a specific category, like + * #GST_ENCODING_CATEGORY_DEVICE. + * * Since: 0.10.32 */ #define GST_TYPE_ENCODING_TARGET \ From 3b32566dd40c6e39ba8a461696f659adb6dc1eba Mon Sep 17 00:00:00 2001 From: Edward Hervey Date: Mon, 3 Jan 2011 16:07:49 +0100 Subject: [PATCH 104/254] encoding-target: Change target suffix to .gep Along with a bunch of other internal cleanups --- gst-libs/gst/pbutils/encoding-target.c | 30 ++++++++++++++------------ tests/check/libs/profile.c | 12 +++++------ 2 files changed, 22 insertions(+), 20 deletions(-) diff --git a/gst-libs/gst/pbutils/encoding-target.c b/gst-libs/gst/pbutils/encoding-target.c index 0cda8596c2..38233cba23 100644 --- a/gst-libs/gst/pbutils/encoding-target.c +++ b/gst-libs/gst/pbutils/encoding-target.c @@ -68,6 +68,8 @@ #define GST_ENCODING_TARGET_HEADER "_gstencodingtarget_" +#define GST_ENCODING_TARGET_DIRECTORY "encoding-profiles" +#define GST_ENCODING_TARGET_SUFFIX ".gep" struct _GstEncodingTarget { @@ -818,12 +820,12 @@ gst_encoding_target_load (const gchar * name, const gchar * category, if (category && !validate_name (category)) goto invalid_category; - lfilename = g_strdup_printf ("%s.gstprofile", name); + lfilename = g_strdup_printf ("%s" GST_ENCODING_TARGET_SUFFIX, name); /* Try from local profiles */ tldir = - g_build_filename (g_get_home_dir (), ".gstreamer-0.10", - "encoding-profile", NULL); + g_build_filename (g_get_home_dir (), ".gstreamer-" GST_MAJORMINOR, + GST_ENCODING_TARGET_DIRECTORY, NULL); target = gst_encoding_target_subload (tldir, category, lfilename, error); g_free (tldir); @@ -831,7 +833,7 @@ gst_encoding_target_load (const gchar * name, const gchar * category, /* Try from system-wide profiles */ tldir = g_build_filename (GST_DATADIR, "gstreamer-" GST_MAJORMINOR, - "encoding-profile", NULL); + GST_ENCODING_TARGET_DIRECTORY, NULL); target = gst_encoding_target_subload (tldir, category, lfilename, error); g_free (tldir); } @@ -946,10 +948,10 @@ gst_encoding_target_save (GstEncodingTarget * target, GError ** error) g_return_val_if_fail (GST_IS_ENCODING_TARGET (target), FALSE); g_return_val_if_fail (target->category != NULL, FALSE); - lfilename = g_strdup_printf ("%s.gstprofile", target->name); + lfilename = g_strdup_printf ("%s" GST_ENCODING_TARGET_SUFFIX, target->name); filename = - g_build_filename (g_get_home_dir (), ".gstreamer-0.10", - "encoding-profile", target->category, lfilename, NULL); + g_build_filename (g_get_home_dir (), ".gstreamer-" GST_MAJORMINOR, + GST_ENCODING_TARGET_DIRECTORY, target->category, lfilename, NULL); g_free (lfilename); res = gst_encoding_target_save_to (target, filename, error); @@ -999,14 +1001,14 @@ gst_encoding_list_available_categories (void) gchar *topdir; /* First try user-local categories */ - topdir = g_build_filename (g_get_home_dir (), ".gstreamer-0.10", - "encoding-profile", NULL); + topdir = g_build_filename (g_get_home_dir (), ".gstreamer-" GST_MAJORMINOR, + GST_ENCODING_TARGET_DIRECTORY, NULL); res = get_categories (topdir); g_free (topdir); /* Extend with system-wide categories */ topdir = g_build_filename (GST_DATADIR, "gstreamer-" GST_MAJORMINOR, - "encoding-profile", NULL); + GST_ENCODING_TARGET_DIRECTORY, NULL); tmp1 = get_categories (topdir); g_free (topdir); @@ -1038,7 +1040,7 @@ sub_get_all_targets (gchar * subdir) gchar *fullname; /* Only try files ending with .gstprofile */ - if (!g_str_has_suffix (filename, ".gstprofile")) + if (!g_str_has_suffix (filename, GST_ENCODING_TARGET_SUFFIX)) continue; fullname = g_build_filename (subdir, filename, NULL); @@ -1113,14 +1115,14 @@ gst_encoding_list_all_targets (const gchar * categoryname) gchar *topdir; /* Get user-locals */ - topdir = g_build_filename (g_get_home_dir (), ".gstreamer-0.10", - "encoding-profile", NULL); + topdir = g_build_filename (g_get_home_dir (), ".gstreamer-" GST_MAJORMINOR, + GST_ENCODING_TARGET_DIRECTORY, NULL); res = get_all_targets (topdir, categoryname); g_free (topdir); /* Get system-wide */ topdir = g_build_filename (GST_DATADIR, "gstreamer-" GST_MAJORMINOR, - "encoding-profile", NULL); + GST_ENCODING_TARGET_DIRECTORY, NULL); tmp1 = get_all_targets (topdir, categoryname); g_free (topdir); diff --git a/tests/check/libs/profile.c b/tests/check/libs/profile.c index deed294cf0..08ccac2c6c 100644 --- a/tests/check/libs/profile.c +++ b/tests/check/libs/profile.c @@ -290,7 +290,7 @@ GST_START_TEST (test_saving_profile) /* Check we can load it */ profile_file_name = g_build_filename (g_get_home_dir (), ".gstreamer-0.10", - "encoding-profile", "herding", "myponytarget2.gstprofile", NULL); + "encoding-profiles", "herding", "myponytarget2.gep", NULL); GST_DEBUG ("Loading target from '%s'", profile_file_name); loaded = gst_encoding_target_load_from (profile_file_name, NULL); fail_unless (loaded != NULL); @@ -412,7 +412,7 @@ GST_START_TEST (test_loading_profile) /* Test loading using fully specified path */ profile_file_name = g_build_filename (g_get_home_dir (), ".gstreamer-0.10", - "encoding-profile", "herding", "myponytarget.gstprofile", NULL); + "encoding-profiles", "herding", "myponytarget.gep", NULL); GST_DEBUG ("Loading target from '%s'", profile_file_name); target = gst_encoding_target_load_from (profile_file_name, NULL); @@ -545,11 +545,11 @@ remove_profile_file (void) gchar *profile_file_name; profile_file_name = g_build_filename (g_get_home_dir (), ".gstreamer-0.10", - "encoding-profile", "herding", "myponytarget.gstprofile", NULL); + "encoding-profiles", "herding", "myponytarget.gep", NULL); g_unlink (profile_file_name); g_free (profile_file_name); profile_file_name = g_build_filename (g_get_home_dir (), ".gstreamer-0.10", - "encoding-profile", "herding", "myponytarget2.gstprofile", NULL); + "encoding-profiles", "herding", "myponytarget2.gep", NULL); g_unlink (profile_file_name); g_free (profile_file_name); } @@ -563,10 +563,10 @@ create_profile_file (void) profile_dir = g_build_filename (g_get_home_dir (), ".gstreamer-0.10", - "encoding-profile", "herding", NULL); + "encoding-profiles", "herding", NULL); profile_file_name = g_build_filename (g_get_home_dir (), ".gstreamer-0.10", - "encoding-profile", "herding", "myponytarget.gstprofile", NULL); + "encoding-profiles", "herding", "myponytarget.gep", NULL); g_mkdir_with_parents (profile_dir, S_IRUSR | S_IWUSR | S_IXUSR); if (!g_file_set_contents (profile_file_name, profile_string, strlen (profile_string), &error)) From 536849bce572e3272c68e70511665f807a6e33bc Mon Sep 17 00:00:00 2001 From: Edward Hervey Date: Mon, 3 Jan 2011 18:51:22 +0100 Subject: [PATCH 105/254] encoding-target: more docs cleanups --- gst-libs/gst/pbutils/encoding-profile.c | 32 ++++++++++++------------- gst-libs/gst/pbutils/encoding-target.c | 7 ++---- gst-libs/gst/pbutils/encoding-target.h | 4 ++++ 3 files changed, 22 insertions(+), 21 deletions(-) diff --git a/gst-libs/gst/pbutils/encoding-profile.c b/gst-libs/gst/pbutils/encoding-profile.c index 5fa3abb14c..00a7f38cbb 100644 --- a/gst-libs/gst/pbutils/encoding-profile.c +++ b/gst-libs/gst/pbutils/encoding-profile.c @@ -298,10 +298,10 @@ gst_encoding_profile_get_restriction (GstEncodingProfile * profile) * @profile: a #GstEncodingProfile * @name: the name to set on the profile * - * Since: 0.10.32 - * * Set @name as the given name for the @profile. A copy of @name will be made * internally. + * + * Since: 0.10.32 */ void gst_encoding_profile_set_name (GstEncodingProfile * profile, const gchar * name) @@ -316,10 +316,10 @@ gst_encoding_profile_set_name (GstEncodingProfile * profile, const gchar * name) * @profile: a #GstEncodingProfile * @description: the description to set on the profile * - * Since: 0.10.32 - * * Set @description as the given description for the @profile. A copy of @description will be made * internally. + * + * Since: 0.10.32 */ void gst_encoding_profile_set_description (GstEncodingProfile * profile, @@ -335,9 +335,9 @@ gst_encoding_profile_set_description (GstEncodingProfile * profile, * @profile: a #GstEncodingProfile * @format: the media format to use in the profile. * - * Since: 0.10.32 - * * Sets the media format used in the profile. + * + * Since: 0.10.32 */ void gst_encoding_profile_set_format (GstEncodingProfile * profile, GstCaps * format) @@ -352,9 +352,9 @@ gst_encoding_profile_set_format (GstEncodingProfile * profile, GstCaps * format) * @profile: a #GstEncodingProfile * @preset: the element preset to use * - * Since: 0.10.32 - * * Sets the preset to use for the profile. + * + * Since: 0.10.32 */ void gst_encoding_profile_set_preset (GstEncodingProfile * profile, @@ -370,10 +370,10 @@ gst_encoding_profile_set_preset (GstEncodingProfile * profile, * @profile: a #GstEncodingProfile * @presence: the number of time the profile can be used * - * Since: 0.10.32 - * * Set the number of time the profile is used in its parent * container profile. If 0, it is not a mandatory stream + * + * Since: 0.10.32 */ void gst_encoding_profile_set_presence (GstEncodingProfile * profile, guint presence) @@ -386,10 +386,10 @@ gst_encoding_profile_set_presence (GstEncodingProfile * profile, guint presence) * @profile: a #GstEncodingProfile * @restriction: the restriction to apply * - * Since: 0.10.32 - * * Set the restriction #GstCaps to apply before the encoder * that will be used in the profile. Does not apply to #GstEncodingContainerProfile. + * + * Since: 0.10.32 */ void gst_encoding_profile_set_restriction (GstEncodingProfile * profile, @@ -501,11 +501,11 @@ gst_encoding_video_profile_get_variableframerate (GstEncodingVideoProfile * * @prof: a #GstEncodingVideoProfile * @pass: the pass number for this profile * - * Since: 0.10.32 - * * Sets the pass number of this video profile. The first pass profile should have * this value set to 1. If this video profile isn't part of a multi-pass profile, * you may set it to 0 (the default value). + * + * Since: 0.10.32 */ void gst_encoding_video_profile_set_pass (GstEncodingVideoProfile * prof, guint pass) @@ -518,12 +518,12 @@ gst_encoding_video_profile_set_pass (GstEncodingVideoProfile * prof, guint pass) * @prof: a #GstEncodingVideoProfile * @variableframerate: a boolean * - * Since: 0.10.32 - * * If set to %TRUE, then the incoming streamm will be allowed to have non-constant * framerate. If set to %FALSE (default value), then the incoming stream will * be normalized by dropping/duplicating frames in order to produce a * constance framerate. + * + * Since: 0.10.32 */ void gst_encoding_video_profile_set_variableframerate (GstEncodingVideoProfile * diff --git a/gst-libs/gst/pbutils/encoding-target.c b/gst-libs/gst/pbutils/encoding-target.c index 38233cba23..632661ebe3 100644 --- a/gst-libs/gst/pbutils/encoding-target.c +++ b/gst-libs/gst/pbutils/encoding-target.c @@ -725,8 +725,7 @@ beach: return res; } -/** - * +/* * returned list contents must be freed */ static GList * @@ -929,9 +928,7 @@ write_failed: * @target: a #GstEncodingTarget * @error: If an error occured, this field will be filled in. * - * Saves the @target to the default location. Unless the user has write access - * to the system-wide encoding target directory, it will be saved in a - * user-local directory. + * Saves the @target to a default user-local directory. * * Since: 0.10.32 * diff --git a/gst-libs/gst/pbutils/encoding-target.h b/gst-libs/gst/pbutils/encoding-target.h index a012011596..db42c9d76a 100644 --- a/gst-libs/gst/pbutils/encoding-target.h +++ b/gst-libs/gst/pbutils/encoding-target.h @@ -34,6 +34,7 @@ G_BEGIN_DECLS /** * GST_ENCODING_CATEGORY_DEVICE: + * * #GstEncodingTarget category for device-specific targets. * The name of the target will usually be the contructor and model of the device, * and that target will contain #GstEncodingProfiles suitable for that device. @@ -42,6 +43,7 @@ G_BEGIN_DECLS /** * GST_ENCODING_CATEGORY_ONLINE_SERVICE: + * * #GstEncodingTarget category for online-services. * The name of the target will usually be the name of the online service * and that target will contain #GstEncodingProfiles suitable for that online @@ -52,6 +54,7 @@ G_BEGIN_DECLS /** * GST_ENCODING_CATEGORY_STORAGE_EDITING: + * * #GstEncodingTarget category for storage, archiving and editing targets. * Those targets can be lossless and/or provide very fast random access content. * The name of the target will usually be the container type or editing target, @@ -62,6 +65,7 @@ G_BEGIN_DECLS /** * GST_ENCODING_CATEGORY_CAPTURE: + * * #GstEncodingTarget category for recording and capture. * Targets within this category are optimized for low latency encoding. */ From 777f816ff162aa7c2d6bd2dbf3b123615e8f91e5 Mon Sep 17 00:00:00 2001 From: Edward Hervey Date: Mon, 3 Jan 2011 18:52:00 +0100 Subject: [PATCH 106/254] encoding-target: Fixup loading/saving methods --- docs/libs/gst-plugins-base-libs-sections.txt | 4 +-- gst-libs/gst/pbutils/encoding-target.c | 34 ++++++++++---------- gst-libs/gst/pbutils/encoding-target.h | 10 +++--- tests/check/libs/profile.c | 4 +-- win32/common/libgstpbutils.def | 4 +-- 5 files changed, 28 insertions(+), 28 deletions(-) diff --git a/docs/libs/gst-plugins-base-libs-sections.txt b/docs/libs/gst-plugins-base-libs-sections.txt index 29969fe947..a6f24ca20d 100644 --- a/docs/libs/gst-plugins-base-libs-sections.txt +++ b/docs/libs/gst-plugins-base-libs-sections.txt @@ -1961,9 +1961,9 @@ gst_encoding_target_get_profiles gst_encoding_target_get_profile gst_encoding_target_add_profile gst_encoding_target_save -gst_encoding_target_save_to +gst_encoding_target_save_to_file gst_encoding_target_load -gst_encoding_target_load_from +gst_encoding_target_load_from_file gst_encoding_list_all_targets gst_encoding_list_available_categories diff --git a/gst-libs/gst/pbutils/encoding-target.c b/gst-libs/gst/pbutils/encoding-target.c index 632661ebe3..3a9d2d3774 100644 --- a/gst-libs/gst/pbutils/encoding-target.c +++ b/gst-libs/gst/pbutils/encoding-target.c @@ -693,8 +693,8 @@ empty_name: } /** - * gst_encoding_target_load_from: - * @path: The file to load the #GstEncodingTarget from + * gst_encoding_target_load_from_file: + * @filepath: The file location to load the #GstEncodingTarget from * @error: If an error occured, this field will be filled in. * * Opens the provided file and returns the contained #GstEncodingTarget. @@ -706,13 +706,13 @@ empty_name: */ GstEncodingTarget * -gst_encoding_target_load_from (const gchar * path, GError ** error) +gst_encoding_target_load_from_file (const gchar * filepath, GError ** error) { GKeyFile *in; gchar *targetname, *categoryname, *description; GstEncodingTarget *res = NULL; - in = load_file_and_read_header (path, &targetname, &categoryname, + in = load_file_and_read_header (filepath, &targetname, &categoryname, &description, error); if (!in) goto beach; @@ -768,14 +768,14 @@ gst_encoding_target_subload (gchar * path, const gchar * category, gchar *filename; filename = g_build_filename (path, category, lfilename, NULL); - target = gst_encoding_target_load_from (filename, error); + target = gst_encoding_target_load_from_file (filename, error); g_free (filename); } else { GList *tmp, *tries = get_matching_filenames (path, lfilename); /* Try to find a file named %s.gstprofile in any subdirectories */ for (tmp = tries; tmp; tmp = tmp->next) { - target = gst_encoding_target_load_from ((gchar *) tmp->data, NULL); + target = gst_encoding_target_load_from_file ((gchar *) tmp->data, NULL); if (target) break; } @@ -854,12 +854,12 @@ invalid_category: } /** - * gst_encoding_target_save_to: + * gst_encoding_target_save_to_file: * @target: a #GstEncodingTarget - * @path: the location to store the @target at. + * @filepath: the location to store the @target at. * @error: If an error occured, this field will be filled in. * - * Saves the @target to the provided location. + * Saves the @target to the provided file location. * * Since: 0.10.32 * @@ -867,17 +867,17 @@ invalid_category: **/ gboolean -gst_encoding_target_save_to (GstEncodingTarget * target, const gchar * path, - GError ** error) +gst_encoding_target_save_to_file (GstEncodingTarget * target, + const gchar * filepath, GError ** error) { GKeyFile *out; gchar *data; gsize data_size; g_return_val_if_fail (GST_IS_ENCODING_TARGET (target), FALSE); - g_return_val_if_fail (path != NULL, FALSE); + g_return_val_if_fail (filepath != NULL, FALSE); - /* FIXME : Check path is valid and writable + /* FIXME : Check filepath is valid and writable * FIXME : Strip out profiles already present in system target */ /* Get unique name... */ @@ -891,7 +891,7 @@ gst_encoding_target_save_to (GstEncodingTarget * target, const gchar * path, if (!(data = g_key_file_to_data (out, &data_size, error))) goto convert_failed; - if (!g_file_set_contents (path, data, data_size, error)) + if (!g_file_set_contents (filepath, data, data_size, error)) goto write_failed; g_key_file_free (out); @@ -916,7 +916,7 @@ convert_failed: write_failed: { - GST_ERROR ("Unable to write file %s: %s", path, (*error)->message); + GST_ERROR ("Unable to write file %s: %s", filepath, (*error)->message); g_key_file_free (out); g_free (data); return FALSE; @@ -951,7 +951,7 @@ gst_encoding_target_save (GstEncodingTarget * target, GError ** error) GST_ENCODING_TARGET_DIRECTORY, target->category, lfilename, NULL); g_free (lfilename); - res = gst_encoding_target_save_to (target, filename, error); + res = gst_encoding_target_save_to_file (target, filename, error); g_free (filename); return TRUE; @@ -1041,7 +1041,7 @@ sub_get_all_targets (gchar * subdir) continue; fullname = g_build_filename (subdir, filename, NULL); - target = gst_encoding_target_load_from (fullname, NULL); + target = gst_encoding_target_load_from_file (fullname, NULL); if (target) { res = g_list_append (res, target); } else diff --git a/gst-libs/gst/pbutils/encoding-target.h b/gst-libs/gst/pbutils/encoding-target.h index db42c9d76a..70c049db3a 100644 --- a/gst-libs/gst/pbutils/encoding-target.h +++ b/gst-libs/gst/pbutils/encoding-target.h @@ -130,14 +130,14 @@ gst_encoding_target_add_profile (GstEncodingTarget *target, GstEncodingProfile * gboolean gst_encoding_target_save (GstEncodingTarget *target, GError **error); -gboolean gst_encoding_target_save_to (GstEncodingTarget *target, - const gchar *path, - GError **error); +gboolean gst_encoding_target_save_to_file (GstEncodingTarget *target, + const gchar *filepath, + GError **error); GstEncodingTarget *gst_encoding_target_load (const gchar *name, const gchar *category, GError **error); -GstEncodingTarget *gst_encoding_target_load_from (const gchar *path, - GError **error); +GstEncodingTarget *gst_encoding_target_load_from_file (const gchar *filepath, + GError **error); GList *gst_encoding_list_available_categories (void); GList *gst_encoding_list_all_targets (const gchar * categoryname); diff --git a/tests/check/libs/profile.c b/tests/check/libs/profile.c index 08ccac2c6c..127b8a3f8b 100644 --- a/tests/check/libs/profile.c +++ b/tests/check/libs/profile.c @@ -292,7 +292,7 @@ GST_START_TEST (test_saving_profile) profile_file_name = g_build_filename (g_get_home_dir (), ".gstreamer-0.10", "encoding-profiles", "herding", "myponytarget2.gep", NULL); GST_DEBUG ("Loading target from '%s'", profile_file_name); - loaded = gst_encoding_target_load_from (profile_file_name, NULL); + loaded = gst_encoding_target_load_from_file (profile_file_name, NULL); fail_unless (loaded != NULL); g_free (profile_file_name); @@ -415,7 +415,7 @@ GST_START_TEST (test_loading_profile) "encoding-profiles", "herding", "myponytarget.gep", NULL); GST_DEBUG ("Loading target from '%s'", profile_file_name); - target = gst_encoding_target_load_from (profile_file_name, NULL); + target = gst_encoding_target_load_from_file (profile_file_name, NULL); g_free (profile_file_name); fail_unless (target != NULL); test_individual_target (target); diff --git a/win32/common/libgstpbutils.def b/win32/common/libgstpbutils.def index 63c125d8a8..e30e8355c6 100644 --- a/win32/common/libgstpbutils.def +++ b/win32/common/libgstpbutils.def @@ -92,10 +92,10 @@ EXPORTS gst_encoding_target_get_profiles gst_encoding_target_get_type gst_encoding_target_load - gst_encoding_target_load_from + gst_encoding_target_load_from_file gst_encoding_target_new gst_encoding_target_save - gst_encoding_target_save_to + gst_encoding_target_save_to_file gst_encoding_video_profile_get_pass gst_encoding_video_profile_get_type gst_encoding_video_profile_get_variableframerate From 5a8858b3bcba9f45b02c37785f813d1820c7f8f6 Mon Sep 17 00:00:00 2001 From: Edward Hervey Date: Mon, 3 Jan 2011 19:07:45 +0100 Subject: [PATCH 107/254] encoding-profile: Give a better usage example --- gst-libs/gst/pbutils/encoding-profile.c | 35 ++++++++++++++++--------- 1 file changed, 22 insertions(+), 13 deletions(-) diff --git a/gst-libs/gst/pbutils/encoding-profile.c b/gst-libs/gst/pbutils/encoding-profile.c index 00a7f38cbb..1e7b525441 100644 --- a/gst-libs/gst/pbutils/encoding-profile.c +++ b/gst-libs/gst/pbutils/encoding-profile.c @@ -85,27 +85,36 @@ * * * - * Example: Loading a profile from disk + * Example: Listing categories, targets and profiles * * |[ * #include * ... - *GstEncodingProfile * - *get_ogg_theora_profile(const gchar *path, const gchar *profilename) - *{ - * GstEncodingProfile *prof = NULL; - * GstEncodingTarget *target = NULL; + * GstEncodingProfile *prof; + * GList *categories, *tmpc; + * GList *targets, *tmpt; + * ... + * categories = gst_encoding_target_list_available_categories(); * - * target = gst_encoding_target_load_from (path); - * if (target == NULL) - * return NULL; + * ... Show available categories to user ... * - * prof = gst_encoding_target_get_profile (target, profilename); + * for (tmpc = categories; tmpc; tmpc = tmpc->next) { + * gchar *category = (gchar *) tmpc->data; * - * gst_encoding_target_unref (target); + * ... and we can list all targets within that category ... + * + * targets = gst_encoding_target_list_all (category); * - * return prof; - *} + * ... and show a list to our users ... + * + * g_list_foreach (targets, (GFunc) gst_encoding_target_unref, NULL); + * g_list_free (targets); + * } + * + * g_list_foreach (categories, (GFunc) g_free, NULL); + * g_list_free (categories); + * + * ... * ]| * * From f458662ab976c7630ae3891f1607f1c651378e69 Mon Sep 17 00:00:00 2001 From: Arun Raghavan Date: Wed, 5 Jan 2011 01:50:34 +0530 Subject: [PATCH 108/254] encoding-profile: Minor documentation updates --- gst-libs/gst/pbutils/encoding-profile.c | 28 ++++++++++++++----------- gst-libs/gst/pbutils/encoding-target.c | 13 ++++++------ 2 files changed, 23 insertions(+), 18 deletions(-) diff --git a/gst-libs/gst/pbutils/encoding-profile.c b/gst-libs/gst/pbutils/encoding-profile.c index 1e7b525441..939b0ba1d1 100644 --- a/gst-libs/gst/pbutils/encoding-profile.c +++ b/gst-libs/gst/pbutils/encoding-profile.c @@ -29,10 +29,10 @@ * * Encoding profiles describe the media types and settings one wishes to use for * an encoding process. The top-level profiles are commonly - * #GstEncodingContainerProfile(s) (which contains user-readable name and - * description along with which container format to use) which references one or - * more #GstEncodingProfile(s) which indicate which encoding format should be - * used on each individual streams. + * #GstEncodingContainerProfile(s) (which contains a user-readable name and + * description along with which container format to use). These, in turn, + * reference one or more #GstEncodingProfile(s) which indicate which encoding + * format should be used on each individual streams. * * * #GstEncodingProfile(s) can be provided to the 'encodebin' element, which will take @@ -249,7 +249,7 @@ gst_encoding_profile_get_description (GstEncodingProfile * profile) * * Since: 0.10.32 * - * Returns: the media format used in the profile. + * Returns: the #GstCaps corresponding to the media format used in the profile. */ const GstCaps * gst_encoding_profile_get_format (GstEncodingProfile * profile) @@ -263,7 +263,7 @@ gst_encoding_profile_get_format (GstEncodingProfile * profile) * * Since: 0.10.32 * - * Returns: the preset to be used in the profile. + * Returns: the name of the #GstPreset to be used in the profile. */ const gchar * gst_encoding_profile_get_preset (GstEncodingProfile * profile) @@ -277,8 +277,8 @@ gst_encoding_profile_get_preset (GstEncodingProfile * profile) * * Since: 0.10.32 * - * Returns: The number of time the profile is used in its parent - * container profile. If 0, it is not a mandatory stream + * Returns: The number of times the profile is used in its parent + * container profile. If 0, it is not a mandatory stream. */ guint gst_encoding_profile_get_presence (GstEncodingProfile * profile) @@ -293,7 +293,10 @@ gst_encoding_profile_get_presence (GstEncodingProfile * profile) * Since: 0.10.32 * * Returns: The restriction #GstCaps to apply before the encoder - * that will be used in the profile. Does not apply to #GstEncodingContainerProfile. + * that will be used in the profile. The fields present in restriction caps are + * properties of the raw stream (that is before encoding), such as height and + * width for video and depth and sampling rate for audio. Does not apply to + * #GstEncodingContainerProfile (since there is no corresponding raw stream). * Can be %NULL. */ const GstCaps * @@ -396,7 +399,8 @@ gst_encoding_profile_set_presence (GstEncodingProfile * profile, guint presence) * @restriction: the restriction to apply * * Set the restriction #GstCaps to apply before the encoder - * that will be used in the profile. Does not apply to #GstEncodingContainerProfile. + * that will be used in the profile. See gst_encoding_profile_set_restriction() + * for more about restrictions. Does not apply to #GstEncodingContainerProfile. * * Since: 0.10.32 */ @@ -730,7 +734,7 @@ gst_encoding_container_profile_new (const gchar * name, * @format: the #GstCaps * @preset: the preset(s) to use on the encoder, can be #NULL * @restriction: the #GstCaps used to restrict the input to the encoder, can be - * NULL. + * NULL. See gst_encoding_profile_get_restriction() for more details. * @presence: the number of time this stream must be used. 0 means any number of * times (including never) * @@ -763,7 +767,7 @@ gst_encoding_video_profile_new (GstCaps * format, const gchar * preset, * @format: the #GstCaps * @preset: the preset(s) to use on the encoder, can be #NULL * @restriction: the #GstCaps used to restrict the input to the encoder, can be - * NULL. + * NULL. See gst_encoding_profile_get_restriction() for more details. * @presence: the number of time this stream must be used. 0 means any number of * times (including never) * diff --git a/gst-libs/gst/pbutils/encoding-target.c b/gst-libs/gst/pbutils/encoding-target.c index 3a9d2d3774..5961c25c3b 100644 --- a/gst-libs/gst/pbutils/encoding-target.c +++ b/gst-libs/gst/pbutils/encoding-target.c @@ -59,7 +59,7 @@ * $HOME/gstreamer-GST_MAJORMINOR/encoding-profile * * Naming convention - * $(target.category)/$(target.name).gstprof + * $(target.category)/$(target.name).gep * * Naming restrictions: * lowercase ASCII letter for the first character @@ -253,9 +253,10 @@ validate_name (const gchar * name) * first character, followed by either lowercase ASCII letters, digits or * hyphens ('-'). * - * The @category *should* be one of the existing well-defined categories, like - * #GST_ENCODING_CATEGORY_DEVICE, but it *can* be a application or user specific - * category if needed. + * The @category should be one of the existing + * well-defined categories, like #GST_ENCODING_CATEGORY_DEVICE, but it + * can be a application or user specific category if + * needed. * * Since: 0.10.32 * @@ -1097,10 +1098,10 @@ compare_targets (const GstEncodingTarget * ta, const GstEncodingTarget * tb) /** * gst_encoding_list_all_targets: * @categoryname: (allow-none): The category, for ex: #GST_ENCODING_CATEGORY_DEVICE. - * Can be NULL. + * Can be %NULL. * * List all available #GstEncodingTarget for the specified category, or all categories - * if @categoryname is NULL. + * if @categoryname is %NULL. * * Returns: (transfer full) (element-type GstEncodingTarget): The list of #GstEncodingTarget */ From ff92c53ec55b3039b796f9d1cd2f5481eafcbaa5 Mon Sep 17 00:00:00 2001 From: Edward Hervey Date: Wed, 5 Jan 2011 20:40:39 +0100 Subject: [PATCH 109/254] docs: Add various new symbols --- docs/libs/gst-plugins-base-libs-sections.txt | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/docs/libs/gst-plugins-base-libs-sections.txt b/docs/libs/gst-plugins-base-libs-sections.txt index a6f24ca20d..0cbfb2ec64 100644 --- a/docs/libs/gst-plugins-base-libs-sections.txt +++ b/docs/libs/gst-plugins-base-libs-sections.txt @@ -547,6 +547,7 @@ GST_MIXER_GET_CLASS GST_MIXER_TYPE GST_IS_MIXER GST_IS_MIXER_CLASS +GST_TYPE_STREAM_VOLUME_FORMAT gst_mixer_get_type gst_mixer_type_get_type gst_mixer_flags_get_type @@ -1098,6 +1099,7 @@ GST_BASE_RTP_DEPAYLOAD_SRCPAD gst_base_rtp_depayload_push gst_base_rtp_depayload_push_ts +gst_base_rtp_depayload_push_list GstBaseRTPDepayloadPrivate @@ -1573,6 +1575,7 @@ gst_rtsp_url_free gst_rtsp_url_get_request_uri gst_rtsp_url_set_port gst_rtsp_url_get_port +gst_rtsp_url_decode_path_components gst_rtsp_url_get_type
@@ -1599,6 +1602,9 @@ GstSDPConnection GST_SDP_BWTYPE_CT GST_SDP_BWTYPE_AS GST_SDP_BWTYPE_EXT_PREFIX +GST_SDP_BWTYPE_RR +GST_SDP_BWTYPE_RS +GST_SDP_BWTYPE_TIAS GstSDPBandwidth GstSDPTime GstSDPZone @@ -1617,6 +1623,8 @@ gst_sdp_message_as_text gst_sdp_message_parse_uri gst_sdp_message_as_uri +gst_sdp_address_is_multicast + gst_sdp_message_get_version gst_sdp_message_set_version gst_sdp_message_get_origin @@ -2034,6 +2042,9 @@ GST_VIDEO_CAPS_YUV GST_VIDEO_CAPS_xBGR GST_VIDEO_CAPS_xRGB GST_VIDEO_CAPS_xRGB_HOST_ENDIAN +GST_VIDEO_CAPS_BGR_15 +GST_VIDEO_CAPS_BGR_16 +GST_VIDEO_CAPS_RGB8_PALETTED GST_VIDEO_CAPS_GRAY8 GST_VIDEO_CAPS_GRAY16 GST_VIDEO_FPS_RANGE @@ -2074,6 +2085,7 @@ gst_video_parse_caps_framerate gst_video_parse_caps_pixel_aspect_ratio gst_video_parse_caps_color_matrix gst_video_parse_caps_chroma_site +gst_video_parse_caps_palette GstVideoConvertFrameCallback gst_video_convert_frame gst_video_convert_frame_async @@ -2081,6 +2093,7 @@ gst_video_event_new_still_frame gst_video_event_parse_still_frame gst_video_format_get_type +GST_TYPE_VIDEO_FORMAT
@@ -2140,6 +2153,7 @@ gst_discoverer_info_get_stream_info gst_discoverer_info_get_stream_list gst_discoverer_info_get_tags gst_discoverer_info_get_uri +gst_discoverer_info_get_seekable gst_discoverer_info_unref GstDiscovererStreamInfo From 19201c1ab04f1b85a1bf8e01f92fac8e0d11c249 Mon Sep 17 00:00:00 2001 From: Edward Hervey Date: Wed, 5 Jan 2011 22:02:35 +0100 Subject: [PATCH 110/254] encoding: encoding_profile_get_output_caps => _get_input_caps Makes more sense name-wise --- docs/libs/gst-plugins-base-libs-sections.txt | 2 +- gst-libs/gst/pbutils/encoding-profile.c | 6 +++--- gst-libs/gst/pbutils/encoding-profile.h | 2 +- gst/encoding/gstencodebin.c | 2 +- tests/check/libs/profile.c | 10 +++++----- tests/examples/encoding/encoding.c | 2 +- 6 files changed, 12 insertions(+), 12 deletions(-) diff --git a/docs/libs/gst-plugins-base-libs-sections.txt b/docs/libs/gst-plugins-base-libs-sections.txt index 0cbfb2ec64..91fb569f68 100644 --- a/docs/libs/gst-plugins-base-libs-sections.txt +++ b/docs/libs/gst-plugins-base-libs-sections.txt @@ -1935,7 +1935,7 @@ gst_encoding_profile_set_preset gst_encoding_profile_set_restriction gst_encoding_profile_set_presence gst_encoding_profile_is_equal -gst_encoding_profile_get_output_caps +gst_encoding_profile_get_input_caps gst_encoding_profile_get_type_nick GstEncodingContainerProfile diff --git a/gst-libs/gst/pbutils/encoding-profile.c b/gst-libs/gst/pbutils/encoding-profile.c index 939b0ba1d1..12300dc792 100644 --- a/gst-libs/gst/pbutils/encoding-profile.c +++ b/gst-libs/gst/pbutils/encoding-profile.c @@ -809,7 +809,7 @@ gst_encoding_profile_is_equal (GstEncodingProfile * a, GstEncodingProfile * b) /** - * gst_encoding_profile_get_output_caps: + * gst_encoding_profile_get_input_caps: * @profile: a #GstEncodingProfile * * Computes the full output caps that this @profile will be able to consume. @@ -820,7 +820,7 @@ gst_encoding_profile_is_equal (GstEncodingProfile * a, GstEncodingProfile * b) * when you are done with the caps. */ GstCaps * -gst_encoding_profile_get_output_caps (GstEncodingProfile * profile) +gst_encoding_profile_get_input_caps (GstEncodingProfile * profile) { GstCaps *out, *tmp; GList *ltmp; @@ -835,7 +835,7 @@ gst_encoding_profile_get_output_caps (GstEncodingProfile * profile) for (ltmp = GST_ENCODING_CONTAINER_PROFILE (profile)->encodingprofiles; ltmp; ltmp = ltmp->next) { GstEncodingProfile *sprof = (GstEncodingProfile *) ltmp->data; - gst_caps_merge (res, gst_encoding_profile_get_output_caps (sprof)); + gst_caps_merge (res, gst_encoding_profile_get_input_caps (sprof)); } return res; } diff --git a/gst-libs/gst/pbutils/encoding-profile.h b/gst-libs/gst/pbutils/encoding-profile.h index 69d3d63436..86beccaf86 100644 --- a/gst-libs/gst/pbutils/encoding-profile.h +++ b/gst-libs/gst/pbutils/encoding-profile.h @@ -143,7 +143,7 @@ void gst_encoding_profile_set_presence(GstEncodingProfile *profile, guint presen gboolean gst_encoding_profile_is_equal (GstEncodingProfile *a, GstEncodingProfile *b); -GstCaps * gst_encoding_profile_get_output_caps (GstEncodingProfile *profile); +GstCaps * gst_encoding_profile_get_input_caps (GstEncodingProfile *profile); const gchar *gst_encoding_profile_get_type_nick (GstEncodingProfile *profile); diff --git a/gst/encoding/gstencodebin.c b/gst/encoding/gstencodebin.c index cccc71d7d2..1d44132070 100644 --- a/gst/encoding/gstencodebin.c +++ b/gst/encoding/gstencodebin.c @@ -497,7 +497,7 @@ next_unused_stream_profile (GstEncodeBin * ebin, GType ptype, GstCaps * caps) GstCaps *outcaps; gboolean res; - outcaps = gst_encoding_profile_get_output_caps (sprof); + outcaps = gst_encoding_profile_get_input_caps (sprof); GST_DEBUG ("Unknown stream, seeing if it's compatible with %" GST_PTR_FORMAT, outcaps); res = gst_caps_can_intersect (outcaps, caps); diff --git a/tests/check/libs/profile.c b/tests/check/libs/profile.c index 127b8a3f8b..1c9f60af98 100644 --- a/tests/check/libs/profile.c +++ b/tests/check/libs/profile.c @@ -76,7 +76,7 @@ GST_START_TEST (test_profile_creation) /* Test caps */ test1 = gst_caps_from_string ("video/x-theora; audio/x-vorbis"); - test2 = gst_encoding_profile_get_output_caps (encprof); + test2 = gst_encoding_profile_get_input_caps (encprof); fail_unless (gst_caps_is_equal (test1, test2)); gst_caps_unref (test1); gst_caps_unref (test2); @@ -90,7 +90,7 @@ GST_START_TEST (test_profile_creation) GST_END_TEST; -GST_START_TEST (test_profile_output_caps) +GST_START_TEST (test_profile_input_caps) { GstEncodingProfile *sprof; GstCaps *vorbis; @@ -103,7 +103,7 @@ GST_START_TEST (test_profile_output_caps) gst_encoding_audio_profile_new (vorbis, NULL, NULL, 0); fail_if (sprof == NULL); - out = gst_encoding_profile_get_output_caps (sprof); + out = gst_encoding_profile_get_input_caps (sprof); fail_if (out == NULL); fail_unless (gst_caps_is_equal (out, vorbis)); gst_caps_unref (out); @@ -118,7 +118,7 @@ GST_START_TEST (test_profile_output_caps) gst_encoding_audio_profile_new (vorbis, NULL, restriction, 0); fail_if (sprof == NULL); - out = gst_encoding_profile_get_output_caps (sprof); + out = gst_encoding_profile_get_input_caps (sprof); fail_if (out == NULL); GST_DEBUG ("got caps %" GST_PTR_FORMAT, out); fail_unless (gst_caps_is_equal (out, test1)); @@ -604,7 +604,7 @@ profile_suite (void) suite_add_tcase (s, tc_chain); tcase_add_test (tc_chain, test_profile_creation); - tcase_add_test (tc_chain, test_profile_output_caps); + tcase_add_test (tc_chain, test_profile_input_caps); tcase_add_test (tc_chain, test_target_naming); tcase_add_test (tc_chain, test_target_profile); if (can_write) { diff --git a/tests/examples/encoding/encoding.c b/tests/examples/encoding/encoding.c index c668148f8b..89674ce445 100644 --- a/tests/examples/encoding/encoding.c +++ b/tests/examples/encoding/encoding.c @@ -304,7 +304,7 @@ transcode_file (gchar * uri, gchar * outputuri, GstEncodingProfile * prof) /* Figure out the streams that can be passed as-is to encodebin */ g_object_get (src, "caps", &rescaps, NULL); rescaps = gst_caps_copy (rescaps); - profilecaps = gst_encoding_profile_get_output_caps (prof); + profilecaps = gst_encoding_profile_get_input_caps (prof); gst_caps_append (rescaps, profilecaps); /* Set properties */ From 8dc70c76b454361472c32108a242646a63a82e36 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim-Philipp=20M=C3=BCller?= Date: Thu, 6 Jan 2011 00:28:39 +0000 Subject: [PATCH 111/254] pbutils: config.h include should come before all other includes --- gst-libs/gst/pbutils/encoding-target.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/gst-libs/gst/pbutils/encoding-target.c b/gst-libs/gst/pbutils/encoding-target.c index 5961c25c3b..0a42ff3eee 100644 --- a/gst-libs/gst/pbutils/encoding-target.c +++ b/gst-libs/gst/pbutils/encoding-target.c @@ -18,11 +18,12 @@ * Boston, MA 02111-1307, USA. */ -#include -#include #ifdef HAVE_CONFIG_H #include "config.h" #endif + +#include +#include #include "encoding-target.h" /* From b40c0b875cbddf30c0c318350cae59f6cad6dfc7 Mon Sep 17 00:00:00 2001 From: Edward Hervey Date: Thu, 6 Jan 2011 08:46:42 +0100 Subject: [PATCH 112/254] tools: don't leak the GMainLoop --- tools/gst-discoverer.c | 1 + 1 file changed, 1 insertion(+) diff --git a/tools/gst-discoverer.c b/tools/gst-discoverer.c index 2182c0f0c9..6a18f407b5 100644 --- a/tools/gst-discoverer.c +++ b/tools/gst-discoverer.c @@ -483,6 +483,7 @@ main (int argc, char **argv) gst_discoverer_stop (dc); g_free (ps); + g_main_loop_unref (ml); } g_object_unref (dc); From fce99dc0be15fca80e6d1e1fd447e3e1338f4e31 Mon Sep 17 00:00:00 2001 From: Edward Hervey Date: Thu, 6 Jan 2011 08:47:04 +0100 Subject: [PATCH 113/254] tools: Improve pretty-printing of tags Avoids escaping strings for nothing and printing out useless buffer contents. --- tools/gst-discoverer.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/tools/gst-discoverer.c b/tools/gst-discoverer.c index 6a18f407b5..c68721b1bc 100644 --- a/tools/gst-discoverer.c +++ b/tools/gst-discoverer.c @@ -243,7 +243,13 @@ print_tag_each (GQuark field_id, const GValue * value, gpointer user_data) gint tab = GPOINTER_TO_INT (user_data); gchar *ser; - ser = gst_value_serialize (value); + if (G_VALUE_HOLDS_STRING (value)) + ser = g_value_dup_string (value); + else if (GST_VALUE_HOLDS_BUFFER (value)) { + GstBuffer *buf = gst_value_get_buffer (value); + ser = g_strdup_printf ("", GST_BUFFER_SIZE (buf)); + } else + ser = gst_value_serialize (value); g_print ("%*s%s: %s\n", tab, " ", gst_tag_get_nick (g_quark_to_string (field_id)), ser); From 2c1bf82d55cf100117eb4fdac85dac9150fe2659 Mon Sep 17 00:00:00 2001 From: Robert Swain Date: Thu, 6 Jan 2011 13:08:53 +0100 Subject: [PATCH 114/254] videorate: Fix behaviour for frame rate cap changes The outgoing buffer timestamp is calculated by scaling an output buffer count by the src pad frame rate caps. If these caps change, we need to reset the count and work from a new base timestamp. The new output buffer timestamp is then the count scaled by the new caps values added onto the base timestamp. --- gst/videorate/gstvideorate.c | 25 +++++++++++++++++++------ gst/videorate/gstvideorate.h | 6 +++++- 2 files changed, 24 insertions(+), 7 deletions(-) diff --git a/gst/videorate/gstvideorate.c b/gst/videorate/gstvideorate.c index 827f0e9290..a0642c210c 100644 --- a/gst/videorate/gstvideorate.c +++ b/gst/videorate/gstvideorate.c @@ -290,6 +290,16 @@ gst_video_rate_setcaps (GstPad * pad, GstCaps * caps) goto no_framerate; if (pad == videorate->srcpad) { + /* out_frame_count is scaled by the frame rate caps when calculating next_ts. + * when the frame rate caps change, we must update base_ts and reset + * out_frame_count */ + if (videorate->to_rate_numerator) { + videorate->base_ts += + gst_util_uint64_scale (videorate->out_frame_count, + videorate->to_rate_denominator * GST_SECOND, + videorate->to_rate_numerator); + } + videorate->out_frame_count = 0; videorate->to_rate_numerator = rate_numerator; videorate->to_rate_denominator = rate_denominator; otherpad = videorate->sinkpad; @@ -394,7 +404,8 @@ gst_video_rate_reset (GstVideoRate * videorate) videorate->in = 0; videorate->out = 0; - videorate->segment_out = 0; + videorate->base_ts = 0; + videorate->out_frame_count = 0; videorate->drop = 0; videorate->dup = 0; videorate->next_ts = GST_CLOCK_TIME_NONE; @@ -473,11 +484,12 @@ gst_video_rate_flush_prev (GstVideoRate * videorate, gboolean duplicate) push_ts = videorate->next_ts; videorate->out++; - videorate->segment_out++; + videorate->out_frame_count++; if (videorate->to_rate_numerator) { /* interpolate next expected timestamp in the segment */ - videorate->next_ts = videorate->segment.accum + videorate->segment.start + - gst_util_uint64_scale (videorate->segment_out, + videorate->next_ts = + videorate->segment.accum + videorate->segment.start + + videorate->base_ts + gst_util_uint64_scale (videorate->out_frame_count, videorate->to_rate_denominator * GST_SECOND, videorate->to_rate_numerator); GST_BUFFER_DURATION (outbuf) = videorate->next_ts - push_ts; @@ -587,7 +599,8 @@ gst_video_rate_event (GstPad * pad, GstEvent * event) gst_video_rate_notify_drop (videorate); } /* clean up for the new one; _chain will resume from the new start */ - videorate->segment_out = 0; + videorate->base_ts = 0; + videorate->out_frame_count = 0; gst_video_rate_swap_prev (videorate, NULL, 0); videorate->next_ts = GST_CLOCK_TIME_NONE; } @@ -783,7 +796,7 @@ gst_video_rate_chain (GstPad * pad, GstBuffer * buffer) * timestamp in the segment */ if (videorate->skip_to_first) { videorate->next_ts = in_ts; - videorate->segment_out = gst_util_uint64_scale (in_ts, + videorate->out_frame_count = gst_util_uint64_scale (in_ts, videorate->to_rate_numerator, videorate->to_rate_denominator * GST_SECOND) - (videorate->segment.accum + videorate->segment.start); diff --git a/gst/videorate/gstvideorate.h b/gst/videorate/gstvideorate.h index 4d6c0615ac..23e20567e9 100644 --- a/gst/videorate/gstvideorate.h +++ b/gst/videorate/gstvideorate.h @@ -55,7 +55,11 @@ struct _GstVideoRate guint64 next_ts; /* Timestamp of next buffer to output */ GstBuffer *prevbuf; guint64 prev_ts; /* Previous buffer timestamp */ - guint64 segment_out; /* in-segment counting */ + guint64 out_frame_count; /* number of frames output since the beginning + * of the segment or the last frame rate caps + * change, whichever was later */ + guint64 base_ts; /* used in next_ts calculation after a + * frame rate caps change */ gboolean discont; guint64 last_ts; /* Timestamp of last input buffer */ From 19d4a5ab4d94b689b8a4e03df217ab2ab28788db Mon Sep 17 00:00:00 2001 From: Arun Raghavan Date: Wed, 5 Jan 2011 15:53:09 +0530 Subject: [PATCH 115/254] discoverer: Documentation updates Some cosmetic changes and expands on some bits of the documentation to make it more newbie-friendly. --- docs/libs/gst-plugins-base-libs-sections.txt | 4 +- gst-libs/gst/pbutils/gstdiscoverer-types.c | 45 ++++++++++++++++++-- gst-libs/gst/pbutils/gstdiscoverer.c | 15 ++++--- gst-libs/gst/pbutils/gstdiscoverer.h | 20 +++++++-- 4 files changed, 68 insertions(+), 16 deletions(-) diff --git a/docs/libs/gst-plugins-base-libs-sections.txt b/docs/libs/gst-plugins-base-libs-sections.txt index 91fb569f68..41235a09ef 100644 --- a/docs/libs/gst-plugins-base-libs-sections.txt +++ b/docs/libs/gst-plugins-base-libs-sections.txt @@ -2154,6 +2154,7 @@ gst_discoverer_info_get_stream_list gst_discoverer_info_get_tags gst_discoverer_info_get_uri gst_discoverer_info_get_seekable +gst_discoverer_info_ref gst_discoverer_info_unref GstDiscovererStreamInfo @@ -2169,8 +2170,6 @@ gst_discoverer_stream_info_ref gst_discoverer_stream_info_unref gst_discoverer_stream_info_list_free gst_discoverer_stream_info_get_stream_type_nick -gst_discoverer_info_copy -gst_discoverer_info_ref gst_discoverer_info_get_audio_streams gst_discoverer_info_get_container_streams gst_discoverer_info_get_streams @@ -2225,6 +2224,7 @@ gst_discoverer_audio_info_get_type gst_discoverer_container_info_get_type gst_discoverer_get_type gst_discoverer_info_get_type +gst_discoverer_info_copy gst_discoverer_result_get_type gst_discoverer_stream_info_get_type gst_discoverer_video_info_get_type diff --git a/gst-libs/gst/pbutils/gstdiscoverer-types.c b/gst-libs/gst/pbutils/gstdiscoverer-types.c index 3cf3562e46..2edf8e923c 100644 --- a/gst-libs/gst/pbutils/gstdiscoverer-types.c +++ b/gst-libs/gst/pbutils/gstdiscoverer-types.c @@ -377,7 +377,7 @@ gst_discoverer_stream_info_list_free (GList * infos) /** * gst_discoverer_info_get_streams: * @info: a #GstDiscovererInfo - * @streamtype: a #GType of #GstDiscovererStreamInfo + * @streamtype: a #GType derived from #GstDiscovererStreamInfo * * Finds the #GstDiscovererStreamInfo contained in @info that match the * given @streamtype. @@ -712,8 +712,7 @@ VIDEO_INFO_ACCESSOR_CODE (height, guint, 0); * gst_discoverer_video_info_get_depth: * @info: a #GstDiscovererVideoInfo * - * Returns: the depth in bits of the video stream (only relevant for - * video streams). + * Returns: the depth in bits of the video stream. * * Since: 0.10.31 */ @@ -942,3 +941,43 @@ DISCOVERER_INFO_ACCESSOR_CODE (misc, const GstStructure *, NULL); */ DISCOVERER_INFO_ACCESSOR_CODE (tags, const GstTagList *, NULL); + +/** + * gst_discoverer_info_ref: + * @info: a #GstDiscovererInfo + * + * Increments the reference count of @info. + * + * Returns: the same #GstDiscovererInfo object + * + * Since: 0.10.31 + */ + +/** + * gst_discoverer_info_unref: + * @info: a #GstDiscovererInfo + * + * Decrements the reference count of @info. + * + * Since: 0.10.31 + */ + +/** + * gst_discoverer_stream_info_ref: + * @info: a #GstDiscovererStreamInfo + * + * Increments the reference count of @info. + * + * Returns: the same #GstDiscovererStreamInfo object + * + * Since: 0.10.31 + */ + +/** + * gst_discoverer_stream_info_unref: + * @info: a #GstDiscovererStreamInfo + * + * Decrements the reference count of @info. + * + * Since: 0.10.31 + */ diff --git a/gst-libs/gst/pbutils/gstdiscoverer.c b/gst-libs/gst/pbutils/gstdiscoverer.c index fa5b742e5d..bc99f43c74 100644 --- a/gst-libs/gst/pbutils/gstdiscoverer.c +++ b/gst-libs/gst/pbutils/gstdiscoverer.c @@ -218,7 +218,7 @@ gst_discoverer_class_init (GstDiscovererClass * klass) * @discoverer: the #GstDiscoverer * @info: the results #GstDiscovererInfo * @error: (type GLib.Error): #GError, which will be non-NULL if an error - * occured during discovery + * occurred during discovery * * Will be emitted when all information on a URI could be discovered. */ @@ -1309,7 +1309,8 @@ gst_discoverer_stop (GstDiscoverer * discoverer) * discovery of the @uri will only take place if gst_discoverer_start() has * been called. * - * A copy of @uri will be done internally, the caller can safely g_free() afterwards. + * A copy of @uri will be made internally, so the caller can safely g_free() + * afterwards. * * Returns: %TRUE if the @uri was succesfully appended to the list of pending * uris, else %FALSE @@ -1342,15 +1343,15 @@ gst_discoverer_discover_uri_async (GstDiscoverer * discoverer, * gst_discoverer_discover_uri: * @discoverer: A #GstDiscoverer * @uri: The URI to run on. - * @err: If an error occured, this field will be filled in. + * @err: If an error occurred, this field will be filled in. * * Synchronously discovers the given @uri. * - * A copy of @uri will be done internally, the caller can safely g_free() + * A copy of @uri will be made internally, so the caller can safely g_free() * afterwards. * - * Returns: (transfer full): the result of the scanning. Can be %NULL iif an - * error occured. + * Returns: (transfer full): the result of the scanning. Can be %NULL if an + * error occurred. * * Since: 0.10.31 */ @@ -1403,7 +1404,7 @@ gst_discoverer_discover_uri (GstDiscoverer * discoverer, const gchar * uri, * Creates a new #GstDiscoverer with the provided timeout. * * Returns: (transfer full): The new #GstDiscoverer. - * If an error happened when creating the discoverer, @err will be set + * If an error occurred when creating the discoverer, @err will be set * accordingly and %NULL will be returned. If @err is set, the caller must * free it when no longer needed using g_error_free(). * diff --git a/gst-libs/gst/pbutils/gstdiscoverer.h b/gst-libs/gst/pbutils/gstdiscoverer.h index da8eb58b32..671dbaa4ed 100644 --- a/gst-libs/gst/pbutils/gstdiscoverer.h +++ b/gst-libs/gst/pbutils/gstdiscoverer.h @@ -38,9 +38,21 @@ GType gst_discoverer_stream_info_get_type (void); /** * GstDiscovererStreamInfo: * - * Base structure for informations concerning a media stream. Depending on the @streamtype, - * One can find more media-specific information in #GstDiscovererAudioInfo, - * #GstDiscovererVideoInfo, #GstDiscovererContainerInfo. + * Base structure for information concerning a media stream. Depending on the + * stream type, one can find more media-specific information in + * #GstDiscovererAudioInfo, #GstDiscovererVideoInfo, and + * #GstDiscovererContainerInfo. + * + * The #GstDiscovererStreamInfo represents the topology of the stream. Siblings + * can be iterated over with gst_discoverer_stream_info_get_next() and + * gst_discoverer_stream_info_get_previous(). Children (sub-streams) of a + * stream can be accessed using the #GstDiscovererContainerInfo API. + * + * As a simple example, if you run #GstDiscoverer on an AVI file with one audio + * and one video stream, you will get a #GstDiscovererContainerInfo + * corresponding to the AVI container, which in turn will have a + * #GstDiscovererAudioInfo sub-stream and a #GstDiscovererVideoInfo sub-stream + * for the audio and video streams respectively. * * Since: 0.10.31 */ @@ -102,7 +114,7 @@ guint gst_discoverer_audio_info_get_max_bitrate(const GstDiscovererAudioInfo* in /** * GstDiscovererVideoInfo: * - * #GstDiscovererStreamInfo specific to video streams. + * #GstDiscovererStreamInfo specific to video streams (this includes images). * * Since: 0.10.31 */ From 133baf3a34b463c979503600c5fbb519a67d484f Mon Sep 17 00:00:00 2001 From: christian schaller Date: Thu, 6 Jan 2011 17:57:41 +0000 Subject: [PATCH 116/254] Update spec file with discoverer and encodebinchanges --- gst-plugins-base.spec.in | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/gst-plugins-base.spec.in b/gst-plugins-base.spec.in index 0e580348d2..b2849274a9 100644 --- a/gst-plugins-base.spec.in +++ b/gst-plugins-base.spec.in @@ -20,8 +20,8 @@ BuildRequires: %{gstreamer}-devel >= %{gst_minver} BuildRequires: gcc-c++ BuildRequires: gtk-doc >= 1.3 -BuildRequires: liboil-devel >= 0.3.14 -Requires: liboil => 0.3.14 +BuildRequires: orc-devel +Requires: orc @USE_GNOME_VFS_TRUE@Requires: gnome-vfs2 > 1.9.4.00 @USE_GNOME_VFS_TRUE@BuildRequires: gnome-vfs2-devel > 1.9.4.00 @@ -81,6 +81,7 @@ rm -rf $RPM_BUILD_ROOT # helper programs %{_bindir}/gst-visualise-%{majorminor} +%{_bindir}/gst-discoverer-%{majorminor} %{_mandir}/man1/gst-visualise-%{majorminor}* # libraries @@ -118,6 +119,7 @@ rm -rf $RPM_BUILD_ROOT %{_libdir}/gstreamer-%{majorminor}/libgstaudiotestsrc.so %{_libdir}/gstreamer-%{majorminor}/libgstgdp.so %{_libdir}/gstreamer-%{majorminor}/libgstapp.so +%{_libdir}/gstreamer-%{majorminor}/libgstencodebin.so # Here are packages not in the base plugins package but not dependant # on an external lib @@ -215,6 +217,11 @@ GStreamer Plugins Base library development and header files. %{_includedir}/gstreamer-%{majorminor}/gst/audio/audio-enumtypes.h %{_includedir}/gstreamer-%{majorminor}/gst/video/video-enumtypes.h %{_includedir}/gstreamer-%{majorminor}/gst/interfaces/streamvolume.h +%{_includedir}/gstreamer-%{majorminor}/gst/pbutils/codec-utils.h +%{_includedir}/gstreamer-%{majorminor}/gst/pbutils/encoding-profile.h +%{_includedir}/gstreamer-%{majorminor}/gst/pbutils/encoding-target.h +%{_includedir}/gstreamer-%{majorminor}/gst/pbutils/gstdiscoverer.h +%{_includedir}/gstreamer-%{majorminor}/gst/pbutils/gstpluginsbaseversion.h %{_libdir}/libgstfft-%{majorminor}.so %{_libdir}/libgstrtsp-%{majorminor}.so From b03b223fb110e3f5f2dcfc476b6db8ff1a205380 Mon Sep 17 00:00:00 2001 From: Vincent Penquerc'h Date: Wed, 29 Dec 2010 15:27:44 +0000 Subject: [PATCH 117/254] oggstream: when the last keyframe position is not known, do not use -1 Instead, use either 0 or 1, depending on bitstream version, which give the correct result for streams which aren't cut off at start. This allows that function to not return negative granpos. https://bugzilla.gnome.org/show_bug.cgi?id=638276 --- ext/ogg/gstoggstream.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/ext/ogg/gstoggstream.c b/ext/ogg/gstoggstream.c index 572f9ca9f5..caa986513e 100644 --- a/ext/ogg/gstoggstream.c +++ b/ext/ogg/gstoggstream.c @@ -255,6 +255,11 @@ granule_to_granulepos_default (GstOggStream * pad, gint64 granule, gint64 keyoffset; if (pad->granuleshift != 0) { + /* If we don't know where the previous keyframe is yet, assume it is + at 0 or 1, depending on bitstream version. If nothing else, this + avoids getting negative granpos back. */ + if (keyframe_granule < 0) + keyframe_granule = pad->theora_has_zero_keyoffset ? 0 : 1; keyoffset = granule - keyframe_granule; return (keyframe_granule << pad->granuleshift) | keyoffset; } else { From 3c4466b816eca8becc69ded9cf011eb45d6dfcdb Mon Sep 17 00:00:00 2001 From: David Schleef Date: Wed, 5 Jan 2011 15:54:15 -0800 Subject: [PATCH 118/254] oggdemux: ignore header pages when looking for keyframe This was causing keyframe_granule to be set to 0 for all streams when seeking to the beginning of the stream, i.e., at the beginning of playback. Fixes #619778. --- ext/ogg/gstoggdemux.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ext/ogg/gstoggdemux.c b/ext/ogg/gstoggdemux.c index 18ecc550b6..76d179e080 100644 --- a/ext/ogg/gstoggdemux.c +++ b/ext/ogg/gstoggdemux.c @@ -2113,7 +2113,7 @@ gst_ogg_demux_do_seek (GstOggDemux * ogg, GstSegment * segment, goto next; granulepos = ogg_page_granulepos (&og); - if (granulepos == -1) { + if (granulepos == -1 || granulepos == 0) { GST_LOG_OBJECT (ogg, "granulepos of next page is -1"); continue; } From 1e80f70d7a3fcdce8898df72b0fa7770aaab77b1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim-Philipp=20M=C3=BCller?= Date: Thu, 6 Jan 2011 20:37:50 +0000 Subject: [PATCH 119/254] tests: ignore new rtsp test binary --- tests/check/libs/.gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/check/libs/.gitignore b/tests/check/libs/.gitignore index 326c47aa4e..f0e5c928e7 100644 --- a/tests/check/libs/.gitignore +++ b/tests/check/libs/.gitignore @@ -8,6 +8,7 @@ netbuffer pbutils profile rtp +rtsp tag utils video From e67417833164c0ddf27248047637efad8088a607 Mon Sep 17 00:00:00 2001 From: Lane Brooks Date: Thu, 6 Jan 2011 23:01:20 +0000 Subject: [PATCH 120/254] textoverlay: make some properties controllable https://bugzilla.gnome.org/show_bug.cgi?id=638859 --- ext/pango/Makefile.am | 2 ++ ext/pango/gsttextoverlay.c | 16 ++++++++++++---- ext/pango/gsttextoverlay.h | 1 + 3 files changed, 15 insertions(+), 4 deletions(-) diff --git a/ext/pango/Makefile.am b/ext/pango/Makefile.am index 197ed33840..2ffea22685 100644 --- a/ext/pango/Makefile.am +++ b/ext/pango/Makefile.am @@ -15,12 +15,14 @@ libgstpango_la_SOURCES = \ libgstpango_la_CFLAGS = \ $(GST_PLUGINS_BASE_CFLAGS) \ $(GST_BASE_CFLAGS) \ + $(GST_CONTROLLER_CFLAGS) \ $(GST_CFLAGS) \ $(PANGO_CFLAGS) libgstpango_la_LIBADD = \ $(GST_PLUGINS_BASE_LIBS) \ $(top_builddir)/gst-libs/gst/video/libgstvideo-$(GST_MAJORMINOR).la \ $(GST_BASE_LIBS) \ + $(GST_CONTROLLER_LIBS) \ $(GST_LIBS) \ $(PANGO_LIBS) libgstpango_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS) diff --git a/ext/pango/gsttextoverlay.c b/ext/pango/gsttextoverlay.c index fa9cf8fd07..4d5f52dc1a 100644 --- a/ext/pango/gsttextoverlay.c +++ b/ext/pango/gsttextoverlay.c @@ -430,7 +430,8 @@ gst_text_overlay_class_init (GstTextOverlayClass * klass) g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_XPOS, g_param_spec_double ("xpos", "horizontal position", "Horizontal position when using position alignment", 0, 1.0, - DEFAULT_PROP_XPOS, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + DEFAULT_PROP_XPOS, + G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE | G_PARAM_STATIC_STRINGS)); /** * GstTextOverlay:ypos * @@ -441,7 +442,8 @@ gst_text_overlay_class_init (GstTextOverlayClass * klass) g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_YPOS, g_param_spec_double ("ypos", "vertical position", "Vertical position when using position alignment", 0, 1.0, - DEFAULT_PROP_YPOS, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + DEFAULT_PROP_YPOS, + G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE | G_PARAM_STATIC_STRINGS)); g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_WRAP_MODE, g_param_spec_enum ("wrap-mode", "wrap mode", "Whether to wrap the text and if so how.", @@ -463,7 +465,8 @@ gst_text_overlay_class_init (GstTextOverlayClass * klass) g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_COLOR, g_param_spec_uint ("color", "Color", "Color to use for text (big-endian ARGB).", 0, G_MAXUINT32, - DEFAULT_PROP_COLOR, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + DEFAULT_PROP_COLOR, + G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE | G_PARAM_STATIC_STRINGS)); /** * GstTextOverlay:line-alignment @@ -489,7 +492,8 @@ gst_text_overlay_class_init (GstTextOverlayClass * klass) g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_SILENT, g_param_spec_boolean ("silent", "silent", "Whether to render the text string", - DEFAULT_PROP_SILENT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + DEFAULT_PROP_SILENT, + G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE | G_PARAM_STATIC_STRINGS)); /** * GstTextOverlay:wait-text * @@ -2247,6 +2251,8 @@ gst_text_overlay_video_chain (GstPad * pad, GstBuffer * buffer) } } + gst_object_sync_values (G_OBJECT (overlay), GST_BUFFER_TIMESTAMP (buffer)); + wait_for_text_buf: GST_OBJECT_LOCK (overlay); @@ -2531,6 +2537,8 @@ gst_text_overlay_change_state (GstElement * element, GstStateChange transition) static gboolean plugin_init (GstPlugin * plugin) { + gst_controller_init (NULL, NULL); + if (!gst_element_register (plugin, "textoverlay", GST_RANK_NONE, GST_TYPE_TEXT_OVERLAY) || !gst_element_register (plugin, "timeoverlay", GST_RANK_NONE, diff --git a/ext/pango/gsttextoverlay.h b/ext/pango/gsttextoverlay.h index 8031478b9e..5fddf3ad09 100644 --- a/ext/pango/gsttextoverlay.h +++ b/ext/pango/gsttextoverlay.h @@ -3,6 +3,7 @@ #include #include +#include #include G_BEGIN_DECLS From b6ae6951747a7ae1f367dfacd94fb3a2c79eb54e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim-Philipp=20M=C3=BCller?= Date: Thu, 6 Jan 2011 23:08:34 +0000 Subject: [PATCH 121/254] textoverlay: make text property controllable too Because we can, and because it's the most interesting one to control really, after xpos/ypos. --- ext/pango/gsttextoverlay.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ext/pango/gsttextoverlay.c b/ext/pango/gsttextoverlay.c index 4d5f52dc1a..915a59c5fb 100644 --- a/ext/pango/gsttextoverlay.c +++ b/ext/pango/gsttextoverlay.c @@ -382,7 +382,7 @@ gst_text_overlay_class_init (GstTextOverlayClass * klass) g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_TEXT, g_param_spec_string ("text", "text", "Text to be display.", DEFAULT_PROP_TEXT, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE | G_PARAM_STATIC_STRINGS)); g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_SHADING, g_param_spec_boolean ("shaded-background", "shaded background", "Whether to shade the background under the text area", From 5d072a4e7c0583762d88abc758fcfe22ead7dd48 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim-Philipp=20M=C3=BCller?= Date: Thu, 6 Jan 2011 23:13:35 +0000 Subject: [PATCH 122/254] po: update translations --- po/fi.po | 83 +++++++++++++++++++++++++++--------------------------- po/ru.po | 86 +++++++++++++++++++++++++++++--------------------------- 2 files changed, 85 insertions(+), 84 deletions(-) diff --git a/po/fi.po b/po/fi.po index e96c76bafa..7819735de1 100644 --- a/po/fi.po +++ b/po/fi.po @@ -10,10 +10,10 @@ # Suomennos: http://gnome.fi/ msgid "" msgstr "" -"Project-Id-Version: gst-plugins-base 0.10.28.2\n" +"Project-Id-Version: gst-plugins-base 0.10.30.3\n" "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/\n" -"POT-Creation-Date: 2010-10-16 01:03+0100\n" -"PO-Revision-Date: 2010-04-26 21:15+0300\n" +"POT-Creation-Date: 2011-01-06 20:42+0000\n" +"PO-Revision-Date: 2010-12-31 23:21+0200\n" "Last-Translator: Tommi Vainikainen \n" "Language-Team: Finnish \n" "Language: fi\n" @@ -21,7 +21,6 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" -"X-Generator: KBabel 1.11.2\n" msgid "Master" msgstr "Pääkanava" @@ -292,119 +291,119 @@ msgid "MusicBrainz TRM ID" msgstr "MusicBrainz TRM-tunniste" msgid "capturing shutter speed" -msgstr "" +msgstr "kuvaamisen suljinnopeus" msgid "Shutter speed used when capturing an image, in seconds" -msgstr "" +msgstr "Suljinnopeus kuvattaessa, sekunteina" msgid "capturing focal ratio" -msgstr "" +msgstr "kuvaamisen aukkosuhde" msgid "Focal ratio (f-number) used when capturing the image" -msgstr "" +msgstr "Aukkosuhde (f-luku) kuvattaessa" msgid "capturing focal length" -msgstr "" +msgstr "kuvaamisen polttoväli" msgid "Focal length of the lens used capturing the image, in mm" -msgstr "" +msgstr "Linssin polttoväli kuvattaessa, millimetriä" msgid "capturing digital zoom ratio" -msgstr "" +msgstr "kuvaamisen digitaalinen zoomaus" msgid "Digital zoom ratio used when capturing an image" -msgstr "" +msgstr "Digitaalinen suurennuskerroin kuvattaessa" msgid "capturing iso speed" -msgstr "" +msgstr "kuvaamisen ISO-nopeus" msgid "The ISO speed used when capturing an image" -msgstr "" +msgstr "ISO-nopeus kuvattaessa" msgid "capturing exposure program" -msgstr "" +msgstr "kuvaamisen valotusohjelma" msgid "The exposure program used when capturing an image" -msgstr "" +msgstr "Valotusohjelma kuvattaessa" msgid "capturing exposure mode" -msgstr "" +msgstr "kuvaamisen valotustapa" msgid "The exposure mode used when capturing an image" -msgstr "" +msgstr "Valotustapa kuvattaessa" msgid "capturing scene capture type" -msgstr "" +msgstr "kuvaamisen kuvausmoodi" msgid "The scene capture mode used when capturing an image" -msgstr "" +msgstr "Kuvausmoodi kuvattaessa" msgid "capturing gain adjustment" -msgstr "" +msgstr "kuvaamisen kirkkauskorjaus" msgid "The overall gain adjustment applied on an image" -msgstr "" +msgstr "Yleinen kirkkauskorjaus, joka kuvalle on tehty" msgid "capturing white balance" -msgstr "" +msgstr "kuvaamisen valkotasapaino" msgid "The white balance mode set when capturing an image" -msgstr "" +msgstr "Valittu valkotasapainotila kuvattaessa" msgid "capturing contrast" -msgstr "" +msgstr "kuvaamisen kontrasti" msgid "The direction of contrast processing applied when capturing an image" -msgstr "" +msgstr "Käytetty kontrastikäsittelyn suunta kuvattessa" msgid "capturing saturation" -msgstr "" +msgstr "kuvaamisen saturaatio" msgid "The direction of saturation processing applied when capturing an image" -msgstr "" +msgstr "Käytetty saturaatiokäsittelyn suunta kuvattessa" msgid "capturing sharpness" -msgstr "" +msgstr "kuvaamisen terävyys" msgid "The direction of sharpness processing applied when capturing an image" -msgstr "" +msgstr "Käytetty terävyyskäsittelyn suunta kuvattessa" msgid "capturing flash fired" -msgstr "" +msgstr "kuvaamisen salamankäyttö" msgid "If the flash fired while capturing an image" -msgstr "" +msgstr "Syttyikö salama kuvattaessa" msgid "capturing flash mode" -msgstr "" +msgstr "kuvaamisen salamamoodi" msgid "The selected flash mode while capturing an image" -msgstr "" +msgstr "Valittu salamamoodi kuvattessa" msgid "capturing metering mode" -msgstr "" +msgstr "kuvaamisen mittausmoodi" msgid "" "The metering mode used while determining exposure for capturing an image" -msgstr "" +msgstr "Käytetty mittausmoodi päätettäessä valotusta kuvattaessa" msgid "capturing source" -msgstr "" +msgstr "kuvaamisen lähde" msgid "The source or type of device used for the capture" -msgstr "" +msgstr "Lähde tai laitetyyppi kuvattaessa" msgid "image horizontal ppi" -msgstr "" +msgstr "kuvan vaakasuora ppi" msgid "Media (image/video) intended horizontal pixel density in ppi" -msgstr "" +msgstr "Median (kuva tai video) tarkoitettu vaakasuora pikselitiheys ppi:nä" msgid "image vertical ppi" -msgstr "" +msgstr "kuvan pystysuora ppi" msgid "Media (image/video) intended vertical pixel density in ppi" -msgstr "" +msgstr "Median (kuva tai video) tarkoitettu pystysuora pikselitiheys ppi:nä" msgid "This CD has no audio tracks" msgstr "Tällä CD-levyllä ei ole ääniraitoja" diff --git a/po/ru.po b/po/ru.po index 5541f8e3c8..646f8e1c26 100644 --- a/po/ru.po +++ b/po/ru.po @@ -3,13 +3,13 @@ # # Артём Попов , 2009. # Pavel Maryanov , 2009. -# Yuri Kozlov , 2010. +# Yuri Kozlov , 2010, 2011. msgid "" msgstr "" -"Project-Id-Version: gst-plugins-base 0.10.29.2\n" +"Project-Id-Version: gst-plugins-base 0.10.30.3\n" "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/\n" -"POT-Creation-Date: 2010-10-16 01:03+0100\n" -"PO-Revision-Date: 2010-09-26 21:29+0400\n" +"POT-Creation-Date: 2011-01-06 20:42+0000\n" +"PO-Revision-Date: 2011-01-01 16:29+0300\n" "Last-Translator: Yuri Kozlov \n" "Language-Team: Russian \n" "Language: ru\n" @@ -51,7 +51,7 @@ msgid "Playback" msgstr "Воспроизведение" msgid "Capture" -msgstr "Захват" +msgstr "Съёмка" msgid "Could not open device for playback in mono mode." msgstr "Не удалось открыть устройство для воспроизведения в режиме моно." @@ -292,119 +292,121 @@ msgid "MusicBrainz TRM ID" msgstr "MusicBrainz TRM ID" msgid "capturing shutter speed" -msgstr "" +msgstr "выдержка при съёмке" msgid "Shutter speed used when capturing an image, in seconds" -msgstr "" +msgstr "Выдержка при съёмке изображения, в секундах" msgid "capturing focal ratio" -msgstr "" +msgstr "диафрагменное число при съёмке" msgid "Focal ratio (f-number) used when capturing the image" -msgstr "" +msgstr "Диафрагменное число (f) при съёмке изображения" msgid "capturing focal length" -msgstr "" +msgstr "фокусное расстояние при съёмке" msgid "Focal length of the lens used capturing the image, in mm" -msgstr "" +msgstr "Фокусное расстояние зеркала при съёмке изображения, в мм" msgid "capturing digital zoom ratio" -msgstr "" +msgstr "коэффициент цифрового трансфокатора при съёмке" msgid "Digital zoom ratio used when capturing an image" -msgstr "" +msgstr "Коэффициент цифрового трансфокатора при съёмке изображения" msgid "capturing iso speed" -msgstr "" +msgstr "чувствительность ISO при съёмке" msgid "The ISO speed used when capturing an image" -msgstr "" +msgstr "Чувствительность ISO при съёмке изображения" msgid "capturing exposure program" -msgstr "" +msgstr "программа экспозиции при съёмке" msgid "The exposure program used when capturing an image" -msgstr "" +msgstr "Программа экспозиции при съёмке изображения" msgid "capturing exposure mode" -msgstr "" +msgstr "режим экспозиции при съёмке" msgid "The exposure mode used when capturing an image" -msgstr "" +msgstr "Режим экспозиции при съёмке изображения" msgid "capturing scene capture type" -msgstr "" +msgstr "тип сцены при съёмке" msgid "The scene capture mode used when capturing an image" -msgstr "" +msgstr "Тип сцены при съёмке изображения" msgid "capturing gain adjustment" -msgstr "" +msgstr "регулировка усиления при съёмке" msgid "The overall gain adjustment applied on an image" -msgstr "" +msgstr "Итоговая настройка усиления, применяемая к изображению" msgid "capturing white balance" -msgstr "" +msgstr "баланс белого при съёмке" msgid "The white balance mode set when capturing an image" -msgstr "" +msgstr "Режим баланса белого при съёмке изображения" msgid "capturing contrast" -msgstr "" +msgstr "контрастность при съёмке" msgid "The direction of contrast processing applied when capturing an image" -msgstr "" +msgstr "Направление обработки контраста при съёмке изображения" msgid "capturing saturation" -msgstr "" +msgstr "насыщенность при съёмке" msgid "The direction of saturation processing applied when capturing an image" -msgstr "" +msgstr "Направление обработки насыщенности при съёмке изображения" msgid "capturing sharpness" -msgstr "" +msgstr "резкость при съёмке" msgid "The direction of sharpness processing applied when capturing an image" -msgstr "" +msgstr "Направление обработки резкости при съёмке изображения" msgid "capturing flash fired" -msgstr "" +msgstr "вспышка при съёмке" msgid "If the flash fired while capturing an image" -msgstr "" +msgstr "Сработала ли вспышка при съёмке изображения" msgid "capturing flash mode" -msgstr "" +msgstr "режим вспышки при съёмке" msgid "The selected flash mode while capturing an image" -msgstr "" +msgstr "Выбранный режим для вспышки при съёмке изображения" msgid "capturing metering mode" -msgstr "" +msgstr "режим замера при съёмке" msgid "" "The metering mode used while determining exposure for capturing an image" msgstr "" +"Режим замера, использованный для определения экспозиции при съёмке " +"изображения" msgid "capturing source" -msgstr "" +msgstr "источник для съёмки" msgid "The source or type of device used for the capture" -msgstr "" +msgstr "Источник или тип устройства, использованный для съёмки" msgid "image horizontal ppi" -msgstr "" +msgstr "изображение в ppi по горизонтали" msgid "Media (image/video) intended horizontal pixel density in ppi" -msgstr "" +msgstr "Горизонтальная плотность носителя (изображение/видео) в ppi" msgid "image vertical ppi" -msgstr "" +msgstr "изображение в ppi по вертикали" msgid "Media (image/video) intended vertical pixel density in ppi" -msgstr "" +msgstr "Вертикальная плотность носителя (изображение/видео) в ppi" msgid "This CD has no audio tracks" msgstr "На CD нет звуковых дорожек" From fdea14f7beb7c517f024d553f82f1979e012911b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim-Philipp=20M=C3=BCller?= Date: Thu, 6 Jan 2011 23:13:53 +0000 Subject: [PATCH 123/254] docs: update docs --- .../gst-plugins-base-plugins.hierarchy | 12 +- .../gst-plugins-base-plugins.interfaces | 16 +- .../gst-plugins-base-plugins.prerequisites | 2 +- docs/plugins/inspect/plugin-adder.xml | 4 +- docs/plugins/inspect/plugin-alsa.xml | 4 +- docs/plugins/inspect/plugin-app.xml | 4 +- docs/plugins/inspect/plugin-audioconvert.xml | 4 +- docs/plugins/inspect/plugin-audiorate.xml | 4 +- docs/plugins/inspect/plugin-audioresample.xml | 4 +- docs/plugins/inspect/plugin-audiotestsrc.xml | 4 +- docs/plugins/inspect/plugin-cdparanoia.xml | 4 +- docs/plugins/inspect/plugin-decodebin.xml | 4 +- docs/plugins/inspect/plugin-encoding.xml | 4 +- .../inspect/plugin-ffmpegcolorspace.xml | 2 +- docs/plugins/inspect/plugin-gdp.xml | 4 +- docs/plugins/inspect/plugin-gio.xml | 4 +- docs/plugins/inspect/plugin-gnomevfs.xml | 4 +- docs/plugins/inspect/plugin-libvisual.xml | 172 +++++++++++++++++- docs/plugins/inspect/plugin-ogg.xml | 4 +- docs/plugins/inspect/plugin-pango.xml | 4 +- docs/plugins/inspect/plugin-playback.xml | 4 +- docs/plugins/inspect/plugin-subparse.xml | 4 +- docs/plugins/inspect/plugin-tcp.xml | 4 +- docs/plugins/inspect/plugin-theora.xml | 4 +- .../inspect/plugin-typefindfunctions.xml | 4 +- docs/plugins/inspect/plugin-uridecodebin.xml | 4 +- docs/plugins/inspect/plugin-video4linux.xml | 4 +- docs/plugins/inspect/plugin-videorate.xml | 4 +- docs/plugins/inspect/plugin-videoscale.xml | 4 +- docs/plugins/inspect/plugin-videotestsrc.xml | 4 +- docs/plugins/inspect/plugin-volume.xml | 4 +- docs/plugins/inspect/plugin-vorbis.xml | 4 +- docs/plugins/inspect/plugin-ximagesink.xml | 4 +- docs/plugins/inspect/plugin-xvimagesink.xml | 4 +- 34 files changed, 248 insertions(+), 72 deletions(-) diff --git a/docs/plugins/gst-plugins-base-plugins.hierarchy b/docs/plugins/gst-plugins-base-plugins.hierarchy index 80aed2e9a5..d8f23638e4 100644 --- a/docs/plugins/gst-plugins-base-plugins.hierarchy +++ b/docs/plugins/gst-plugins-base-plugins.hierarchy @@ -3,6 +3,7 @@ GObject GOutputStream GstColorBalanceChannel GstMixerTrack + GstMixerOptions GstObject GstBus GstClock @@ -74,7 +75,6 @@ GObject GstOgmAudioParse GstOgmTextParse GstOgmVideoParse - GstPlaybin2InputSelector GstSsaParse GstStreamSelector GstSubParse @@ -86,12 +86,20 @@ GObject GstTheoraEnc GstTheoraParse GstVideoRate + GstVisual + GstVisualbumpscope + GstVisualcorona + GstVisualinfinite + GstVisualjakdaw + GstVisualjess + GstVisuallv_analyzer + GstVisuallv_scope + GstVisualoinksie GstVorbisDec GstVorbisEnc GstVorbisParse GstVorbisTag GstPad - GstPlaybin2SelectorPad GstPadTemplate GstPlugin GstPluginFeature diff --git a/docs/plugins/gst-plugins-base-plugins.interfaces b/docs/plugins/gst-plugins-base-plugins.interfaces index 630084dd30..7e1560c365 100644 --- a/docs/plugins/gst-plugins-base-plugins.interfaces +++ b/docs/plugins/gst-plugins-base-plugins.interfaces @@ -3,30 +3,30 @@ GstPipeline GstChildProxy GstPlayBaseBin GstChildProxy GstPlayBin GstChildProxy GstPlayBin2 GstChildProxy GstStreamVolume +GstDecodeBin2 GstChildProxy +GstURIDecodeBin GstChildProxy GstDecodeBin GstChildProxy GstPlaySink GstChildProxy GstSubtitleOverlay GstChildProxy -GstDecodeBin2 GstChildProxy -GstURIDecodeBin GstChildProxy GstEncodeBin GstChildProxy +GstVorbisEnc GstTagSetter GstPreset +GstVorbisTag GstTagSetter GstCddaBaseSrc GstURIHandler GstCdParanoiaSrc GstURIHandler GstAlsaSrc GstImplementsInterface GstMixer GstPropertyProbe GstV4lElement GstImplementsInterface GstTuner GstXOverlay GstColorBalance GstPropertyProbe GstV4lSrc GstImplementsInterface GstTuner GstXOverlay GstColorBalance GstPropertyProbe -GstGnomeVFSSrc GstURIHandler GstGioSrc GstURIHandler +GstGnomeVFSSrc GstURIHandler GstAppSrc GstURIHandler -GstGnomeVFSSink GstURIHandler -GstAlsaSink GstPropertyProbe GstGioSink GstURIHandler +GstAlsaSink GstPropertyProbe +GstGnomeVFSSink GstURIHandler GstXImageSink GstImplementsInterface GstNavigation GstXOverlay GstXvImageSink GstImplementsInterface GstNavigation GstXOverlay GstColorBalance GstPropertyProbe GstAppSink GstURIHandler -GstVorbisEnc GstTagSetter GstPreset -GstVorbisTag GstTagSetter -GstTheoraEnc GstPreset GstAlsaMixerElement GstImplementsInterface GstMixer GstPropertyProbe +GstTheoraEnc GstPreset GstOggMux GstPreset GstVolume GstImplementsInterface GstMixer GstStreamVolume PangoCairoFcFontMap PangoCairoFontMap diff --git a/docs/plugins/gst-plugins-base-plugins.prerequisites b/docs/plugins/gst-plugins-base-plugins.prerequisites index a6aa7d0abe..6a9de60c7d 100644 --- a/docs/plugins/gst-plugins-base-plugins.prerequisites +++ b/docs/plugins/gst-plugins-base-plugins.prerequisites @@ -2,9 +2,9 @@ GstChildProxy GstObject GstTagSetter GstElement GstImplementsInterface GstElement GstMixer GstImplementsInterface GstElement +GstTuner GstImplementsInterface GstElement GstXOverlay GstImplementsInterface GstElement GstColorBalance GstImplementsInterface GstElement -GstTuner GstImplementsInterface GstElement GstStreamVolume GObject GFile GObject PangoCairoFontMap PangoFontMap diff --git a/docs/plugins/inspect/plugin-adder.xml b/docs/plugins/inspect/plugin-adder.xml index c30794c40a..5eba37e6b5 100644 --- a/docs/plugins/inspect/plugin-adder.xml +++ b/docs/plugins/inspect/plugin-adder.xml @@ -3,10 +3,10 @@ Adds multiple streams ../../gst/adder/.libs/libgstadder.so libgstadder.so - 0.10.31.1 + 0.10.31.2 LGPL gst-plugins-base - GStreamer Base Plug-ins git + GStreamer Base Plug-ins prerelease Unknown package origin diff --git a/docs/plugins/inspect/plugin-alsa.xml b/docs/plugins/inspect/plugin-alsa.xml index 17db83fa40..de3f1bea28 100644 --- a/docs/plugins/inspect/plugin-alsa.xml +++ b/docs/plugins/inspect/plugin-alsa.xml @@ -3,10 +3,10 @@ ALSA plugin library ../../ext/alsa/.libs/libgstalsa.so libgstalsa.so - 0.10.31.1 + 0.10.31.2 LGPL gst-plugins-base - GStreamer Base Plug-ins git + GStreamer Base Plug-ins prerelease Unknown package origin diff --git a/docs/plugins/inspect/plugin-app.xml b/docs/plugins/inspect/plugin-app.xml index cd3d5aab60..74d711cff7 100644 --- a/docs/plugins/inspect/plugin-app.xml +++ b/docs/plugins/inspect/plugin-app.xml @@ -3,10 +3,10 @@ Elements used to communicate with applications ../../gst/app/.libs/libgstapp.so libgstapp.so - 0.10.31.1 + 0.10.31.2 LGPL gst-plugins-base - GStreamer Base Plug-ins git + GStreamer Base Plug-ins prerelease Unknown package origin diff --git a/docs/plugins/inspect/plugin-audioconvert.xml b/docs/plugins/inspect/plugin-audioconvert.xml index 69a5d716a5..34c1106df6 100644 --- a/docs/plugins/inspect/plugin-audioconvert.xml +++ b/docs/plugins/inspect/plugin-audioconvert.xml @@ -3,10 +3,10 @@ Convert audio to different formats ../../gst/audioconvert/.libs/libgstaudioconvert.so libgstaudioconvert.so - 0.10.31.1 + 0.10.31.2 LGPL gst-plugins-base - GStreamer Base Plug-ins git + GStreamer Base Plug-ins prerelease Unknown package origin diff --git a/docs/plugins/inspect/plugin-audiorate.xml b/docs/plugins/inspect/plugin-audiorate.xml index 598c2d723f..db1a40c5cb 100644 --- a/docs/plugins/inspect/plugin-audiorate.xml +++ b/docs/plugins/inspect/plugin-audiorate.xml @@ -3,10 +3,10 @@ Adjusts audio frames ../../gst/audiorate/.libs/libgstaudiorate.so libgstaudiorate.so - 0.10.31.1 + 0.10.31.2 LGPL gst-plugins-base - GStreamer Base Plug-ins git + GStreamer Base Plug-ins prerelease Unknown package origin diff --git a/docs/plugins/inspect/plugin-audioresample.xml b/docs/plugins/inspect/plugin-audioresample.xml index 91552c331b..7f45b1331c 100644 --- a/docs/plugins/inspect/plugin-audioresample.xml +++ b/docs/plugins/inspect/plugin-audioresample.xml @@ -3,10 +3,10 @@ Resamples audio ../../gst/audioresample/.libs/libgstaudioresample.so libgstaudioresample.so - 0.10.31.1 + 0.10.31.2 LGPL gst-plugins-base - GStreamer Base Plug-ins git + GStreamer Base Plug-ins prerelease Unknown package origin diff --git a/docs/plugins/inspect/plugin-audiotestsrc.xml b/docs/plugins/inspect/plugin-audiotestsrc.xml index 7d973f04fd..cfce475e4c 100644 --- a/docs/plugins/inspect/plugin-audiotestsrc.xml +++ b/docs/plugins/inspect/plugin-audiotestsrc.xml @@ -3,10 +3,10 @@ Creates audio test signals of given frequency and volume ../../gst/audiotestsrc/.libs/libgstaudiotestsrc.so libgstaudiotestsrc.so - 0.10.31.1 + 0.10.31.2 LGPL gst-plugins-base - GStreamer Base Plug-ins git + GStreamer Base Plug-ins prerelease Unknown package origin diff --git a/docs/plugins/inspect/plugin-cdparanoia.xml b/docs/plugins/inspect/plugin-cdparanoia.xml index 708cddc72c..d6b900bac8 100644 --- a/docs/plugins/inspect/plugin-cdparanoia.xml +++ b/docs/plugins/inspect/plugin-cdparanoia.xml @@ -3,10 +3,10 @@ Read audio from CD in paranoid mode ../../ext/cdparanoia/.libs/libgstcdparanoia.so libgstcdparanoia.so - 0.10.31.1 + 0.10.31.2 LGPL gst-plugins-base - GStreamer Base Plug-ins git + GStreamer Base Plug-ins prerelease Unknown package origin diff --git a/docs/plugins/inspect/plugin-decodebin.xml b/docs/plugins/inspect/plugin-decodebin.xml index 7b77239847..1a4af7336b 100644 --- a/docs/plugins/inspect/plugin-decodebin.xml +++ b/docs/plugins/inspect/plugin-decodebin.xml @@ -3,10 +3,10 @@ decoder bin ../../gst/playback/.libs/libgstdecodebin.so libgstdecodebin.so - 0.10.31.1 + 0.10.31.2 LGPL gst-plugins-base - GStreamer Base Plug-ins git + GStreamer Base Plug-ins prerelease Unknown package origin diff --git a/docs/plugins/inspect/plugin-encoding.xml b/docs/plugins/inspect/plugin-encoding.xml index ab61ef771b..9d2298a51f 100644 --- a/docs/plugins/inspect/plugin-encoding.xml +++ b/docs/plugins/inspect/plugin-encoding.xml @@ -3,10 +3,10 @@ various encoding-related elements ../../gst/encoding/.libs/libgstencodebin.so libgstencodebin.so - 0.10.31.1 + 0.10.31.2 LGPL gst-plugins-base - GStreamer Base Plug-ins git + GStreamer Base Plug-ins prerelease Unknown package origin diff --git a/docs/plugins/inspect/plugin-ffmpegcolorspace.xml b/docs/plugins/inspect/plugin-ffmpegcolorspace.xml index 229a21a163..fede4f677e 100644 --- a/docs/plugins/inspect/plugin-ffmpegcolorspace.xml +++ b/docs/plugins/inspect/plugin-ffmpegcolorspace.xml @@ -3,7 +3,7 @@ colorspace conversion copied from FFMpeg 0.4.9-pre1 ../../gst/ffmpegcolorspace/.libs/libgstffmpegcolorspace.so libgstffmpegcolorspace.so - 0.10.31.1 + 0.10.31.2 LGPL gst-plugins-base FFMpeg diff --git a/docs/plugins/inspect/plugin-gdp.xml b/docs/plugins/inspect/plugin-gdp.xml index 40af444fbe..73753f178c 100644 --- a/docs/plugins/inspect/plugin-gdp.xml +++ b/docs/plugins/inspect/plugin-gdp.xml @@ -3,10 +3,10 @@ Payload/depayload GDP packets ../../gst/gdp/.libs/libgstgdp.so libgstgdp.so - 0.10.31.1 + 0.10.31.2 LGPL gst-plugins-base - GStreamer Base Plug-ins git + GStreamer Base Plug-ins prerelease Unknown package origin diff --git a/docs/plugins/inspect/plugin-gio.xml b/docs/plugins/inspect/plugin-gio.xml index 578df73a75..756ecaca22 100644 --- a/docs/plugins/inspect/plugin-gio.xml +++ b/docs/plugins/inspect/plugin-gio.xml @@ -3,10 +3,10 @@ GIO elements ../../ext/gio/.libs/libgstgio.so libgstgio.so - 0.10.31.1 + 0.10.31.2 LGPL gst-plugins-base - GStreamer Base Plug-ins git + GStreamer Base Plug-ins prerelease Unknown package origin diff --git a/docs/plugins/inspect/plugin-gnomevfs.xml b/docs/plugins/inspect/plugin-gnomevfs.xml index bbc828b085..265aab3ea3 100644 --- a/docs/plugins/inspect/plugin-gnomevfs.xml +++ b/docs/plugins/inspect/plugin-gnomevfs.xml @@ -3,10 +3,10 @@ elements to read from and write to Gnome-VFS uri's ../../ext/gnomevfs/.libs/libgstgnomevfs.so libgstgnomevfs.so - 0.10.31.1 + 0.10.31.2 LGPL gst-plugins-base - GStreamer Base Plug-ins git + GStreamer Base Plug-ins prerelease Unknown package origin diff --git a/docs/plugins/inspect/plugin-libvisual.xml b/docs/plugins/inspect/plugin-libvisual.xml index 0af3fc75d5..27dacee067 100644 --- a/docs/plugins/inspect/plugin-libvisual.xml +++ b/docs/plugins/inspect/plugin-libvisual.xml @@ -3,11 +3,179 @@ libvisual visualization plugins ../../ext/libvisual/.libs/libgstlibvisual.so libgstlibvisual.so - 0.10.31.1 + 0.10.31.2 LGPL gst-plugins-base - GStreamer Base Plug-ins git + GStreamer Base Plug-ins prerelease Unknown package origin + + libvisual_bumpscope + libvisual Bumpscope plugin plugin v.0.0.1 + Visualization + Bumpscope visual plugin + Benjamin Otte <otte@gnome.org> + + + sink + sink + always +
audio/x-raw-int, width=(int)16, depth=(int)16, endianness=(int)1234, signed=(boolean)true, channels=(int){ 1, 2 }, rate=(int){ 8000, 11250, 22500, 32000, 44100, 48000, 96000 }
+
+ + src + source + always +
video/x-raw-rgb, bpp=(int)32, depth=(int)24, endianness=(int)4321, red_mask=(int)65280, green_mask=(int)16711680, blue_mask=(int)-16777216, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]; video/x-raw-rgb, bpp=(int)24, depth=(int)24, endianness=(int)4321, red_mask=(int)255, green_mask=(int)65280, blue_mask=(int)16711680, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]; video/x-raw-rgb, bpp=(int)16, depth=(int)16, endianness=(int)1234, red_mask=(int)63488, green_mask=(int)2016, blue_mask=(int)31, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]
+
+
+
+ + libvisual_corona + libvisual libvisual corona plugin plugin v.0.1 + Visualization + Libvisual corona plugin + Benjamin Otte <otte@gnome.org> + + + sink + sink + always +
audio/x-raw-int, width=(int)16, depth=(int)16, endianness=(int)1234, signed=(boolean)true, channels=(int){ 1, 2 }, rate=(int){ 8000, 11250, 22500, 32000, 44100, 48000, 96000 }
+
+ + src + source + always +
video/x-raw-rgb, bpp=(int)32, depth=(int)24, endianness=(int)4321, red_mask=(int)65280, green_mask=(int)16711680, blue_mask=(int)-16777216, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]; video/x-raw-rgb, bpp=(int)24, depth=(int)24, endianness=(int)4321, red_mask=(int)255, green_mask=(int)65280, blue_mask=(int)16711680, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]; video/x-raw-rgb, bpp=(int)16, depth=(int)16, endianness=(int)1234, red_mask=(int)63488, green_mask=(int)2016, blue_mask=(int)31, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]
+
+
+
+ + libvisual_infinite + libvisual infinite plugin plugin v.0.1 + Visualization + Infinite visual plugin + Benjamin Otte <otte@gnome.org> + + + sink + sink + always +
audio/x-raw-int, width=(int)16, depth=(int)16, endianness=(int)1234, signed=(boolean)true, channels=(int){ 1, 2 }, rate=(int){ 8000, 11250, 22500, 32000, 44100, 48000, 96000 }
+
+ + src + source + always +
video/x-raw-rgb, bpp=(int)32, depth=(int)24, endianness=(int)4321, red_mask=(int)65280, green_mask=(int)16711680, blue_mask=(int)-16777216, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]; video/x-raw-rgb, bpp=(int)24, depth=(int)24, endianness=(int)4321, red_mask=(int)255, green_mask=(int)65280, blue_mask=(int)16711680, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]; video/x-raw-rgb, bpp=(int)16, depth=(int)16, endianness=(int)1234, red_mask=(int)63488, green_mask=(int)2016, blue_mask=(int)31, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]
+
+
+
+ + libvisual_jakdaw + libvisual Jakdaw plugin plugin v.0.0.1 + Visualization + jakdaw visual plugin + Benjamin Otte <otte@gnome.org> + + + sink + sink + always +
audio/x-raw-int, width=(int)16, depth=(int)16, endianness=(int)1234, signed=(boolean)true, channels=(int){ 1, 2 }, rate=(int){ 8000, 11250, 22500, 32000, 44100, 48000, 96000 }
+
+ + src + source + always +
video/x-raw-rgb, bpp=(int)32, depth=(int)24, endianness=(int)4321, red_mask=(int)65280, green_mask=(int)16711680, blue_mask=(int)-16777216, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]; video/x-raw-rgb, bpp=(int)24, depth=(int)24, endianness=(int)4321, red_mask=(int)255, green_mask=(int)65280, blue_mask=(int)16711680, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]; video/x-raw-rgb, bpp=(int)16, depth=(int)16, endianness=(int)1234, red_mask=(int)63488, green_mask=(int)2016, blue_mask=(int)31, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]
+
+
+
+ + libvisual_jess + libvisual jess plugin plugin v.0.1 + Visualization + Jess visual plugin + Benjamin Otte <otte@gnome.org> + + + sink + sink + always +
audio/x-raw-int, width=(int)16, depth=(int)16, endianness=(int)1234, signed=(boolean)true, channels=(int){ 1, 2 }, rate=(int){ 8000, 11250, 22500, 32000, 44100, 48000, 96000 }
+
+ + src + source + always +
video/x-raw-rgb, bpp=(int)32, depth=(int)24, endianness=(int)4321, red_mask=(int)65280, green_mask=(int)16711680, blue_mask=(int)-16777216, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]; video/x-raw-rgb, bpp=(int)24, depth=(int)24, endianness=(int)4321, red_mask=(int)255, green_mask=(int)65280, blue_mask=(int)16711680, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]; video/x-raw-rgb, bpp=(int)16, depth=(int)16, endianness=(int)1234, red_mask=(int)63488, green_mask=(int)2016, blue_mask=(int)31, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]
+
+
+
+ + libvisual_lv_analyzer + libvisual libvisual analyzer plugin v.1.0 + Visualization + Libvisual analyzer plugin + Benjamin Otte <otte@gnome.org> + + + sink + sink + always +
audio/x-raw-int, width=(int)16, depth=(int)16, endianness=(int)1234, signed=(boolean)true, channels=(int){ 1, 2 }, rate=(int){ 8000, 11250, 22500, 32000, 44100, 48000, 96000 }
+
+ + src + source + always +
video/x-raw-rgb, bpp=(int)32, depth=(int)24, endianness=(int)4321, red_mask=(int)65280, green_mask=(int)16711680, blue_mask=(int)-16777216, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]; video/x-raw-rgb, bpp=(int)24, depth=(int)24, endianness=(int)4321, red_mask=(int)255, green_mask=(int)65280, blue_mask=(int)16711680, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]; video/x-raw-rgb, bpp=(int)16, depth=(int)16, endianness=(int)1234, red_mask=(int)63488, green_mask=(int)2016, blue_mask=(int)31, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]
+
+
+
+ + libvisual_lv_scope + libvisual libvisual scope plugin v.0.1 + Visualization + Libvisual scope plugin + Benjamin Otte <otte@gnome.org> + + + sink + sink + always +
audio/x-raw-int, width=(int)16, depth=(int)16, endianness=(int)1234, signed=(boolean)true, channels=(int){ 1, 2 }, rate=(int){ 8000, 11250, 22500, 32000, 44100, 48000, 96000 }
+
+ + src + source + always +
video/x-raw-rgb, bpp=(int)32, depth=(int)24, endianness=(int)4321, red_mask=(int)65280, green_mask=(int)16711680, blue_mask=(int)-16777216, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]; video/x-raw-rgb, bpp=(int)24, depth=(int)24, endianness=(int)4321, red_mask=(int)255, green_mask=(int)65280, blue_mask=(int)16711680, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]; video/x-raw-rgb, bpp=(int)16, depth=(int)16, endianness=(int)1234, red_mask=(int)63488, green_mask=(int)2016, blue_mask=(int)31, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]
+
+
+
+ + libvisual_oinksie + libvisual oinksie plugin plugin v.0.1 + Visualization + Libvisual Oinksie visual plugin + Benjamin Otte <otte@gnome.org> + + + sink + sink + always +
audio/x-raw-int, width=(int)16, depth=(int)16, endianness=(int)1234, signed=(boolean)true, channels=(int){ 1, 2 }, rate=(int){ 8000, 11250, 22500, 32000, 44100, 48000, 96000 }
+
+ + src + source + always +
video/x-raw-rgb, bpp=(int)32, depth=(int)24, endianness=(int)4321, red_mask=(int)65280, green_mask=(int)16711680, blue_mask=(int)-16777216, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]; video/x-raw-rgb, bpp=(int)24, depth=(int)24, endianness=(int)4321, red_mask=(int)255, green_mask=(int)65280, blue_mask=(int)16711680, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]; video/x-raw-rgb, bpp=(int)16, depth=(int)16, endianness=(int)1234, red_mask=(int)63488, green_mask=(int)2016, blue_mask=(int)31, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]
+
+
+
\ No newline at end of file diff --git a/docs/plugins/inspect/plugin-ogg.xml b/docs/plugins/inspect/plugin-ogg.xml index 33477006ab..f0cb513a42 100644 --- a/docs/plugins/inspect/plugin-ogg.xml +++ b/docs/plugins/inspect/plugin-ogg.xml @@ -3,10 +3,10 @@ ogg stream manipulation (info about ogg: http://xiph.org) ../../ext/ogg/.libs/libgstogg.so libgstogg.so - 0.10.31.1 + 0.10.31.2 LGPL gst-plugins-base - GStreamer Base Plug-ins git + GStreamer Base Plug-ins prerelease Unknown package origin diff --git a/docs/plugins/inspect/plugin-pango.xml b/docs/plugins/inspect/plugin-pango.xml index 411e39263e..b64ed3d8a2 100644 --- a/docs/plugins/inspect/plugin-pango.xml +++ b/docs/plugins/inspect/plugin-pango.xml @@ -3,10 +3,10 @@ Pango-based text rendering and overlay ../../ext/pango/.libs/libgstpango.so libgstpango.so - 0.10.31.1 + 0.10.31.2 LGPL gst-plugins-base - GStreamer Base Plug-ins git + GStreamer Base Plug-ins prerelease Unknown package origin diff --git a/docs/plugins/inspect/plugin-playback.xml b/docs/plugins/inspect/plugin-playback.xml index 55a711e3ec..edfc232b17 100644 --- a/docs/plugins/inspect/plugin-playback.xml +++ b/docs/plugins/inspect/plugin-playback.xml @@ -3,10 +3,10 @@ various playback elements ../../gst/playback/.libs/libgstplaybin.so libgstplaybin.so - 0.10.31.1 + 0.10.31.2 LGPL gst-plugins-base - GStreamer Base Plug-ins git + GStreamer Base Plug-ins prerelease Unknown package origin diff --git a/docs/plugins/inspect/plugin-subparse.xml b/docs/plugins/inspect/plugin-subparse.xml index fec053023f..6b9485befe 100644 --- a/docs/plugins/inspect/plugin-subparse.xml +++ b/docs/plugins/inspect/plugin-subparse.xml @@ -3,10 +3,10 @@ Subtitle parsing ../../gst/subparse/.libs/libgstsubparse.so libgstsubparse.so - 0.10.31.1 + 0.10.31.2 LGPL gst-plugins-base - GStreamer Base Plug-ins git + GStreamer Base Plug-ins prerelease Unknown package origin diff --git a/docs/plugins/inspect/plugin-tcp.xml b/docs/plugins/inspect/plugin-tcp.xml index 2397dd0fe6..a6dafe4495 100644 --- a/docs/plugins/inspect/plugin-tcp.xml +++ b/docs/plugins/inspect/plugin-tcp.xml @@ -3,10 +3,10 @@ transfer data over the network via TCP ../../gst/tcp/.libs/libgsttcp.so libgsttcp.so - 0.10.31.1 + 0.10.31.2 LGPL gst-plugins-base - GStreamer Base Plug-ins git + GStreamer Base Plug-ins prerelease Unknown package origin diff --git a/docs/plugins/inspect/plugin-theora.xml b/docs/plugins/inspect/plugin-theora.xml index 2c6c2b5de7..2136a8937e 100644 --- a/docs/plugins/inspect/plugin-theora.xml +++ b/docs/plugins/inspect/plugin-theora.xml @@ -3,10 +3,10 @@ Theora plugin library ../../ext/theora/.libs/libgsttheora.so libgsttheora.so - 0.10.31.1 + 0.10.31.2 LGPL gst-plugins-base - GStreamer Base Plug-ins git + GStreamer Base Plug-ins prerelease Unknown package origin diff --git a/docs/plugins/inspect/plugin-typefindfunctions.xml b/docs/plugins/inspect/plugin-typefindfunctions.xml index 413e99d347..f66c5ab0f2 100644 --- a/docs/plugins/inspect/plugin-typefindfunctions.xml +++ b/docs/plugins/inspect/plugin-typefindfunctions.xml @@ -3,10 +3,10 @@ default typefind functions ../../gst/typefind/.libs/libgsttypefindfunctions.so libgsttypefindfunctions.so - 0.10.31.1 + 0.10.31.2 LGPL gst-plugins-base - GStreamer Base Plug-ins git + GStreamer Base Plug-ins prerelease Unknown package origin diff --git a/docs/plugins/inspect/plugin-uridecodebin.xml b/docs/plugins/inspect/plugin-uridecodebin.xml index bafb780f33..b7e1f0be47 100644 --- a/docs/plugins/inspect/plugin-uridecodebin.xml +++ b/docs/plugins/inspect/plugin-uridecodebin.xml @@ -3,10 +3,10 @@ URI Decoder bin ../../gst/playback/.libs/libgstdecodebin2.so libgstdecodebin2.so - 0.10.31.1 + 0.10.31.2 LGPL gst-plugins-base - GStreamer Base Plug-ins git + GStreamer Base Plug-ins prerelease Unknown package origin diff --git a/docs/plugins/inspect/plugin-video4linux.xml b/docs/plugins/inspect/plugin-video4linux.xml index c184dce9b4..a47b6dfe4c 100644 --- a/docs/plugins/inspect/plugin-video4linux.xml +++ b/docs/plugins/inspect/plugin-video4linux.xml @@ -3,10 +3,10 @@ elements for Video 4 Linux ../../sys/v4l/.libs/libgstvideo4linux.so libgstvideo4linux.so - 0.10.31.1 + 0.10.31.2 LGPL gst-plugins-base - GStreamer Base Plug-ins git + GStreamer Base Plug-ins prerelease Unknown package origin diff --git a/docs/plugins/inspect/plugin-videorate.xml b/docs/plugins/inspect/plugin-videorate.xml index b7c7dbda42..9f2335dc3d 100644 --- a/docs/plugins/inspect/plugin-videorate.xml +++ b/docs/plugins/inspect/plugin-videorate.xml @@ -3,10 +3,10 @@ Adjusts video frames ../../gst/videorate/.libs/libgstvideorate.so libgstvideorate.so - 0.10.31.1 + 0.10.31.2 LGPL gst-plugins-base - GStreamer Base Plug-ins git + GStreamer Base Plug-ins prerelease Unknown package origin diff --git a/docs/plugins/inspect/plugin-videoscale.xml b/docs/plugins/inspect/plugin-videoscale.xml index 63a0f753f8..3f44920421 100644 --- a/docs/plugins/inspect/plugin-videoscale.xml +++ b/docs/plugins/inspect/plugin-videoscale.xml @@ -3,10 +3,10 @@ Resizes video ../../gst/videoscale/.libs/libgstvideoscale.so libgstvideoscale.so - 0.10.31.1 + 0.10.31.2 LGPL gst-plugins-base - GStreamer Base Plug-ins git + GStreamer Base Plug-ins prerelease Unknown package origin diff --git a/docs/plugins/inspect/plugin-videotestsrc.xml b/docs/plugins/inspect/plugin-videotestsrc.xml index c8ccb14a9d..1f4c864a6b 100644 --- a/docs/plugins/inspect/plugin-videotestsrc.xml +++ b/docs/plugins/inspect/plugin-videotestsrc.xml @@ -3,10 +3,10 @@ Creates a test video stream ../../gst/videotestsrc/.libs/libgstvideotestsrc.so libgstvideotestsrc.so - 0.10.31.1 + 0.10.31.2 LGPL gst-plugins-base - GStreamer Base Plug-ins git + GStreamer Base Plug-ins prerelease Unknown package origin diff --git a/docs/plugins/inspect/plugin-volume.xml b/docs/plugins/inspect/plugin-volume.xml index 331d20a279..8d6112a0d9 100644 --- a/docs/plugins/inspect/plugin-volume.xml +++ b/docs/plugins/inspect/plugin-volume.xml @@ -3,10 +3,10 @@ plugin for controlling audio volume ../../gst/volume/.libs/libgstvolume.so libgstvolume.so - 0.10.31.1 + 0.10.31.2 LGPL gst-plugins-base - GStreamer Base Plug-ins git + GStreamer Base Plug-ins prerelease Unknown package origin diff --git a/docs/plugins/inspect/plugin-vorbis.xml b/docs/plugins/inspect/plugin-vorbis.xml index a00b815ecb..2db944dbb1 100644 --- a/docs/plugins/inspect/plugin-vorbis.xml +++ b/docs/plugins/inspect/plugin-vorbis.xml @@ -3,10 +3,10 @@ Vorbis plugin library ../../ext/vorbis/.libs/libgstvorbis.so libgstvorbis.so - 0.10.31.1 + 0.10.31.2 LGPL gst-plugins-base - GStreamer Base Plug-ins git + GStreamer Base Plug-ins prerelease Unknown package origin diff --git a/docs/plugins/inspect/plugin-ximagesink.xml b/docs/plugins/inspect/plugin-ximagesink.xml index be3996315c..a309242c28 100644 --- a/docs/plugins/inspect/plugin-ximagesink.xml +++ b/docs/plugins/inspect/plugin-ximagesink.xml @@ -3,10 +3,10 @@ X11 video output element based on standard Xlib calls ../../sys/ximage/.libs/libgstximagesink.so libgstximagesink.so - 0.10.31.1 + 0.10.31.2 LGPL gst-plugins-base - GStreamer Base Plug-ins git + GStreamer Base Plug-ins prerelease Unknown package origin diff --git a/docs/plugins/inspect/plugin-xvimagesink.xml b/docs/plugins/inspect/plugin-xvimagesink.xml index 33280649ef..1f45bb37d1 100644 --- a/docs/plugins/inspect/plugin-xvimagesink.xml +++ b/docs/plugins/inspect/plugin-xvimagesink.xml @@ -3,10 +3,10 @@ XFree86 video output plugin using Xv extension ../../sys/xvimage/.libs/libgstxvimagesink.so libgstxvimagesink.so - 0.10.31.1 + 0.10.31.2 LGPL gst-plugins-base - GStreamer Base Plug-ins git + GStreamer Base Plug-ins prerelease Unknown package origin From ca8ceb4bafbbf1c246f991b1563796e21ca0e1e8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim-Philipp=20M=C3=BCller?= Date: Thu, 6 Jan 2011 23:17:12 +0000 Subject: [PATCH 124/254] win32: udpate pbutils .def file for API change --- win32/common/libgstpbutils.def | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/win32/common/libgstpbutils.def b/win32/common/libgstpbutils.def index e30e8355c6..083e294914 100644 --- a/win32/common/libgstpbutils.def +++ b/win32/common/libgstpbutils.def @@ -70,8 +70,8 @@ EXPORTS gst_encoding_profile_find gst_encoding_profile_get_description gst_encoding_profile_get_format + gst_encoding_profile_get_input_caps gst_encoding_profile_get_name - gst_encoding_profile_get_output_caps gst_encoding_profile_get_presence gst_encoding_profile_get_preset gst_encoding_profile_get_restriction From a266fe8d306d3fb6512cd2328db4594e807b5140 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim-Philipp=20M=C3=BCller?= Date: Fri, 7 Jan 2011 00:43:07 +0000 Subject: [PATCH 125/254] tests: never disable g_assert() and cast checks for the unit tests The unit tests are riddled with g_assert() and friends, sometimes containing functional code like set_state() calls in them even (looking at you, pipeline/capsfilter-renegotiation). Make sure we don't disable assert and cast checks for the unit tests even if this has been specified for the rest of the code base, e.g. via --disable-glib-asserts. --- tests/check/Makefile.am | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/check/Makefile.am b/tests/check/Makefile.am index 31c9be1b4d..0cc03a4c37 100644 --- a/tests/check/Makefile.am +++ b/tests/check/Makefile.am @@ -151,7 +151,8 @@ VALGRIND_TO_FIX = \ noinst_PROGRAMS = $(check_libvisual) AM_CFLAGS = $(GST_CFLAGS) $(GST_CHECK_CFLAGS) \ - -DGST_TEST_FILES_PATH="\"$(TEST_FILES_DIRECTORY)\"" + -DGST_TEST_FILES_PATH="\"$(TEST_FILES_DIRECTORY)\"" \ + -UG_DISABLE_ASSERT -UG_DISABLE_CAST_CHECKS LDADD = $(GST_LIBS) $(GST_CHECK_LIBS) # valgrind testing From d7bdf0d49a65571b1f67578952a83771c386a2ac Mon Sep 17 00:00:00 2001 From: Edward Hervey Date: Fri, 7 Jan 2011 12:51:11 +0100 Subject: [PATCH 126/254] encodebin: Extend documentation https://bugzilla.gnome.org/show_bug.cgi?id=638901 --- gst/encoding/gstencodebin.c | 83 ++++++++++++++++++++++++++++++++++++- 1 file changed, 81 insertions(+), 2 deletions(-) diff --git a/gst/encoding/gstencodebin.c b/gst/encoding/gstencodebin.c index 1d44132070..311d8d3020 100644 --- a/gst/encoding/gstencodebin.c +++ b/gst/encoding/gstencodebin.c @@ -32,10 +32,70 @@ /** * SECTION:element-encodebin * - * encodebin provides a bin for encoding/muxing various streams according to + * EncodeBin provides a bin for encoding/muxing various streams according to * a specified #GstEncodingProfile. * - * + * Based on the profile that was set (via the #GstEncodeBin:profile property), + * EncodeBin will internally select and configure the required elements + * (encoders, muxers, but also audio and video converters) so that you can + * provide it raw or pre-encoded streams of data in input and have your + * encoded/muxed/converted stream in output. + * + * + * Features + * + * + * Automatic encoder and muxer selection based on elements available on the + * system. + * + * + * Conversion of raw audio/video streams (scaling, framerate conversion, + * colorspace conversion, samplerate conversion) to conform to the profile + * output format. + * + * + * Variable number of streams. If the presence property for a stream encoding + * profile is 0, you can request any number of sink pads for it via the + * standard request pad gstreamer API or the #GstEncodeBin::request-pad action + * signal. + * + * + * Avoid reencoding (passthrough). If the input stream is already encoded and is + * compatible with what the #GstEncodingProfile expects, then the stream won't + * be re-encoded but just passed through downstream to the muxer or the output. + * + * + * Mix pre-encoded and raw streams as input. In addition to the passthrough + * feature above, you can feed both raw audio/video *AND* already-encoded data + * to a pad. #GstEncodeBin will take care of passing through the compatible + * segments and re-encoding the segments of media that need encoding. + * + * + * Standard behaviour is to use a #GstEncodingContainerProfile to have both + * encoding and muxing performed. But you can also provide a single stream + * profile (like #GstEncodingAudioProfile) to only have the encoding done and + * handle the encoded output yourself. + * + * + * Audio imperfection corrections. Incoming audio streams can have non perfect + * timestamps (jitter), like the streams coming from ASF files. #GstEncodeBin + * will automatically fix those imperfections for you. See + * #GstEncodeBin:audio-jitter-tolerance for more details. + * + * + * Variable or Constant video framerate. If your #GstEncodingVideoProfile has + * the variableframerate property deactivated (default), then the incoming + * raw video stream will be retimestampped in order to produce a constant + * framerate. + * + * + * Cross-boundary re-encoding. When feeding compatible pre-encoded streams that + * fall on segment boundaries, and for supported formats (right now only H263), + * the GOP will be decoded/reencoded when needed to produce an encoded output + * that fits exactly within the request GstSegment. + * + * + * */ @@ -227,6 +287,13 @@ gst_encode_bin_class_init (GstEncodeBinClass * klass) gobject_klass->get_property = gst_encode_bin_get_property; /* Properties */ + + /** + * GstEncodeBin:profile: + * + * The #GstEncodingProfile to use. This property must be set before going + * to %GST_STATE_PAUSED or higher. + */ g_object_class_install_property (gobject_klass, PROP_PROFILE, gst_param_spec_mini_object ("profile", "Profile", "The GstEncodingProfile to use", GST_TYPE_ENCODING_PROFILE, @@ -262,6 +329,18 @@ gst_encode_bin_class_init (GstEncodeBinClass * klass) G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); /* Signals */ + /** + * GstEncodeBin::request-pad + * @encodebin: a #GstEncodeBin instance + * @caps: a #GstCaps + * + * Use this method to request an unused sink request #GstPad that can take the + * provided @caps as input. You must release the pad with + * gst_element_release_request_pad() when you are done with it. + * + * Returns: A compatible #GstPad, or %NULL if no compatible #GstPad could be + * created or is available. + */ gst_encode_bin_signals[SIGNAL_REQUEST_PAD] = g_signal_new ("request-pad", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION, G_STRUCT_OFFSET (GstEncodeBinClass, From 251400a69b6f5e2dc39a4cc9d86c472a872d82c3 Mon Sep 17 00:00:00 2001 From: Edward Hervey Date: Fri, 7 Jan 2011 13:04:11 +0100 Subject: [PATCH 127/254] encodebin: Add missing-plugin support https://bugzilla.gnome.org/show_bug.cgi?id=638903 --- gst/encoding/gstencodebin.c | 18 ++++++++++++++++++ gst/encoding/gstencodebin.h | 2 +- 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/gst/encoding/gstencodebin.c b/gst/encoding/gstencodebin.c index 311d8d3020..ada95f8f5f 100644 --- a/gst/encoding/gstencodebin.c +++ b/gst/encoding/gstencodebin.c @@ -94,6 +94,12 @@ * the GOP will be decoded/reencoded when needed to produce an encoded output * that fits exactly within the request GstSegment. * + * + * Missing plugin support. If a #GstElement is missing to encode/mux to the + * request profile formats, a missing-plugin #GstMessage will be posted on the + * #GstBus, allowing systems that support the missing-plugin system to offer the + * user a way to install the missing element. + * * * */ @@ -1259,6 +1265,11 @@ splitter_encoding_failure: no_encoder: GST_ERROR_OBJECT (ebin, "Couldn't create encoder for format %" GST_PTR_FORMAT, format); + /* missing plugin support */ + gst_element_post_message (GST_ELEMENT_CAST (ebin), + gst_missing_encoder_message_new (GST_ELEMENT_CAST (ebin), format)); + GST_ELEMENT_ERROR (ebin, CORE, MISSING_PLUGIN, (NULL), + ("Couldn't create encoder for format %" GST_PTR_FORMAT, format)); goto cleanup; no_muxer_pad: @@ -1456,6 +1467,13 @@ no_muxer: { GST_WARNING ("No available muxer for %" GST_PTR_FORMAT, gst_encoding_profile_get_format (ebin->profile)); + /* missing plugin support */ + gst_element_post_message (GST_ELEMENT_CAST (ebin), + gst_missing_encoder_message_new (GST_ELEMENT_CAST (ebin), + gst_encoding_profile_get_format (ebin->profile))); + GST_ELEMENT_ERROR (ebin, CORE, MISSING_PLUGIN, (NULL), + ("No available muxer for format %" GST_PTR_FORMAT, + gst_encoding_profile_get_format (ebin->profile))); return FALSE; } diff --git a/gst/encoding/gstencodebin.h b/gst/encoding/gstencodebin.h index 8082817de3..2d594b0f6d 100644 --- a/gst/encoding/gstencodebin.h +++ b/gst/encoding/gstencodebin.h @@ -22,7 +22,7 @@ #define __GST_ENCODEBIN_H__ #include -#include +#include #include "gstencode-marshal.h" #define GST_TYPE_ENCODE_BIN (gst_encode_bin_get_type()) From 8537f4326cd6c7e638b28b4920187fb54dbfa272 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim-Philipp=20M=C3=BCller?= Date: Fri, 7 Jan 2011 12:50:07 +0000 Subject: [PATCH 128/254] 0.10.31.2 pre-release --- configure.ac | 6 +++--- win32/common/_stdint.h | 4 ++-- win32/common/config.h | 16 +++++++++++----- win32/common/pbutils-enumtypes.c | 2 ++ win32/common/video-enumtypes.c | 5 +++++ 5 files changed, 23 insertions(+), 10 deletions(-) diff --git a/configure.ac b/configure.ac index 287cc476f3..6478a6cb75 100644 --- a/configure.ac +++ b/configure.ac @@ -5,7 +5,7 @@ dnl please read gstreamer/docs/random/autotools before changing this file dnl initialize autoconf dnl releases only do -Wall, git and prerelease does -Werror too dnl use a three digit version number for releases, and four for git/prerelease -AC_INIT(GStreamer Base Plug-ins, 0.10.31.1, +AC_INIT(GStreamer Base Plug-ins, 0.10.31.2, http://bugzilla.gnome.org/enter_bug.cgi?product=GStreamer, gst-plugins-base) @@ -49,7 +49,7 @@ dnl - interfaces added/removed/changed -> increment CURRENT, REVISION = 0 dnl - interfaces added -> increment AGE dnl - interfaces removed -> AGE = 0 dnl sets GST_LT_LDFLAGS -AS_LIBTOOL(GST, 22, 0, 22) +AS_LIBTOOL(GST, 23, 0, 23) dnl FIXME: this macro doesn't actually work; dnl the generated libtool script has no support for the listed tags. @@ -60,7 +60,7 @@ AC_LIBTOOL_WIN32_DLL AM_PROG_LIBTOOL dnl *** required versions of GStreamer stuff *** -GST_REQ=0.10.31.1 +GST_REQ=0.10.31.2 dnl *** autotools stuff **** diff --git a/win32/common/_stdint.h b/win32/common/_stdint.h index c731bb5cf6..c8fd32c590 100644 --- a/win32/common/_stdint.h +++ b/win32/common/_stdint.h @@ -1,8 +1,8 @@ #ifndef _GST_PLUGINS_BASE__STDINT_H #define _GST_PLUGINS_BASE__STDINT_H 1 #ifndef _GENERATED_STDINT_H -#define _GENERATED_STDINT_H "gst-plugins-base 0.10.31.1" -/* generated using gnu compiler gcc (Debian 4.4.5-8) 4.4.5 */ +#define _GENERATED_STDINT_H "gst-plugins-base 0.10.31.2" +/* generated using gnu compiler gcc (Debian 4.4.5-10) 4.4.5 */ #define _STDINT_HAVE_STDINT_H 1 #include #endif diff --git a/win32/common/config.h b/win32/common/config.h index 463159c018..4070219959 100644 --- a/win32/common/config.h +++ b/win32/common/config.h @@ -53,6 +53,9 @@ /* The GnomeVFS modules directory. */ #undef GNOME_VFS_MODULES_DIR +/* system wide data directory */ +#define GST_DATADIR PREFIX "\\share" + /* macro to use to show function name */ #undef GST_FUNCTION @@ -68,14 +71,17 @@ /* GStreamer license */ #define GST_LICENSE "LGPL" +/* major/minor version */ +#define GST_MAJORMINOR "0.10" + /* package name in plugins */ -#define GST_PACKAGE_NAME "GStreamer Base Plug-ins git" +#define GST_PACKAGE_NAME "GStreamer Base Plug-ins prerelease" /* package origin */ #define GST_PACKAGE_ORIGIN "Unknown package origin" /* GStreamer package release date/time for plugins as YYYY-MM-DD */ -#define GST_PACKAGE_RELEASE_DATETIME "2010-12-02T00:05Z" +#define GST_PACKAGE_RELEASE_DATETIME "2011-01-06T23:48Z" /* I know the API is subject to change. */ #undef G_UDEV_API_IS_SUBJECT_TO_CHANGE @@ -331,7 +337,7 @@ #define PACKAGE_NAME "GStreamer Base Plug-ins" /* Define to the full name and version of this package. */ -#define PACKAGE_STRING "GStreamer Base Plug-ins 0.10.31.1" +#define PACKAGE_STRING "GStreamer Base Plug-ins 0.10.31.2" /* Define to the one symbol short name of this package. */ #define PACKAGE_TARNAME "gst-plugins-base" @@ -340,7 +346,7 @@ #undef PACKAGE_URL /* Define to the version of this package. */ -#define PACKAGE_VERSION "0.10.31.1" +#define PACKAGE_VERSION "0.10.31.2" /* directory where plugins are located */ #ifdef _DEBUG @@ -368,7 +374,7 @@ #undef STDC_HEADERS /* Version number of package */ -#define VERSION "0.10.31.1" +#define VERSION "0.10.31.2" /* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most significant byte first (like Motorola and SPARC, unlike Intel). */ diff --git a/win32/common/pbutils-enumtypes.c b/win32/common/pbutils-enumtypes.c index 8303b77bb8..2652ec066c 100644 --- a/win32/common/pbutils-enumtypes.c +++ b/win32/common/pbutils-enumtypes.c @@ -6,6 +6,8 @@ #include "pbutils.h" #include "codec-utils.h" #include "descriptions.h" +#include "encoding-profile.h" +#include "encoding-target.h" #include "install-plugins.h" #include "missing-plugins.h" #include "gstdiscoverer.h" diff --git a/win32/common/video-enumtypes.c b/win32/common/video-enumtypes.c index 66477c22bc..f1ba0e5773 100644 --- a/win32/common/video-enumtypes.c +++ b/win32/common/video-enumtypes.c @@ -48,6 +48,11 @@ gst_video_format_get_type (void) {GST_VIDEO_FORMAT_BGR15, "GST_VIDEO_FORMAT_BGR15", "bgr15"}, {GST_VIDEO_FORMAT_UYVP, "GST_VIDEO_FORMAT_UYVP", "uyvp"}, {GST_VIDEO_FORMAT_A420, "GST_VIDEO_FORMAT_A420", "a420"}, + {GST_VIDEO_FORMAT_RGB8_PALETTED, "GST_VIDEO_FORMAT_RGB8_PALETTED", + "rgb8-paletted"}, + {GST_VIDEO_FORMAT_YUV9, "GST_VIDEO_FORMAT_YUV9", "yuv9"}, + {GST_VIDEO_FORMAT_YVU9, "GST_VIDEO_FORMAT_YVU9", "yvu9"}, + {GST_VIDEO_FORMAT_IYU1, "GST_VIDEO_FORMAT_IYU1", "iyu1"}, {0, NULL, NULL} }; GType g_define_type_id = g_enum_register_static ("GstVideoFormat", values); From c53ef04af7470e073c5ebc03a87e02f329d7f79c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim-Philipp=20M=C3=BCller?= Date: Sat, 8 Jan 2011 01:12:02 +0000 Subject: [PATCH 129/254] pkg-config: add girdir and typelibdir variables to .pc files We need them when building gir and typelib files for libraries that depend on these, such as gst-rtsp-server for example, in an uninstalled setup. --- pkgconfig/gstreamer-app-uninstalled.pc.in | 2 ++ pkgconfig/gstreamer-app.pc.in | 4 ++++ pkgconfig/gstreamer-audio-uninstalled.pc.in | 2 ++ pkgconfig/gstreamer-audio.pc.in | 4 ++++ pkgconfig/gstreamer-cdda-uninstalled.pc.in | 2 ++ pkgconfig/gstreamer-cdda.pc.in | 4 ++++ pkgconfig/gstreamer-fft-uninstalled.pc.in | 2 ++ pkgconfig/gstreamer-fft.pc.in | 4 ++++ pkgconfig/gstreamer-floatcast.pc.in | 4 ++++ pkgconfig/gstreamer-interfaces-uninstalled.pc.in | 2 ++ pkgconfig/gstreamer-interfaces.pc.in | 4 ++++ pkgconfig/gstreamer-netbuffer-uninstalled.pc.in | 2 ++ pkgconfig/gstreamer-netbuffer.pc.in | 4 ++++ pkgconfig/gstreamer-pbutils-uninstalled.pc.in | 2 ++ pkgconfig/gstreamer-pbutils.pc.in | 4 ++++ pkgconfig/gstreamer-riff-uninstalled.pc.in | 2 ++ pkgconfig/gstreamer-riff.pc.in | 4 ++++ pkgconfig/gstreamer-rtp-uninstalled.pc.in | 2 ++ pkgconfig/gstreamer-rtp.pc.in | 4 ++++ pkgconfig/gstreamer-rtsp-uninstalled.pc.in | 2 ++ pkgconfig/gstreamer-rtsp.pc.in | 4 ++++ pkgconfig/gstreamer-sdp-uninstalled.pc.in | 2 ++ pkgconfig/gstreamer-sdp.pc.in | 4 ++++ pkgconfig/gstreamer-tag-uninstalled.pc.in | 2 ++ pkgconfig/gstreamer-tag.pc.in | 4 ++++ pkgconfig/gstreamer-video-uninstalled.pc.in | 2 ++ pkgconfig/gstreamer-video.pc.in | 4 ++++ 27 files changed, 82 insertions(+) diff --git a/pkgconfig/gstreamer-app-uninstalled.pc.in b/pkgconfig/gstreamer-app-uninstalled.pc.in index 015bedcd8b..b989798ee7 100644 --- a/pkgconfig/gstreamer-app-uninstalled.pc.in +++ b/pkgconfig/gstreamer-app-uninstalled.pc.in @@ -4,6 +4,8 @@ exec_prefix= libdir= # includedir is builddir because it is used to find gstconfig.h in places includedir=@abs_top_builddir@/gst-libs +girdir=@abs_top_builddir@/gst-libs/gst/app +typelibdir=@abs_top_builddir@/gst-libs/gst/app Name: GStreamer Application Library, Uninstalled Description: Helper functions and base classes for application integration, uninstalled diff --git a/pkgconfig/gstreamer-app.pc.in b/pkgconfig/gstreamer-app.pc.in index ef3d27c38b..8152effe5f 100644 --- a/pkgconfig/gstreamer-app.pc.in +++ b/pkgconfig/gstreamer-app.pc.in @@ -2,6 +2,10 @@ prefix=@prefix@ exec_prefix=@exec_prefix@ libdir=@libdir@ includedir=@includedir@/gstreamer-@GST_MAJORMINOR@ +datarootdir=${prefix}/share +datadir=${datarootdir} +girdir=${datadir}/gir-1.0 +typelibdir=${libdir}/girepository-1.0 Name: GStreamer Application Library Description: Helper functions and base classes for application integration diff --git a/pkgconfig/gstreamer-audio-uninstalled.pc.in b/pkgconfig/gstreamer-audio-uninstalled.pc.in index da927d3fef..ce55cf94bc 100644 --- a/pkgconfig/gstreamer-audio-uninstalled.pc.in +++ b/pkgconfig/gstreamer-audio-uninstalled.pc.in @@ -4,6 +4,8 @@ exec_prefix= libdir= # includedir is builddir because it is used to find gstconfig.h in places includedir=@abs_top_builddir@/gst-libs +girdir=@abs_top_builddir@/gst-libs/gst/audio +typelibdir=@abs_top_builddir@/gst-libs/gst/audio Name: GStreamer Audio Library, Uninstalled Description: Audio helper functions and base classes, uninstalled diff --git a/pkgconfig/gstreamer-audio.pc.in b/pkgconfig/gstreamer-audio.pc.in index 623638144f..5743ccf959 100644 --- a/pkgconfig/gstreamer-audio.pc.in +++ b/pkgconfig/gstreamer-audio.pc.in @@ -2,6 +2,10 @@ prefix=@prefix@ exec_prefix=@exec_prefix@ libdir=@libdir@ includedir=@includedir@/gstreamer-@GST_MAJORMINOR@ +datarootdir=${prefix}/share +datadir=${datarootdir} +girdir=${datadir}/gir-1.0 +typelibdir=${libdir}/girepository-1.0 Name: GStreamer Audio library Description: Audio helper functions and base classes diff --git a/pkgconfig/gstreamer-cdda-uninstalled.pc.in b/pkgconfig/gstreamer-cdda-uninstalled.pc.in index b3fa27d003..15773e8de3 100644 --- a/pkgconfig/gstreamer-cdda-uninstalled.pc.in +++ b/pkgconfig/gstreamer-cdda-uninstalled.pc.in @@ -4,6 +4,8 @@ exec_prefix= libdir= # includedir is builddir because it is used to find gstconfig.h in places includedir=@abs_top_builddir@/gst-libs +girdir=@abs_top_builddir@/gst-libs/gst/cdda +typelibdir=@abs_top_builddir@/gst-libs/gst/cdda Name: GStreamer CDDA Library, Uninstalled Description: CDDA base classes, uninstalled diff --git a/pkgconfig/gstreamer-cdda.pc.in b/pkgconfig/gstreamer-cdda.pc.in index b67eac169f..86f4a2bf0b 100644 --- a/pkgconfig/gstreamer-cdda.pc.in +++ b/pkgconfig/gstreamer-cdda.pc.in @@ -2,6 +2,10 @@ prefix=@prefix@ exec_prefix=@exec_prefix@ libdir=@libdir@ includedir=@includedir@/gstreamer-@GST_MAJORMINOR@ +datarootdir=${prefix}/share +datadir=${datarootdir} +girdir=${datadir}/gir-1.0 +typelibdir=${libdir}/girepository-1.0 Name: GStreamer CDDA Library Description: CDDA base classes diff --git a/pkgconfig/gstreamer-fft-uninstalled.pc.in b/pkgconfig/gstreamer-fft-uninstalled.pc.in index 67b0fff9d7..163f3f0653 100644 --- a/pkgconfig/gstreamer-fft-uninstalled.pc.in +++ b/pkgconfig/gstreamer-fft-uninstalled.pc.in @@ -4,6 +4,8 @@ exec_prefix= libdir= # includedir is builddir because it is used to find gstconfig.h in places includedir=@abs_top_builddir@/gst-libs +girdir=@abs_top_builddir@/gst-libs/gst/fft +typelibdir=@abs_top_builddir@/gst-libs/gst/fft Name: GStreamer FFT Library, Uninstalled Description: FFT implementation, uninstalled diff --git a/pkgconfig/gstreamer-fft.pc.in b/pkgconfig/gstreamer-fft.pc.in index 20ffdd667f..5680a0c6df 100644 --- a/pkgconfig/gstreamer-fft.pc.in +++ b/pkgconfig/gstreamer-fft.pc.in @@ -2,6 +2,10 @@ prefix=@prefix@ exec_prefix=@exec_prefix@ libdir=@libdir@ includedir=@includedir@/gstreamer-@GST_MAJORMINOR@ +datarootdir=${prefix}/share +datadir=${datarootdir} +girdir=${datadir}/gir-1.0 +typelibdir=${libdir}/girepository-1.0 Name: GStreamer FFT Library Description: FFT implementation diff --git a/pkgconfig/gstreamer-floatcast.pc.in b/pkgconfig/gstreamer-floatcast.pc.in index 1714eaafa6..c54b098919 100644 --- a/pkgconfig/gstreamer-floatcast.pc.in +++ b/pkgconfig/gstreamer-floatcast.pc.in @@ -2,6 +2,10 @@ prefix=@prefix@ exec_prefix=@exec_prefix@ libdir=@libdir@ includedir=@includedir@/gstreamer-@GST_MAJORMINOR@ +datarootdir=${prefix}/share +datadir=${datarootdir} +girdir=${datadir}/gir-1.0 +typelibdir=${libdir}/girepository-1.0 Name: GStreamer Floatcast Library Description: Platform independent floating point macros diff --git a/pkgconfig/gstreamer-interfaces-uninstalled.pc.in b/pkgconfig/gstreamer-interfaces-uninstalled.pc.in index 90dd7405a5..676a23fbf0 100644 --- a/pkgconfig/gstreamer-interfaces-uninstalled.pc.in +++ b/pkgconfig/gstreamer-interfaces-uninstalled.pc.in @@ -4,6 +4,8 @@ exec_prefix= libdir= # includedir is builddir because it is used to find gstconfig.h in places includedir=@abs_top_builddir@/gst-libs +girdir=@abs_top_builddir@/gst-libs/gst/interfaces +typelibdir=@abs_top_builddir@/gst-libs/gst/interfaces Name: GStreamer Interfaces Library, Uninstalled Description: Interfaces for GStreamer elements, uninstalled diff --git a/pkgconfig/gstreamer-interfaces.pc.in b/pkgconfig/gstreamer-interfaces.pc.in index 30828e4b4e..24749be89f 100644 --- a/pkgconfig/gstreamer-interfaces.pc.in +++ b/pkgconfig/gstreamer-interfaces.pc.in @@ -2,6 +2,10 @@ prefix=@prefix@ exec_prefix=@exec_prefix@ libdir=@libdir@ includedir=@includedir@/gstreamer-@GST_MAJORMINOR@ +datarootdir=${prefix}/share +datadir=${datarootdir} +girdir=${datadir}/gir-1.0 +typelibdir=${libdir}/girepository-1.0 Name: GStreamer Interfaces Library Description: Interfaces for GStreamer elements diff --git a/pkgconfig/gstreamer-netbuffer-uninstalled.pc.in b/pkgconfig/gstreamer-netbuffer-uninstalled.pc.in index ecf84d026c..941c728ed1 100644 --- a/pkgconfig/gstreamer-netbuffer-uninstalled.pc.in +++ b/pkgconfig/gstreamer-netbuffer-uninstalled.pc.in @@ -4,6 +4,8 @@ exec_prefix= libdir= # includedir is builddir because it is used to find gstconfig.h in places includedir=@abs_top_builddir@/gst-libs +girdir=@abs_top_builddir@/gst-libs/gst/netbuffer +typelibdir=@abs_top_builddir@/gst-libs/gst/netbuffer Name: GStreamer Network Buffer Library, Uninstalled Description: Network buffer for use in network sources/sinks, uninstalled diff --git a/pkgconfig/gstreamer-netbuffer.pc.in b/pkgconfig/gstreamer-netbuffer.pc.in index 44809fb61a..28d7ed27f2 100644 --- a/pkgconfig/gstreamer-netbuffer.pc.in +++ b/pkgconfig/gstreamer-netbuffer.pc.in @@ -2,6 +2,10 @@ prefix=@prefix@ exec_prefix=@exec_prefix@ libdir=@libdir@ includedir=@includedir@/gstreamer-@GST_MAJORMINOR@ +datarootdir=${prefix}/share +datadir=${datarootdir} +girdir=${datadir}/gir-1.0 +typelibdir=${libdir}/girepository-1.0 Name: GStreamer Network Buffer Library Description: Network buffer for use in network sources/sinks diff --git a/pkgconfig/gstreamer-pbutils-uninstalled.pc.in b/pkgconfig/gstreamer-pbutils-uninstalled.pc.in index 57258328a1..e08758c979 100644 --- a/pkgconfig/gstreamer-pbutils-uninstalled.pc.in +++ b/pkgconfig/gstreamer-pbutils-uninstalled.pc.in @@ -4,6 +4,8 @@ exec_prefix= libdir= # includedir is builddir because it is used to find gstconfig.h in places includedir=@abs_top_builddir@/gst-libs +girdir=@abs_top_builddir@/gst-libs/gst/pbutils +typelibdir=@abs_top_builddir@/gst-libs/gst/pbutils Name: GStreamer Base Utils Library, Uninstalled Description: General utility functions, uninstalled diff --git a/pkgconfig/gstreamer-pbutils.pc.in b/pkgconfig/gstreamer-pbutils.pc.in index 59954240bf..e1626a454c 100644 --- a/pkgconfig/gstreamer-pbutils.pc.in +++ b/pkgconfig/gstreamer-pbutils.pc.in @@ -2,6 +2,10 @@ prefix=@prefix@ exec_prefix=@exec_prefix@ libdir=@libdir@ includedir=@includedir@/gstreamer-@GST_MAJORMINOR@ +datarootdir=${prefix}/share +datadir=${datarootdir} +girdir=${datadir}/gir-1.0 +typelibdir=${libdir}/girepository-1.0 Name: GStreamer Base Utils Library Description: General utility functions diff --git a/pkgconfig/gstreamer-riff-uninstalled.pc.in b/pkgconfig/gstreamer-riff-uninstalled.pc.in index 490c0b02e4..2592ba14f9 100644 --- a/pkgconfig/gstreamer-riff-uninstalled.pc.in +++ b/pkgconfig/gstreamer-riff-uninstalled.pc.in @@ -4,6 +4,8 @@ exec_prefix= libdir= # includedir is builddir because it is used to find gstconfig.h in places includedir=@abs_top_builddir@/gst-libs +girdir=@abs_top_builddir@/gst-libs/gst/riff +typelibdir=@abs_top_builddir@/gst-libs/gst/riff Name: GStreamer RIFF Library, Uninstalled Description: RIFF helper functions, uninstalled diff --git a/pkgconfig/gstreamer-riff.pc.in b/pkgconfig/gstreamer-riff.pc.in index 054d417ef9..0858276bf3 100644 --- a/pkgconfig/gstreamer-riff.pc.in +++ b/pkgconfig/gstreamer-riff.pc.in @@ -2,6 +2,10 @@ prefix=@prefix@ exec_prefix=@exec_prefix@ libdir=@libdir@ includedir=@includedir@/gstreamer-@GST_MAJORMINOR@ +datarootdir=${prefix}/share +datadir=${datarootdir} +girdir=${datadir}/gir-1.0 +typelibdir=${libdir}/girepository-1.0 Name: GStreamer RIFF Library Description: RIFF helper functions diff --git a/pkgconfig/gstreamer-rtp-uninstalled.pc.in b/pkgconfig/gstreamer-rtp-uninstalled.pc.in index f976829b88..96c66cd741 100644 --- a/pkgconfig/gstreamer-rtp-uninstalled.pc.in +++ b/pkgconfig/gstreamer-rtp-uninstalled.pc.in @@ -4,6 +4,8 @@ exec_prefix= libdir= # includedir is builddir because it is used to find gstconfig.h in places includedir=@abs_top_builddir@/gst-libs +girdir=@abs_top_builddir@/gst-libs/gst/rtp +typelibdir=@abs_top_builddir@/gst-libs/gst/rtp Name: GStreamer RTP Library, Uninstalled Description: RTP base classes and helper functions, uninstalled diff --git a/pkgconfig/gstreamer-rtp.pc.in b/pkgconfig/gstreamer-rtp.pc.in index c7a3b15dd9..ff74a9d126 100644 --- a/pkgconfig/gstreamer-rtp.pc.in +++ b/pkgconfig/gstreamer-rtp.pc.in @@ -2,6 +2,10 @@ prefix=@prefix@ exec_prefix=@exec_prefix@ libdir=@libdir@ includedir=@includedir@/gstreamer-@GST_MAJORMINOR@ +datarootdir=${prefix}/share +datadir=${datarootdir} +girdir=${datadir}/gir-1.0 +typelibdir=${libdir}/girepository-1.0 Name: GStreamer RTP Library Description: RTP base classes and helper functions diff --git a/pkgconfig/gstreamer-rtsp-uninstalled.pc.in b/pkgconfig/gstreamer-rtsp-uninstalled.pc.in index 3bf86b1716..53258ec098 100644 --- a/pkgconfig/gstreamer-rtsp-uninstalled.pc.in +++ b/pkgconfig/gstreamer-rtsp-uninstalled.pc.in @@ -4,6 +4,8 @@ exec_prefix= libdir= # includedir is builddir because it is used to find gstconfig.h in places includedir=@abs_top_builddir@/gst-libs +girdir=@abs_top_builddir@/gst-libs/gst/rtsp +typelibdir=@abs_top_builddir@/gst-libs/gst/rtsp Name: GStreamer RTSP Library, Uninstalled Description: RTSP base classes and helper functions, uninstalled diff --git a/pkgconfig/gstreamer-rtsp.pc.in b/pkgconfig/gstreamer-rtsp.pc.in index b2ca7cf63e..203e4002cb 100644 --- a/pkgconfig/gstreamer-rtsp.pc.in +++ b/pkgconfig/gstreamer-rtsp.pc.in @@ -2,6 +2,10 @@ prefix=@prefix@ exec_prefix=@exec_prefix@ libdir=@libdir@ includedir=@includedir@/gstreamer-@GST_MAJORMINOR@ +datarootdir=${prefix}/share +datadir=${datarootdir} +girdir=${datadir}/gir-1.0 +typelibdir=${libdir}/girepository-1.0 Name: GStreamer RTSP Library Description: RTSP base classes and helper functions diff --git a/pkgconfig/gstreamer-sdp-uninstalled.pc.in b/pkgconfig/gstreamer-sdp-uninstalled.pc.in index d4591b5837..bd1d89ddb2 100644 --- a/pkgconfig/gstreamer-sdp-uninstalled.pc.in +++ b/pkgconfig/gstreamer-sdp-uninstalled.pc.in @@ -4,6 +4,8 @@ exec_prefix= libdir= # includedir is builddir because it is used to find gstconfig.h in places includedir=@abs_top_builddir@/gst-libs +girdir=@abs_top_builddir@/gst-libs/gst/sdp +typelibdir=@abs_top_builddir@/gst-libs/gst/sdp Name: GStreamer SDP Library, Uninstalled Description: SDP helper functions, uninstalled diff --git a/pkgconfig/gstreamer-sdp.pc.in b/pkgconfig/gstreamer-sdp.pc.in index bf9c56acc4..9bb0f4044d 100644 --- a/pkgconfig/gstreamer-sdp.pc.in +++ b/pkgconfig/gstreamer-sdp.pc.in @@ -2,6 +2,10 @@ prefix=@prefix@ exec_prefix=@exec_prefix@ libdir=@libdir@ includedir=@includedir@/gstreamer-@GST_MAJORMINOR@ +datarootdir=${prefix}/share +datadir=${datarootdir} +girdir=${datadir}/gir-1.0 +typelibdir=${libdir}/girepository-1.0 Name: GStreamer SDP Library Description: SDP helper functions diff --git a/pkgconfig/gstreamer-tag-uninstalled.pc.in b/pkgconfig/gstreamer-tag-uninstalled.pc.in index 5f2e791157..b953a4c1a7 100644 --- a/pkgconfig/gstreamer-tag-uninstalled.pc.in +++ b/pkgconfig/gstreamer-tag-uninstalled.pc.in @@ -4,6 +4,8 @@ exec_prefix= libdir= # includedir is builddir because it is used to find gstconfig.h in places includedir=@abs_top_builddir@/gst-libs +girdir=@abs_top_builddir@/gst-libs/gst/tag +typelibdir=@abs_top_builddir@/gst-libs/gst/tag Name: GStreamer Tag Library, Uninstalled Description: Tag base classes and helper functions, uninstalled diff --git a/pkgconfig/gstreamer-tag.pc.in b/pkgconfig/gstreamer-tag.pc.in index 33c27b542e..a7a564c3b4 100644 --- a/pkgconfig/gstreamer-tag.pc.in +++ b/pkgconfig/gstreamer-tag.pc.in @@ -2,6 +2,10 @@ prefix=@prefix@ exec_prefix=@exec_prefix@ libdir=@libdir@ includedir=@includedir@/gstreamer-@GST_MAJORMINOR@ +datarootdir=${prefix}/share +datadir=${datarootdir} +girdir=${datadir}/gir-1.0 +typelibdir=${libdir}/girepository-1.0 Name: GStreamer Tag Library Description: Tag base classes and helper functions diff --git a/pkgconfig/gstreamer-video-uninstalled.pc.in b/pkgconfig/gstreamer-video-uninstalled.pc.in index 63792967b6..450be2bc2d 100644 --- a/pkgconfig/gstreamer-video-uninstalled.pc.in +++ b/pkgconfig/gstreamer-video-uninstalled.pc.in @@ -4,6 +4,8 @@ exec_prefix= libdir= # includedir is builddir because it is used to find gstconfig.h in places includedir=@abs_top_builddir@/gst-libs +girdir=@abs_top_builddir@/gst-libs/gst/video +typelibdir=@abs_top_builddir@/gst-libs/gst/video Name: GStreamer Video Library, Uninstalled Description: Video base classes and helper functions, uninstalled diff --git a/pkgconfig/gstreamer-video.pc.in b/pkgconfig/gstreamer-video.pc.in index cdddeb31b8..59a217d74e 100644 --- a/pkgconfig/gstreamer-video.pc.in +++ b/pkgconfig/gstreamer-video.pc.in @@ -2,6 +2,10 @@ prefix=@prefix@ exec_prefix=@exec_prefix@ libdir=@libdir@ includedir=@includedir@/gstreamer-@GST_MAJORMINOR@ +datarootdir=${prefix}/share +datadir=${datarootdir} +girdir=${datadir}/gir-1.0 +typelibdir=${libdir}/girepository-1.0 Name: GStreamer Video Library Description: Video base classes and helper functions From 0ed757db336fa80ce9f99558865651cf534fabcd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim-Philipp=20M=C3=BCller?= Date: Sat, 8 Jan 2011 02:10:03 +0000 Subject: [PATCH 130/254] gobject-introspection: use same PKG_CONFIG_PATH for g-ir-compiler as for g-ir-scanner Make sure to use the PKG_CONFIG_PATH set at configure time instead of just relying on an env-var set one. This makes sure both g-ir-compiler and g-ir-scanner use the same PKG_CONFIG_PATH for determining include paths etc. --- gst-libs/gst/app/Makefile.am | 3 ++- gst-libs/gst/audio/Makefile.am | 3 ++- gst-libs/gst/cdda/Makefile.am | 3 ++- gst-libs/gst/fft/Makefile.am | 3 ++- gst-libs/gst/interfaces/Makefile.am | 3 ++- gst-libs/gst/netbuffer/Makefile.am | 3 ++- gst-libs/gst/pbutils/Makefile.am | 3 ++- gst-libs/gst/riff/Makefile.am | 3 ++- gst-libs/gst/rtp/Makefile.am | 3 ++- gst-libs/gst/rtsp/Makefile.am | 3 ++- gst-libs/gst/sdp/Makefile.am | 3 ++- gst-libs/gst/tag/Makefile.am | 3 ++- gst-libs/gst/video/Makefile.am | 3 ++- 13 files changed, 26 insertions(+), 13 deletions(-) diff --git a/gst-libs/gst/app/Makefile.am b/gst-libs/gst/app/Makefile.am index 8848a7d534..cf2c85288c 100644 --- a/gst-libs/gst/app/Makefile.am +++ b/gst-libs/gst/app/Makefile.am @@ -70,7 +70,8 @@ typelibsdir = $(libdir)/girepository-1.0/ typelibs_DATA = $(BUILT_GIRSOURCES:.gir=.typelib) %.typelib: %.gir $(INTROSPECTION_COMPILER) - $(AM_V_GEN)$(INTROSPECTION_COMPILER) \ + $(AM_V_GEN)PKG_CONFIG_PATH="$(GST_PKG_CONFIG_PATH)" \ + $(INTROSPECTION_COMPILER) \ --includedir=$(srcdir) \ --includedir=$(builddir) \ --includedir=`$(PKG_CONFIG) --variable=girdir gstreamer-0.10` \ diff --git a/gst-libs/gst/audio/Makefile.am b/gst-libs/gst/audio/Makefile.am index 441168330b..b449e24aab 100644 --- a/gst-libs/gst/audio/Makefile.am +++ b/gst-libs/gst/audio/Makefile.am @@ -101,7 +101,8 @@ typelibsdir = $(libdir)/girepository-1.0/ typelibs_DATA = $(BUILT_GIRSOURCES:.gir=.typelib) %.typelib: %.gir $(INTROSPECTION_COMPILER) - $(AM_V_GEN)$(INTROSPECTION_COMPILER) \ + $(AM_V_GEN)PKG_CONFIG_PATH="$(GST_PKG_CONFIG_PATH)" \ + $(INTROSPECTION_COMPILER) \ --includedir=$(srcdir) \ --includedir=$(builddir) \ --includedir=$(builddir)/../interfaces \ diff --git a/gst-libs/gst/cdda/Makefile.am b/gst-libs/gst/cdda/Makefile.am index 31bae21ac1..5985c84d18 100644 --- a/gst-libs/gst/cdda/Makefile.am +++ b/gst-libs/gst/cdda/Makefile.am @@ -54,7 +54,8 @@ typelibsdir = $(libdir)/girepository-1.0/ typelibs_DATA = $(BUILT_GIRSOURCES:.gir=.typelib) %.typelib: %.gir $(INTROSPECTION_COMPILER) - $(AM_V_GEN)$(INTROSPECTION_COMPILER) \ + $(AM_V_GEN)PKG_CONFIG_PATH="$(GST_PKG_CONFIG_PATH)" \ + $(INTROSPECTION_COMPILER) \ --includedir=$(srcdir) \ --includedir=$(builddir) \ --includedir=$(builddir)/../tag \ diff --git a/gst-libs/gst/fft/Makefile.am b/gst-libs/gst/fft/Makefile.am index 046d4d9ba8..bf14e55ee4 100644 --- a/gst-libs/gst/fft/Makefile.am +++ b/gst-libs/gst/fft/Makefile.am @@ -77,7 +77,8 @@ typelibsdir = $(libdir)/girepository-1.0/ typelibs_DATA = $(BUILT_GIRSOURCES:.gir=.typelib) %.typelib: %.gir $(INTROSPECTION_COMPILER) - $(AM_V_GEN)$(INTROSPECTION_COMPILER) \ + $(AM_V_GEN)PKG_CONFIG_PATH="$(GST_PKG_CONFIG_PATH)" \ + $(INTROSPECTION_COMPILER) \ --includedir=$(srcdir) \ --includedir=$(builddir) \ --includedir=`$(PKG_CONFIG) --variable=girdir gstreamer-0.10` \ diff --git a/gst-libs/gst/interfaces/Makefile.am b/gst-libs/gst/interfaces/Makefile.am index e262448128..eca6a805a5 100644 --- a/gst-libs/gst/interfaces/Makefile.am +++ b/gst-libs/gst/interfaces/Makefile.am @@ -108,7 +108,8 @@ typelibsdir = $(libdir)/girepository-1.0/ typelibs_DATA = $(BUILT_GIRSOURCES:.gir=.typelib) %.typelib: %.gir $(INTROSPECTION_COMPILER) - $(AM_V_GEN)$(INTROSPECTION_COMPILER) \ + $(AM_V_GEN)PKG_CONFIG_PATH="$(GST_PKG_CONFIG_PATH)" \ + $(INTROSPECTION_COMPILER) \ --includedir=$(srcdir) \ --includedir=$(builddir) \ --includedir=`$(PKG_CONFIG) --variable=girdir gstreamer-0.10` \ diff --git a/gst-libs/gst/netbuffer/Makefile.am b/gst-libs/gst/netbuffer/Makefile.am index 5a78b9d11b..9f70a396a2 100644 --- a/gst-libs/gst/netbuffer/Makefile.am +++ b/gst-libs/gst/netbuffer/Makefile.am @@ -42,7 +42,8 @@ typelibsdir = $(libdir)/girepository-1.0/ typelibs_DATA = $(BUILT_GIRSOURCES:.gir=.typelib) %.typelib: %.gir $(INTROSPECTION_COMPILER) - $(AM_V_GEN)$(INTROSPECTION_COMPILER) \ + $(AM_V_GEN)PKG_CONFIG_PATH="$(GST_PKG_CONFIG_PATH)" \ + $(INTROSPECTION_COMPILER) \ --includedir=$(srcdir) \ --includedir=$(builddir) \ --includedir=`$(PKG_CONFIG) --variable=girdir gstreamer-0.10` \ diff --git a/gst-libs/gst/pbutils/Makefile.am b/gst-libs/gst/pbutils/Makefile.am index fea84c46d4..82a10bf795 100644 --- a/gst-libs/gst/pbutils/Makefile.am +++ b/gst-libs/gst/pbutils/Makefile.am @@ -105,7 +105,8 @@ typelibsdir = $(libdir)/girepository-1.0/ typelibs_DATA = $(BUILT_GIRSOURCES:.gir=.typelib) %.typelib: %.gir $(INTROSPECTION_COMPILER) - $(AM_V_GEN)$(INTROSPECTION_COMPILER) \ + $(AM_V_GEN)PKG_CONFIG_PATH="$(GST_PKG_CONFIG_PATH)" \ + $(INTROSPECTION_COMPILER) \ --includedir=$(srcdir) \ --includedir=$(srcdir)/../video \ --includedir=$(builddir) \ diff --git a/gst-libs/gst/riff/Makefile.am b/gst-libs/gst/riff/Makefile.am index 879f980993..5da50d63fc 100644 --- a/gst-libs/gst/riff/Makefile.am +++ b/gst-libs/gst/riff/Makefile.am @@ -61,7 +61,8 @@ typelibsdir = $(libdir)/girepository-1.0/ typelibs_DATA = $(BUILT_GIRSOURCES:.gir=.typelib) %.typelib: %.gir $(INTROSPECTION_COMPILER) - $(AM_V_GEN)$(INTROSPECTION_COMPILER) \ + $(AM_V_GEN)PKG_CONFIG_PATH="$(GST_PKG_CONFIG_PATH)" \ + $(INTROSPECTION_COMPILER) \ --includedir=$(srcdir) \ --includedir=$(builddir) \ --includedir=$(builddir)/../tag \ diff --git a/gst-libs/gst/rtp/Makefile.am b/gst-libs/gst/rtp/Makefile.am index 9c983664b4..36a423ae66 100644 --- a/gst-libs/gst/rtp/Makefile.am +++ b/gst-libs/gst/rtp/Makefile.am @@ -57,7 +57,8 @@ typelibsdir = $(libdir)/girepository-1.0/ typelibs_DATA = $(BUILT_GIRSOURCES:.gir=.typelib) %.typelib: %.gir $(INTROSPECTION_COMPILER) - $(AM_V_GEN)$(INTROSPECTION_COMPILER) \ + $(AM_V_GEN)PKG_CONFIG_PATH="$(GST_PKG_CONFIG_PATH)" \ + $(INTROSPECTION_COMPILER) \ --includedir=$(srcdir) \ --includedir=$(builddir) \ --includedir=`$(PKG_CONFIG) --variable=girdir gstreamer-0.10` \ diff --git a/gst-libs/gst/rtsp/Makefile.am b/gst-libs/gst/rtsp/Makefile.am index 65777a7397..87a2ecd7fd 100644 --- a/gst-libs/gst/rtsp/Makefile.am +++ b/gst-libs/gst/rtsp/Makefile.am @@ -90,7 +90,8 @@ typelibsdir = $(libdir)/girepository-1.0/ typelibs_DATA = $(BUILT_GIRSOURCES:.gir=.typelib) %.typelib: %.gir $(INTROSPECTION_COMPILER) - $(AM_V_GEN)$(INTROSPECTION_COMPILER) \ + $(AM_V_GEN)PKG_CONFIG_PATH="$(GST_PKG_CONFIG_PATH)" \ + $(INTROSPECTION_COMPILER) \ --includedir=$(srcdir) \ --includedir=$(builddir) \ --includedir=$(builddir)/../sdp \ diff --git a/gst-libs/gst/sdp/Makefile.am b/gst-libs/gst/sdp/Makefile.am index b122f2fc9d..fd8017e98a 100644 --- a/gst-libs/gst/sdp/Makefile.am +++ b/gst-libs/gst/sdp/Makefile.am @@ -45,7 +45,8 @@ typelibsdir = $(libdir)/girepository-1.0/ typelibs_DATA = $(BUILT_GIRSOURCES:.gir=.typelib) %.typelib: %.gir $(INTROSPECTION_COMPILER) - $(AM_V_GEN)$(INTROSPECTION_COMPILER) \ + $(AM_V_GEN)PKG_CONFIG_PATH="$(GST_PKG_CONFIG_PATH)" \ + $(INTROSPECTION_COMPILER) \ --includedir=$(srcdir) \ --includedir=$(builddir) \ --includedir=`$(PKG_CONFIG) --variable=girdir gstreamer-0.10` \ diff --git a/gst-libs/gst/tag/Makefile.am b/gst-libs/gst/tag/Makefile.am index aac1c13d09..9e82463703 100644 --- a/gst-libs/gst/tag/Makefile.am +++ b/gst-libs/gst/tag/Makefile.am @@ -54,7 +54,8 @@ typelibsdir = $(libdir)/girepository-1.0/ typelibs_DATA = $(BUILT_GIRSOURCES:.gir=.typelib) %.typelib: %.gir $(INTROSPECTION_COMPILER) - $(AM_V_GEN)$(INTROSPECTION_COMPILER) \ + $(AM_V_GEN)PKG_CONFIG_PATH="$(GST_PKG_CONFIG_PATH)" \ + $(INTROSPECTION_COMPILER) \ --includedir=$(srcdir) \ --includedir=$(builddir) \ --includedir=`$(PKG_CONFIG) --variable=girdir gstreamer-0.10` \ diff --git a/gst-libs/gst/video/Makefile.am b/gst-libs/gst/video/Makefile.am index 8a9019cb60..26d5d1b347 100644 --- a/gst-libs/gst/video/Makefile.am +++ b/gst-libs/gst/video/Makefile.am @@ -68,7 +68,8 @@ typelibsdir = $(libdir)/girepository-1.0/ typelibs_DATA = $(BUILT_GIRSOURCES:.gir=.typelib) %.typelib: %.gir $(INTROSPECTION_COMPILER) - $(AM_V_GEN)$(INTROSPECTION_COMPILER) \ + $(AM_V_GEN)PKG_CONFIG_PATH="$(GST_PKG_CONFIG_PATH)" \ + $(INTROSPECTION_COMPILER) \ --includedir=$(srcdir) \ --includedir=$(builddir) \ --includedir=`$(PKG_CONFIG) --variable=girdir gstreamer-0.10` \ From 8049513b88e6fe58c680e81e911e6f20ee29e3d4 Mon Sep 17 00:00:00 2001 From: Koop Mast Date: Sat, 8 Jan 2011 02:16:19 +0000 Subject: [PATCH 131/254] configure: fix bash-ism https://bugzilla.gnome.org/show_bug.cgi?id=638961 --- configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index 6478a6cb75..4477041a8b 100644 --- a/configure.ac +++ b/configure.ac @@ -892,7 +892,7 @@ AC_SUBST(GST_LIBS) dnl LDFLAGS really should only contain flags, not libs - they get added before dnl whatevertarget_LIBS and -L flags here affect the rest of the linking GST_ALL_LDFLAGS="-no-undefined" -if test "x${enable_Bsymbolic}" == "xyes"; then +if test "x${enable_Bsymbolic}" = "xyes"; then GST_ALL_LDFLAGS="$GST_ALL_LDFLAGS -Wl,-Bsymbolic-functions" fi AC_SUBST(GST_ALL_LDFLAGS) From 43553b4dcb78f38d680bb79163cb15fe81d265fd Mon Sep 17 00:00:00 2001 From: Yang Xichuan Date: Mon, 10 Jan 2011 15:55:26 +0800 Subject: [PATCH 132/254] oggdemux: remove outdated comment https://bugzilla.gnome.org/show_bug.cgi?id=639121 --- ext/ogg/gstoggdemux.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/ext/ogg/gstoggdemux.c b/ext/ogg/gstoggdemux.c index 76d179e080..f25dbe30d7 100644 --- a/ext/ogg/gstoggdemux.c +++ b/ext/ogg/gstoggdemux.c @@ -1397,10 +1397,7 @@ gst_ogg_demux_sink_event (GstPad * pad, GstEvent * event) return res; } -/* submit the given buffer to the ogg sync. - * - * Returns the number of bytes submited. - */ +/* submit the given buffer to the ogg sync */ static GstFlowReturn gst_ogg_demux_submit_buffer (GstOggDemux * ogg, GstBuffer * buffer) { From 0753c24439ee4416c08eb0cb000b0ec3a4f9f2eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim-Philipp=20M=C3=BCller?= Date: Mon, 10 Jan 2011 14:53:04 +0000 Subject: [PATCH 133/254] Automatic update of common submodule From 46445ad to ccbaa85 --- common | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common b/common index 46445ad50f..ccbaa85fc5 160000 --- a/common +++ b/common @@ -1 +1 @@ -Subproject commit 46445ad50f184d2640dd205361e0446e9121ba5f +Subproject commit ccbaa85fc58099fb90f1b5a0fad4d92d45500d19 From 7e26ffdf6ccfe197f05af6427791f30337cbac5d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim-Philipp=20M=C3=BCller?= Date: Mon, 10 Jan 2011 16:35:44 +0000 Subject: [PATCH 134/254] Automatic update of common submodule From ccbaa85 to e572c87 --- common | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common b/common index ccbaa85fc5..e572c87c58 160000 --- a/common +++ b/common @@ -1 +1 @@ -Subproject commit ccbaa85fc58099fb90f1b5a0fad4d92d45500d19 +Subproject commit e572c87c582166a6c65edf2a6a0fa73e31a3b04c From e2cc2f4c7708401a630ba6d4241877629d7ecb0a Mon Sep 17 00:00:00 2001 From: Stefan Kost Date: Tue, 11 Jan 2011 15:49:54 +0200 Subject: [PATCH 135/254] Automatic update of common submodule From e572c87 to f94d739 --- common | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common b/common index e572c87c58..f94d739915 160000 --- a/common +++ b/common @@ -1 +1 @@ -Subproject commit e572c87c582166a6c65edf2a6a0fa73e31a3b04c +Subproject commit f94d73991563ea2dcae2218b4847e32998f06816 From 7c55ad4db33f60771d72ab7c109006d45dc335d3 Mon Sep 17 00:00:00 2001 From: Byeong-ryeol Kim Date: Tue, 11 Jan 2011 14:52:51 +0000 Subject: [PATCH 136/254] gobject-introspection: fix issue when gold linker is used Need to pass libgstreamer-0.10 explicitly to linker, since we're calling gst_init(), which in turn is needed because the encoding target get_type() function calls gst_value_register(). https://bugzilla.gnome.org/show_bug.cgi?id=639039 --- gst-libs/gst/pbutils/Makefile.am | 1 + 1 file changed, 1 insertion(+) diff --git a/gst-libs/gst/pbutils/Makefile.am b/gst-libs/gst/pbutils/Makefile.am index 82a10bf795..97df346976 100644 --- a/gst-libs/gst/pbutils/Makefile.am +++ b/gst-libs/gst/pbutils/Makefile.am @@ -85,6 +85,7 @@ GstPbutils-@GST_MAJORMINOR@.gir: $(INTROSPECTION_SCANNER) libgstpbutils-@GST_MAJ --add-include-path=$(srcdir)/../video \ --add-include-path=`$(PKG_CONFIG) --variable=girdir gstreamer-0.10` \ --library=libgstpbutils-0.10.la \ + --library=gstreamer-0.10 \ --include=Gst-0.10 \ --libtool="$(top_builddir)/libtool" \ --pkg gstreamer-0.10 \ From 53893cfba881f573aa398d2660b451fe138bf3e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim-Philipp=20M=C3=BCller?= Date: Tue, 11 Jan 2011 14:59:38 +0000 Subject: [PATCH 137/254] gobject-introspection: pass --library-path as well to make it find the right libgstreamer Makes things work again properly in uninstalled setups (and presumably in installed setups where GStreamer is installed into a non-standard prefix). Requires fixes from core git. https://bugzilla.gnome.org/show_bug.cgi?id=639039 --- gst-libs/gst/pbutils/Makefile.am | 1 + 1 file changed, 1 insertion(+) diff --git a/gst-libs/gst/pbutils/Makefile.am b/gst-libs/gst/pbutils/Makefile.am index 97df346976..2a129c9c93 100644 --- a/gst-libs/gst/pbutils/Makefile.am +++ b/gst-libs/gst/pbutils/Makefile.am @@ -85,6 +85,7 @@ GstPbutils-@GST_MAJORMINOR@.gir: $(INTROSPECTION_SCANNER) libgstpbutils-@GST_MAJ --add-include-path=$(srcdir)/../video \ --add-include-path=`$(PKG_CONFIG) --variable=girdir gstreamer-0.10` \ --library=libgstpbutils-0.10.la \ + --library-path=`$(PKG_CONFIG) --variable=libdir gstreamer-0.10` \ --library=gstreamer-0.10 \ --include=Gst-0.10 \ --libtool="$(top_builddir)/libtool" \ From 74375d258e0e626e6e3f37cbd20220454267f07a Mon Sep 17 00:00:00 2001 From: Bastien Nocera Date: Tue, 11 Jan 2011 14:41:53 +0000 Subject: [PATCH 138/254] examples: allow building with newer GTK+ GtkFunction is gone, and there's no update policies for GtkRanges any more (but the default was continuous anyway, so no need to set it to that mode explicitly). https://bugzilla.gnome.org/show_bug.cgi?id=639215 --- tests/examples/seek/jsseek.c | 7 ++----- tests/examples/seek/scrubby.c | 6 ++---- tests/examples/seek/seek.c | 7 ++----- 3 files changed, 6 insertions(+), 14 deletions(-) diff --git a/tests/examples/seek/jsseek.c b/tests/examples/seek/jsseek.c index fcff009577..d12840baaf 100644 --- a/tests/examples/seek/jsseek.c +++ b/tests/examples/seek/jsseek.c @@ -1408,7 +1408,7 @@ set_update_fill (gboolean active) if (active) { if (fill_id == 0) { fill_id = - g_timeout_add (FILL_INTERVAL, (GtkFunction) update_fill, pipeline); + g_timeout_add (FILL_INTERVAL, (GSourceFunc) update_fill, pipeline); } } else { if (fill_id) { @@ -1427,7 +1427,7 @@ set_update_scale (gboolean active) if (active) { if (update_id == 0) { update_id = - g_timeout_add (UPDATE_INTERVAL, (GtkFunction) update_scale, pipeline); + g_timeout_add (UPDATE_INTERVAL, (GSourceFunc) update_scale, pipeline); } } else { if (update_id) { @@ -2841,8 +2841,6 @@ main (int argc, char **argv) shuttle_hscale = gtk_hscale_new (shuttle_adjustment); gtk_scale_set_digits (GTK_SCALE (shuttle_hscale), 2); gtk_scale_set_value_pos (GTK_SCALE (shuttle_hscale), GTK_POS_TOP); - gtk_range_set_update_policy (GTK_RANGE (shuttle_hscale), - GTK_UPDATE_CONTINUOUS); g_signal_connect (shuttle_hscale, "value_changed", G_CALLBACK (shuttle_value_changed), pipeline); g_signal_connect (shuttle_hscale, "format_value", @@ -2861,7 +2859,6 @@ main (int argc, char **argv) gtk_scale_set_value_pos (GTK_SCALE (hscale), GTK_POS_RIGHT); gtk_range_set_show_fill_level (GTK_RANGE (hscale), TRUE); gtk_range_set_fill_level (GTK_RANGE (hscale), 100.0); - gtk_range_set_update_policy (GTK_RANGE (hscale), GTK_UPDATE_CONTINUOUS); g_signal_connect (hscale, "button_press_event", G_CALLBACK (start_seek), pipeline); diff --git a/tests/examples/seek/scrubby.c b/tests/examples/seek/scrubby.c index aa6b358501..c9a02f42bb 100644 --- a/tests/examples/seek/scrubby.c +++ b/tests/examples/seek/scrubby.c @@ -314,7 +314,7 @@ static gboolean stop_seek (GtkWidget * widget, gpointer user_data) { update_id = - g_timeout_add (UPDATE_INTERVAL, (GtkFunction) update_scale, pipeline); + g_timeout_add (UPDATE_INTERVAL, (GSourceFunc) update_scale, pipeline); GST_DEBUG ("stop seek"); @@ -340,7 +340,7 @@ play_cb (GtkButton * button, gpointer data) gst_element_get_state (pipeline, NULL, NULL, GST_CLOCK_TIME_NONE); gst_element_set_state (pipeline, GST_STATE_PLAYING); update_id = - g_timeout_add (UPDATE_INTERVAL, (GtkFunction) update_scale, pipeline); + g_timeout_add (UPDATE_INTERVAL, (GSourceFunc) update_scale, pipeline); } } @@ -507,13 +507,11 @@ main (int argc, char **argv) 1.0, 1.0)); hscale = gtk_hscale_new (adjustment); gtk_scale_set_digits (GTK_SCALE (hscale), 2); - gtk_range_set_update_policy (GTK_RANGE (hscale), GTK_UPDATE_CONTINUOUS); sadjustment = GTK_ADJUSTMENT (gtk_adjustment_new (1.0, 0.0, 5.0, 0.1, 1.0, 0.0)); shscale = gtk_hscale_new (sadjustment); gtk_scale_set_digits (GTK_SCALE (shscale), 2); - gtk_range_set_update_policy (GTK_RANGE (shscale), GTK_UPDATE_CONTINUOUS); schanged_id = g_signal_connect (shscale, "value_changed", G_CALLBACK (speed_cb), diff --git a/tests/examples/seek/seek.c b/tests/examples/seek/seek.c index d1957385d3..b82a851f1c 100644 --- a/tests/examples/seek/seek.c +++ b/tests/examples/seek/seek.c @@ -1398,7 +1398,7 @@ set_update_fill (gboolean active) if (active) { if (fill_id == 0) { fill_id = - g_timeout_add (FILL_INTERVAL, (GtkFunction) update_fill, pipeline); + g_timeout_add (FILL_INTERVAL, (GSourceFunc) update_fill, pipeline); } } else { if (fill_id) { @@ -1417,7 +1417,7 @@ set_update_scale (gboolean active) if (active) { if (update_id == 0) { update_id = - g_timeout_add (UPDATE_INTERVAL, (GtkFunction) update_scale, pipeline); + g_timeout_add (UPDATE_INTERVAL, (GSourceFunc) update_scale, pipeline); } } else { if (update_id) { @@ -2787,8 +2787,6 @@ main (int argc, char **argv) shuttle_hscale = gtk_hscale_new (shuttle_adjustment); gtk_scale_set_digits (GTK_SCALE (shuttle_hscale), 2); gtk_scale_set_value_pos (GTK_SCALE (shuttle_hscale), GTK_POS_TOP); - gtk_range_set_update_policy (GTK_RANGE (shuttle_hscale), - GTK_UPDATE_CONTINUOUS); g_signal_connect (shuttle_hscale, "value_changed", G_CALLBACK (shuttle_value_changed), pipeline); g_signal_connect (shuttle_hscale, "format_value", @@ -2807,7 +2805,6 @@ main (int argc, char **argv) gtk_scale_set_value_pos (GTK_SCALE (hscale), GTK_POS_RIGHT); gtk_range_set_show_fill_level (GTK_RANGE (hscale), TRUE); gtk_range_set_fill_level (GTK_RANGE (hscale), N_GRAD); - gtk_range_set_update_policy (GTK_RANGE (hscale), GTK_UPDATE_CONTINUOUS); g_signal_connect (hscale, "button_press_event", G_CALLBACK (start_seek), pipeline); From 3647af24f1a6ab03185875dc7702353d2986e311 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim-Philipp=20M=C3=BCller?= Date: Tue, 11 Jan 2011 18:59:39 +0000 Subject: [PATCH 139/254] po: update translations --- po/da.po | 130 ++++++++++++++++++++++++++-------------------------- po/gl.po | 85 +++++++++++++++++----------------- po/pt_BR.po | 81 +++++++++++++++++--------------- 3 files changed, 151 insertions(+), 145 deletions(-) diff --git a/po/da.po b/po/da.po index 23d1fa013f..1a4278e44b 100644 --- a/po/da.po +++ b/po/da.po @@ -3,16 +3,38 @@ # This file is distributed under the same license as the gst-plugins-base package. # # Mogens Jaeger , 2007. -# Joe Hansen , 2009, 2010. +# Joe Hansen , 2009, 2010, 2011. # # capture -> optage +# gain -> forstærkning # shutter -> lukketid +# +# Hej Torben, de fleste af dem her er vist afklaringen af hvorvidt det er et +# udsagnsord eller navneord. Har du været i koden og kigge? Ville godt nok +# være ked af at rette alle dem her, for så bare at »opdage« at de var gode nok, +# Nu har jeg haft src/gst-plugins-base/tags.c åben i en nylig version +# (gst-blugins-base version 0.10.31), og jeg tror ikke strengene bruges, +# mens der sker en aktiv handling. +# I filen ser det således ud: +# /* photography tags */ +# gst_tag_register (GST_TAG_CAPTURING_SHUTTER_SPEED, +# GST_TAG_FLAG_META, +# GST_TYPE_FRACTION, +# _("capturing shutter speed"), +# _("Shutter speed used when capturing an image, +# in seconds"), NULL); +# Dette kan du se som en indgang i en tabel over strenge. Den første korte +# streng er navnet på mærket, den anden er en beskrivelse af samme mærke. +# Strengene er altså betegnelser/navneord. +# +# brugt kunne erstattes med der blev brugt (men skal så rettes igennem for alle). +# msgid "" msgstr "" -"Project-Id-Version: gst-plugins-base 0.10.30.3\n" +"Project-Id-Version: gst-plugins-base 0.10.31.2\n" "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/\n" -"POT-Creation-Date: 2010-11-01 16:36+0000\n" -"PO-Revision-Date: 2010-10-27 16:38+0100\n" +"POT-Creation-Date: 2011-01-11 18:58+0000\n" +"PO-Revision-Date: 2011-01-07 16:38+0100\n" "Last-Translator: Joe Hansen \n" "Language-Team: Danish \n" "Language: da\n" @@ -292,108 +314,119 @@ msgstr "spor TRM-id" msgid "MusicBrainz TRM ID" msgstr "MusicBrainz TRM-id" +# nb ikke handling men navneord. +# "optagelukkertid" / "optagerlukkertid" +# Mogens: shutter speed = lukkerhastighed msgid "capturing shutter speed" -msgstr "optager hastighed for lukketid" +msgstr "optagerlukkertid" msgid "Shutter speed used when capturing an image, in seconds" -msgstr "Lukketidshastighed brug når et billede optages, i sekunder" +msgstr "Lukketidshastighed brugt når et billede optages, i sekunder" msgid "capturing focal ratio" -msgstr "optager brændforhold" +msgstr "brændforhold for optager" msgid "Focal ratio (f-number) used when capturing the image" msgstr "Brændforhold (f-nummer) brugt under optagelse af billedet" msgid "capturing focal length" -msgstr "optager brændvidde" +msgstr "brændvidde for optager" msgid "Focal length of the lens used capturing the image, in mm" -msgstr "Brændvidde på linser brugt under optagelse af billedet, i mm" +msgstr "Brændvidde på linse brugt under optagelse af billedet, i mm" msgid "capturing digital zoom ratio" -msgstr "optager digitalt zoomforhold" +msgstr "digitalt zoomforhold for optager" msgid "Digital zoom ratio used when capturing an image" msgstr "Digitalt zoomforhold brugt under optagelse af et billede" msgid "capturing iso speed" -msgstr "optager iso-hastighed" +msgstr "iso-hastighed for optager" msgid "The ISO speed used when capturing an image" msgstr "ISO-hastigheden brugt under optagelse af et billede" msgid "capturing exposure program" -msgstr "optager belysningsprogram" +msgstr "belysningsprogram for optagelse" msgid "The exposure program used when capturing an image" msgstr "Belysningsprogrammet brugt under optagelse af et billede" msgid "capturing exposure mode" -msgstr "optager belysningstilstand" +msgstr "belysningstilstand for optagelse" msgid "The exposure mode used when capturing an image" msgstr "Belysningstilstanden brugt under optagelse af et billede" +# "optagelsestype for optagelse af scene" / +# "optagelsestype for sceneoptagelse" / +# "sceneoptagelsestype for optager" / +# "optageroptagelsestype for scene" +# De to første rammer vist forlægget mest præcist. msgid "capturing scene capture type" -msgstr "optager optagelsestype for scene" +msgstr "optagelsestype for optagelse af scene" msgid "The scene capture mode used when capturing an image" -msgstr "Optagelsestilstanden for scene under optagelse af et billede" +msgstr "Sceneoptagelsestilstanden brugt da billedet blev optaget" +# "justering af optageforstærkning" / +# "justering af optagerforstærkning" msgid "capturing gain adjustment" -msgstr "optager forøgelsesjustering" +msgstr "justering af optageforstærkning" msgid "The overall gain adjustment applied on an image" -msgstr "Den samlede forøgelsesjustering brugt på et billede" +msgstr "Den samlede optageforstærkning brugt på et billede" msgid "capturing white balance" -msgstr "optager hvidbalance" +msgstr "hvidbalance for optagelse" msgid "The white balance mode set when capturing an image" msgstr "Hvidbalancetilstanden angivet under optagelse af et billede" +# kontrast for optagelse msgid "capturing contrast" -msgstr "optager kontrast" +msgstr "optagekontrast" +# Jeg tror "direction" skal oversættes til "indstilling af" +# (sml. "director" ~ "instruction" ~ "instruering" ~ "indstilling" msgid "The direction of contrast processing applied when capturing an image" -msgstr "Retningen på kontrastprocessen brugt under optagelse af et billede" +msgstr "Indstilling af kontrastprocessen brugt under optagelse af et billede" msgid "capturing saturation" -msgstr "optager farvemætning" +msgstr "farvemætning for optagelse" msgid "The direction of saturation processing applied when capturing an image" msgstr "" -"Retningen på farvemætningsprocessen brugt under optagelse af et billede" +"Indstillingen af farvemætningsprocessen brugt under optagelse af et billede" msgid "capturing sharpness" -msgstr "optager skarphed" +msgstr "optageskarphed" msgid "The direction of sharpness processing applied when capturing an image" -msgstr "Retningen på skarphedsprocessen brugt under optagelse af et billede" +msgstr "skarphedindstilling brugt under optagelse af et billede" msgid "capturing flash fired" -msgstr "optager blitzen der blev brugt" +msgstr "optagerblitzen der blev brugt" msgid "If the flash fired while capturing an image" msgstr "Hvorvidt blitzen blev brugt under optagelse af et billede" msgid "capturing flash mode" -msgstr "optager blitztilstand" +msgstr "optagererens blitztilstand" msgid "The selected flash mode while capturing an image" msgstr "Den valgte blitztilstand under optagelse af et billede" msgid "capturing metering mode" -msgstr "optager måletilstanden" +msgstr "optagerens måletilstand" msgid "" "The metering mode used while determining exposure for capturing an image" -msgstr "" -"Måletilstanden brugt under bestemmelse af belysning under optagelse af et " -"billede" +msgstr "Måletilstanden brugt da optagelsens belysning skulle bestemmes" msgid "capturing source" -msgstr "optager kilde" +msgstr "optagekilde" msgid "The source or type of device used for the capture" msgstr "Kilden eller typen af enhed brugt under optagelsen" @@ -608,38 +641,3 @@ msgstr "Enheden \"%s\" er allerede i brug." #, c-format msgid "Could not open device \"%s\" for reading and writing." msgstr "Kunne ikke tilgå enheden \"%s\"." - -#~ msgid "Can't display both text subtitles and subpictures." -#~ msgstr "Kan ikke vise både undertekster og underbilleder." - -#~ msgid "No Temp directory specified." -#~ msgstr "Ingen midlertidig mappe angivet." - -#~ msgid "Could not create temp file \"%s\"." -#~ msgstr "Kunne ikke oprette midlertidig fil \"%s\"." - -#~ msgid "Could not open file \"%s\" for reading." -#~ msgstr "Kunne ikke åbne fil \"%s\" til læsning." - -#~ msgid "Internal data flow error." -#~ msgstr "Intern datastrømsfejl." - -# eller oprette (evt. sammensat). -# beholdt danne og ikke sammensat da tillægsord. -#~ msgid "Could not create \"decodebin2\" element." -#~ msgstr "Kunne ikke danne et \"decodebin2\" element." - -#~ msgid "Could not create \"queue2\" element." -#~ msgstr "Kunne ikke danne et \"queue2\" element." - -#~ msgid "Could not create \"typefind\" element." -#~ msgstr "Kunne ikke danne et \"typefind\" element." - -#~ msgid "No file name specified." -#~ msgstr "Intet filnavn angivet." - -#~ msgid "artist sortname" -#~ msgstr "kunstner sorteringsnavn" - -#~ msgid "MusicBrainz artist sortname" -#~ msgstr "MusicBrainz kunstner sorteringsnavn" diff --git a/po/gl.po b/po/gl.po index 97ef2dcb68..47676d4c05 100644 --- a/po/gl.po +++ b/po/gl.po @@ -1,21 +1,21 @@ # SOME DESCRIPTIVE TITLE. # Copyright (C) 2010 Fran Dieguez # This file is distributed under the same license as the gst-plugins-base package. -# Fran Diéguez , 2010. +# Fran Diéguez , 2010, 2011. # msgid "" msgstr "" -"Project-Id-Version: gst-plugins-base 0.10.29.2\n" +"Project-Id-Version: gst-plugins-base 0.10.31.2\n" "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/\n" -"POT-Creation-Date: 2010-10-16 01:03+0100\n" -"PO-Revision-Date: 2010-08-19 15:01+0200\n" +"POT-Creation-Date: 2011-01-11 18:58+0000\n" +"PO-Revision-Date: 2011-01-09 21:20+0100\n" "Last-Translator: Fran Diéguez \n" "Language-Team: Galician \n" "Language: gl\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=2; plural=(n!=1);\\\n" +"Plural-Forms: nplurals=2; plural=(n!=1);\n" "X-Poedit-Language: galego\n" msgid "Master" @@ -291,119 +291,120 @@ msgid "MusicBrainz TRM ID" msgstr "ID TRM en MusicBrainz" msgid "capturing shutter speed" -msgstr "" +msgstr "velocidade do obturador da toma" msgid "Shutter speed used when capturing an image, in seconds" -msgstr "" +msgstr "Velocidade do obturador usada ao tomar unha imaxe, en segundos" msgid "capturing focal ratio" -msgstr "" +msgstr "taxa focal da toma" msgid "Focal ratio (f-number) used when capturing the image" -msgstr "" +msgstr "Taxa focal (número-f) usada ao tomar a imaxe" msgid "capturing focal length" -msgstr "" +msgstr "lonxitude focal da toma" msgid "Focal length of the lens used capturing the image, in mm" -msgstr "" +msgstr "Lonxitude focal da lente usada ao tomar a imaxe, en mm" msgid "capturing digital zoom ratio" -msgstr "" +msgstr "taxa de ampliación dixital da toma" msgid "Digital zoom ratio used when capturing an image" -msgstr "" +msgstr "Taxa de ampliación dixital usada ao tomar unha imaxe" msgid "capturing iso speed" -msgstr "" +msgstr "velocidade ISO da toma" msgid "The ISO speed used when capturing an image" -msgstr "" +msgstr "A velocidade de captura ISO usada ao tomar unha imaxe" msgid "capturing exposure program" -msgstr "" +msgstr "programa de exposición da toma" msgid "The exposure program used when capturing an image" -msgstr "" +msgstr "O programa de exposición usado ao tomar unha imaxe" msgid "capturing exposure mode" -msgstr "" +msgstr "modo de exposición da toma" msgid "The exposure mode used when capturing an image" -msgstr "" +msgstr "O modo de exposición usado ao tomar unha imaxe" msgid "capturing scene capture type" -msgstr "" +msgstr "tipo de escena usado na toma" msgid "The scene capture mode used when capturing an image" -msgstr "" +msgstr "O modo de captura usado ao tomar unha imaxe" msgid "capturing gain adjustment" -msgstr "" +msgstr "axuste de ganancia da toma" msgid "The overall gain adjustment applied on an image" -msgstr "" +msgstr "O axuste xeral de ganancia aplicado nunha imaxe" msgid "capturing white balance" -msgstr "" +msgstr "balance de brancos da toma" msgid "The white balance mode set when capturing an image" -msgstr "" +msgstr "O modo de balance de brancos usado ao tomar unha imaxe" msgid "capturing contrast" -msgstr "" +msgstr "contraste da toma" msgid "The direction of contrast processing applied when capturing an image" -msgstr "" +msgstr "A dirección de contraste procesada aplicada ao tomar unha imaxe" msgid "capturing saturation" -msgstr "" +msgstr "saturación da toma" msgid "The direction of saturation processing applied when capturing an image" -msgstr "" +msgstr "A dirección de saturación procesada aplicada ao tomar unha imaxe" msgid "capturing sharpness" -msgstr "" +msgstr "nitidez da toma" msgid "The direction of sharpness processing applied when capturing an image" -msgstr "" +msgstr "A dirección de nitidez procesada aplicada ao tomar unha imaxe" msgid "capturing flash fired" -msgstr "" +msgstr "disparo de flash da toma" msgid "If the flash fired while capturing an image" -msgstr "" +msgstr "Se o flash se disparou ao capturar unha imaxe" msgid "capturing flash mode" -msgstr "" +msgstr "modo de flash da toma" msgid "The selected flash mode while capturing an image" -msgstr "" +msgstr "O modo de flash seleccionado ao tomar unha imaxe" msgid "capturing metering mode" -msgstr "" +msgstr "modo de medición da toma" msgid "" "The metering mode used while determining exposure for capturing an image" msgstr "" +"O modo de medición usado ao determinar a exposición ao tomar unha imaxe" msgid "capturing source" -msgstr "" +msgstr "orixe da toma" msgid "The source or type of device used for the capture" -msgstr "" +msgstr "A orixe ou tipo de dispositivo usado para a toma" msgid "image horizontal ppi" -msgstr "" +msgstr "ppi horizontal da imaxe" msgid "Media (image/video) intended horizontal pixel density in ppi" -msgstr "" +msgstr "Densidade horizontal de píxeles, en ppi, do medio (imaxe ou vídeo)" msgid "image vertical ppi" -msgstr "" +msgstr "ppi vertical da imaxe" msgid "Media (image/video) intended vertical pixel density in ppi" -msgstr "" +msgstr "Densidade vertical de píxeles, en ppi, do medio (imaxe ou vídeo)" msgid "This CD has no audio tracks" msgstr "Este CD non contén pistas de son" diff --git a/po/pt_BR.po b/po/pt_BR.po index f38d3e9f9e..30a86ba8a9 100644 --- a/po/pt_BR.po +++ b/po/pt_BR.po @@ -1,16 +1,16 @@ # Brazilian Portuguese translation of gst-plugins-base. -# Copyright (C) 2008-2010 Free Software Foundation, Inc. +# Copyright (C) 2008-2011 Free Software Foundation, Inc. # This file is distributed under the same license as the gst-plugins-base package. -# Fabrício Godoy , 2008-2010. +# Fabrício Godoy , 2008-2011. # # PCM -> PCM # msgid "" msgstr "" -"Project-Id-Version: gst-plugins-base-0.10.29.2\n" +"Project-Id-Version: gst-plugins-base-0.10.31.2\n" "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/\n" -"POT-Creation-Date: 2010-10-16 01:03+0100\n" -"PO-Revision-Date: 2010-06-28 20:25-0300\n" +"POT-Creation-Date: 2011-01-11 18:58+0000\n" +"PO-Revision-Date: 2011-01-08 01:02-0300\n" "Last-Translator: Fabrício Godoy \n" "Language-Team: Brazilian Portuguese \n" "Language: pt_BR\n" @@ -292,119 +292,126 @@ msgid "MusicBrainz TRM ID" msgstr "ident. da trilha TRM no MusicBrainz" msgid "capturing shutter speed" -msgstr "" +msgstr "velocidade do obturador ao capturar" msgid "Shutter speed used when capturing an image, in seconds" -msgstr "" +msgstr "Velocidade do obturador usada ao capturar uma imagem, em segundos" msgid "capturing focal ratio" -msgstr "" +msgstr "taxa focal ao capturar" msgid "Focal ratio (f-number) used when capturing the image" -msgstr "" +msgstr "Taxa focal usada ao capturar a imagem, f-number" msgid "capturing focal length" -msgstr "" +msgstr "distância focal ao capturar" msgid "Focal length of the lens used capturing the image, in mm" -msgstr "" +msgstr "Distância focal das lentes usada ao capturar a imagem, em mm" msgid "capturing digital zoom ratio" -msgstr "" +msgstr "taxa de zoom digital ao capturar" msgid "Digital zoom ratio used when capturing an image" -msgstr "" +msgstr "Taxa de zoom digital usada ao capturar uma imagem" msgid "capturing iso speed" -msgstr "" +msgstr "velocidade ISO ao capturar" msgid "The ISO speed used when capturing an image" -msgstr "" +msgstr "A velocidade ISO usada ao capturar uma imagem" msgid "capturing exposure program" -msgstr "" +msgstr "programa de exposição ao capturar" msgid "The exposure program used when capturing an image" -msgstr "" +msgstr "O programa de exposição usado ao capturar uma imagem" msgid "capturing exposure mode" -msgstr "" +msgstr "modo de exposição ao capturar" msgid "The exposure mode used when capturing an image" -msgstr "" +msgstr "O modo de exposição usado ao capturar uma imagem" msgid "capturing scene capture type" -msgstr "" +msgstr "tipo de captura de cena ao capturar" msgid "The scene capture mode used when capturing an image" -msgstr "" +msgstr "O modo de captura de cena usado ao capturar uma imagem" msgid "capturing gain adjustment" -msgstr "" +msgstr "ajuste de ganho ao capturar" msgid "The overall gain adjustment applied on an image" -msgstr "" +msgstr "O ajuste de ganho geral aplicado na imagem" msgid "capturing white balance" -msgstr "" +msgstr "balanço de branco ao capturar" msgid "The white balance mode set when capturing an image" -msgstr "" +msgstr "O modo de balanço de branco definido ao capturar uma imagem" msgid "capturing contrast" -msgstr "" +msgstr "contraste ao capturar" msgid "The direction of contrast processing applied when capturing an image" msgstr "" +"O procedimento de processamento de contraste aplicado ao capturar uma imagem" msgid "capturing saturation" -msgstr "" +msgstr "saturação ao capturar" msgid "The direction of saturation processing applied when capturing an image" msgstr "" +"O procedimento de processamento de saturação aplicado ao capturar uma imagem" msgid "capturing sharpness" -msgstr "" +msgstr "nitidez ao capturar" msgid "The direction of sharpness processing applied when capturing an image" msgstr "" +"O procedimento de processamento de nitidez aplicado ao capturar uma imagem" msgid "capturing flash fired" -msgstr "" +msgstr "disparar flash ao capturar" msgid "If the flash fired while capturing an image" -msgstr "" +msgstr "Define se o flash é disparado ao capturar uma imagem" msgid "capturing flash mode" -msgstr "" +msgstr "modo de flash ao capturar" msgid "The selected flash mode while capturing an image" -msgstr "" +msgstr "O modo de flash selecionado ao capturar uma imagem" msgid "capturing metering mode" -msgstr "" +msgstr "modo de medição de luz ao capturar" msgid "" "The metering mode used while determining exposure for capturing an image" msgstr "" +"O modo de medição de luz usado ao determinar a exposição para captura de uma " +"imagem" msgid "capturing source" -msgstr "" +msgstr "fonte ao capturar" msgid "The source or type of device used for the capture" -msgstr "" +msgstr "A fonte ou tipo de dispositivo usado para a captura" msgid "image horizontal ppi" -msgstr "" +msgstr "PPI horizontal da imagem" msgid "Media (image/video) intended horizontal pixel density in ppi" msgstr "" +"Densidade de pixels horizontais desejado para a mídia (imagem/vídeo), em PPI" msgid "image vertical ppi" -msgstr "" +msgstr "PPI vertical da imagem" msgid "Media (image/video) intended vertical pixel density in ppi" msgstr "" +"Densidade de pixels verticais desejado para a mídia (imagem/vídeo), em PPI" msgid "This CD has no audio tracks" msgstr "Este CD não tem trilhas de áudio" From a6fd7c4675fe13a5e0a6de2b241bb85e9b523b37 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim-Philipp=20M=C3=BCller?= Date: Tue, 11 Jan 2011 19:19:50 +0000 Subject: [PATCH 140/254] 0.10.31.3 pre-release --- configure.ac | 4 ++-- docs/plugins/gst-plugins-base-plugins.prerequisites | 2 +- docs/plugins/inspect/plugin-adder.xml | 2 +- docs/plugins/inspect/plugin-alsa.xml | 2 +- docs/plugins/inspect/plugin-app.xml | 2 +- docs/plugins/inspect/plugin-audioconvert.xml | 2 +- docs/plugins/inspect/plugin-audiorate.xml | 2 +- docs/plugins/inspect/plugin-audioresample.xml | 2 +- docs/plugins/inspect/plugin-audiotestsrc.xml | 2 +- docs/plugins/inspect/plugin-cdparanoia.xml | 2 +- docs/plugins/inspect/plugin-decodebin.xml | 2 +- docs/plugins/inspect/plugin-encoding.xml | 2 +- docs/plugins/inspect/plugin-ffmpegcolorspace.xml | 2 +- docs/plugins/inspect/plugin-gdp.xml | 2 +- docs/plugins/inspect/plugin-gio.xml | 2 +- docs/plugins/inspect/plugin-gnomevfs.xml | 2 +- docs/plugins/inspect/plugin-libvisual.xml | 2 +- docs/plugins/inspect/plugin-ogg.xml | 2 +- docs/plugins/inspect/plugin-pango.xml | 2 +- docs/plugins/inspect/plugin-playback.xml | 2 +- docs/plugins/inspect/plugin-subparse.xml | 2 +- docs/plugins/inspect/plugin-tcp.xml | 2 +- docs/plugins/inspect/plugin-theora.xml | 2 +- docs/plugins/inspect/plugin-typefindfunctions.xml | 2 +- docs/plugins/inspect/plugin-uridecodebin.xml | 2 +- docs/plugins/inspect/plugin-video4linux.xml | 2 +- docs/plugins/inspect/plugin-videorate.xml | 2 +- docs/plugins/inspect/plugin-videoscale.xml | 2 +- docs/plugins/inspect/plugin-videotestsrc.xml | 2 +- docs/plugins/inspect/plugin-volume.xml | 2 +- docs/plugins/inspect/plugin-vorbis.xml | 2 +- docs/plugins/inspect/plugin-ximagesink.xml | 2 +- docs/plugins/inspect/plugin-xvimagesink.xml | 2 +- win32/common/_stdint.h | 2 +- win32/common/config.h | 8 ++++---- 35 files changed, 39 insertions(+), 39 deletions(-) diff --git a/configure.ac b/configure.ac index 4477041a8b..3a4f8f48d9 100644 --- a/configure.ac +++ b/configure.ac @@ -5,7 +5,7 @@ dnl please read gstreamer/docs/random/autotools before changing this file dnl initialize autoconf dnl releases only do -Wall, git and prerelease does -Werror too dnl use a three digit version number for releases, and four for git/prerelease -AC_INIT(GStreamer Base Plug-ins, 0.10.31.2, +AC_INIT(GStreamer Base Plug-ins, 0.10.31.3, http://bugzilla.gnome.org/enter_bug.cgi?product=GStreamer, gst-plugins-base) @@ -60,7 +60,7 @@ AC_LIBTOOL_WIN32_DLL AM_PROG_LIBTOOL dnl *** required versions of GStreamer stuff *** -GST_REQ=0.10.31.2 +GST_REQ=0.10.31.3 dnl *** autotools stuff **** diff --git a/docs/plugins/gst-plugins-base-plugins.prerequisites b/docs/plugins/gst-plugins-base-plugins.prerequisites index 6a9de60c7d..48604c0da2 100644 --- a/docs/plugins/gst-plugins-base-plugins.prerequisites +++ b/docs/plugins/gst-plugins-base-plugins.prerequisites @@ -6,5 +6,5 @@ GstTuner GstImplementsInterface GstElement GstXOverlay GstImplementsInterface GstElement GstColorBalance GstImplementsInterface GstElement GstStreamVolume GObject -GFile GObject PangoCairoFontMap PangoFontMap +GFile GObject diff --git a/docs/plugins/inspect/plugin-adder.xml b/docs/plugins/inspect/plugin-adder.xml index 5eba37e6b5..e177535653 100644 --- a/docs/plugins/inspect/plugin-adder.xml +++ b/docs/plugins/inspect/plugin-adder.xml @@ -3,7 +3,7 @@ Adds multiple streams ../../gst/adder/.libs/libgstadder.so libgstadder.so - 0.10.31.2 + 0.10.31.3 LGPL gst-plugins-base GStreamer Base Plug-ins prerelease diff --git a/docs/plugins/inspect/plugin-alsa.xml b/docs/plugins/inspect/plugin-alsa.xml index de3f1bea28..b2b1d251c2 100644 --- a/docs/plugins/inspect/plugin-alsa.xml +++ b/docs/plugins/inspect/plugin-alsa.xml @@ -3,7 +3,7 @@ ALSA plugin library ../../ext/alsa/.libs/libgstalsa.so libgstalsa.so - 0.10.31.2 + 0.10.31.3 LGPL gst-plugins-base GStreamer Base Plug-ins prerelease diff --git a/docs/plugins/inspect/plugin-app.xml b/docs/plugins/inspect/plugin-app.xml index 74d711cff7..037ea532ab 100644 --- a/docs/plugins/inspect/plugin-app.xml +++ b/docs/plugins/inspect/plugin-app.xml @@ -3,7 +3,7 @@ Elements used to communicate with applications ../../gst/app/.libs/libgstapp.so libgstapp.so - 0.10.31.2 + 0.10.31.3 LGPL gst-plugins-base GStreamer Base Plug-ins prerelease diff --git a/docs/plugins/inspect/plugin-audioconvert.xml b/docs/plugins/inspect/plugin-audioconvert.xml index 34c1106df6..74c50b5834 100644 --- a/docs/plugins/inspect/plugin-audioconvert.xml +++ b/docs/plugins/inspect/plugin-audioconvert.xml @@ -3,7 +3,7 @@ Convert audio to different formats ../../gst/audioconvert/.libs/libgstaudioconvert.so libgstaudioconvert.so - 0.10.31.2 + 0.10.31.3 LGPL gst-plugins-base GStreamer Base Plug-ins prerelease diff --git a/docs/plugins/inspect/plugin-audiorate.xml b/docs/plugins/inspect/plugin-audiorate.xml index db1a40c5cb..e04d22a46f 100644 --- a/docs/plugins/inspect/plugin-audiorate.xml +++ b/docs/plugins/inspect/plugin-audiorate.xml @@ -3,7 +3,7 @@ Adjusts audio frames ../../gst/audiorate/.libs/libgstaudiorate.so libgstaudiorate.so - 0.10.31.2 + 0.10.31.3 LGPL gst-plugins-base GStreamer Base Plug-ins prerelease diff --git a/docs/plugins/inspect/plugin-audioresample.xml b/docs/plugins/inspect/plugin-audioresample.xml index 7f45b1331c..da43623dd8 100644 --- a/docs/plugins/inspect/plugin-audioresample.xml +++ b/docs/plugins/inspect/plugin-audioresample.xml @@ -3,7 +3,7 @@ Resamples audio ../../gst/audioresample/.libs/libgstaudioresample.so libgstaudioresample.so - 0.10.31.2 + 0.10.31.3 LGPL gst-plugins-base GStreamer Base Plug-ins prerelease diff --git a/docs/plugins/inspect/plugin-audiotestsrc.xml b/docs/plugins/inspect/plugin-audiotestsrc.xml index cfce475e4c..1ced48ac0d 100644 --- a/docs/plugins/inspect/plugin-audiotestsrc.xml +++ b/docs/plugins/inspect/plugin-audiotestsrc.xml @@ -3,7 +3,7 @@ Creates audio test signals of given frequency and volume ../../gst/audiotestsrc/.libs/libgstaudiotestsrc.so libgstaudiotestsrc.so - 0.10.31.2 + 0.10.31.3 LGPL gst-plugins-base GStreamer Base Plug-ins prerelease diff --git a/docs/plugins/inspect/plugin-cdparanoia.xml b/docs/plugins/inspect/plugin-cdparanoia.xml index d6b900bac8..7cb62e515b 100644 --- a/docs/plugins/inspect/plugin-cdparanoia.xml +++ b/docs/plugins/inspect/plugin-cdparanoia.xml @@ -3,7 +3,7 @@ Read audio from CD in paranoid mode ../../ext/cdparanoia/.libs/libgstcdparanoia.so libgstcdparanoia.so - 0.10.31.2 + 0.10.31.3 LGPL gst-plugins-base GStreamer Base Plug-ins prerelease diff --git a/docs/plugins/inspect/plugin-decodebin.xml b/docs/plugins/inspect/plugin-decodebin.xml index 1a4af7336b..55d91e0aa7 100644 --- a/docs/plugins/inspect/plugin-decodebin.xml +++ b/docs/plugins/inspect/plugin-decodebin.xml @@ -3,7 +3,7 @@ decoder bin ../../gst/playback/.libs/libgstdecodebin.so libgstdecodebin.so - 0.10.31.2 + 0.10.31.3 LGPL gst-plugins-base GStreamer Base Plug-ins prerelease diff --git a/docs/plugins/inspect/plugin-encoding.xml b/docs/plugins/inspect/plugin-encoding.xml index 9d2298a51f..e3447a27f2 100644 --- a/docs/plugins/inspect/plugin-encoding.xml +++ b/docs/plugins/inspect/plugin-encoding.xml @@ -3,7 +3,7 @@ various encoding-related elements ../../gst/encoding/.libs/libgstencodebin.so libgstencodebin.so - 0.10.31.2 + 0.10.31.3 LGPL gst-plugins-base GStreamer Base Plug-ins prerelease diff --git a/docs/plugins/inspect/plugin-ffmpegcolorspace.xml b/docs/plugins/inspect/plugin-ffmpegcolorspace.xml index fede4f677e..f25f9f89a5 100644 --- a/docs/plugins/inspect/plugin-ffmpegcolorspace.xml +++ b/docs/plugins/inspect/plugin-ffmpegcolorspace.xml @@ -3,7 +3,7 @@ colorspace conversion copied from FFMpeg 0.4.9-pre1 ../../gst/ffmpegcolorspace/.libs/libgstffmpegcolorspace.so libgstffmpegcolorspace.so - 0.10.31.2 + 0.10.31.3 LGPL gst-plugins-base FFMpeg diff --git a/docs/plugins/inspect/plugin-gdp.xml b/docs/plugins/inspect/plugin-gdp.xml index 73753f178c..16c9a25f05 100644 --- a/docs/plugins/inspect/plugin-gdp.xml +++ b/docs/plugins/inspect/plugin-gdp.xml @@ -3,7 +3,7 @@ Payload/depayload GDP packets ../../gst/gdp/.libs/libgstgdp.so libgstgdp.so - 0.10.31.2 + 0.10.31.3 LGPL gst-plugins-base GStreamer Base Plug-ins prerelease diff --git a/docs/plugins/inspect/plugin-gio.xml b/docs/plugins/inspect/plugin-gio.xml index 756ecaca22..ceb93c6eda 100644 --- a/docs/plugins/inspect/plugin-gio.xml +++ b/docs/plugins/inspect/plugin-gio.xml @@ -3,7 +3,7 @@ GIO elements ../../ext/gio/.libs/libgstgio.so libgstgio.so - 0.10.31.2 + 0.10.31.3 LGPL gst-plugins-base GStreamer Base Plug-ins prerelease diff --git a/docs/plugins/inspect/plugin-gnomevfs.xml b/docs/plugins/inspect/plugin-gnomevfs.xml index 265aab3ea3..622160e257 100644 --- a/docs/plugins/inspect/plugin-gnomevfs.xml +++ b/docs/plugins/inspect/plugin-gnomevfs.xml @@ -3,7 +3,7 @@ elements to read from and write to Gnome-VFS uri's ../../ext/gnomevfs/.libs/libgstgnomevfs.so libgstgnomevfs.so - 0.10.31.2 + 0.10.31.3 LGPL gst-plugins-base GStreamer Base Plug-ins prerelease diff --git a/docs/plugins/inspect/plugin-libvisual.xml b/docs/plugins/inspect/plugin-libvisual.xml index 27dacee067..c24b43050f 100644 --- a/docs/plugins/inspect/plugin-libvisual.xml +++ b/docs/plugins/inspect/plugin-libvisual.xml @@ -3,7 +3,7 @@ libvisual visualization plugins ../../ext/libvisual/.libs/libgstlibvisual.so libgstlibvisual.so - 0.10.31.2 + 0.10.31.3 LGPL gst-plugins-base GStreamer Base Plug-ins prerelease diff --git a/docs/plugins/inspect/plugin-ogg.xml b/docs/plugins/inspect/plugin-ogg.xml index f0cb513a42..cf1ff06f6b 100644 --- a/docs/plugins/inspect/plugin-ogg.xml +++ b/docs/plugins/inspect/plugin-ogg.xml @@ -3,7 +3,7 @@ ogg stream manipulation (info about ogg: http://xiph.org) ../../ext/ogg/.libs/libgstogg.so libgstogg.so - 0.10.31.2 + 0.10.31.3 LGPL gst-plugins-base GStreamer Base Plug-ins prerelease diff --git a/docs/plugins/inspect/plugin-pango.xml b/docs/plugins/inspect/plugin-pango.xml index b64ed3d8a2..1aabc0b397 100644 --- a/docs/plugins/inspect/plugin-pango.xml +++ b/docs/plugins/inspect/plugin-pango.xml @@ -3,7 +3,7 @@ Pango-based text rendering and overlay ../../ext/pango/.libs/libgstpango.so libgstpango.so - 0.10.31.2 + 0.10.31.3 LGPL gst-plugins-base GStreamer Base Plug-ins prerelease diff --git a/docs/plugins/inspect/plugin-playback.xml b/docs/plugins/inspect/plugin-playback.xml index edfc232b17..6a583e77c2 100644 --- a/docs/plugins/inspect/plugin-playback.xml +++ b/docs/plugins/inspect/plugin-playback.xml @@ -3,7 +3,7 @@ various playback elements ../../gst/playback/.libs/libgstplaybin.so libgstplaybin.so - 0.10.31.2 + 0.10.31.3 LGPL gst-plugins-base GStreamer Base Plug-ins prerelease diff --git a/docs/plugins/inspect/plugin-subparse.xml b/docs/plugins/inspect/plugin-subparse.xml index 6b9485befe..bf03318514 100644 --- a/docs/plugins/inspect/plugin-subparse.xml +++ b/docs/plugins/inspect/plugin-subparse.xml @@ -3,7 +3,7 @@ Subtitle parsing ../../gst/subparse/.libs/libgstsubparse.so libgstsubparse.so - 0.10.31.2 + 0.10.31.3 LGPL gst-plugins-base GStreamer Base Plug-ins prerelease diff --git a/docs/plugins/inspect/plugin-tcp.xml b/docs/plugins/inspect/plugin-tcp.xml index a6dafe4495..877182d8c9 100644 --- a/docs/plugins/inspect/plugin-tcp.xml +++ b/docs/plugins/inspect/plugin-tcp.xml @@ -3,7 +3,7 @@ transfer data over the network via TCP ../../gst/tcp/.libs/libgsttcp.so libgsttcp.so - 0.10.31.2 + 0.10.31.3 LGPL gst-plugins-base GStreamer Base Plug-ins prerelease diff --git a/docs/plugins/inspect/plugin-theora.xml b/docs/plugins/inspect/plugin-theora.xml index 2136a8937e..f75dc67ba1 100644 --- a/docs/plugins/inspect/plugin-theora.xml +++ b/docs/plugins/inspect/plugin-theora.xml @@ -3,7 +3,7 @@ Theora plugin library ../../ext/theora/.libs/libgsttheora.so libgsttheora.so - 0.10.31.2 + 0.10.31.3 LGPL gst-plugins-base GStreamer Base Plug-ins prerelease diff --git a/docs/plugins/inspect/plugin-typefindfunctions.xml b/docs/plugins/inspect/plugin-typefindfunctions.xml index f66c5ab0f2..af18239150 100644 --- a/docs/plugins/inspect/plugin-typefindfunctions.xml +++ b/docs/plugins/inspect/plugin-typefindfunctions.xml @@ -3,7 +3,7 @@ default typefind functions ../../gst/typefind/.libs/libgsttypefindfunctions.so libgsttypefindfunctions.so - 0.10.31.2 + 0.10.31.3 LGPL gst-plugins-base GStreamer Base Plug-ins prerelease diff --git a/docs/plugins/inspect/plugin-uridecodebin.xml b/docs/plugins/inspect/plugin-uridecodebin.xml index b7e1f0be47..5a738ce578 100644 --- a/docs/plugins/inspect/plugin-uridecodebin.xml +++ b/docs/plugins/inspect/plugin-uridecodebin.xml @@ -3,7 +3,7 @@ URI Decoder bin ../../gst/playback/.libs/libgstdecodebin2.so libgstdecodebin2.so - 0.10.31.2 + 0.10.31.3 LGPL gst-plugins-base GStreamer Base Plug-ins prerelease diff --git a/docs/plugins/inspect/plugin-video4linux.xml b/docs/plugins/inspect/plugin-video4linux.xml index a47b6dfe4c..435090d38a 100644 --- a/docs/plugins/inspect/plugin-video4linux.xml +++ b/docs/plugins/inspect/plugin-video4linux.xml @@ -3,7 +3,7 @@ elements for Video 4 Linux ../../sys/v4l/.libs/libgstvideo4linux.so libgstvideo4linux.so - 0.10.31.2 + 0.10.31.3 LGPL gst-plugins-base GStreamer Base Plug-ins prerelease diff --git a/docs/plugins/inspect/plugin-videorate.xml b/docs/plugins/inspect/plugin-videorate.xml index 9f2335dc3d..245333d31a 100644 --- a/docs/plugins/inspect/plugin-videorate.xml +++ b/docs/plugins/inspect/plugin-videorate.xml @@ -3,7 +3,7 @@ Adjusts video frames ../../gst/videorate/.libs/libgstvideorate.so libgstvideorate.so - 0.10.31.2 + 0.10.31.3 LGPL gst-plugins-base GStreamer Base Plug-ins prerelease diff --git a/docs/plugins/inspect/plugin-videoscale.xml b/docs/plugins/inspect/plugin-videoscale.xml index 3f44920421..e159cdd0b0 100644 --- a/docs/plugins/inspect/plugin-videoscale.xml +++ b/docs/plugins/inspect/plugin-videoscale.xml @@ -3,7 +3,7 @@ Resizes video ../../gst/videoscale/.libs/libgstvideoscale.so libgstvideoscale.so - 0.10.31.2 + 0.10.31.3 LGPL gst-plugins-base GStreamer Base Plug-ins prerelease diff --git a/docs/plugins/inspect/plugin-videotestsrc.xml b/docs/plugins/inspect/plugin-videotestsrc.xml index 1f4c864a6b..59812ac369 100644 --- a/docs/plugins/inspect/plugin-videotestsrc.xml +++ b/docs/plugins/inspect/plugin-videotestsrc.xml @@ -3,7 +3,7 @@ Creates a test video stream ../../gst/videotestsrc/.libs/libgstvideotestsrc.so libgstvideotestsrc.so - 0.10.31.2 + 0.10.31.3 LGPL gst-plugins-base GStreamer Base Plug-ins prerelease diff --git a/docs/plugins/inspect/plugin-volume.xml b/docs/plugins/inspect/plugin-volume.xml index 8d6112a0d9..acb080fda9 100644 --- a/docs/plugins/inspect/plugin-volume.xml +++ b/docs/plugins/inspect/plugin-volume.xml @@ -3,7 +3,7 @@ plugin for controlling audio volume ../../gst/volume/.libs/libgstvolume.so libgstvolume.so - 0.10.31.2 + 0.10.31.3 LGPL gst-plugins-base GStreamer Base Plug-ins prerelease diff --git a/docs/plugins/inspect/plugin-vorbis.xml b/docs/plugins/inspect/plugin-vorbis.xml index 2db944dbb1..32be50deae 100644 --- a/docs/plugins/inspect/plugin-vorbis.xml +++ b/docs/plugins/inspect/plugin-vorbis.xml @@ -3,7 +3,7 @@ Vorbis plugin library ../../ext/vorbis/.libs/libgstvorbis.so libgstvorbis.so - 0.10.31.2 + 0.10.31.3 LGPL gst-plugins-base GStreamer Base Plug-ins prerelease diff --git a/docs/plugins/inspect/plugin-ximagesink.xml b/docs/plugins/inspect/plugin-ximagesink.xml index a309242c28..3756f5cf01 100644 --- a/docs/plugins/inspect/plugin-ximagesink.xml +++ b/docs/plugins/inspect/plugin-ximagesink.xml @@ -3,7 +3,7 @@ X11 video output element based on standard Xlib calls ../../sys/ximage/.libs/libgstximagesink.so libgstximagesink.so - 0.10.31.2 + 0.10.31.3 LGPL gst-plugins-base GStreamer Base Plug-ins prerelease diff --git a/docs/plugins/inspect/plugin-xvimagesink.xml b/docs/plugins/inspect/plugin-xvimagesink.xml index 1f45bb37d1..92479cc15e 100644 --- a/docs/plugins/inspect/plugin-xvimagesink.xml +++ b/docs/plugins/inspect/plugin-xvimagesink.xml @@ -3,7 +3,7 @@ XFree86 video output plugin using Xv extension ../../sys/xvimage/.libs/libgstxvimagesink.so libgstxvimagesink.so - 0.10.31.2 + 0.10.31.3 LGPL gst-plugins-base GStreamer Base Plug-ins prerelease diff --git a/win32/common/_stdint.h b/win32/common/_stdint.h index c8fd32c590..1256a35500 100644 --- a/win32/common/_stdint.h +++ b/win32/common/_stdint.h @@ -1,7 +1,7 @@ #ifndef _GST_PLUGINS_BASE__STDINT_H #define _GST_PLUGINS_BASE__STDINT_H 1 #ifndef _GENERATED_STDINT_H -#define _GENERATED_STDINT_H "gst-plugins-base 0.10.31.2" +#define _GENERATED_STDINT_H "gst-plugins-base 0.10.31.3" /* generated using gnu compiler gcc (Debian 4.4.5-10) 4.4.5 */ #define _STDINT_HAVE_STDINT_H 1 #include diff --git a/win32/common/config.h b/win32/common/config.h index 4070219959..1bb7cfbd47 100644 --- a/win32/common/config.h +++ b/win32/common/config.h @@ -81,7 +81,7 @@ #define GST_PACKAGE_ORIGIN "Unknown package origin" /* GStreamer package release date/time for plugins as YYYY-MM-DD */ -#define GST_PACKAGE_RELEASE_DATETIME "2011-01-06T23:48Z" +#define GST_PACKAGE_RELEASE_DATETIME "2011-01-11T18:57Z" /* I know the API is subject to change. */ #undef G_UDEV_API_IS_SUBJECT_TO_CHANGE @@ -337,7 +337,7 @@ #define PACKAGE_NAME "GStreamer Base Plug-ins" /* Define to the full name and version of this package. */ -#define PACKAGE_STRING "GStreamer Base Plug-ins 0.10.31.2" +#define PACKAGE_STRING "GStreamer Base Plug-ins 0.10.31.3" /* Define to the one symbol short name of this package. */ #define PACKAGE_TARNAME "gst-plugins-base" @@ -346,7 +346,7 @@ #undef PACKAGE_URL /* Define to the version of this package. */ -#define PACKAGE_VERSION "0.10.31.2" +#define PACKAGE_VERSION "0.10.31.3" /* directory where plugins are located */ #ifdef _DEBUG @@ -374,7 +374,7 @@ #undef STDC_HEADERS /* Version number of package */ -#define VERSION "0.10.31.2" +#define VERSION "0.10.31.3" /* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most significant byte first (like Motorola and SPARC, unlike Intel). */ From 11b1f2721d367f831c0b5bf48a8daaf6555e5d6b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim-Philipp=20M=C3=BCller?= Date: Wed, 12 Jan 2011 15:51:52 +0000 Subject: [PATCH 141/254] configure: require gobject-introspection >= 0.9.12 Earlier versions don't honour the -L/--library-path option, which we need. See commit 4d0ccdad in gobject-introspection git. Should "fix" build on lucid/maverick build bots. --- configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index 3a4f8f48d9..4af26b9896 100644 --- a/configure.ac +++ b/configure.ac @@ -151,7 +151,7 @@ AC_PATH_PROG(VALGRIND_PATH, valgrind, no) AM_CONDITIONAL(HAVE_VALGRIND, test ! "x$VALGRIND_PATH" = "xno") dnl check for gobject-introspection -GOBJECT_INTROSPECTION_CHECK([0.6.3]) +GOBJECT_INTROSPECTION_CHECK([0.9.12]) dnl check for documentation tools GTK_DOC_CHECK([1.3]) From ba76490dd4224d4e03a2830bb93707c983ecb33e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim-Philipp=20M=C3=BCller?= Date: Wed, 12 Jan 2011 17:51:43 +0000 Subject: [PATCH 142/254] docs: add some more Since: markers for new encoding-profile API --- gst-libs/gst/pbutils/encoding-profile.c | 2 ++ gst-libs/gst/pbutils/encoding-target.c | 6 +++++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/gst-libs/gst/pbutils/encoding-profile.c b/gst-libs/gst/pbutils/encoding-profile.c index 12300dc792..b1c8051b6e 100644 --- a/gst-libs/gst/pbutils/encoding-profile.c +++ b/gst-libs/gst/pbutils/encoding-profile.c @@ -893,6 +893,8 @@ gst_encoding_profile_get_type_nick (GstEncodingProfile * profile) * Find the #GstEncodingProfile with the specified name and category. * * Returns: (transfer full): The matching #GstEncodingProfile or %NULL. + * + * Since: 0.10.32 */ GstEncodingProfile * gst_encoding_profile_find (const gchar * targetname, const gchar * profilename, diff --git a/gst-libs/gst/pbutils/encoding-target.c b/gst-libs/gst/pbutils/encoding-target.c index 0a42ff3eee..8795e1c3a1 100644 --- a/gst-libs/gst/pbutils/encoding-target.c +++ b/gst-libs/gst/pbutils/encoding-target.c @@ -991,7 +991,9 @@ get_categories (gchar * path) * * Returns: (transfer full) (element-type gchar*): A list * of #GstEncodingTarget categories. -*/ + * + * Since: 0.10.32 + */ GList * gst_encoding_list_available_categories (void) { @@ -1105,6 +1107,8 @@ compare_targets (const GstEncodingTarget * ta, const GstEncodingTarget * tb) * if @categoryname is %NULL. * * Returns: (transfer full) (element-type GstEncodingTarget): The list of #GstEncodingTarget + * + * Since: 0.10.32 */ GList * gst_encoding_list_all_targets (const gchar * categoryname) From adb84c6dae9485b712685ea014b96f21250e1fbf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim-Philipp=20M=C3=BCller?= Date: Thu, 13 Jan 2011 13:59:41 +0000 Subject: [PATCH 143/254] typefinding: set framed=false on DTS caps --- gst/typefind/gsttypefindfunctions.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/gst/typefind/gsttypefindfunctions.c b/gst/typefind/gsttypefindfunctions.c index 66a5275d64..373df083d6 100644 --- a/gst/typefind/gsttypefindfunctions.c +++ b/gst/typefind/gsttypefindfunctions.c @@ -1432,10 +1432,11 @@ dts_type_find (GstTypeFind * tf, gpointer unused) if (chans > 0) { gst_type_find_suggest_simple (tf, prob, "audio/x-dts", - "rate", G_TYPE_INT, rate, "channels", G_TYPE_INT, chans, NULL); + "rate", G_TYPE_INT, rate, "channels", G_TYPE_INT, chans, + "framed", G_TYPE_BOOLEAN, FALSE, NULL); } else { gst_type_find_suggest_simple (tf, prob, "audio/x-dts", - "rate", G_TYPE_INT, rate, NULL); + "rate", G_TYPE_INT, rate, "framed", G_TYPE_BOOLEAN, FALSE, NULL); } return; From c40fdbf5523346018313dac5024e1678463c292c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim-Philipp=20M=C3=BCller?= Date: Sun, 16 Jan 2011 16:46:22 +0000 Subject: [PATCH 144/254] pbutils: save localised strings properly when writing encoding targets to a file Use LC_MESSAGES rather than LC_ALL. Save/load description as untranslated string when using an English language locale. Strip locale information to the language, so we don't save keys like description[fr_FR.UTF-8]=... https://bugzilla.gnome.org/show_bug.cgi?id=638860 --- gst-libs/gst/pbutils/encoding-target.c | 55 ++++++++++++++++++++++---- 1 file changed, 47 insertions(+), 8 deletions(-) diff --git a/gst-libs/gst/pbutils/encoding-target.c b/gst-libs/gst/pbutils/encoding-target.c index 8795e1c3a1..a4fd0b3958 100644 --- a/gst-libs/gst/pbutils/encoding-target.c +++ b/gst-libs/gst/pbutils/encoding-target.c @@ -409,6 +409,22 @@ serialize_stream_profiles (GKeyFile * out, GstEncodingProfile * sprof, return TRUE; } +static gchar * +get_locale (void) +{ + const char *loc = setlocale (LC_MESSAGES, NULL); + gchar *ret; + + if (loc == NULL || g_ascii_strncasecmp (loc, "en", 2) == 0) + return NULL; + + /* en_GB.UTF-8 => en */ + ret = g_ascii_strdown (loc, -1); + ret = g_strcanon (ret, "abcdefghijklmnopqrstuvwxyz", '\0'); + GST_LOG ("using locale: %s", ret); + return ret; +} + /* Serialize the top-level profiles * Note: They don't have to be containerprofiles */ static gboolean @@ -434,9 +450,18 @@ serialize_encoding_profile (GKeyFile * out, GstEncodingProfile * prof) g_key_file_set_value (out, profgroupname, "type", gst_encoding_profile_get_type_nick (prof)); - if (profdesc) - g_key_file_set_locale_string (out, profgroupname, "description", - setlocale (LC_ALL, NULL), profdesc); + if (profdesc) { + gchar *locale; + + locale = get_locale (); + if (locale != NULL) { + g_key_file_set_locale_string (out, profgroupname, "description", + locale, profdesc); + g_free (locale); + } else { + g_key_file_set_string (out, profgroupname, "description", profdesc); + } + } if (profformat) { gchar *tmpc = gst_caps_to_string (profformat); g_key_file_set_string (out, profgroupname, "format", tmpc); @@ -534,11 +559,25 @@ parse_encoding_profile (GKeyFile * in, gchar * parentprofilename, pname = g_key_file_get_value (in, profilename, "name", NULL); /* First try to get localized description */ - description = - g_key_file_get_locale_string (in, profilename, "description", - setlocale (LC_ALL, NULL), NULL); - if (description == NULL) - description = g_key_file_get_value (in, profilename, "description", NULL); + { + gchar *locale; + + locale = get_locale (); + if (locale != NULL) { + /* will try to fall back to untranslated string if no translation found */ + description = g_key_file_get_locale_string (in, profilename, + "description", locale, NULL); + g_free (locale); + } else { + description = + g_key_file_get_string (in, profilename, "description", NULL); + } + } + + /* Note: a missing description is normal for non-container profiles */ + if (description == NULL) { + GST_LOG ("Missing 'description' field for streamprofile %s", profilename); + } /* Parse the remaining fields */ proftype = g_key_file_get_value (in, profilename, "type", NULL); From 3a165c60bf2d7c047d3a5b311d54889abc8b2503 Mon Sep 17 00:00:00 2001 From: David Schleef Date: Sun, 16 Jan 2011 14:55:46 -0800 Subject: [PATCH 145/254] gdppay: make newsegment buffer metadata writable --- gst/gdp/gstgdppay.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/gst/gdp/gstgdppay.c b/gst/gdp/gstgdppay.c index ea8595b283..f9e27da1e0 100644 --- a/gst/gdp/gstgdppay.c +++ b/gst/gdp/gstgdppay.c @@ -475,6 +475,8 @@ gst_gdp_pay_reset_streamheader (GstGDPPay * this) GST_DEBUG_OBJECT (this, "Setting caps on src pad %" GST_PTR_FORMAT, caps); gst_pad_set_caps (this->srcpad, caps); gst_buffer_set_caps (this->caps_buf, caps); + this->new_segment_buf = + gst_buffer_make_metadata_writable (this->new_segment_buf); gst_buffer_set_caps (this->new_segment_buf, caps); /* if these are our first ever buffers, send out new_segment first */ From e730ce71dc72df6d380d53c1a65aacb0c0c134b6 Mon Sep 17 00:00:00 2001 From: Arun Raghavan Date: Tue, 18 Jan 2011 00:08:32 +0530 Subject: [PATCH 146/254] discoverer: Make sure we call _stop() before being freed This ensures that everything is properly cleaned up before the GstDiscoverer object is freed. Specifically, it makes sure that we've removed the async timeout callback before freeing the object to avoid a potential crash later on. https://bugzilla.gnome.org/show_bug.cgi?id=639755 --- gst-libs/gst/pbutils/gstdiscoverer.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/gst-libs/gst/pbutils/gstdiscoverer.c b/gst-libs/gst/pbutils/gstdiscoverer.c index bc99f43c74..ab32b915ed 100644 --- a/gst-libs/gst/pbutils/gstdiscoverer.c +++ b/gst-libs/gst/pbutils/gstdiscoverer.c @@ -304,7 +304,8 @@ discoverer_reset (GstDiscoverer * dc) dc->priv->pending_uris = NULL; } - gst_element_set_state ((GstElement *) dc->priv->pipeline, GST_STATE_NULL); + if (dc->priv->pipeline) + gst_element_set_state ((GstElement *) dc->priv->pipeline, GST_STATE_NULL); } static void @@ -325,6 +326,8 @@ gst_discoverer_dispose (GObject * obj) dc->priv->bus = NULL; } + gst_discoverer_stop (dc); + if (dc->priv->lock) { g_mutex_free (dc->priv->lock); dc->priv->lock = NULL; @@ -1271,9 +1274,11 @@ gst_discoverer_stop (GstDiscoverer * discoverer) /* We prevent any further processing by setting the bus to * flushing and setting the pipeline to READY. * _reset() will take care of the rest of the cleanup */ - gst_bus_set_flushing (discoverer->priv->bus, TRUE); - gst_element_set_state ((GstElement *) discoverer->priv->pipeline, - GST_STATE_READY); + if (discoverer->priv->bus) + gst_bus_set_flushing (discoverer->priv->bus, TRUE); + if (discoverer->priv->pipeline) + gst_element_set_state ((GstElement *) discoverer->priv->pipeline, + GST_STATE_READY); } discoverer->priv->running = FALSE; DISCO_UNLOCK (discoverer); From 65a298fdeee5b9214f83878a6d757e90d45562cb Mon Sep 17 00:00:00 2001 From: Arun Raghavan Date: Mon, 17 Jan 2011 15:30:08 +0530 Subject: [PATCH 147/254] discoverer: Validate timeouts before processing them This avoids a race where the timeout callback is scheduled to run but we get sufficient information to finish discovery before actually getting around to executing the callback. See the documentation of g_source_is_destroyed() for more details. https://bugzilla.gnome.org/show_bug.cgi?id=639730 --- gst-libs/gst/pbutils/gstdiscoverer.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/gst-libs/gst/pbutils/gstdiscoverer.c b/gst-libs/gst/pbutils/gstdiscoverer.c index ab32b915ed..46e2cfbb6b 100644 --- a/gst-libs/gst/pbutils/gstdiscoverer.c +++ b/gst-libs/gst/pbutils/gstdiscoverer.c @@ -1153,12 +1153,14 @@ discoverer_bus_cb (GstBus * bus, GstMessage * msg, GstDiscoverer * dc) static gboolean async_timeout_cb (GstDiscoverer * dc) { - dc->priv->timeoutid = 0; - GST_DEBUG ("Setting result to TIMEOUT"); - dc->priv->current_info->result = GST_DISCOVERER_TIMEOUT; - dc->priv->processing = FALSE; - discoverer_collect (dc); - discoverer_cleanup (dc); + if (!g_source_is_destroyed (g_main_current_source ())) { + dc->priv->timeoutid = 0; + GST_DEBUG ("Setting result to TIMEOUT"); + dc->priv->current_info->result = GST_DISCOVERER_TIMEOUT; + dc->priv->processing = FALSE; + discoverer_collect (dc); + discoverer_cleanup (dc); + } return FALSE; } From 6ac2e5d3846b2038113ed2dda7c298e296faa938 Mon Sep 17 00:00:00 2001 From: Arun Raghavan Date: Tue, 18 Jan 2011 01:09:53 +0530 Subject: [PATCH 148/254] discoverer: Drop new stream tags once preroll is done This makes sure we do not touch the stream taglist once the pipeline has been prerolled. Adding of stream tags happens in the pad event probe which runs in a different thread from discoverer stream processing, so modifying the tag list while discoverer might be processing it can sometimes cause a crash. https://bugzilla.gnome.org/show_bug.cgi?id=639778 --- gst-libs/gst/pbutils/gstdiscoverer.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/gst-libs/gst/pbutils/gstdiscoverer.c b/gst-libs/gst/pbutils/gstdiscoverer.c index 46e2cfbb6b..8422d8f10b 100644 --- a/gst-libs/gst/pbutils/gstdiscoverer.c +++ b/gst-libs/gst/pbutils/gstdiscoverer.c @@ -393,10 +393,15 @@ _event_probe (GstPad * pad, GstEvent * event, PrivateStream * ps) gst_event_parse_tag (event, &tl); GST_DEBUG_OBJECT (pad, "tags %" GST_PTR_FORMAT, tl); DISCO_LOCK (ps->dc); - tmp = gst_tag_list_merge (ps->tags, tl, GST_TAG_MERGE_APPEND); - if (ps->tags) - gst_tag_list_free (ps->tags); - ps->tags = tmp; + /* If preroll is complete, drop these tags - the collected information is + * possibly already being processed and adding more tags would be racy */ + if (G_LIKELY (ps->dc->priv->processing)) { + tmp = gst_tag_list_merge (ps->tags, tl, GST_TAG_MERGE_APPEND); + if (ps->tags) + gst_tag_list_free (ps->tags); + ps->tags = tmp; + } else + GST_DEBUG_OBJECT (ps->dc, "Dropping tags since preroll is done"); DISCO_UNLOCK (ps->dc); } @@ -1143,7 +1148,10 @@ discoverer_bus_cb (GstBus * bus, GstMessage * msg, GstDiscoverer * dc) if (dc->priv->processing) { if (handle_message (dc, msg)) { GST_DEBUG ("Stopping asynchronously"); + /* Serialise with _event_probe() */ + DISCO_LOCK (dc); dc->priv->processing = FALSE; + DISCO_UNLOCK (dc); discoverer_collect (dc); discoverer_cleanup (dc); } From b311b833c1998bd8694cebe888a4b159b291023d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim-Philipp=20M=C3=BCller?= Date: Mon, 17 Jan 2011 23:59:48 +0000 Subject: [PATCH 149/254] app: make GstAppBuffer get_type() function thread-safe --- gst-libs/gst/app/gstappbuffer.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/gst-libs/gst/app/gstappbuffer.c b/gst-libs/gst/app/gstappbuffer.c index 06f354f869..2fa72bb8ad 100644 --- a/gst-libs/gst/app/gstappbuffer.c +++ b/gst-libs/gst/app/gstappbuffer.c @@ -37,9 +37,9 @@ static GstBufferClass *parent_class; GType gst_app_buffer_get_type (void) { - static GType _gst_app_buffer_type; + static volatile gsize app_buffer_type = 0; - if (G_UNLIKELY (_gst_app_buffer_type == 0)) { + if (g_once_init_enter (&app_buffer_type)) { static const GTypeInfo app_buffer_info = { sizeof (GstBufferClass), NULL, @@ -52,10 +52,12 @@ gst_app_buffer_get_type (void) (GInstanceInitFunc) gst_app_buffer_init, NULL }; - _gst_app_buffer_type = g_type_register_static (GST_TYPE_BUFFER, - "GstAppBuffer", &app_buffer_info, 0); + GType tmp = g_type_register_static (GST_TYPE_BUFFER, "GstAppBuffer", + &app_buffer_info, 0); + g_once_init_leave (&app_buffer_type, tmp); } - return _gst_app_buffer_type; + + return (GType) app_buffer_type; } static void From cd758cdbd926c267a96b53a9fdf2f4486ec399ad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim-Philipp=20M=C3=BCller?= Date: Tue, 18 Jan 2011 00:09:37 +0000 Subject: [PATCH 150/254] app: export gst_app_stream_type_get_type() API: gst_app_stream_type_get_type() API: GST_TYPE_APP_STREAM_TYPE https://bugzilla.gnome.org/show_bug.cgi?id=639747 --- gst-libs/gst/app/gstappsrc.c | 25 +++++++++++++------------ gst-libs/gst/app/gstappsrc.h | 4 ++++ win32/common/libgstapp.def | 1 + 3 files changed, 18 insertions(+), 12 deletions(-) diff --git a/gst-libs/gst/app/gstappsrc.c b/gst-libs/gst/app/gstappsrc.c index b5baefa2f9..f051711e26 100644 --- a/gst-libs/gst/app/gstappsrc.c +++ b/gst-libs/gst/app/gstappsrc.c @@ -198,23 +198,24 @@ GST_STATIC_PAD_TEMPLATE ("src", GST_PAD_ALWAYS, GST_STATIC_CAPS_ANY); - -#define GST_TYPE_APP_STREAM_TYPE (stream_type_get_type ()) -static GType -stream_type_get_type (void) +GType +gst_app_stream_type_get_type (void) { - static GType stream_type_type = 0; + static volatile gsize stream_type_type = 0; static const GEnumValue stream_type[] = { - {GST_APP_STREAM_TYPE_STREAM, "Stream", "stream"}, - {GST_APP_STREAM_TYPE_SEEKABLE, "Seekable", "seekable"}, - {GST_APP_STREAM_TYPE_RANDOM_ACCESS, "Random Access", "random-access"}, - {0, NULL, NULL}, + {GST_APP_STREAM_TYPE_STREAM, "GST_APP_STREAM_TYPE_STREAM", "stream"}, + {GST_APP_STREAM_TYPE_SEEKABLE, "GST_APP_STREAM_TYPE_SEEKABLE", "seekable"}, + {GST_APP_STREAM_TYPE_RANDOM_ACCESS, "GST_APP_STREAM_TYPE_RANDOM_ACCESS", + "random-access"}, + {0, NULL, NULL} }; - if (!stream_type_type) { - stream_type_type = g_enum_register_static ("GstAppStreamType", stream_type); + if (g_once_init_enter (&stream_type_type)) { + GType tmp = g_enum_register_static ("GstAppStreamType", stream_type); + g_once_init_leave (&stream_type_type, tmp); } - return stream_type_type; + + return (GType) stream_type_type; } static void gst_app_src_uri_handler_init (gpointer g_iface, diff --git a/gst-libs/gst/app/gstappsrc.h b/gst-libs/gst/app/gstappsrc.h index a1e09f7a50..041cb68215 100644 --- a/gst-libs/gst/app/gstappsrc.h +++ b/gst-libs/gst/app/gstappsrc.h @@ -117,6 +117,10 @@ struct _GstAppSrcClass GType gst_app_src_get_type(void); +/* GType getter for GstAppStreamType, since 0.10.32 */ +#define GST_TYPE_APP_STREAM_TYPE (gst_app_stream_type_get_type ()) +GType gst_app_stream_type_get_type (void); + void gst_app_src_set_caps (GstAppSrc *appsrc, const GstCaps *caps); GstCaps* gst_app_src_get_caps (GstAppSrc *appsrc); diff --git a/win32/common/libgstapp.def b/win32/common/libgstapp.def index 9b1aa24313..892d680e4d 100644 --- a/win32/common/libgstapp.def +++ b/win32/common/libgstapp.def @@ -31,3 +31,4 @@ EXPORTS gst_app_src_set_max_bytes gst_app_src_set_size gst_app_src_set_stream_type + gst_app_stream_type_get_type From d1bcdea7dcf4e5ecc7687e1652db64634afbd7b6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim-Philipp=20M=C3=BCller?= Date: Tue, 18 Jan 2011 01:06:50 +0000 Subject: [PATCH 151/254] pbutils: don't assume LC_MESSAGES is always defined, also check for ENABLE_NLS Should fix build with mingw32 build bot again. --- gst-libs/gst/pbutils/encoding-target.c | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/gst-libs/gst/pbutils/encoding-target.c b/gst-libs/gst/pbutils/encoding-target.c index a4fd0b3958..295708b817 100644 --- a/gst-libs/gst/pbutils/encoding-target.c +++ b/gst-libs/gst/pbutils/encoding-target.c @@ -412,9 +412,23 @@ serialize_stream_profiles (GKeyFile * out, GstEncodingProfile * sprof, static gchar * get_locale (void) { - const char *loc = setlocale (LC_MESSAGES, NULL); + const char *loc = NULL; gchar *ret; +#ifdef ENABLE_NLS +#if defined(LC_MESSAGES) + loc = setlocale (LC_MESSAGES, NULL); + GST_LOG ("LC_MESSAGES: %s", GST_STR_NULL (loc)); +#elif defined(LC_ALL) + loc = setlocale (LC_ALL, NULL); + GST_LOG ("LC_ALL: %s", GST_STR_NULL (loc)); +#else + GST_LOG ("Neither LC_ALL nor LC_MESSAGES defined"); +#endif +#else /* !ENABLE_NLS */ + GST_LOG ("i18n disabled"); +#endif + if (loc == NULL || g_ascii_strncasecmp (loc, "en", 2) == 0) return NULL; From 97f84c1eee8856f90e1601807aae14e5112f816f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim-Philipp=20M=C3=BCller?= Date: Tue, 18 Jan 2011 10:40:29 +0000 Subject: [PATCH 152/254] encoding-target: change keyfile header to 'GStreamer Encoding Target' which is more in line with other files such as .desktop files. --- gst-libs/gst/pbutils/encoding-target.c | 4 ++-- tests/check/libs/profile.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/gst-libs/gst/pbutils/encoding-target.c b/gst-libs/gst/pbutils/encoding-target.c index 295708b817..2e92173863 100644 --- a/gst-libs/gst/pbutils/encoding-target.c +++ b/gst-libs/gst/pbutils/encoding-target.c @@ -31,7 +31,7 @@ * * GKeyFile style. * - * [_gstencodingtarget_] + * [GStreamer Encoding Target] * name : * category : * description : #translatable @@ -68,7 +68,7 @@ */ -#define GST_ENCODING_TARGET_HEADER "_gstencodingtarget_" +#define GST_ENCODING_TARGET_HEADER "GStreamer Encoding Target" #define GST_ENCODING_TARGET_DIRECTORY "encoding-profiles" #define GST_ENCODING_TARGET_SUFFIX ".gep" diff --git a/tests/check/libs/profile.c b/tests/check/libs/profile.c index 1c9f60af98..285a58ebd4 100644 --- a/tests/check/libs/profile.c +++ b/tests/check/libs/profile.c @@ -511,7 +511,7 @@ GST_END_TEST; static const gchar *profile_string = "\ -[_gstencodingtarget_]\n\ +[GStreamer Encoding Target]\n\ name=myponytarget\n\ category=herding\n\ description=Plenty of pony glitter profiles\n\ From 5d38bf57f0525b510c71327dbadc515cf6d4745e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim-Philipp=20M=C3=BCller?= Date: Tue, 18 Jan 2011 10:44:01 +0000 Subject: [PATCH 153/254] docs: update docs --- docs/plugins/gst-plugins-base-plugins.args | 2 +- docs/plugins/inspect/plugin-adder.xml | 2 +- docs/plugins/inspect/plugin-alsa.xml | 2 +- docs/plugins/inspect/plugin-app.xml | 2 +- docs/plugins/inspect/plugin-audioconvert.xml | 2 +- docs/plugins/inspect/plugin-audiorate.xml | 2 +- docs/plugins/inspect/plugin-audioresample.xml | 2 +- docs/plugins/inspect/plugin-audiotestsrc.xml | 2 +- docs/plugins/inspect/plugin-cdparanoia.xml | 2 +- docs/plugins/inspect/plugin-decodebin.xml | 2 +- docs/plugins/inspect/plugin-encoding.xml | 2 +- docs/plugins/inspect/plugin-ffmpegcolorspace.xml | 2 +- docs/plugins/inspect/plugin-gdp.xml | 2 +- docs/plugins/inspect/plugin-gio.xml | 2 +- docs/plugins/inspect/plugin-gnomevfs.xml | 2 +- docs/plugins/inspect/plugin-libvisual.xml | 2 +- docs/plugins/inspect/plugin-ogg.xml | 2 +- docs/plugins/inspect/plugin-pango.xml | 2 +- docs/plugins/inspect/plugin-playback.xml | 2 +- docs/plugins/inspect/plugin-subparse.xml | 2 +- docs/plugins/inspect/plugin-tcp.xml | 2 +- docs/plugins/inspect/plugin-theora.xml | 2 +- docs/plugins/inspect/plugin-typefindfunctions.xml | 2 +- docs/plugins/inspect/plugin-uridecodebin.xml | 2 +- docs/plugins/inspect/plugin-video4linux.xml | 2 +- docs/plugins/inspect/plugin-videorate.xml | 2 +- docs/plugins/inspect/plugin-videoscale.xml | 2 +- docs/plugins/inspect/plugin-videotestsrc.xml | 2 +- docs/plugins/inspect/plugin-volume.xml | 2 +- docs/plugins/inspect/plugin-vorbis.xml | 2 +- docs/plugins/inspect/plugin-ximagesink.xml | 2 +- docs/plugins/inspect/plugin-xvimagesink.xml | 2 +- 32 files changed, 32 insertions(+), 32 deletions(-) diff --git a/docs/plugins/gst-plugins-base-plugins.args b/docs/plugins/gst-plugins-base-plugins.args index d3a40c5156..9469513c3a 100644 --- a/docs/plugins/gst-plugins-base-plugins.args +++ b/docs/plugins/gst-plugins-base-plugins.args @@ -3255,7 +3255,7 @@ rw Stream Type the type of the stream. -Stream +GST_APP_STREAM_TYPE_STREAM diff --git a/docs/plugins/inspect/plugin-adder.xml b/docs/plugins/inspect/plugin-adder.xml index e177535653..f2fd2cff12 100644 --- a/docs/plugins/inspect/plugin-adder.xml +++ b/docs/plugins/inspect/plugin-adder.xml @@ -3,7 +3,7 @@ Adds multiple streams ../../gst/adder/.libs/libgstadder.so libgstadder.so - 0.10.31.3 + 0.10.31.4 LGPL gst-plugins-base GStreamer Base Plug-ins prerelease diff --git a/docs/plugins/inspect/plugin-alsa.xml b/docs/plugins/inspect/plugin-alsa.xml index b2b1d251c2..13a0c2594f 100644 --- a/docs/plugins/inspect/plugin-alsa.xml +++ b/docs/plugins/inspect/plugin-alsa.xml @@ -3,7 +3,7 @@ ALSA plugin library ../../ext/alsa/.libs/libgstalsa.so libgstalsa.so - 0.10.31.3 + 0.10.31.4 LGPL gst-plugins-base GStreamer Base Plug-ins prerelease diff --git a/docs/plugins/inspect/plugin-app.xml b/docs/plugins/inspect/plugin-app.xml index 037ea532ab..fd011b5001 100644 --- a/docs/plugins/inspect/plugin-app.xml +++ b/docs/plugins/inspect/plugin-app.xml @@ -3,7 +3,7 @@ Elements used to communicate with applications ../../gst/app/.libs/libgstapp.so libgstapp.so - 0.10.31.3 + 0.10.31.4 LGPL gst-plugins-base GStreamer Base Plug-ins prerelease diff --git a/docs/plugins/inspect/plugin-audioconvert.xml b/docs/plugins/inspect/plugin-audioconvert.xml index 74c50b5834..023f3bfa2b 100644 --- a/docs/plugins/inspect/plugin-audioconvert.xml +++ b/docs/plugins/inspect/plugin-audioconvert.xml @@ -3,7 +3,7 @@ Convert audio to different formats ../../gst/audioconvert/.libs/libgstaudioconvert.so libgstaudioconvert.so - 0.10.31.3 + 0.10.31.4 LGPL gst-plugins-base GStreamer Base Plug-ins prerelease diff --git a/docs/plugins/inspect/plugin-audiorate.xml b/docs/plugins/inspect/plugin-audiorate.xml index e04d22a46f..d3038db415 100644 --- a/docs/plugins/inspect/plugin-audiorate.xml +++ b/docs/plugins/inspect/plugin-audiorate.xml @@ -3,7 +3,7 @@ Adjusts audio frames ../../gst/audiorate/.libs/libgstaudiorate.so libgstaudiorate.so - 0.10.31.3 + 0.10.31.4 LGPL gst-plugins-base GStreamer Base Plug-ins prerelease diff --git a/docs/plugins/inspect/plugin-audioresample.xml b/docs/plugins/inspect/plugin-audioresample.xml index da43623dd8..bf957b434c 100644 --- a/docs/plugins/inspect/plugin-audioresample.xml +++ b/docs/plugins/inspect/plugin-audioresample.xml @@ -3,7 +3,7 @@ Resamples audio ../../gst/audioresample/.libs/libgstaudioresample.so libgstaudioresample.so - 0.10.31.3 + 0.10.31.4 LGPL gst-plugins-base GStreamer Base Plug-ins prerelease diff --git a/docs/plugins/inspect/plugin-audiotestsrc.xml b/docs/plugins/inspect/plugin-audiotestsrc.xml index 1ced48ac0d..19faa69a5d 100644 --- a/docs/plugins/inspect/plugin-audiotestsrc.xml +++ b/docs/plugins/inspect/plugin-audiotestsrc.xml @@ -3,7 +3,7 @@ Creates audio test signals of given frequency and volume ../../gst/audiotestsrc/.libs/libgstaudiotestsrc.so libgstaudiotestsrc.so - 0.10.31.3 + 0.10.31.4 LGPL gst-plugins-base GStreamer Base Plug-ins prerelease diff --git a/docs/plugins/inspect/plugin-cdparanoia.xml b/docs/plugins/inspect/plugin-cdparanoia.xml index 7cb62e515b..c5d4f00320 100644 --- a/docs/plugins/inspect/plugin-cdparanoia.xml +++ b/docs/plugins/inspect/plugin-cdparanoia.xml @@ -3,7 +3,7 @@ Read audio from CD in paranoid mode ../../ext/cdparanoia/.libs/libgstcdparanoia.so libgstcdparanoia.so - 0.10.31.3 + 0.10.31.4 LGPL gst-plugins-base GStreamer Base Plug-ins prerelease diff --git a/docs/plugins/inspect/plugin-decodebin.xml b/docs/plugins/inspect/plugin-decodebin.xml index 55d91e0aa7..a316cbd3fd 100644 --- a/docs/plugins/inspect/plugin-decodebin.xml +++ b/docs/plugins/inspect/plugin-decodebin.xml @@ -3,7 +3,7 @@ decoder bin ../../gst/playback/.libs/libgstdecodebin.so libgstdecodebin.so - 0.10.31.3 + 0.10.31.4 LGPL gst-plugins-base GStreamer Base Plug-ins prerelease diff --git a/docs/plugins/inspect/plugin-encoding.xml b/docs/plugins/inspect/plugin-encoding.xml index e3447a27f2..83963edb3e 100644 --- a/docs/plugins/inspect/plugin-encoding.xml +++ b/docs/plugins/inspect/plugin-encoding.xml @@ -3,7 +3,7 @@ various encoding-related elements ../../gst/encoding/.libs/libgstencodebin.so libgstencodebin.so - 0.10.31.3 + 0.10.31.4 LGPL gst-plugins-base GStreamer Base Plug-ins prerelease diff --git a/docs/plugins/inspect/plugin-ffmpegcolorspace.xml b/docs/plugins/inspect/plugin-ffmpegcolorspace.xml index f25f9f89a5..b52980d107 100644 --- a/docs/plugins/inspect/plugin-ffmpegcolorspace.xml +++ b/docs/plugins/inspect/plugin-ffmpegcolorspace.xml @@ -3,7 +3,7 @@ colorspace conversion copied from FFMpeg 0.4.9-pre1 ../../gst/ffmpegcolorspace/.libs/libgstffmpegcolorspace.so libgstffmpegcolorspace.so - 0.10.31.3 + 0.10.31.4 LGPL gst-plugins-base FFMpeg diff --git a/docs/plugins/inspect/plugin-gdp.xml b/docs/plugins/inspect/plugin-gdp.xml index 16c9a25f05..9ac43936db 100644 --- a/docs/plugins/inspect/plugin-gdp.xml +++ b/docs/plugins/inspect/plugin-gdp.xml @@ -3,7 +3,7 @@ Payload/depayload GDP packets ../../gst/gdp/.libs/libgstgdp.so libgstgdp.so - 0.10.31.3 + 0.10.31.4 LGPL gst-plugins-base GStreamer Base Plug-ins prerelease diff --git a/docs/plugins/inspect/plugin-gio.xml b/docs/plugins/inspect/plugin-gio.xml index ceb93c6eda..db0ee8b7a6 100644 --- a/docs/plugins/inspect/plugin-gio.xml +++ b/docs/plugins/inspect/plugin-gio.xml @@ -3,7 +3,7 @@ GIO elements ../../ext/gio/.libs/libgstgio.so libgstgio.so - 0.10.31.3 + 0.10.31.4 LGPL gst-plugins-base GStreamer Base Plug-ins prerelease diff --git a/docs/plugins/inspect/plugin-gnomevfs.xml b/docs/plugins/inspect/plugin-gnomevfs.xml index 622160e257..e92b7cc9c4 100644 --- a/docs/plugins/inspect/plugin-gnomevfs.xml +++ b/docs/plugins/inspect/plugin-gnomevfs.xml @@ -3,7 +3,7 @@ elements to read from and write to Gnome-VFS uri's ../../ext/gnomevfs/.libs/libgstgnomevfs.so libgstgnomevfs.so - 0.10.31.3 + 0.10.31.4 LGPL gst-plugins-base GStreamer Base Plug-ins prerelease diff --git a/docs/plugins/inspect/plugin-libvisual.xml b/docs/plugins/inspect/plugin-libvisual.xml index c24b43050f..5ee4ddd914 100644 --- a/docs/plugins/inspect/plugin-libvisual.xml +++ b/docs/plugins/inspect/plugin-libvisual.xml @@ -3,7 +3,7 @@ libvisual visualization plugins ../../ext/libvisual/.libs/libgstlibvisual.so libgstlibvisual.so - 0.10.31.3 + 0.10.31.4 LGPL gst-plugins-base GStreamer Base Plug-ins prerelease diff --git a/docs/plugins/inspect/plugin-ogg.xml b/docs/plugins/inspect/plugin-ogg.xml index cf1ff06f6b..f857ce6e59 100644 --- a/docs/plugins/inspect/plugin-ogg.xml +++ b/docs/plugins/inspect/plugin-ogg.xml @@ -3,7 +3,7 @@ ogg stream manipulation (info about ogg: http://xiph.org) ../../ext/ogg/.libs/libgstogg.so libgstogg.so - 0.10.31.3 + 0.10.31.4 LGPL gst-plugins-base GStreamer Base Plug-ins prerelease diff --git a/docs/plugins/inspect/plugin-pango.xml b/docs/plugins/inspect/plugin-pango.xml index 1aabc0b397..32388269ef 100644 --- a/docs/plugins/inspect/plugin-pango.xml +++ b/docs/plugins/inspect/plugin-pango.xml @@ -3,7 +3,7 @@ Pango-based text rendering and overlay ../../ext/pango/.libs/libgstpango.so libgstpango.so - 0.10.31.3 + 0.10.31.4 LGPL gst-plugins-base GStreamer Base Plug-ins prerelease diff --git a/docs/plugins/inspect/plugin-playback.xml b/docs/plugins/inspect/plugin-playback.xml index 6a583e77c2..b98913b1ba 100644 --- a/docs/plugins/inspect/plugin-playback.xml +++ b/docs/plugins/inspect/plugin-playback.xml @@ -3,7 +3,7 @@ various playback elements ../../gst/playback/.libs/libgstplaybin.so libgstplaybin.so - 0.10.31.3 + 0.10.31.4 LGPL gst-plugins-base GStreamer Base Plug-ins prerelease diff --git a/docs/plugins/inspect/plugin-subparse.xml b/docs/plugins/inspect/plugin-subparse.xml index bf03318514..a978ecb254 100644 --- a/docs/plugins/inspect/plugin-subparse.xml +++ b/docs/plugins/inspect/plugin-subparse.xml @@ -3,7 +3,7 @@ Subtitle parsing ../../gst/subparse/.libs/libgstsubparse.so libgstsubparse.so - 0.10.31.3 + 0.10.31.4 LGPL gst-plugins-base GStreamer Base Plug-ins prerelease diff --git a/docs/plugins/inspect/plugin-tcp.xml b/docs/plugins/inspect/plugin-tcp.xml index 877182d8c9..c467234b8e 100644 --- a/docs/plugins/inspect/plugin-tcp.xml +++ b/docs/plugins/inspect/plugin-tcp.xml @@ -3,7 +3,7 @@ transfer data over the network via TCP ../../gst/tcp/.libs/libgsttcp.so libgsttcp.so - 0.10.31.3 + 0.10.31.4 LGPL gst-plugins-base GStreamer Base Plug-ins prerelease diff --git a/docs/plugins/inspect/plugin-theora.xml b/docs/plugins/inspect/plugin-theora.xml index f75dc67ba1..7aae9c3ead 100644 --- a/docs/plugins/inspect/plugin-theora.xml +++ b/docs/plugins/inspect/plugin-theora.xml @@ -3,7 +3,7 @@ Theora plugin library ../../ext/theora/.libs/libgsttheora.so libgsttheora.so - 0.10.31.3 + 0.10.31.4 LGPL gst-plugins-base GStreamer Base Plug-ins prerelease diff --git a/docs/plugins/inspect/plugin-typefindfunctions.xml b/docs/plugins/inspect/plugin-typefindfunctions.xml index af18239150..68ed50101c 100644 --- a/docs/plugins/inspect/plugin-typefindfunctions.xml +++ b/docs/plugins/inspect/plugin-typefindfunctions.xml @@ -3,7 +3,7 @@ default typefind functions ../../gst/typefind/.libs/libgsttypefindfunctions.so libgsttypefindfunctions.so - 0.10.31.3 + 0.10.31.4 LGPL gst-plugins-base GStreamer Base Plug-ins prerelease diff --git a/docs/plugins/inspect/plugin-uridecodebin.xml b/docs/plugins/inspect/plugin-uridecodebin.xml index 5a738ce578..4d6c9b7a82 100644 --- a/docs/plugins/inspect/plugin-uridecodebin.xml +++ b/docs/plugins/inspect/plugin-uridecodebin.xml @@ -3,7 +3,7 @@ URI Decoder bin ../../gst/playback/.libs/libgstdecodebin2.so libgstdecodebin2.so - 0.10.31.3 + 0.10.31.4 LGPL gst-plugins-base GStreamer Base Plug-ins prerelease diff --git a/docs/plugins/inspect/plugin-video4linux.xml b/docs/plugins/inspect/plugin-video4linux.xml index 435090d38a..90a172e992 100644 --- a/docs/plugins/inspect/plugin-video4linux.xml +++ b/docs/plugins/inspect/plugin-video4linux.xml @@ -3,7 +3,7 @@ elements for Video 4 Linux ../../sys/v4l/.libs/libgstvideo4linux.so libgstvideo4linux.so - 0.10.31.3 + 0.10.31.4 LGPL gst-plugins-base GStreamer Base Plug-ins prerelease diff --git a/docs/plugins/inspect/plugin-videorate.xml b/docs/plugins/inspect/plugin-videorate.xml index 245333d31a..bbd6c8e272 100644 --- a/docs/plugins/inspect/plugin-videorate.xml +++ b/docs/plugins/inspect/plugin-videorate.xml @@ -3,7 +3,7 @@ Adjusts video frames ../../gst/videorate/.libs/libgstvideorate.so libgstvideorate.so - 0.10.31.3 + 0.10.31.4 LGPL gst-plugins-base GStreamer Base Plug-ins prerelease diff --git a/docs/plugins/inspect/plugin-videoscale.xml b/docs/plugins/inspect/plugin-videoscale.xml index e159cdd0b0..f0161a836f 100644 --- a/docs/plugins/inspect/plugin-videoscale.xml +++ b/docs/plugins/inspect/plugin-videoscale.xml @@ -3,7 +3,7 @@ Resizes video ../../gst/videoscale/.libs/libgstvideoscale.so libgstvideoscale.so - 0.10.31.3 + 0.10.31.4 LGPL gst-plugins-base GStreamer Base Plug-ins prerelease diff --git a/docs/plugins/inspect/plugin-videotestsrc.xml b/docs/plugins/inspect/plugin-videotestsrc.xml index 59812ac369..4b61afaa3d 100644 --- a/docs/plugins/inspect/plugin-videotestsrc.xml +++ b/docs/plugins/inspect/plugin-videotestsrc.xml @@ -3,7 +3,7 @@ Creates a test video stream ../../gst/videotestsrc/.libs/libgstvideotestsrc.so libgstvideotestsrc.so - 0.10.31.3 + 0.10.31.4 LGPL gst-plugins-base GStreamer Base Plug-ins prerelease diff --git a/docs/plugins/inspect/plugin-volume.xml b/docs/plugins/inspect/plugin-volume.xml index acb080fda9..b8db2cf6a0 100644 --- a/docs/plugins/inspect/plugin-volume.xml +++ b/docs/plugins/inspect/plugin-volume.xml @@ -3,7 +3,7 @@ plugin for controlling audio volume ../../gst/volume/.libs/libgstvolume.so libgstvolume.so - 0.10.31.3 + 0.10.31.4 LGPL gst-plugins-base GStreamer Base Plug-ins prerelease diff --git a/docs/plugins/inspect/plugin-vorbis.xml b/docs/plugins/inspect/plugin-vorbis.xml index 32be50deae..62dab2c737 100644 --- a/docs/plugins/inspect/plugin-vorbis.xml +++ b/docs/plugins/inspect/plugin-vorbis.xml @@ -3,7 +3,7 @@ Vorbis plugin library ../../ext/vorbis/.libs/libgstvorbis.so libgstvorbis.so - 0.10.31.3 + 0.10.31.4 LGPL gst-plugins-base GStreamer Base Plug-ins prerelease diff --git a/docs/plugins/inspect/plugin-ximagesink.xml b/docs/plugins/inspect/plugin-ximagesink.xml index 3756f5cf01..f72e084e48 100644 --- a/docs/plugins/inspect/plugin-ximagesink.xml +++ b/docs/plugins/inspect/plugin-ximagesink.xml @@ -3,7 +3,7 @@ X11 video output element based on standard Xlib calls ../../sys/ximage/.libs/libgstximagesink.so libgstximagesink.so - 0.10.31.3 + 0.10.31.4 LGPL gst-plugins-base GStreamer Base Plug-ins prerelease diff --git a/docs/plugins/inspect/plugin-xvimagesink.xml b/docs/plugins/inspect/plugin-xvimagesink.xml index 92479cc15e..735a111f97 100644 --- a/docs/plugins/inspect/plugin-xvimagesink.xml +++ b/docs/plugins/inspect/plugin-xvimagesink.xml @@ -3,7 +3,7 @@ XFree86 video output plugin using Xv extension ../../sys/xvimage/.libs/libgstxvimagesink.so libgstxvimagesink.so - 0.10.31.3 + 0.10.31.4 LGPL gst-plugins-base GStreamer Base Plug-ins prerelease From c5fd3b40fed9b47de9f41ef1c6aacb72ce352811 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim-Philipp=20M=C3=BCller?= Date: Tue, 18 Jan 2011 10:45:01 +0000 Subject: [PATCH 154/254] 0.10.31.4 pre-releases --- configure.ac | 2 +- win32/common/_stdint.h | 2 +- win32/common/config.h | 8 ++++---- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/configure.ac b/configure.ac index 4af26b9896..cbf2bf4772 100644 --- a/configure.ac +++ b/configure.ac @@ -5,7 +5,7 @@ dnl please read gstreamer/docs/random/autotools before changing this file dnl initialize autoconf dnl releases only do -Wall, git and prerelease does -Werror too dnl use a three digit version number for releases, and four for git/prerelease -AC_INIT(GStreamer Base Plug-ins, 0.10.31.3, +AC_INIT(GStreamer Base Plug-ins, 0.10.31.4, http://bugzilla.gnome.org/enter_bug.cgi?product=GStreamer, gst-plugins-base) diff --git a/win32/common/_stdint.h b/win32/common/_stdint.h index 1256a35500..25668c57e8 100644 --- a/win32/common/_stdint.h +++ b/win32/common/_stdint.h @@ -1,7 +1,7 @@ #ifndef _GST_PLUGINS_BASE__STDINT_H #define _GST_PLUGINS_BASE__STDINT_H 1 #ifndef _GENERATED_STDINT_H -#define _GENERATED_STDINT_H "gst-plugins-base 0.10.31.3" +#define _GENERATED_STDINT_H "gst-plugins-base 0.10.31.4" /* generated using gnu compiler gcc (Debian 4.4.5-10) 4.4.5 */ #define _STDINT_HAVE_STDINT_H 1 #include diff --git a/win32/common/config.h b/win32/common/config.h index 1bb7cfbd47..329bede4b9 100644 --- a/win32/common/config.h +++ b/win32/common/config.h @@ -81,7 +81,7 @@ #define GST_PACKAGE_ORIGIN "Unknown package origin" /* GStreamer package release date/time for plugins as YYYY-MM-DD */ -#define GST_PACKAGE_RELEASE_DATETIME "2011-01-11T18:57Z" +#define GST_PACKAGE_RELEASE_DATETIME "2011-01-18T10:17Z" /* I know the API is subject to change. */ #undef G_UDEV_API_IS_SUBJECT_TO_CHANGE @@ -337,7 +337,7 @@ #define PACKAGE_NAME "GStreamer Base Plug-ins" /* Define to the full name and version of this package. */ -#define PACKAGE_STRING "GStreamer Base Plug-ins 0.10.31.3" +#define PACKAGE_STRING "GStreamer Base Plug-ins 0.10.31.4" /* Define to the one symbol short name of this package. */ #define PACKAGE_TARNAME "gst-plugins-base" @@ -346,7 +346,7 @@ #undef PACKAGE_URL /* Define to the version of this package. */ -#define PACKAGE_VERSION "0.10.31.3" +#define PACKAGE_VERSION "0.10.31.4" /* directory where plugins are located */ #ifdef _DEBUG @@ -374,7 +374,7 @@ #undef STDC_HEADERS /* Version number of package */ -#define VERSION "0.10.31.3" +#define VERSION "0.10.31.4" /* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most significant byte first (like Motorola and SPARC, unlike Intel). */ From c2e0ec6d0bef44827476d96ee9e5ae92dec8be46 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim-Philipp=20M=C3=BCller?= Date: Fri, 21 Jan 2011 10:50:06 +0000 Subject: [PATCH 155/254] Release 0.10.32 --- ChangeLog | 1663 ++++++++++++++++- NEWS | 129 +- RELEASE | 407 ++-- configure.ac | 4 +- docs/plugins/inspect/plugin-adder.xml | 4 +- docs/plugins/inspect/plugin-alsa.xml | 4 +- docs/plugins/inspect/plugin-app.xml | 4 +- docs/plugins/inspect/plugin-audioconvert.xml | 4 +- docs/plugins/inspect/plugin-audiorate.xml | 4 +- docs/plugins/inspect/plugin-audioresample.xml | 4 +- docs/plugins/inspect/plugin-audiotestsrc.xml | 4 +- docs/plugins/inspect/plugin-cdparanoia.xml | 4 +- docs/plugins/inspect/plugin-decodebin.xml | 4 +- docs/plugins/inspect/plugin-encoding.xml | 4 +- .../inspect/plugin-ffmpegcolorspace.xml | 2 +- docs/plugins/inspect/plugin-gdp.xml | 4 +- docs/plugins/inspect/plugin-gio.xml | 4 +- docs/plugins/inspect/plugin-gnomevfs.xml | 4 +- docs/plugins/inspect/plugin-libvisual.xml | 4 +- docs/plugins/inspect/plugin-ogg.xml | 4 +- docs/plugins/inspect/plugin-pango.xml | 4 +- docs/plugins/inspect/plugin-playback.xml | 4 +- docs/plugins/inspect/plugin-subparse.xml | 4 +- docs/plugins/inspect/plugin-tcp.xml | 4 +- docs/plugins/inspect/plugin-theora.xml | 4 +- .../inspect/plugin-typefindfunctions.xml | 4 +- docs/plugins/inspect/plugin-uridecodebin.xml | 4 +- docs/plugins/inspect/plugin-video4linux.xml | 4 +- docs/plugins/inspect/plugin-videorate.xml | 4 +- docs/plugins/inspect/plugin-videoscale.xml | 4 +- docs/plugins/inspect/plugin-videotestsrc.xml | 4 +- docs/plugins/inspect/plugin-volume.xml | 4 +- docs/plugins/inspect/plugin-vorbis.xml | 4 +- docs/plugins/inspect/plugin-ximagesink.xml | 4 +- docs/plugins/inspect/plugin-xvimagesink.xml | 4 +- gst-plugins-base.doap | 11 + win32/common/_stdint.h | 2 +- win32/common/config.h | 10 +- 38 files changed, 2003 insertions(+), 345 deletions(-) diff --git a/ChangeLog b/ChangeLog index b79442ba8e..fecf15a46f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,9 +1,1666 @@ -=== release 0.10.31 === +=== release 0.10.32 === -2010-11-30 Tim-Philipp Müller +2011-01-21 Tim-Philipp Müller * configure.ac: - releasing 0.10.31, "Dance Like It's 1982" + releasing 0.10.32, "Your Life You Like It Well" + +2011-01-18 10:45:01 +0000 Tim-Philipp Müller + + * configure.ac: + * win32/common/_stdint.h: + * win32/common/config.h: + 0.10.31.4 pre-releases + +2011-01-18 10:44:01 +0000 Tim-Philipp Müller + + * docs/plugins/gst-plugins-base-plugins.args: + * docs/plugins/inspect/plugin-adder.xml: + * docs/plugins/inspect/plugin-alsa.xml: + * docs/plugins/inspect/plugin-app.xml: + * docs/plugins/inspect/plugin-audioconvert.xml: + * docs/plugins/inspect/plugin-audiorate.xml: + * docs/plugins/inspect/plugin-audioresample.xml: + * docs/plugins/inspect/plugin-audiotestsrc.xml: + * docs/plugins/inspect/plugin-cdparanoia.xml: + * docs/plugins/inspect/plugin-decodebin.xml: + * docs/plugins/inspect/plugin-encoding.xml: + * docs/plugins/inspect/plugin-ffmpegcolorspace.xml: + * docs/plugins/inspect/plugin-gdp.xml: + * docs/plugins/inspect/plugin-gio.xml: + * docs/plugins/inspect/plugin-gnomevfs.xml: + * docs/plugins/inspect/plugin-libvisual.xml: + * docs/plugins/inspect/plugin-ogg.xml: + * docs/plugins/inspect/plugin-pango.xml: + * docs/plugins/inspect/plugin-playback.xml: + * docs/plugins/inspect/plugin-subparse.xml: + * docs/plugins/inspect/plugin-tcp.xml: + * docs/plugins/inspect/plugin-theora.xml: + * docs/plugins/inspect/plugin-typefindfunctions.xml: + * docs/plugins/inspect/plugin-uridecodebin.xml: + * docs/plugins/inspect/plugin-video4linux.xml: + * docs/plugins/inspect/plugin-videorate.xml: + * docs/plugins/inspect/plugin-videoscale.xml: + * docs/plugins/inspect/plugin-videotestsrc.xml: + * docs/plugins/inspect/plugin-volume.xml: + * docs/plugins/inspect/plugin-vorbis.xml: + * docs/plugins/inspect/plugin-ximagesink.xml: + * docs/plugins/inspect/plugin-xvimagesink.xml: + docs: update docs + +2011-01-18 10:40:29 +0000 Tim-Philipp Müller + + * gst-libs/gst/pbutils/encoding-target.c: + * tests/check/libs/profile.c: + encoding-target: change keyfile header to 'GStreamer Encoding Target' + which is more in line with other files such as .desktop files. + +2011-01-18 01:06:50 +0000 Tim-Philipp Müller + + * gst-libs/gst/pbutils/encoding-target.c: + pbutils: don't assume LC_MESSAGES is always defined, also check for ENABLE_NLS + Should fix build with mingw32 build bot again. + +2011-01-18 00:09:37 +0000 Tim-Philipp Müller + + * gst-libs/gst/app/gstappsrc.c: + * gst-libs/gst/app/gstappsrc.h: + * win32/common/libgstapp.def: + app: export gst_app_stream_type_get_type() + API: gst_app_stream_type_get_type() + API: GST_TYPE_APP_STREAM_TYPE + https://bugzilla.gnome.org/show_bug.cgi?id=639747 + +2011-01-17 23:59:48 +0000 Tim-Philipp Müller + + * gst-libs/gst/app/gstappbuffer.c: + app: make GstAppBuffer get_type() function thread-safe + +2011-01-18 01:09:53 +0530 Arun Raghavan + + * gst-libs/gst/pbutils/gstdiscoverer.c: + discoverer: Drop new stream tags once preroll is done + This makes sure we do not touch the stream taglist once the pipeline has + been prerolled. Adding of stream tags happens in the pad event probe + which runs in a different thread from discoverer stream processing, so + modifying the tag list while discoverer might be processing it can + sometimes cause a crash. + https://bugzilla.gnome.org/show_bug.cgi?id=639778 + +2011-01-17 15:30:08 +0530 Arun Raghavan + + * gst-libs/gst/pbutils/gstdiscoverer.c: + discoverer: Validate timeouts before processing them + This avoids a race where the timeout callback is scheduled to run but we + get sufficient information to finish discovery before actually getting + around to executing the callback. See the documentation of + g_source_is_destroyed() for more details. + https://bugzilla.gnome.org/show_bug.cgi?id=639730 + +2011-01-18 00:08:32 +0530 Arun Raghavan + + * gst-libs/gst/pbutils/gstdiscoverer.c: + discoverer: Make sure we call _stop() before being freed + This ensures that everything is properly cleaned up before the + GstDiscoverer object is freed. Specifically, it makes sure that we've + removed the async timeout callback before freeing the object to avoid a + potential crash later on. + https://bugzilla.gnome.org/show_bug.cgi?id=639755 + +2011-01-16 14:55:46 -0800 David Schleef + + * gst/gdp/gstgdppay.c: + gdppay: make newsegment buffer metadata writable + +2011-01-16 16:46:22 +0000 Tim-Philipp Müller + + * gst-libs/gst/pbutils/encoding-target.c: + pbutils: save localised strings properly when writing encoding targets to a file + Use LC_MESSAGES rather than LC_ALL. Save/load description as untranslated string + when using an English language locale. Strip locale information to the language, + so we don't save keys like description[fr_FR.UTF-8]=... + https://bugzilla.gnome.org/show_bug.cgi?id=638860 + +2011-01-13 13:59:41 +0000 Tim-Philipp Müller + + * gst/typefind/gsttypefindfunctions.c: + typefinding: set framed=false on DTS caps + +2011-01-12 17:51:43 +0000 Tim-Philipp Müller + + * gst-libs/gst/pbutils/encoding-profile.c: + * gst-libs/gst/pbutils/encoding-target.c: + docs: add some more Since: markers for new encoding-profile API + +2011-01-12 15:51:52 +0000 Tim-Philipp Müller + + * configure.ac: + configure: require gobject-introspection >= 0.9.12 + Earlier versions don't honour the -L/--library-path option, + which we need. See commit 4d0ccdad in gobject-introspection git. + Should "fix" build on lucid/maverick build bots. + +2011-01-11 19:19:50 +0000 Tim-Philipp Müller + + * configure.ac: + * docs/plugins/gst-plugins-base-plugins.prerequisites: + * docs/plugins/inspect/plugin-adder.xml: + * docs/plugins/inspect/plugin-alsa.xml: + * docs/plugins/inspect/plugin-app.xml: + * docs/plugins/inspect/plugin-audioconvert.xml: + * docs/plugins/inspect/plugin-audiorate.xml: + * docs/plugins/inspect/plugin-audioresample.xml: + * docs/plugins/inspect/plugin-audiotestsrc.xml: + * docs/plugins/inspect/plugin-cdparanoia.xml: + * docs/plugins/inspect/plugin-decodebin.xml: + * docs/plugins/inspect/plugin-encoding.xml: + * docs/plugins/inspect/plugin-ffmpegcolorspace.xml: + * docs/plugins/inspect/plugin-gdp.xml: + * docs/plugins/inspect/plugin-gio.xml: + * docs/plugins/inspect/plugin-gnomevfs.xml: + * docs/plugins/inspect/plugin-libvisual.xml: + * docs/plugins/inspect/plugin-ogg.xml: + * docs/plugins/inspect/plugin-pango.xml: + * docs/plugins/inspect/plugin-playback.xml: + * docs/plugins/inspect/plugin-subparse.xml: + * docs/plugins/inspect/plugin-tcp.xml: + * docs/plugins/inspect/plugin-theora.xml: + * docs/plugins/inspect/plugin-typefindfunctions.xml: + * docs/plugins/inspect/plugin-uridecodebin.xml: + * docs/plugins/inspect/plugin-video4linux.xml: + * docs/plugins/inspect/plugin-videorate.xml: + * docs/plugins/inspect/plugin-videoscale.xml: + * docs/plugins/inspect/plugin-videotestsrc.xml: + * docs/plugins/inspect/plugin-volume.xml: + * docs/plugins/inspect/plugin-vorbis.xml: + * docs/plugins/inspect/plugin-ximagesink.xml: + * docs/plugins/inspect/plugin-xvimagesink.xml: + * win32/common/_stdint.h: + * win32/common/config.h: + 0.10.31.3 pre-release + +2011-01-11 18:59:39 +0000 Tim-Philipp Müller + + * po/da.po: + * po/gl.po: + * po/pt_BR.po: + po: update translations + +2011-01-11 14:41:53 +0000 Bastien Nocera + + * tests/examples/seek/jsseek.c: + * tests/examples/seek/scrubby.c: + * tests/examples/seek/seek.c: + examples: allow building with newer GTK+ + GtkFunction is gone, and there's no update policies for + GtkRanges any more (but the default was continuous anyway, + so no need to set it to that mode explicitly). + https://bugzilla.gnome.org/show_bug.cgi?id=639215 + +2011-01-11 14:59:38 +0000 Tim-Philipp Müller + + * gst-libs/gst/pbutils/Makefile.am: + gobject-introspection: pass --library-path as well to make it find the right libgstreamer + Makes things work again properly in uninstalled setups (and + presumably in installed setups where GStreamer is installed + into a non-standard prefix). Requires fixes from core git. + https://bugzilla.gnome.org/show_bug.cgi?id=639039 + +2011-01-11 14:52:51 +0000 Byeong-ryeol Kim + + * gst-libs/gst/pbutils/Makefile.am: + gobject-introspection: fix issue when gold linker is used + Need to pass libgstreamer-0.10 explicitly to linker, since we're + calling gst_init(), which in turn is needed because the encoding + target get_type() function calls gst_value_register(). + https://bugzilla.gnome.org/show_bug.cgi?id=639039 + +2011-01-11 15:49:54 +0200 Stefan Kost + + * common: + Automatic update of common submodule + From e572c87 to f94d739 + +2011-01-10 16:35:44 +0000 Tim-Philipp Müller + + * common: + Automatic update of common submodule + From ccbaa85 to e572c87 + +2011-01-10 14:53:04 +0000 Tim-Philipp Müller + + * common: + Automatic update of common submodule + From 46445ad to ccbaa85 + +2011-01-10 15:55:26 +0800 Yang Xichuan + + * ext/ogg/gstoggdemux.c: + oggdemux: remove outdated comment + https://bugzilla.gnome.org/show_bug.cgi?id=639121 + +2011-01-08 02:16:19 +0000 Koop Mast + + * configure.ac: + configure: fix bash-ism + https://bugzilla.gnome.org/show_bug.cgi?id=638961 + +2011-01-08 02:10:03 +0000 Tim-Philipp Müller + + * gst-libs/gst/app/Makefile.am: + * gst-libs/gst/audio/Makefile.am: + * gst-libs/gst/cdda/Makefile.am: + * gst-libs/gst/fft/Makefile.am: + * gst-libs/gst/interfaces/Makefile.am: + * gst-libs/gst/netbuffer/Makefile.am: + * gst-libs/gst/pbutils/Makefile.am: + * gst-libs/gst/riff/Makefile.am: + * gst-libs/gst/rtp/Makefile.am: + * gst-libs/gst/rtsp/Makefile.am: + * gst-libs/gst/sdp/Makefile.am: + * gst-libs/gst/tag/Makefile.am: + * gst-libs/gst/video/Makefile.am: + gobject-introspection: use same PKG_CONFIG_PATH for g-ir-compiler as for g-ir-scanner + Make sure to use the PKG_CONFIG_PATH set at configure time instead of + just relying on an env-var set one. This makes sure both g-ir-compiler + and g-ir-scanner use the same PKG_CONFIG_PATH for determining include + paths etc. + +2011-01-08 01:12:02 +0000 Tim-Philipp Müller + + * pkgconfig/gstreamer-app-uninstalled.pc.in: + * pkgconfig/gstreamer-app.pc.in: + * pkgconfig/gstreamer-audio-uninstalled.pc.in: + * pkgconfig/gstreamer-audio.pc.in: + * pkgconfig/gstreamer-cdda-uninstalled.pc.in: + * pkgconfig/gstreamer-cdda.pc.in: + * pkgconfig/gstreamer-fft-uninstalled.pc.in: + * pkgconfig/gstreamer-fft.pc.in: + * pkgconfig/gstreamer-floatcast.pc.in: + * pkgconfig/gstreamer-interfaces-uninstalled.pc.in: + * pkgconfig/gstreamer-interfaces.pc.in: + * pkgconfig/gstreamer-netbuffer-uninstalled.pc.in: + * pkgconfig/gstreamer-netbuffer.pc.in: + * pkgconfig/gstreamer-pbutils-uninstalled.pc.in: + * pkgconfig/gstreamer-pbutils.pc.in: + * pkgconfig/gstreamer-riff-uninstalled.pc.in: + * pkgconfig/gstreamer-riff.pc.in: + * pkgconfig/gstreamer-rtp-uninstalled.pc.in: + * pkgconfig/gstreamer-rtp.pc.in: + * pkgconfig/gstreamer-rtsp-uninstalled.pc.in: + * pkgconfig/gstreamer-rtsp.pc.in: + * pkgconfig/gstreamer-sdp-uninstalled.pc.in: + * pkgconfig/gstreamer-sdp.pc.in: + * pkgconfig/gstreamer-tag-uninstalled.pc.in: + * pkgconfig/gstreamer-tag.pc.in: + * pkgconfig/gstreamer-video-uninstalled.pc.in: + * pkgconfig/gstreamer-video.pc.in: + pkg-config: add girdir and typelibdir variables to .pc files + We need them when building gir and typelib files for + libraries that depend on these, such as gst-rtsp-server + for example, in an uninstalled setup. + +2011-01-07 12:50:07 +0000 Tim-Philipp Müller + + * configure.ac: + * win32/common/_stdint.h: + * win32/common/config.h: + * win32/common/pbutils-enumtypes.c: + * win32/common/video-enumtypes.c: + 0.10.31.2 pre-release + +2011-01-07 13:04:11 +0100 Edward Hervey + + * gst/encoding/gstencodebin.c: + * gst/encoding/gstencodebin.h: + encodebin: Add missing-plugin support + https://bugzilla.gnome.org/show_bug.cgi?id=638903 + +2011-01-07 12:51:11 +0100 Edward Hervey + + * gst/encoding/gstencodebin.c: + encodebin: Extend documentation + https://bugzilla.gnome.org/show_bug.cgi?id=638901 + +2011-01-07 00:43:07 +0000 Tim-Philipp Müller + + * tests/check/Makefile.am: + tests: never disable g_assert() and cast checks for the unit tests + The unit tests are riddled with g_assert() and friends, sometimes + containing functional code like set_state() calls in them even + (looking at you, pipeline/capsfilter-renegotiation). Make sure we + don't disable assert and cast checks for the unit tests even if + this has been specified for the rest of the code base, e.g. via + --disable-glib-asserts. + +2011-01-06 23:17:12 +0000 Tim-Philipp Müller + + * win32/common/libgstpbutils.def: + win32: udpate pbutils .def file for API change + +2011-01-06 23:13:53 +0000 Tim-Philipp Müller + + * docs/plugins/gst-plugins-base-plugins.hierarchy: + * docs/plugins/gst-plugins-base-plugins.interfaces: + * docs/plugins/gst-plugins-base-plugins.prerequisites: + * docs/plugins/inspect/plugin-adder.xml: + * docs/plugins/inspect/plugin-alsa.xml: + * docs/plugins/inspect/plugin-app.xml: + * docs/plugins/inspect/plugin-audioconvert.xml: + * docs/plugins/inspect/plugin-audiorate.xml: + * docs/plugins/inspect/plugin-audioresample.xml: + * docs/plugins/inspect/plugin-audiotestsrc.xml: + * docs/plugins/inspect/plugin-cdparanoia.xml: + * docs/plugins/inspect/plugin-decodebin.xml: + * docs/plugins/inspect/plugin-encoding.xml: + * docs/plugins/inspect/plugin-ffmpegcolorspace.xml: + * docs/plugins/inspect/plugin-gdp.xml: + * docs/plugins/inspect/plugin-gio.xml: + * docs/plugins/inspect/plugin-gnomevfs.xml: + * docs/plugins/inspect/plugin-libvisual.xml: + * docs/plugins/inspect/plugin-ogg.xml: + * docs/plugins/inspect/plugin-pango.xml: + * docs/plugins/inspect/plugin-playback.xml: + * docs/plugins/inspect/plugin-subparse.xml: + * docs/plugins/inspect/plugin-tcp.xml: + * docs/plugins/inspect/plugin-theora.xml: + * docs/plugins/inspect/plugin-typefindfunctions.xml: + * docs/plugins/inspect/plugin-uridecodebin.xml: + * docs/plugins/inspect/plugin-video4linux.xml: + * docs/plugins/inspect/plugin-videorate.xml: + * docs/plugins/inspect/plugin-videoscale.xml: + * docs/plugins/inspect/plugin-videotestsrc.xml: + * docs/plugins/inspect/plugin-volume.xml: + * docs/plugins/inspect/plugin-vorbis.xml: + * docs/plugins/inspect/plugin-ximagesink.xml: + * docs/plugins/inspect/plugin-xvimagesink.xml: + docs: update docs + +2011-01-06 23:13:35 +0000 Tim-Philipp Müller + + * po/fi.po: + * po/ru.po: + po: update translations + +2011-01-06 23:08:34 +0000 Tim-Philipp Müller + + * ext/pango/gsttextoverlay.c: + textoverlay: make text property controllable too + Because we can, and because it's the most interesting one + to control really, after xpos/ypos. + +2011-01-06 23:01:20 +0000 Lane Brooks + + * ext/pango/Makefile.am: + * ext/pango/gsttextoverlay.c: + * ext/pango/gsttextoverlay.h: + textoverlay: make some properties controllable + https://bugzilla.gnome.org/show_bug.cgi?id=638859 + +2011-01-06 20:37:50 +0000 Tim-Philipp Müller + + * tests/check/libs/.gitignore: + tests: ignore new rtsp test binary + +2011-01-05 15:54:15 -0800 David Schleef + + * ext/ogg/gstoggdemux.c: + oggdemux: ignore header pages when looking for keyframe + This was causing keyframe_granule to be set to 0 for all streams + when seeking to the beginning of the stream, i.e., at the + beginning of playback. Fixes #619778. + +2010-12-29 15:27:44 +0000 Vincent Penquerc'h + + * ext/ogg/gstoggstream.c: + oggstream: when the last keyframe position is not known, do not use -1 + Instead, use either 0 or 1, depending on bitstream version, which give + the correct result for streams which aren't cut off at start. + This allows that function to not return negative granpos. + https://bugzilla.gnome.org/show_bug.cgi?id=638276 + +2011-01-06 17:57:41 +0000 christian schaller + + * gst-plugins-base.spec.in: + Update spec file with discoverer and encodebinchanges + +2011-01-05 15:53:09 +0530 Arun Raghavan + + * docs/libs/gst-plugins-base-libs-sections.txt: + * gst-libs/gst/pbutils/gstdiscoverer-types.c: + * gst-libs/gst/pbutils/gstdiscoverer.c: + * gst-libs/gst/pbutils/gstdiscoverer.h: + discoverer: Documentation updates + Some cosmetic changes and expands on some bits of the documentation to + make it more newbie-friendly. + +2011-01-06 13:08:53 +0100 Robert Swain + + * gst/videorate/gstvideorate.c: + * gst/videorate/gstvideorate.h: + videorate: Fix behaviour for frame rate cap changes + The outgoing buffer timestamp is calculated by scaling an output buffer + count by the src pad frame rate caps. If these caps change, we need to + reset the count and work from a new base timestamp. The new output + buffer timestamp is then the count scaled by the new caps values added + onto the base timestamp. + +2011-01-06 08:47:04 +0100 Edward Hervey + + * tools/gst-discoverer.c: + tools: Improve pretty-printing of tags + Avoids escaping strings for nothing and printing out useless buffer contents. + +2011-01-06 08:46:42 +0100 Edward Hervey + + * tools/gst-discoverer.c: + tools: don't leak the GMainLoop + +2011-01-06 00:28:39 +0000 Tim-Philipp Müller + + * gst-libs/gst/pbutils/encoding-target.c: + pbutils: config.h include should come before all other includes + +2011-01-05 22:02:35 +0100 Edward Hervey + + * docs/libs/gst-plugins-base-libs-sections.txt: + * gst-libs/gst/pbutils/encoding-profile.c: + * gst-libs/gst/pbutils/encoding-profile.h: + * gst/encoding/gstencodebin.c: + * tests/check/libs/profile.c: + * tests/examples/encoding/encoding.c: + encoding: encoding_profile_get_output_caps => _get_input_caps + Makes more sense name-wise + +2011-01-05 20:40:39 +0100 Edward Hervey + + * docs/libs/gst-plugins-base-libs-sections.txt: + docs: Add various new symbols + +2011-01-05 01:50:34 +0530 Arun Raghavan + + * gst-libs/gst/pbutils/encoding-profile.c: + * gst-libs/gst/pbutils/encoding-target.c: + encoding-profile: Minor documentation updates + +2011-01-03 19:07:45 +0100 Edward Hervey + + * gst-libs/gst/pbutils/encoding-profile.c: + encoding-profile: Give a better usage example + +2011-01-03 18:52:00 +0100 Edward Hervey + + * docs/libs/gst-plugins-base-libs-sections.txt: + * gst-libs/gst/pbutils/encoding-target.c: + * gst-libs/gst/pbutils/encoding-target.h: + * tests/check/libs/profile.c: + * win32/common/libgstpbutils.def: + encoding-target: Fixup loading/saving methods + +2011-01-03 18:51:22 +0100 Edward Hervey + + * gst-libs/gst/pbutils/encoding-profile.c: + * gst-libs/gst/pbutils/encoding-target.c: + * gst-libs/gst/pbutils/encoding-target.h: + encoding-target: more docs cleanups + +2011-01-03 16:07:49 +0100 Edward Hervey + + * gst-libs/gst/pbutils/encoding-target.c: + * tests/check/libs/profile.c: + encoding-target: Change target suffix to .gep + Along with a bunch of other internal cleanups + +2011-01-03 13:21:26 +0100 Edward Hervey + + * gst-libs/gst/pbutils/encoding-target.c: + * gst-libs/gst/pbutils/encoding-target.h: + encoding-target: Add more docs regarding categories + +2011-01-03 13:20:19 +0100 Edward Hervey + + * docs/libs/gst-plugins-base-libs-sections.txt: + * gst-libs/gst/pbutils/encoding-target.c: + * gst-libs/gst/pbutils/encoding-target.h: + * tests/check/libs/profile.c: + * win32/common/libgstpbutils.def: + encoding-target: Add API for list all categories and targets + API: gst_encoding_list_available_categories + API: gst_encoding_list_all_targets + +2010-12-22 18:18:00 +0100 Edward Hervey + + * docs/libs/gst-plugins-base-libs-sections.txt: + * gst-libs/gst/pbutils/Makefile.am: + * gst-libs/gst/pbutils/encoding-profile.c: + * gst-libs/gst/pbutils/encoding-profile.h: + * tests/check/libs/profile.c: + * win32/common/libgstpbutils.def: + encoding-profile: Add convenience method to find a profile + API: gst_encoding_profile_find + +2010-12-22 18:16:33 +0100 Edward Hervey + + * configure.ac: + * gst-libs/gst/pbutils/encoding-target.c: + * gst-libs/gst/pbutils/encoding-target.h: + * tests/check/libs/profile.c: + encoding-target: Implement save/load feature + Fixes #637735 + +2010-12-22 11:41:41 +0100 Edward Hervey + + * docs/libs/gst-plugins-base-libs-sections.txt: + * gst-libs/gst/pbutils/encoding-profile.c: + * gst-libs/gst/pbutils/encoding-target.c: + * gst-libs/gst/pbutils/encoding-target.h: + * tests/check/libs/profile.c: + * win32/common/libgstpbutils.def: + encoding-target: Add method to get a profile by name + API: gst_encoding_target_get_profile + +2011-01-05 19:30:50 +0100 Edward Hervey + + * gst/encoding/gstencodebin.c: + encodebin: Convert to new GstElementClass::request_new_pad_full vmethod + +2011-01-05 15:31:09 +0100 Edward Hervey + + * gst-libs/gst/pbutils/pbutils.h: + pbutils: Don't forget to include the encoding headers + +2011-01-05 12:02:02 +0100 Edward Hervey + + * gst-libs/gst/video/video.c: + video: Fix uninitialized variables + reported by macosx gcc + +2010-12-07 14:59:46 +0530 Arun Raghavan + + * gst-libs/gst/pbutils/codec-utils.c: + codec-utils: Minor documentation changes + +2011-01-02 15:48:47 -0800 David Schleef + + * gst/typefind/gsttypefindfunctions.c: + typefind: Add stream-format to h264 caps + +2011-01-02 17:21:54 +0000 Tim-Philipp Müller + + * gst-libs/gst/audio/gstbaseaudiosink.c: + baseaudiosink: default to enable-last-buffer=FALSE for audio sinks + There isn't really any good reason to get the last buffer from an + audio sink, so don't make the sink keep it around unnecessarily. + +2010-12-31 12:14:22 +0000 Tim-Philipp Müller + + * configure.ac: + * gst/playback/Makefile.am: + * gst/playback/gstinputselector.c: + * gst/playback/gstinputselector.h: + * gst/playback/gstplay-marshal.list: + * gst/playback/gstplaybin2.c: + playbin2: use input-selector from core instead of internal copy + +2010-12-31 01:24:50 +0000 Tim-Philipp Müller + + * tests/icles/.gitignore: + * tests/icles/Makefile.am: + tests: add input-selector-test and output-selector-test + Moved from gst-plugins-bad into -base, becasue it uses videotestsrc + and other elements from -base, so it can't be in core. + +2010-11-24 12:22:01 +0200 Stefan Kost + + * tests/icles/output-selector-test.c: + output-selector-test: don't hardcode videosinks and use more colorspace conv. + Use autovideosink instead of hardcoded sinks. Use an additional colorspace + converter between videotestsrc and timeoverlay. + +2009-10-27 11:51:05 -0700 Michael Smith + + * tests/icles/output-selector-test.c: + tests: Remove executable bits from non-executable files. + +2009-02-24 16:33:51 +0100 Sebastian Dröge + + * tests/icles/input-selector-test.c: + tests: move examples directory to tests/examples as in every other GStreamer module + +2008-06-19 13:18:24 +0000 Stefan Kost + + tests: Use BOILERPLATE macro and update output-selector test to the latest api changes. + Original commit message from CVS: + * gst/selector/gstoutputselector.c: + * tests/icles/output-selector-test.c: + Use BOILERPLATE macro and update test to the latest api changes. + +2008-02-07 13:48:20 +0000 Stefan Kost + + tests/icles/output-selector-test.c: Add a fixme comment. + Original commit message from CVS: + * gst/multifile/gstmultifilesink.c: + Add a fixme comment. + * gst/selector/gstoutputselector.c: + Fix same leak as in input-selector. + * tests/icles/output-selector-test.c: + Improve the test. + +2008-01-29 07:38:31 +0000 Stefan Kost + + Replace the switch plugin with the selector plugin. Add output-selector as the opposite of input-selector (was switc... + Original commit message from CVS: + * configure.ac: + * docs/plugins/Makefile.am: + * docs/plugins/gst-plugins-bad-plugins-docs.sgml: + * docs/plugins/gst-plugins-bad-plugins-sections.txt: + * docs/plugins/gst-plugins-bad-plugins.args: + * docs/plugins/gst-plugins-bad-plugins.hierarchy: + * docs/plugins/gst-plugins-bad-plugins.interfaces: + * docs/plugins/gst-plugins-bad-plugins.signals: + * docs/plugins/inspect/plugin-metadata.xml: + * docs/plugins/inspect/plugin-selector.xml: + * docs/plugins/inspect/plugin-soundtouch.xml: + * docs/plugins/inspect/plugin-switch.xml: + * gst/selector/.cvsignore: + * gst/selector/Makefile.am: + * gst/selector/gstinputselector.c: + * gst/selector/gstinputselector.h: + * gst/selector/gstoutputselector.c: + * gst/selector/gstoutputselector.h: + * gst/selector/gstselector-marshal.list: + * gst/selector/gstselector.c: + * gst/selector/selector.vcproj: + * gst/switch/.cvsignore: + * gst/switch/Makefile.am: + * gst/switch/gstswitch-marshal.list: + * gst/switch/gstswitch.c: + * gst/switch/gstswitch.h: + * gst/switch/switch.vcproj: + * tests/icles/.cvsignore: + * tests/icles/Makefile.am: + * tests/icles/output-selector-test.c: + Replace the switch plugin with the selector plugin. Add output- + selector as the opposite of input-selectoo (was switch). Add a test + for output-selector. Add docs for the elements. The vcproj needs + update. Fixes #500142. + +2010-12-30 18:08:05 +0100 Wim Taymans + + * gst-libs/gst/rtp/gstbasertpaudiopayload.c: + baseaudiopay: fix timestamps on buffer lists + Fix the outgoing timestamps and RTP timestamps on outgoing buffers when using + buffer lists. + +2010-12-29 22:36:41 +0000 Tim-Philipp Müller + + * gst/typefind/gsttypefindfunctions.c: + typefinding: assume EBML files without doctype are matroska + https://bugzilla.gnome.org/show_bug.cgi?id=638019 + +2010-12-29 12:53:36 +0100 Wim Taymans + + * gst/tcp/gstmultifdsink.c: + multifdsink: only keep last valid timestamp + Fixes #634397 + +2010-10-13 17:09:13 +0200 Andoni Morales Alastruey + + * gst/tcp/gstmultifdsink.c: + * gst/tcp/gstmultifdsink.h: + multifdsink: add first and last buffer's timestamp to the stats + +2010-12-29 11:51:42 +0000 Tim-Philipp Müller + + * ext/ogg/gstoggstream.c: + ogg: fix typo in comment + +2010-12-28 17:39:58 +0000 Vincent Penquerc'h + + * ext/ogg/gstoggstream.c: + oggstream: fix interpretation of Theora granule position + The offset part of the granpos is not a sign of the newer encoding. + Use the version number instead. + This fixes the criticals thrown by theoraparse, and (at last) the + remaining part of #553244. + +2010-11-25 17:01:04 +0100 Havard Graff + + * gst-libs/gst/audio/gstbaseaudiosink.c: + baseaudiosink: protect against ringbuffer disappearing while in a query + Observed a case where the sink went to null-state during the query, + hence the ringbuffer-pointer was NULL, causing a crash. + Moving the ringbuffer-check code until after the query, and hold the + lock during the check and while using the spec-values. It should not matter + to the query wether the ringbuffer is present or not, and it actually + gets a time bit more time to get the ringbuffer set up in this case! + Fixes #635231 + +2010-12-28 19:39:18 +0100 Wim Taymans + + * ext/ogg/gstoggdemux.c: + oggdemux: handle pads that are not added yet + Don't try to stream data on pads that are not added yet. This happens while we + discover the different streams. + +2010-12-28 11:41:49 +0100 Wim Taymans + + * gst-libs/gst/rtp/gstbasertpdepayload.c: + basedepay: fix refcounting issue + Make sure that when _make_writable() returns a new buffer, we actually push that + one instead of the old one. + +2010-12-25 15:22:42 +0000 Vincent Penquerc'h + + * ext/ogg/gstoggstream.c: + oggstream: implement tag extraction for Kate streams + This will mainly allow Totem to know the language of those streams, + so the subtitle selection menu gets properly filled out. + https://bugzilla.gnome.org/show_bug.cgi?id=638005 + +2010-12-26 17:29:38 +0000 Tim-Philipp Müller + + * gst-libs/gst/pbutils/descriptions.c: + pbutils: add description for DVB subtitle caps + +2010-12-23 17:18:17 +0000 Vincent Penquerc'h + + * ext/ogg/gstoggdemux.c: + oggdemux: set headers on caps + This will allow switching from one stream to another without having to send + the headers for the new stream again. + https://bugzilla.gnome.org/show_bug.cgi?id=637927 + +2010-12-22 15:29:56 -0800 David Schleef + + * ext/ogg/gstoggstream.c: + oggstream: Fix parsing of theora size + +2010-12-22 19:06:56 +0000 Vincent Penquerc'h + + * ext/ogg/gstoggdemux.c: + oggdemux: Don't use gst_pad_alloc_buffer() + allocate buffers using gst_buffer_new_and_alloc() instead of + gst_pad_alloc_buffer_and_set_caps(), as the first one will + cause the pad to block, and we don't want that since that will + prevent subsequent pads from being fed if a block occurs at + start, when all pads must be fed for playback to start. + This fixes autoplugging of the tiger element and other things. + https://bugzilla.gnome.org/show_bug.cgi?id=637822 + +2010-12-22 18:12:14 +0100 Edward Hervey + + * gst/encoding/gstencodebin.c: + encodebin: Also use "Formatter"s for container formats + +2010-12-22 18:19:48 +0100 Edward Hervey + + * gst-libs/gst/pbutils/encoding-target.c: + encoding-target: Fix typo + +2010-12-22 10:32:03 -0300 Thiago Santos + + * gst-libs/gst/tag/gstexiftag.c: + tag: exif: Fix unitialized data warning + Fixes a valgrind warning on jifmux tests on -bad caused by + unitialized bytes. + Fixes #637758 + +2010-12-22 13:56:12 +0100 Alessandro Decina + + * gst/encoding/gstencodebin.c: + encodebin: minor fix in error handling. + Don't call gst_bin_remove (bin, ). + +2010-12-21 18:51:29 +0100 Edward Hervey + + * gst-libs/gst/pbutils/encoding-target.c: + * gst-libs/gst/pbutils/gstdiscoverer-types.c: + * gst-libs/gst/pbutils/gstdiscoverer.c: + * gst-libs/gst/pbutils/install-plugins.c: + * gst-libs/gst/pbutils/missing-plugins.c: + pbutils: More gtk-doc annotations + +2010-12-21 10:26:40 +0000 Vincent Penquerc'h + + * gst/playback/gstplaybin2.c: + playbin2: delay stream-changed messages + https://bugzilla.gnome.org/show_bug.cgi?id=637586 + +2010-12-21 16:33:50 +0100 Edward Hervey + + * gst-libs/gst/pbutils/encoding-target.c: + * tests/check/libs/profile.c: + encoding-target: Ensure target names and categories are valid + +2010-12-21 15:11:10 +0100 Wim Taymans + + * gst-libs/gst/rtp/gstbasertpdepayload.h: + depay: update some docs + +2010-12-21 15:02:18 +0100 Wim Taymans + + * gst-libs/gst/rtp/gstbasertpdepayload.c: + * gst-libs/gst/rtp/gstbasertpdepayload.h: + rtpdepayloade: add support for getting events + Add support for intercepting sink events in the depayloader by adding a new + vmethod. + +2010-12-21 13:37:41 +0100 Wim Taymans + + * ext/vorbis/gstvorbisdec.c: + vorbisdec: keep timestamps when no decoded output + Keep track of the timestamps even when we didn't generate decodable output. + +2010-12-21 13:19:38 +0100 Wim Taymans + + * ext/vorbis/gstvorbisdec.c: + vorbisdec: avoid using invalid timestamps + +2010-12-21 10:41:27 +0100 Wim Taymans + + * tests/examples/seek/seek.c: + seek: don't pause for live buffering messages + +2010-12-20 18:29:15 +0100 Wim Taymans + + * gst-libs/gst/rtp/gstbasertppayload.c: + basertppay: use RTP base time when invalid timestamps + When we have an invalid running-time (because we clipped, for example) use the + RTP base time for timestamping instead of generating wrong RTP timestamps. + +2010-12-20 18:28:14 +0100 Wim Taymans + + * gst-libs/gst/rtp/gstbasertppayload.c: + rtppayload: copy applied rate to segment + Use set_segment_full to copy all segment values to the segment structure. + +2010-12-21 13:09:34 +0100 Edward Hervey + + * tests/check/elements/encodebin.c: + * tests/check/libs/profile.c: + tests: Update container-less profile checks + +2010-12-21 13:08:15 +0100 Edward Hervey + + * gst-libs/gst/pbutils/encoding-profile.c: + encoding-profile: Add guard against profiles without format + +2010-12-21 13:07:27 +0100 Edward Hervey + + * gst/encoding/gstencodebin.c: + encodebin: Fix usage of non-container profiles + +2010-12-17 16:10:53 +0100 Edward Hervey + + * docs/plugins/inspect/plugin-videoscale.xml: + docs: Update for videoscale class changes + +2010-12-20 17:46:48 +0100 Edward Hervey + + * common: + Automatic update of common submodule + From 169462a to 46445ad + +2010-12-19 13:41:22 +0100 Edward Hervey + + * gst-libs/gst/pbutils/gstdiscoverer.c: + gstdiscoverer: Don't leak tags + +2010-12-19 13:22:23 +0100 Edward Hervey + + * tools/gst-discoverer.c: + gst-discoverer: show global tags by default + +2010-12-19 09:53:08 +0100 Sebastian Dröge + + * tests/check/libs/rtsp.c: + rtsp: Fix memory leaks in the gst_rtsp_url_decode_path_components() unit tests + +2010-12-18 20:47:00 +0100 Sebastian Dröge + + * tests/examples/encoding/Makefile.am: + examples: Fix encodebin example CFLAGS and LDFLAGS + Previously it would only succeed to link if a new enough + libgstpbutils-0.10 was installed in the default library + search path. + +2010-12-17 14:16:18 +0000 Vincent Penquerc'h + + * ext/ogg/gstoggdemux.c: + * ext/ogg/gstoggstream.c: + ogg: implement packet duration query for kate streams + https://bugzilla.gnome.org/show_bug.cgi?id=637519 + +2010-12-17 19:06:27 -0600 Rob Clark + + * gst-libs/gst/pbutils/encoding-profile.c: + * gst-libs/gst/pbutils/encoding-profile.h: + * gst/encoding/gstencodebin.c: + fix compile errors on macosx + with i686-apple-darwin10-gcc-4.2.1: + encoding-profile.h:134: warning: type qualifiers ignored on function return type + encoding-profile.c:240: warning: type qualifiers ignored on function return type + gstencodebin.c: In function 'next_unused_stream_profile': + gstencodebin.c:454: warning: format '%d' expects type 'int', but argument 8 has type 'GType' + gstencodebin.c:464: warning: format '%d' expects type 'int', but argument 8 has type 'GType' + +2010-12-17 00:49:26 -0800 Leo Singer + + * gst/audioresample/gstaudioresample.c: + audioresample: corrected buffer duration calculation to account for nonzero initial timestamp + Since we calculate timestamps by: + timestamp = t0 + (out samples) / (out rate) + and durations by: + duration = ((out samples) + (processed samples)) / (out rate) - timestamp + if t0 is nonzero, this would simplify to + duration = t0 + (processed samples) / (out rate). + This duration is too large by the amount t0. We should have done: + duration = t0 + ((out samples) + (processed samples)) / (out rate) - timestamp + so that + duration = (processed samples) / (out rate). + +2010-12-16 20:40:33 -0800 Leo Singer + + * gst/audioresample/gstaudioresample.h: + audioresample: changed num_gap_samples, num_nongap_samples from guint32 to guint64 so that gaps of greater than or equal to 2^32 samples do not cause integer overflow + +2010-12-16 20:38:31 -0800 Leo Singer + + * gst/audioresample/gstaudioresample.c: + audioresample: push half a history length, instead of a full history length, at end-of-stream so that output segment and input segment have same duration + +2010-12-16 20:34:13 -0800 Leo Singer + + * gst/audioresample/gstaudioresample.c: + * gst/audioresample/gstaudioresample.h: + audioresample: renamed count_gap, count_nongap to more descriptive num_gap_samples, num_nongap_samples + +2010-12-16 20:32:07 -0800 Leo Singer + + * gst/audioresample/gstaudioresample.c: + audioresample: replaced void* with gpointer + +2010-12-16 20:30:24 -0800 Leo Singer + + * gst/audioresample/gstaudioresample.c: + audioresample: initial filter transient discarded; unit tests passing + +2010-12-16 20:09:58 -0800 Leo Singer + + * gst/audioresample/gstaudioresample.c: + * gst/audioresample/gstaudioresample.h: + * gst/audioresample/resample.c: + * gst/audioresample/speex_resampler.h: + * gst/audioresample/speex_resampler_wrapper.h: + Revert "Revert "audioresample: Add GAP flag support"" + This reverts commit 35c76b3409dde7f2dcc8232388a47a1b99b661a7. + Conflicts: + gst/audioresample/gstaudioresample.c + gst/audioresample/gstaudioresample.h + +2010-12-16 10:26:43 +0000 Vincent Penquerc'h + + * ext/pango/gsttextoverlay.c: + timeoverlay: add missing break + https://bugzilla.gnome.org/show_bug.cgi?id=637377 + +2010-12-16 10:11:43 +0100 Sebastian Dröge + + * gst/videoscale/gstvideoscale.c: + videoscale: Change classification to Filter/Converter/Video/Scaler + +2010-12-15 23:47:29 +0200 Stefan Kost + + * win32/common/libgstrtsp.def: + win32: update the def file with the new rtsp api + +2010-12-15 17:51:36 +0100 Andy Wingo + + add gst_rtsp_url_decode_path_components + * gst-libs/gst/rtsp/gstrtspurl.h: + * gst-libs/gst/rtsp/gstrtspurl.c (gst_rtsp_url_decode_path_components): + New public function, returns a strv of uri-decoded path components. + * tests/check/Makefile.am: + * tests/check/libs/rtsp.c: Add tests. + +2010-12-15 16:35:43 +0100 Wim Taymans + + * win32/common/libgstrtp.def: + win32: update defs file + +2010-12-15 16:30:55 +0100 Wim Taymans + + * gst-libs/gst/rtp/gstrtpbuffer.c: + rtpbuffer: relax arrangement for RTP bufferlists + Don't assume there are exactly 2 buffers but allow cases where the header and + payload are in 1 buffer or where the payload is in more buffers. + +2010-12-15 14:55:34 +0200 Stefan Kost + + * common: + Automatic update of common submodule + From 20742ae to 169462a + +2010-12-15 12:58:47 +0100 Wim Taymans + + * gst-libs/gst/rtp/gstbasertpdepayload.c: + * gst-libs/gst/rtp/gstbasertpdepayload.h: + basedepay: add support for buffer lists in the depayloader + Add support for buffer lists in the depayloader. + +2010-09-13 10:08:47 +0200 Edward Hervey + + * configure.ac: + * tests/examples/Makefile.am: + * tests/examples/encoding/.gitignore: + * tests/examples/encoding/Makefile.am: + * tests/examples/encoding/encoding.c: + * tests/examples/encoding/gstcapslist.c: + * tests/examples/encoding/gstcapslist.h: + examples: encoding example + Along with gstcapslist + +2010-08-13 17:36:38 +0200 Edward Hervey + + * configure.ac: + * docs/plugins/Makefile.am: + * docs/plugins/gst-plugins-base-plugins-docs.sgml: + * docs/plugins/gst-plugins-base-plugins-sections.txt: + * docs/plugins/gst-plugins-base-plugins.args: + * docs/plugins/gst-plugins-base-plugins.hierarchy: + * docs/plugins/gst-plugins-base-plugins.interfaces: + * docs/plugins/gst-plugins-base-plugins.signals: + * docs/plugins/inspect/plugin-encoding.xml: + * docs/plugins/inspect/plugin-libvisual.xml: + * gst/encoding/.gitignore: + * gst/encoding/Makefile.am: + * gst/encoding/gstencode-marshal.list: + * gst/encoding/gstencodebin.c: + * gst/encoding/gstencodebin.h: + * gst/encoding/gstsmartencoder.c: + * gst/encoding/gstsmartencoder.h: + * gst/encoding/gststreamcombiner.c: + * gst/encoding/gststreamcombiner.h: + * gst/encoding/gststreamsplitter.c: + * gst/encoding/gststreamsplitter.h: + * tests/check/Makefile.am: + * tests/check/elements/.gitignore: + * tests/check/elements/encodebin.c: + gst: New encoding plugin + https://bugzilla.gnome.org/show_bug.cgi?id=627476 + +2010-08-13 17:27:52 +0200 Edward Hervey + + * docs/design/Makefile.am: + * docs/design/design-encoding.txt: + * docs/libs/gst-plugins-base-libs-docs.sgml: + * docs/libs/gst-plugins-base-libs-sections.txt: + * docs/libs/gst-plugins-base-libs.types: + * gst-libs/gst/pbutils/Makefile.am: + * gst-libs/gst/pbutils/encoding-profile.c: + * gst-libs/gst/pbutils/encoding-profile.h: + * gst-libs/gst/pbutils/encoding-target.c: + * gst-libs/gst/pbutils/encoding-target.h: + * tests/check/Makefile.am: + * tests/check/libs/.gitignore: + * tests/check/libs/profile.c: + * win32/common/libgstpbutils.def: + pbutils: New Profile library + https://bugzilla.gnome.org/show_bug.cgi?id=627476 + +2010-12-15 12:21:05 +0200 Stefan Kost + + * configure.ac: + configure: use the -Bsymbolic-functions linker flag if supported + This feature turns intra library calls into direct function calls and thus makes + them a little faster. The downside is that this causes problems for e.g. + LD_PRELOAD based tools. Thus add a configure option to turn it off. + +2010-12-14 00:16:13 -0800 David Schleef + + * gst/typefind/gsttypefindfunctions.c: + typefind: Add check for yuv4mpeg + +2010-12-13 18:05:41 +0200 Stefan Kost + + * gst-libs/gst/pbutils/descriptions.c: + pbutils: spell out two more container formats + +2010-12-13 16:20:23 +0200 Stefan Kost + + * gst-libs/gst/pbutils/gstdiscoverer-types.c: + * gst-libs/gst/pbutils/gstdiscoverer.c: + * gst-libs/gst/pbutils/gstdiscoverer.h: + * gst-libs/gst/pbutils/pbutils-private.h: + * tools/gst-discoverer.c: + * win32/common/libgstpbutils.def: + discoverer: query seekability + Besides the duration we can also query the seekability of a stream. Use the new + API in the gst-discoverer tool. + API: gst_discoverer_info_get_seekable + +2010-12-13 16:23:04 +0200 Stefan Kost + + * common: + Automatic update of common submodule + From 011bcc8 to 20742ae + +2010-12-13 13:04:40 +0100 Mark Nauwelaerts + + * tests/check/elements/audioresample.c: + tests: audioresample: adjust unit test to relaxed discont checking + +2010-12-13 12:34:58 +0200 Stefan Kost + + * docs/Makefile.am: + * docs/design/Makefile.am: + make: move the design doc also on the Makefile.am level (for dist) + +2010-12-13 10:05:00 +0100 Mark Nauwelaerts + + * gst/audioresample/gstaudioresample.c: + audioresample: relax discont checking slightly + +2010-12-13 09:56:04 +0100 Mark Nauwelaerts + + * gst/audioresample/gstaudioresample.c: + * gst/audioresample/gstaudioresample.h: + audioresample: provide as much valid output ts and offset as valid input + ... by independently tracking time and offset, rather than having no offset + leading to no output ts. + +2010-12-13 10:41:24 +0200 Stefan Kost + + * gst/typefind/gsttypefindfunctions.c: + typefinders: name "aac" typefinder "audio/aac" + This is in sync how we call the others. + +2010-12-13 09:58:53 +0200 Stefan Kost + + * docs/design-audiosinks.txt: + * docs/design/design-audiosinks.txt: + docs: move design doc to design folder + +2010-12-11 19:33:33 +0200 Zeeshan Ali (Khattak) + + * gst/videotestsrc/generate_sine_table.c: + videotestsrc: Add a missing return statement + +2010-12-11 17:18:49 +0100 Sebastian Dröge + + * gst/playback/gstdecodebin2.c: + decodebin2: Deprecate new-decoded-pad and removed-decoded-pad signals + They're really the same as pad-added and pad-removed from GstElement + and it doesn't make sense to have two signals for the same thing. + +2010-12-11 17:14:36 +0100 Sebastian Dröge + + * gst/playback/gstdecodebin2.c: + decodebin2: Emit "remove-decoded-pad" signal when pads are removed from decodebin2 + Fixes bug #636198. + +2010-12-10 18:57:56 +0100 Wim Taymans + + * gst-libs/gst/app/gstappsink.c: + appsink: unset flushing flag when starting + When we start again after being stopped, clear the flushing flag or else + it will always be TRUE. + Fixes #636769 + +2010-12-09 16:57:35 +0100 Edward Hervey + + * gst-libs/gst/pbutils/descriptions.c: + pbutils: Add/Fix some media descriptions + Fixes #623413 + +2010-12-09 08:40:25 +0100 Gavin Stark + + * sys/xvimage/xvimagesink.c: + xvimagesink: Use gst_caps_can_intersect() instead of gst_caps_intersect() + Fixes a memory leak and bug #636827. + +2010-12-08 12:55:24 +0100 Mark Nauwelaerts + + * gst/typefind/gsttypefindfunctions.c: + typefinding: improve iso media typefinding + ... by also considering compatible brands rather than only aiming at major brand + (of which there are a seemingly ever expanding great many). + +2010-12-08 12:28:32 +0200 Stefan Kost + + * tests/check/libs/pbutils.c: + tests: remove superflous ';' and reindent + +2010-12-08 12:09:45 +0200 Stefan Kost + + * gst-libs/gst/pbutils/gstdiscoverer-types.c: + * gst-libs/gst/pbutils/gstdiscoverer.c: + * gst-libs/gst/rtp/gstrtpbuffer.c: + docs: fix wrong use of Since: keyword + +2010-12-07 20:28:37 +0200 René Stadler + + * tests/check/gst/typefindfunctions.c: + tests: add AC-3, E-AC-3 typefind tests + +2010-12-03 17:33:40 +0200 René Stadler + + * gst/typefind/gsttypefindfunctions.c: + typefind: ignore AC-3 BSIDs 9, 10 and >16 + These are reserved for future extensions which will not be backwards + compatible to E-AC-3. + +2010-12-03 16:54:21 +0200 René Stadler + + * gst/typefind/gsttypefindfunctions.c: + typefind: accept consecutive AC-3 frames of different sizes + This is perfectly valid and occurs in particular when there are + (in)dependent substreams present. + +2010-12-03 16:22:32 +0200 René Stadler + + * gst/typefind/gsttypefindfunctions.c: + typefind: remove useless masking in (E-)AC-3 typefinders + +2010-12-03 16:14:15 +0200 René Stadler + + * gst/typefind/gsttypefindfunctions.c: + typefind: stop scanning after suggesting E-AC-3 caps + +2010-12-03 18:08:58 +0200 René Stadler + + * gst/typefind/gsttypefindfunctions.c: + typefind: fix E-AC-3 frame size parsing + Frame size is given in words; it is already multiplied by two where + needed, so the left shift is superfluous. This extra multiplication + caused the code to inspect the third packet instead of the second, + which would fail for files where the second packet has a size + different from the first. + +2010-12-07 17:35:14 +0100 Edward Hervey + + * gst-libs/gst/rtsp/gstrtsptransport.h: + rtsp: Move around the typedefs to make GIR happy + Otherwise it will generate they symbols as _GstRTSP* (with the leading + underscore). + +2010-12-04 14:48:46 +0000 Tim-Philipp Müller + + * tests/examples/app/appsrc-ra.c: + * tests/examples/app/appsrc-seekable.c: + * tests/examples/app/appsrc-stream.c: + * tests/examples/app/appsrc-stream2.c: + tests: use GLib 2.22 API unconditionally + +2010-12-04 14:45:58 +0000 Tim-Philipp Müller + + * gst-libs/gst/pbutils/gstdiscoverer.c: + * gst-libs/gst/tag/lang.c: + * gst-libs/gst/tag/mklangtables.c: + * gst-libs/gst/video/convertframe.c: + libs: use GLib 2.22 API unconditionally + +2010-12-03 17:41:18 +0100 Benjamin Gaignard + + * Android.mk: + * android/NOTICE: + * android/alsa.mk: + * android/app.mk: + * android/app_plugin.mk: + * android/audio.mk: + * android/audioconvert.mk: + * android/decodebin.mk: + * android/decodebin2.mk: + * android/gdp.mk: + * android/gst-libs/gst/app/gstapp-marshal.c: + * android/gst-libs/gst/app/gstapp-marshal.h: + * android/gst-libs/gst/audio/audio-enumtypes.c: + * android/gst-libs/gst/audio/audio-enumtypes.h: + * android/gst-libs/gst/interfaces/interfaces-enumtypes.c: + * android/gst-libs/gst/interfaces/interfaces-enumtypes.h: + * android/gst-libs/gst/interfaces/interfaces-marshal.c: + * android/gst-libs/gst/interfaces/interfaces-marshal.h: + * android/gst-libs/gst/pbutils/pbutils-enumtypes.c: + * android/gst-libs/gst/pbutils/pbutils-enumtypes.h: + * android/gst-libs/gst/rtsp/gstrtsp-enumtypes.c: + * android/gst-libs/gst/rtsp/gstrtsp-enumtypes.h: + * android/gst-libs/gst/rtsp/gstrtsp-marshal.c: + * android/gst-libs/gst/rtsp/gstrtsp-marshal.h: + * android/gst-libs/gst/video/video-enumtypes.c: + * android/gst-libs/gst/video/video-enumtypes.h: + * android/gst/playback/gstplay-marshal.c: + * android/gst/playback/gstplay-marshal.h: + * android/gst/tcp/gsttcp-enumtypes.c: + * android/gst/tcp/gsttcp-enumtypes.h: + * android/gst/tcp/gsttcp-marshal.c: + * android/gst/tcp/gsttcp-marshal.h: + * android/interfaces.mk: + * android/netbuffer.mk: + * android/pbutils.mk: + * android/playbin.mk: + * android/queue2.mk: + * android/riff.mk: + * android/rtp.mk: + * android/rtsp.mk: + * android/sdp.mk: + * android/tag.mk: + * android/tcp.mk: + * android/typefindfunctions.mk: + * android/video.mk: + Add build system for Android + +2010-12-03 15:46:07 +0100 Wim Taymans + + * win32/common/libgstvideo.def: + defs: add new symbol + +2010-10-27 13:49:41 +0200 Mark Nauwelaerts + + * ext/ogg/gstoggstream.c: + oggstream: additional tag extraction + ... supporting theora, flac, speex, celt. + Fixes #629349. + +2010-10-27 12:08:25 +0200 Mark Nauwelaerts + + * ext/ogg/gstoggdemux.c: + * ext/ogg/gstoggstream.c: + * ext/ogg/gstoggstream.h: + oggstream: use separate tag extraction vfunction + +2010-10-27 11:58:53 +0200 Mark Nauwelaerts + + * ext/ogg/gstoggstream.c: + oggstream: refactor vorbis comment tag extraction + +2010-10-27 11:16:15 +0200 Mark Nauwelaerts + + * ext/ogg/gstoggdemux.c: + oggdemux: plug some oggstream leaks + +2010-10-27 10:59:03 +0200 Mark Nauwelaerts + + * ext/ogg/gstoggstream.c: + * ext/ogg/gstoggstream.h: + oggstream: streamline tag extraction and prevent some leaks + +2010-10-27 10:58:16 +0200 Mark Nauwelaerts + + * ext/ogg/gstoggdemux.c: + oggdemux: send stream tags after newsegment and global tags + +2010-09-14 23:08:51 +0300 Sreerenj Balachandran + + * ext/ogg/gstoggdemux.c: + * ext/ogg/gstoggstream.c: + * ext/ogg/gstoggstream.h: + oggdemux: perform more (vorbis comment header) tag extractions + In particular, move comment header parsing to gstoggstrem.c. + Thanks to Felipe Contreras. + Fixes #629349 (partially). + +2010-10-27 10:20:15 +0200 Mark Nauwelaerts + + * gst-libs/gst/riff/riff-ids.h: + riff: document omitted field in _gst_riff_strf_auds + (aka WAVEFORMATEX) + +2010-10-10 17:15:53 -0700 David Schleef + + * ext/ogg/gstoggstream.c: + oggstream: fix incorrect warning on skeleton headers + +2010-11-20 19:02:50 -0800 David Schleef + + * ext/ogg/gstoggparse.c: + * ext/ogg/gstoggstream.c: + * ext/ogg/gstoggstream.h: + oggparse: Set DELTA_UNIT on buffers + +2010-12-03 00:01:06 +0000 Tim-Philipp Müller + + * tests/check/libs/video.c: + tests: fix video library unit test and skip non-working YUV9/YVU9 parts for now + +2010-12-02 23:49:31 +0000 Tim-Philipp Müller + + * gst-libs/gst/video/video.c: + video: add missing break statement for the GST_VIDEO_FORMAT_RGB8_PALETTED case + +2010-11-15 22:02:07 +0200 Evan Broder + + * tools/gst-visualise-m.m: + gst-visualise: trim unused perl dependency + Remove an unused perl module. Fixes #634522. + +2010-11-01 23:07:12 +0200 Stefan Kost + + * gst/playback/gstplaybin2.c: + playbin2: add some logging for failure case + +2010-11-01 23:06:21 +0200 Stefan Kost + + * gst/playback/gstinputselector.c: + inputselector: log times in human readable form + +2010-11-01 22:44:16 +0200 Stefan Kost + + * gst/playback/gstinputselector.c: + inputselector: more G_PARAM_STATIC_STRINGS use + +2010-11-01 22:42:23 +0200 Stefan Kost + + * gst/playback/gstinputselector.c: + inputselector: move reoccuring logs to LOG and remove a double info + Less debug spew in DEBUG category. No need to log pad again if we use + GST_LOG_OBJECT(pad,...). + +2010-12-02 19:11:37 +0100 Edward Hervey + + * gst-libs/gst/rtsp/Makefile.am: + libgstrtsp: Fix typo in .pc to use for GIR + +2010-12-02 15:16:25 +0100 Edward Hervey + + * docs/libs/gst-plugins-base-libs-sections.txt: + * docs/plugins/gst-plugins-base-plugins.hierarchy: + * docs/plugins/gst-plugins-base-plugins.interfaces: + * docs/plugins/gst-plugins-base-plugins.prerequisites: + docs: Add a whole bunch of symbols that were unused to the proper sections + +2010-11-10 11:02:27 +0100 Wim Taymans + + * gst-libs/gst/sdp/gstsdpmessage.c: + sdp: only parse TTL for IP4 addresses + Only IP4 addresses can have a TTL in the address. + +2010-11-10 10:53:41 +0100 Wim Taymans + + * gst-libs/gst/sdp/gstsdpmessage.c: + * gst-libs/gst/sdp/gstsdpmessage.h: + * win32/common/libgstsdp.def: + sdp: add method to check for multicast addresses + Expose a previously internal method to check for multicast addresses. + See #634093 + +2010-11-03 11:13:08 +0100 Sebastian Dröge + + * gst-libs/gst/pbutils/gstpluginsbaseversion.h.in: + pbutils: Take nano version into account in GST_CHECK_PLUGINS_BASE_VERSION() + If the nano is > 0 the current version should be handled the same as + micro + 1. + +2010-11-03 09:51:40 +0100 Sebastian Dröge + + * gst-libs/gst/video/video.c: + * gst-libs/gst/video/video.h: + video: Add YUV9, YVU9 and IYU1 video formats + API: GST_VIDEO_FORMAT_YUV9: planar 4:1:0 YUV + API: GST_VIDEO_FORMAT_YVU9: planar 4:1:0 YUV (chroma planes swapped) + API: GST_VIDEO_FORMAT_IYU1: packed 4:1:1 YUV (Cr-Y0-Y1-Cb-Y2-Y3) + +2010-11-02 11:57:09 +0100 Sebastian Dröge + + * gst-libs/gst/video/video.c: + * gst-libs/gst/video/video.h: + video: Add 8-bit paletted RGB + API: Add GST_VIDEO_FORMAT_RGB8_PALETTED + API: Add GST_VIDEO_CAPS_RGB8_PALETTED + API: Add gst_video_parse_caps_palette() + +2010-10-31 19:17:28 +0100 Sebastian Dröge + + * ext/gnomevfs/gstgnomevfssrc.c: + gnomevfssrc: Remove dead assignment + +2010-10-31 19:14:27 +0100 Sebastian Dröge + + * gst/tcp/gsttcp.c: + tcp: Remove dead assignment + +2010-10-31 19:11:53 +0100 Sebastian Dröge + + * gst/playback/gstplaysink.c: + playsink: gen_video_chain() always returns a bin, no need to check for that + +2010-10-31 19:08:32 +0100 Sebastian Dröge + + * gst/playback/gststreamsynchronizer.c: + streamsynchronizer: If we get EOS for an unknown stream just do nothing + instead of dereferencing NULL pointers. This can happen if the stream + was just removed from the streamsynchronizer in a bad time. + +2010-10-31 19:06:00 +0100 Sebastian Dröge + + * gst/playback/gstplaysink.c: + playsink: gen_video_deinterlace_chain() always returns a bin, no need to check that + +2010-10-31 19:01:49 +0100 Sebastian Dröge + + * sys/v4l/v4l_calls.c: + v4l: If no video tuner is the requested one don't read unitialized data + +2010-10-25 14:13:16 +0100 Sebastian Dröge + + * sys/ximage/ximagesink.c: + ximagesink: Add docs for the new property + Including Since markers + +2010-10-25 14:11:01 +0100 Sebastian Dröge + + * sys/xvimage/xvimagesink.c: + xvimagesink: Add docs for the new property + Including Since markers + +2010-10-25 14:09:39 +0100 Sebastian Dröge + + * sys/xvimage/xvimagesink.c: + xvimagesink: Use PROP_ instead of ARG_ for the property enums + +2010-10-25 14:09:20 +0100 Andrea Sebastianutti + + * sys/xvimage/xvimagesink.c: + xvimagesink: Add read-only properties window-width and window-height + +2010-10-25 14:08:43 +0100 Andrea Sebastianutti + + * sys/ximage/ximagesink.c: + ximagsink: Add read-only properties window-width and window-height + +2010-10-17 14:26:23 +0200 Sebastian Dröge + + * gst-libs/gst/video/video.c: + video: Return correct component width/height for A420 + +2010-12-02 00:15:25 +0000 Tim-Philipp Müller + + * configure.ac: + Bump GLib requirement to >= 2.22 + See http://gstreamer.freedesktop.org/wiki/ReleasePlanning/GLibRequirement + +2010-12-02 00:12:51 +0000 Tim-Philipp Müller + + * configure.ac: + * docs/plugins/gst-plugins-base-plugins.hierarchy: + * docs/plugins/inspect/plugin-adder.xml: + * docs/plugins/inspect/plugin-alsa.xml: + * docs/plugins/inspect/plugin-app.xml: + * docs/plugins/inspect/plugin-audioconvert.xml: + * docs/plugins/inspect/plugin-audiorate.xml: + * docs/plugins/inspect/plugin-audioresample.xml: + * docs/plugins/inspect/plugin-audiotestsrc.xml: + * docs/plugins/inspect/plugin-cdparanoia.xml: + * docs/plugins/inspect/plugin-decodebin.xml: + * docs/plugins/inspect/plugin-ffmpegcolorspace.xml: + * docs/plugins/inspect/plugin-gdp.xml: + * docs/plugins/inspect/plugin-gio.xml: + * docs/plugins/inspect/plugin-gnomevfs.xml: + * docs/plugins/inspect/plugin-libvisual.xml: + * docs/plugins/inspect/plugin-ogg.xml: + * docs/plugins/inspect/plugin-pango.xml: + * docs/plugins/inspect/plugin-playback.xml: + * docs/plugins/inspect/plugin-subparse.xml: + * docs/plugins/inspect/plugin-tcp.xml: + * docs/plugins/inspect/plugin-theora.xml: + * docs/plugins/inspect/plugin-typefindfunctions.xml: + * docs/plugins/inspect/plugin-uridecodebin.xml: + * docs/plugins/inspect/plugin-video4linux.xml: + * docs/plugins/inspect/plugin-videorate.xml: + * docs/plugins/inspect/plugin-videoscale.xml: + * docs/plugins/inspect/plugin-videotestsrc.xml: + * docs/plugins/inspect/plugin-volume.xml: + * docs/plugins/inspect/plugin-vorbis.xml: + * docs/plugins/inspect/plugin-ximagesink.xml: + * docs/plugins/inspect/plugin-xvimagesink.xml: + * win32/common/_stdint.h: + * win32/common/config.h: + Back to development + +=== release 0.10.31 === + +2010-11-30 19:25:44 +0000 Tim-Philipp Müller + + * ChangeLog: + * NEWS: + * RELEASE: + * configure.ac: + * docs/plugins/gst-plugins-base-plugins.args: + * docs/plugins/gst-plugins-base-plugins.hierarchy: + * docs/plugins/inspect/plugin-adder.xml: + * docs/plugins/inspect/plugin-alsa.xml: + * docs/plugins/inspect/plugin-app.xml: + * docs/plugins/inspect/plugin-audioconvert.xml: + * docs/plugins/inspect/plugin-audiorate.xml: + * docs/plugins/inspect/plugin-audioresample.xml: + * docs/plugins/inspect/plugin-audiotestsrc.xml: + * docs/plugins/inspect/plugin-cdparanoia.xml: + * docs/plugins/inspect/plugin-decodebin.xml: + * docs/plugins/inspect/plugin-ffmpegcolorspace.xml: + * docs/plugins/inspect/plugin-gdp.xml: + * docs/plugins/inspect/plugin-gio.xml: + * docs/plugins/inspect/plugin-gnomevfs.xml: + * docs/plugins/inspect/plugin-libvisual.xml: + * docs/plugins/inspect/plugin-ogg.xml: + * docs/plugins/inspect/plugin-pango.xml: + * docs/plugins/inspect/plugin-playback.xml: + * docs/plugins/inspect/plugin-subparse.xml: + * docs/plugins/inspect/plugin-tcp.xml: + * docs/plugins/inspect/plugin-theora.xml: + * docs/plugins/inspect/plugin-typefindfunctions.xml: + * docs/plugins/inspect/plugin-uridecodebin.xml: + * docs/plugins/inspect/plugin-video4linux.xml: + * docs/plugins/inspect/plugin-videorate.xml: + * docs/plugins/inspect/plugin-videoscale.xml: + * docs/plugins/inspect/plugin-videotestsrc.xml: + * docs/plugins/inspect/plugin-volume.xml: + * docs/plugins/inspect/plugin-vorbis.xml: + * docs/plugins/inspect/plugin-ximagesink.xml: + * docs/plugins/inspect/plugin-xvimagesink.xml: + * gst-plugins-base.doap: + * win32/common/_stdint.h: + * win32/common/config.h: + Release 0.10.31 2010-11-24 17:34:21 +0200 Stefan Kost diff --git a/NEWS b/NEWS index 491aae962a..acd3e61e97 100644 --- a/NEWS +++ b/NEWS @@ -1,4 +1,131 @@ -This is GStreamer Base Plug-ins 0.10.31, "Dance Like It's 1982" +This is GStreamer Base Plug-ins 0.10.32, "Your Life You Like It Well" + +Changes since 0.10.31: + + * GLib requirement is now >= 2.22, gobject-introspection >= 0.9.12 + * New encodebin element + * New encoding profile and encoding targets API in pbutils + * audioresample: corrected buffer duration calculation to account for nonzero initial timestamp + * audioresample: provide as much valid output ts and offset as valid input + * audioresample: push half a history length, instead of a full history length, at end-of-stream + so that output segment and input segment have same duration + * decodebin2: deprecate new-decoded-pad and removed-decoded-pad signals (use "pad-added" and "pad-removed" instead) + * multifdsink: add first and last buffer's timestamp to the stats; only keep last valid timestamp + * oggdemux: extract more tags (vorbis comment headers, Kate) + * oggdemux: ignore header pages when looking for keyframe; set headers on caps + * oggdemux: fix interpretation of Theora granule position and parsing of Theora size + * oggparse: Set DELTA_UNIT on buffers + * playbin2: delay stream-changed messages, fixing KATE subtitle recognition + * textoverlay: make text, xpos, ypos, color, and silent properties controllable + * typefinding: (E)AC-3 and ISO typefinder improvements; add yuv4mpeg typefinder + * typefinding: add "stream-format" to h264 caps, and framed=false to DTS caps + * typefinding: assume EBML files without doctype are matroska + * videorate: fix behaviour for frame rate cap changes + * vorbisdec: avoid using invalid timestamps; keep timestamps when no decoded output + * ximagesink, xvimagesink: add read-only window-width and window-height properties + * baseaudiopay: fix timestamps on buffer lists + * baseaudiosink: protect against ringbuffer disappearing while in a query + * basedepay: add support for buffer lists in the depayloader + * basertppay: use RTP base time when invalid timestamps + * rtpbuffer: relax arrangement for RTP bufferlists + * rtpdepayloader: add support for getting events + * rtppayload: copy applied rate to segment + * sdp: add method to check for multicast addresses + * sdp: only parse TTL for IP4 addresses + * video: add 8-bit paletted RGB, YUV9, YVU9 and IYU1 video formats + * video: return correct component width/height for A420 + +Bugs fixed since 0.10.31: + + * 619778 : oggdemux: fails on zero-length pages with Patent_Absurdity_HD_3540kbit.ogv + * 586570 : Add GAP Flag support to audioresample + * 623413 : pbutils: Add/Fix some media descriptions + * 627476 : New profile library and encoding plugin + * 629349 : [oggdemux] extract stream tags for tagreadbin and transcoding + * 632667 : [ximagesink] added read-only properties window-width and window-height + * 634397 : [multifdsink] [PATCH] Add the timestamp of the first and last buffer to the stats + * 634522 : gst-visualize-m.m imports but doesn't use File::Basename + * 635231 : baseaudiosink: protect against ringbuffer disappearing while in a query + * 636198 : decodebin2: " removed-decoded-pad " signal never fired + * 636769 : [appsink] Flushing property is never reset + * 636827 : Usage of gst_caps_interset where gst_caps_can_intersect was intended? + * 637324 : oggdemux: unable to demux Ogg files with Skeleton in push mode + * 637377 : timeoverlay: add missing break + * 637519 : ogg: implement packet duration query for kate streams + * 637586 : playbin2 fails to recognize subtitle caps from katedec + * 637735 : [encoding-profile] automatic load/save support and registry + * 637758 : [exiftag] Generates buffers with uninitialized data during taglist- > exif buffer serialization + * 637822 : oggdemux: allocate buffers using gst_buffer_new_and_alloc + * 637927 : oggdemux: set headers on caps + * 638200 : [oggdemux] fails to playback video file + * 638276 : oggstream: when the last keyframe position is not known, do not use -1 + * 638859 : textoverlay: make misc. properties controllable + * 638901 : [encodebin] proper element documentation + * 638903 : [encodebin] missing-plugin support + * 638961 : Small configure bashism 0.10.31.2 + * 639039 : gobject-introspection: GstPbutils gir scanner fails to link with gold linker + * 639121 : oggdemux: outdated comment for gst_ogg_demux_submit_buffer() + * 639215 : examples: Allow building with newer GTK+ + * 639730 : discoverer: Validate timeouts before processing them + * 639755 : discoverer: Clean up callbacks in dispose() + * 639778 : discoverer: Drop new stream tags once preroll is done + * 639790 : [gdp] Fix metadata g_warning + * 639747 : Please export GST_TYPE_APP_STREAM_TYPE + * 553244 : theoraparse doesn't work at all (throws criticals and asserts) + + +API added since 0.10.31: + + * gst_app_stream_type_get_type() + * gst_discoverer_info_get_seekable() + * gst_encoding_audio_profile_get_type() + * gst_encoding_audio_profile_new() + * gst_encoding_container_profile_add_profile() + * gst_encoding_container_profile_contains_profile() + * gst_encoding_container_profile_get_profiles() + * gst_encoding_container_profile_get_type() + * gst_encoding_container_profile_new() + * gst_encoding_list_all_targets() + * gst_encoding_list_available_categories() + * gst_encoding_profile_find() + * gst_encoding_profile_get_description() + * gst_encoding_profile_get_format() + * gst_encoding_profile_get_input_caps() + * gst_encoding_profile_get_name() + * gst_encoding_profile_get_presence() + * gst_encoding_profile_get_preset() + * gst_encoding_profile_get_restriction() + * gst_encoding_profile_get_type() + * gst_encoding_profile_get_type_nick() + * gst_encoding_profile_is_equal() + * gst_encoding_profile_set_description() + * gst_encoding_profile_set_format() + * gst_encoding_profile_set_name() + * gst_encoding_profile_set_presence() + * gst_encoding_profile_set_preset() + * gst_encoding_profile_set_restriction() + * gst_encoding_target_add_profile() + * gst_encoding_target_get_category() + * gst_encoding_target_get_description() + * gst_encoding_target_get_name() + * gst_encoding_target_get_profile() + * gst_encoding_target_get_profiles() + * gst_encoding_target_get_type() + * gst_encoding_target_load() + * gst_encoding_target_load_from_file() + * gst_encoding_target_new() + * gst_encoding_target_save() + * gst_encoding_target_save_to_file() + * gst_encoding_video_profile_get_pass() + * gst_encoding_video_profile_get_type() + * gst_encoding_video_profile_get_variableframerate() + * gst_encoding_video_profile_new() + * gst_encoding_video_profile_set_pass() + * gst_encoding_video_profile_set_variableframerate() + * gst_base_rtp_depayload_push_list() + * gst_rtsp_url_decode_path_components() + * gst_sdp_address_is_multicast() + * gst_video_parse_caps_palette() Changes since 0.10.30: diff --git a/RELEASE b/RELEASE index 3a273c9fd2..70d1baa3a7 100644 --- a/RELEASE +++ b/RELEASE @@ -1,5 +1,5 @@ -Release notes for GStreamer Base Plug-ins 0.10.31 "Dance Like It's 1982" +Release notes for GStreamer Base Plug-ins 0.10.32 "Your Life You Like It Well" @@ -9,8 +9,6 @@ GStreamer Base Plug-ins. The 0.10.x series is a stable series targeted at end users. -It is not API or ABI compatible with the stable 0.8.x series. -It is, however, parallel installable with the 0.8.x series. @@ -27,13 +25,14 @@ This module contains elements for, among others: containers: ogg codecs: vorbis, theora text: textoverlay, subparse - sources: audiotestsrc, videotestsrc, gnomevfssrc, giosrc, appsrc + sources: audiotestsrc, videotestsrc, gnomevfssrc, giosrc network: tcp typefind functions audio processing: audioconvert, adder, audiorate, audioresample, volume visualisation: libvisual video processing: ffmpegcolorspace - aggregate elements: uridecodebin, playbin2, decodebin2, decodebin, playbin + aggregate elements: uridecodebin, playbin2, decodebin2, decodebin, playbin, encodebin + libraries: app, audio, cdda, fft, interfaces, netbuffer, pbutils, riff, rtp, rtsp, sdp, tag, video Other modules containing plug-ins are: @@ -54,263 +53,130 @@ contains a set of less supported plug-ins that haven't passed the Features of this release - * adder: Make sure FLUSH_STOP is always sent after a flushing seek - * alsasrc, alsasink: add "card-name" property to get the card name in addition to the device name - * appsrc: don't override buffer caps if appsrc caps are NULL; fix element classification - * audioclock: add a function to invalidate the clock - * audioconvert: optimise remaining conversion code paths with Orc as well - * baseaudiosink,baseaudiosrc: post clock-provide and clock-lost messages when going from/to READY to/from PAUSED - * baseaudiosink: subtract the render_delay from our latency - * decodebin2: don't add non prerolled stream to topology - * ffmpegcolorspace: add support for A420 and fix support for 8 bit paletted RGB and IYU1 - * gnomevfsrc: set GST_PARAM_MUTABLE_READY flag on the "handle" property - * libvisual: add latency query; only drop frames that are really too old - * multifdsink: gdp protocol is deprecated. People should use gdppay instead - * oggdemux: fix seeking with negative rate with skeleton; fix wrong flowreturn handling - * pbutils: AAC profile and level detection utility functions - * pbutils: H.264 and MPEG-4 profile and level extraction utility functions - * pbutils: new GstDiscoverer utility API for extracting metadata and tags - * playbin2, decodebin2: declare stable, deprecate the old playbin/decodebin - * playbin2, uridecodebin: add property to configure ring buffer size - * rtcpbuffer: add function to manipulation the data in RTCP feedback packets - * rtpbuffer: add functions to add RFC 5285 header extensions to GstBufferLists - * rtpbuffer: add function to add RTP header extensions with a two bytes header - * rtpbuffer: add function to append RFC 5285 one byte header extensions - * rtpbuffer: add function to parse RFC 5285 header extensions - * rtpbuffer: add function to read RFC 5285 header extensions from GstBufferLists - * rtpbuffer: add function to transform a GstBuffer into a GstBufferList - * rtsp: improve rtsp timeout calculation and handling - * sdp: add methods to convert between uri and message - * tags: try ISO-8859-1 as second fallback in case WINDOWS-1252 is not supported - * tags: add many more photography/capture tags - * tags: EXIF and XMP tag handling improvements - * textoverlay: add support for NV12, NV21 and AYUV; configurable text color and position - * theoradec: expose telemetry properties only if libtheora was compiled with --enable-telemetry - * theoraenc: add support for two-pass encoding; allow change of bitrate and quality on-the-fly - * tools: standalone gst-discoverer-0.10 tool for discovering media file properties - * typefinding: detect avc1 ftyp as video/quicktime - * typefinding: export 3gp profile in caps - * typefinding: detect enhanced AC-3 - * typefinding: extend AAC typefinder to detect LOAS streams - * typefinding: fix ADTS caps stream-format detail - * typefinding: more reliable mpeg-ts typefinding - * uridecodebin: Only enable progressive downloading if the upstream duration in bytes is known - * video: add gst_video_convert_frame*() utility functions - * videorate: fixate the pixel-aspect-ratio if necessary - * videorate: mark duplicated frames with the GAP flag - * videoscale: add support for adding black borders to keep the DAR if necessary ("add-borders" property) - * videoscale: Fix caps fixating if the height is fixed but the width isn't - * videoscale: only set the PAR if the caps already had a PAR - * videoscale: refactor using more Orc code - * videotestsrc: new patterns: solid-color, ball, bar and smpte100 - * videotestsrc: add "foreground-color" and "background-color" properties, deprecate "colorspec" property - * videotestsrc: add support for UYVP format, fix NV21 rendering - * volume: use Orc to optimise many code paths - * vorbisdec: decode pending buffers upon EOS when doing reverse playback - * xoverlay: add set_window_handle() with guintptr argument, deprecate set_xwindow_id() which doesn't work on some platforms - * xoverlay: allow render rectangle coordinates to be negative + * GLib requirement is now >= 2.22, gobject-introspection >= 0.9.12 + * New encodebin element + * New encoding profile and encoding targets API in pbutils + * audioresample: corrected buffer duration calculation to account for nonzero initial timestamp + * audioresample: provide as much valid output ts and offset as valid input + * audioresample: push half a history length, instead of a full history length, at end-of-stream so that output segment and input segment have same duration + * decodebin2: deprecate new-decoded-pad and removed-decoded-pad signals (use "pad-added" and "pad-removed" instead) + * multifdsink: add first and last buffer's timestamp to the stats; only keep last valid timestamp + * oggdemux: extract more tags (vorbis comment headers, Kate) + * oggdemux: ignore header pages when looking for keyframe; set headers on caps + * oggdemux: fix interpretation of Theora granule position and parsing of Theora size + * oggparse: Set DELTA_UNIT on buffers + * playbin2: delay stream-changed messages, fixing KATE subtitle recognition + * textoverlay: make text, xpos, ypos, color, and silent properties controllable + * typefinding: (E)AC-3 and ISO typefinder improvements; add yuv4mpeg typefinder + * typefinding: add "stream-format" to h264 caps, and framed=false to DTS caps + * typefinding: assume EBML files without doctype are matroska + * videorate: fix behaviour for frame rate cap changes + * vorbisdec: avoid using invalid timestamps; keep timestamps when no decoded output + * ximagesink, xvimagesink: add read-only window-width and window-height properties + * baseaudiopay: fix timestamps on buffer lists + * baseaudiosink: protect against ringbuffer disappearing while in a query + * basedepay: add support for buffer lists in the depayloader + * basertppay: use RTP base time when invalid timestamps + * rtpbuffer: relax arrangement for RTP bufferlists + * rtpdepayloader: add support for getting events + * rtppayload: copy applied rate to segment + * sdp: add method to check for multicast addresses + * sdp: only parse TTL for IP4 addresses + * video: add 8-bit paletted RGB, YUV9, YVU9 and IYU1 video formats + * video: return correct component width/height for A420 Bugs fixed in this release - * 628028 : [uridecodebin] Don't enable progressive downloading for live streams - * 623846 : typefinding: add support for " enhanced ac3 " (eac3) - * 602437 : [playbin2] [gapless] Completely broken when switching between files with audio/video only - * 612264 : Notification needed when the first buffer is pushed by the basertppayloader - * 615471 : [videoscale] Interlaced handling makes output worse than no interlaced handling at all - * 616392 : videotestsrc colorspec=0/1 does not affect color-matrix in caps - * 617314 : pbutils: Add codec-specific utility functions for AAC, H.264, MPEG-4 video - * 617506 : [videoscale] Add support for adding black borders if necessary to keep the DAR - * 620291 : typefindfunctions: Export 3gp profile in caps - * 623663 : [typefinding] mpeg-ts file detected as audio/mpeg - * 623807 : [audioclock] Add gst_audio_clock_new_full() with GDestroyNotify for the user_data - * 623837 : typefind: only associate .webm with WebM - * 623918 : [typefind] Extend AAC typefinder to detect LOAS stream - * 624598 : [adder] crash in orc_sse_set_mxcsr() - * 624656 : [videoscale] UYVY scaling broken, introduces green lines - * 624919 : [videotestsrc] add solid color pattern - * 624920 : [textoverlay] configurable text color and position - * 624949 : [playbin2] declare playbin2 stable - * 625001 : [examples] Don't use GdkDraw/GdkGC - * 625118 : [playbin2] Race condition with EOS events in gapless mode - * 625944 : [pbutils] GstDiscoverer - API to discover metadata and stream information - * 626125 : [alsa] Conditional jump or move depends on uninitialised value(s) - * 626570 : [tag] Add resolution tags - * 626581 : [playbin2] regression: occasional deadlocks in streamsynchronizer - * 626621 : [playbin2] streamsynchronizer regressions - * 626629 : [ffmpegcolorspace] doesn't handle palettes any longer - * 626718 : playback: Delay usage of GstFactoryList - * 627203 : [alsa] alsasrc and alsasink should expose card name via property - * 627297 : [regression] build-failure - * 627565 : [xoverlay][win64] gulong can't hold a HANDLE - * 627768 : add NV12 support to textoverlay - * 627780 : GstClockOverlay re-renders string even if it hasn't changed, resulting in very high CPU usage. - * 627924 : riff: add support for 2vuy - * 628009 : [volume] Float processing with orc broken - * 628400 : [videorate] does not generate buffers to fill the duration of the last frame - * 628500 : videotestsrc: add moving color bars pattern - * 628747 : gst-plugins-base: unable to build because of compiler warning in libggsttag - * 629157 : Move video frame conversion from playback plugin to libgstvideo - * 629672 : gnomevfsrsrc: " handle " property should also have the GST_PARAM_MUTABLE_READY flag - * 629848 : build problem with current gtk+: implicit declaration of function 'gdk_draw_rectangle', GtkStyle' has no member named 'black_gc' - * 630303 : theoraenc: Make the bitrate/quality dynamically modifiable - * 630353 : [appsrc] Avoid losing buffers' caps - * 630440 : ringbuffer: use g_once for type-init - * 630443 : baseaudiosink: Add getter and setter for drift tolerance - * 630471 : [tag] ligatures " Œ " and " œ " are not supported in freeform strings - * 630496 : seek example: add new #define to set seek bar graininess - * 630802 : videotestsrc.c doesn't compile in Visual Studio 2008 - * 631128 : Add methods to manipulate RFC 5285 header extensions - * 631312 : [streamsynchronizer] Advancing segments too much - * 631633 : [oggdemux] fix seeking with negative rate with skeleton - * 631703 : [oggdemux] sintel ogv delay when playing - * 631756 : Fix build with glib 2.21.3 - * 631773 : [tags] Add new exif tags: sharpness, metering mode, file/capturing source - * 631774 : [xvimagesink] sets non-simple caps on pad_alloced buffer - * 632167 : [oggdemux] doesn't parse/push all headers in pull mode - * 632653 : [seek] Don't use deprecated combo box API - * 632656 : [uridecodebin] internal decodebin2 might fail to reach PLAYING in streaming case - * 632789 : [PATCH] tests/icles/: adapted test-colorkey.c and test-xoverlay.c to deprecation of gtk_widget_hide_all - * 632809 : [regression] build failure in 0.10.30.2 in tools/ - * 632988 : [discoverer] gst_caps_ref() critical for substreams of unknown streams - * 633023 : [discoverer] Add versionized gst-discoverer tool - * 633203 : Regression: streamsynchroniser + disabled deinterlacing = no DVD menu highlights/subtitles - * 633311 : discoverer: use specific types in getters, rename some boolean getters - * 633336 : [discoverer] Move documentation into the correct section - * 633455 : [rtsp] don't let the rtsp connection timeout - * 634014 : GTK+3 is a moving target, lets not compile against it by default. - * 634584 : decodebin2 docs should mention that " new-decoded-pad " signal may be emitted after " no-more-pads " - * 635067 : [*decodebin*] pad template leaked - * 635392 : Missing information on exported packages from GIRs - * 621349 : [theoraenc] Implement two-pass encoding - * 628488 : [theoradec] add properties to enable telemetry overlay - * 629746 : Enumerations have incorrect names of enum values (GEnumValue.value_name) - * 626869 : The RTP depayloader is sometimes sending partial frames down the pipeline without the DISCONT bit set + * 619778 : oggdemux: fails on zero-length pages with Patent_Absurdity_HD_3540kbit.ogv + * 586570 : Add GAP Flag support to audioresample + * 623413 : pbutils: Add/Fix some media descriptions + * 627476 : New profile library and encoding plugin + * 629349 : [oggdemux] extract stream tags for tagreadbin and transcoding + * 632667 : [ximagesink] added read-only properties window-width and window-height + * 634397 : [multifdsink] [PATCH] Add the timestamp of the first and last buffer to the stats + * 634522 : gst-visualize-m.m imports but doesn't use File::Basename + * 635231 : baseaudiosink: protect against ringbuffer disappearing while in a query + * 636198 : decodebin2: " removed-decoded-pad " signal never fired + * 636769 : [appsink] Flushing property is never reset + * 636827 : Usage of gst_caps_interset where gst_caps_can_intersect was intended? + * 637324 : oggdemux: unable to demux Ogg files with Skeleton in push mode + * 637377 : timeoverlay: add missing break + * 637519 : ogg: implement packet duration query for kate streams + * 637586 : playbin2 fails to recognize subtitle caps from katedec + * 637735 : [encoding-profile] automatic load/save support and registry + * 637758 : [exiftag] Generates buffers with uninitialized data during taglist- > exif buffer serialization + * 637822 : oggdemux: allocate buffers using gst_buffer_new_and_alloc + * 637927 : oggdemux: set headers on caps + * 638200 : [oggdemux] fails to playback video file + * 638276 : oggstream: when the last keyframe position is not known, do not use -1 + * 638859 : textoverlay: make misc. properties controllable + * 638901 : [encodebin] proper element documentation + * 638903 : [encodebin] missing-plugin support + * 638961 : Small configure bashism 0.10.31.2 + * 639039 : gobject-introspection: GstPbutils gir scanner fails to link with gold linker + * 639121 : oggdemux: outdated comment for gst_ogg_demux_submit_buffer() + * 639215 : examples: Allow building with newer GTK+ + * 639730 : discoverer: Validate timeouts before processing them + * 639755 : discoverer: Clean up callbacks in dispose() + * 639778 : discoverer: Drop new stream tags once preroll is done + * 639790 : [gdp] Fix metadata g_warning + * 639747 : Please export GST_TYPE_APP_STREAM_TYPE + * 553244 : theoraparse doesn't work at all (throws criticals and asserts) API changed in this release - API additions: - * gst_audio_clock_invalidate() - * gst_audio_clock_new_full() - * gst_base_audio_sink_get_drift_tolerance() - * gst_base_audio_sink_set_drift_tolerance() - * gst_x_overlay_got_window_handle() - * gst_x_overlay_set_window_handle() - * GstXOverlay::set_window_handle() - * gst_codec_utils_aac_caps_set_level_and_profile() - * gst_codec_utils_aac_get_level() - * gst_codec_utils_aac_get_profile() - * gst_codec_utils_aac_get_sample_rate_from_index() - * gst_codec_utils_h264_caps_set_level_and_profile() - * gst_codec_utils_h264_get_level() - * gst_codec_utils_h264_get_profile() - * gst_codec_utils_mpeg4video_caps_set_level_and_profile() - * gst_codec_utils_mpeg4video_get_level() - * gst_codec_utils_mpeg4video_get_profile() - * gst_discoverer_audio_info_get_bitrate() - * gst_discoverer_audio_info_get_channels() - * gst_discoverer_audio_info_get_depth() - * gst_discoverer_audio_info_get_max_bitrate() - * gst_discoverer_audio_info_get_sample_rate() - * gst_discoverer_audio_info_get_type() - * gst_discoverer_container_info_get_streams() - * gst_discoverer_container_info_get_type() - * gst_discoverer_discover_uri() - * gst_discoverer_discover_uri_async() - * gst_discoverer_get_type() - * gst_discoverer_info_copy() - * gst_discoverer_info_get_audio_streams() - * gst_discoverer_info_get_container_streams() - * gst_discoverer_info_get_duration() - * gst_discoverer_info_get_misc() - * gst_discoverer_info_get_result() - * gst_discoverer_info_get_stream_info() - * gst_discoverer_info_get_stream_list() - * gst_discoverer_info_get_streams() - * gst_discoverer_info_get_tags() - * gst_discoverer_info_get_type() - * gst_discoverer_info_get_uri() - * gst_discoverer_info_get_video_streams() - * gst_discoverer_new() - * gst_discoverer_result_get_type() - * gst_discoverer_start() - * gst_discoverer_stop() - * gst_discoverer_stream_info_get_caps() - * gst_discoverer_stream_info_get_misc() - * gst_discoverer_stream_info_get_next() - * gst_discoverer_stream_info_get_previous() - * gst_discoverer_stream_info_get_stream_type_nick() - * gst_discoverer_stream_info_get_tags() - * gst_discoverer_stream_info_get_type() - * gst_discoverer_stream_info_list_free() - * gst_discoverer_video_info_get_bitrate() - * gst_discoverer_video_info_get_depth() - * gst_discoverer_video_info_get_framerate_denom() - * gst_discoverer_video_info_get_framerate_num() - * gst_discoverer_video_info_get_height() - * gst_discoverer_video_info_get_max_bitrate() - * gst_discoverer_video_info_get_par_denom() - * gst_discoverer_video_info_get_par_num() - * gst_discoverer_video_info_get_type() - * gst_discoverer_video_info_get_width() - * gst_discoverer_video_info_is_image() - * gst_discoverer_video_info_is_interlaced() - * GST_PLUGINS_BASE_VERSION_MAJOR - * GST_PLUGINS_BASE_VERSION_MINOR - * GST_PLUGINS_BASE_VERSION_MICRO - * GST_PLUGINS_BASE_VERSION_NANO - * GST_CHECK_PLUGINS_BASE_VERSION - * gst_plugins_base_version() - * gst_plugins_base_version_string() - * gst_rtcp_packet_fb_get_fci() - * gst_rtcp_packet_fb_get_fci_length() - * gst_rtcp_packet_fb_set_fci_length() - * gst_rtp_buffer_add_extension_onebyte_header() - * gst_rtp_buffer_add_extension_twobytes_header() - * gst_rtp_buffer_get_extension_onebyte_header() - * gst_rtp_buffer_get_extension_twobytes_header() - * gst_rtp_buffer_list_add_extension_onebyte_header() - * gst_rtp_buffer_list_add_extension_twobytes_header() - * gst_rtp_buffer_list_from_buffer() - * gst_rtp_buffer_list_get_extension_onebyte_header() - * gst_rtp_buffer_list_get_extension_twobytes_header() - * gst_sdp_message_as_uri() - * gst_sdp_message_parse_uri() - * GST_TAG_CAPTURING_SOURCE - * GST_TAG_CAPTURING_METERING_MODE - * GST_TAG_CAPTURING_SHARPNESS - * GST_TAG_IMAGE_HORIZONTAL_PPI - * GST_TAG_IMAGE_VERTICAL_PPI - * GST_TAG_CAPTURING_FLASH_FIRED - * GST_TAG_CAPTURING_FLASH_MODE - * GST_TAG_CAPTURING_EXPOSURE_PROGRAM - * GST_TAG_CAPTURING_EXPOSURE_MODE - * GST_TAG_CAPTURING_SCENE_CAPTURE_TYPE - * GST_TAG_CAPTURING_GAIN_ADJUSTMENT - * GST_TAG_CAPTURING_WHITE_BALANCE - * GST_TAG_CAPTURING_CONTRAST - * GST_TAG_CAPTURING_SATURATION - * GST_TAG_CAPTURING_SHUTTER_SPEED - * GST_TAG_CAPTURING_FOCAL_RATIO - * GST_TAG_CAPTURING_FOCAL_LENGTH - * GST_TAG_CAPTURING_DIGITAL_ZOOM_RATIO - * GST_TAG_CAPTURING_ISO_SPEED - * GST_VIDEO_FORMAT_UYVP - * GST_VIDEO_FORMAT_A420 - * gst_video_convert_frame() - * gst_video_convert_frame_async() - * GstTextOverlay:xpos - * GstTextOverlay:ypos - * GstTextOverlay:color - * GstVideoTestSrc:solid-color - * GstVideoTestSrc::foreground-color - * GstVideoTestSrc::background-color - -- API deprecations: - - * gst_x_overlay_set_xwindow_id() - * gst_x_overlay_got_xwindow_id() - * GstXOverlay::set_xwindow_id() + * gst_app_stream_type_get_type() + * gst_discoverer_info_get_seekable() + * gst_encoding_audio_profile_get_type() + * gst_encoding_audio_profile_new() + * gst_encoding_container_profile_add_profile() + * gst_encoding_container_profile_contains_profile() + * gst_encoding_container_profile_get_profiles() + * gst_encoding_container_profile_get_type() + * gst_encoding_container_profile_new() + * gst_encoding_list_all_targets() + * gst_encoding_list_available_categories() + * gst_encoding_profile_find() + * gst_encoding_profile_get_description() + * gst_encoding_profile_get_format() + * gst_encoding_profile_get_input_caps() + * gst_encoding_profile_get_name() + * gst_encoding_profile_get_presence() + * gst_encoding_profile_get_preset() + * gst_encoding_profile_get_restriction() + * gst_encoding_profile_get_type() + * gst_encoding_profile_get_type_nick() + * gst_encoding_profile_is_equal() + * gst_encoding_profile_set_description() + * gst_encoding_profile_set_format() + * gst_encoding_profile_set_name() + * gst_encoding_profile_set_presence() + * gst_encoding_profile_set_preset() + * gst_encoding_profile_set_restriction() + * gst_encoding_target_add_profile() + * gst_encoding_target_get_category() + * gst_encoding_target_get_description() + * gst_encoding_target_get_name() + * gst_encoding_target_get_profile() + * gst_encoding_target_get_profiles() + * gst_encoding_target_get_type() + * gst_encoding_target_load() + * gst_encoding_target_load_from_file() + * gst_encoding_target_new() + * gst_encoding_target_save() + * gst_encoding_target_save_to_file() + * gst_encoding_video_profile_get_pass() + * gst_encoding_video_profile_get_type() + * gst_encoding_video_profile_get_variableframerate() + * gst_encoding_video_profile_new() + * gst_encoding_video_profile_set_pass() + * gst_encoding_video_profile_set_variableframerate() + * gst_base_rtp_depayload_push_list() + * gst_rtsp_url_decode_path_components() + * gst_sdp_address_is_multicast() + * gst_video_parse_caps_palette() Download @@ -340,25 +206,23 @@ Applications Contributors to this release * Alessandro Decina - * Alexey Fisher - * American Dynamics - * Andrzej K. Haczewski + * Andoni Morales Alastruey + * Andrea Sebastianutti + * Andy Wingo * Arun Raghavan - * Chris Shoemaker + * Bastien Nocera + * Benjamin Gaignard + * Byeong-ryeol Kim * David Schleef * Edward Hervey - * Evan Nemerson - * Guillaume Emont - * Harri Mähönen + * Evan Broder + * Gavin Stark * Havard Graff - * Jan Schmidt + * Koop Mast + * Lane Brooks * Leo Singer * Mark Nauwelaerts - * Matthias Clasen - * Olivier Crête - * Parthasarathi Susarla - * Philip Jägenstedt - * Philippe Normand + * Michael Smith * René Stadler * Rob Clark * Robert Swain @@ -366,11 +230,10 @@ Contributors to this release * Sreerenj Balachandran * Stefan Kost * Thiago Santos - * Thijs Vermeir * Tim-Philipp Müller - * Tristan Matthews * Vincent Penquerc'h - * Vladimir * Wim Taymans - * Zaheer Abbas Merali -  + * Yang Xichuan + * Zeeshan Ali (Khattak) + * christian schaller +  \ No newline at end of file diff --git a/configure.ac b/configure.ac index cbf2bf4772..3325abc63c 100644 --- a/configure.ac +++ b/configure.ac @@ -5,7 +5,7 @@ dnl please read gstreamer/docs/random/autotools before changing this file dnl initialize autoconf dnl releases only do -Wall, git and prerelease does -Werror too dnl use a three digit version number for releases, and four for git/prerelease -AC_INIT(GStreamer Base Plug-ins, 0.10.31.4, +AC_INIT(GStreamer Base Plug-ins, 0.10.32, http://bugzilla.gnome.org/enter_bug.cgi?product=GStreamer, gst-plugins-base) @@ -60,7 +60,7 @@ AC_LIBTOOL_WIN32_DLL AM_PROG_LIBTOOL dnl *** required versions of GStreamer stuff *** -GST_REQ=0.10.31.3 +GST_REQ=0.10.32 dnl *** autotools stuff **** diff --git a/docs/plugins/inspect/plugin-adder.xml b/docs/plugins/inspect/plugin-adder.xml index f2fd2cff12..5085f65d28 100644 --- a/docs/plugins/inspect/plugin-adder.xml +++ b/docs/plugins/inspect/plugin-adder.xml @@ -3,10 +3,10 @@ Adds multiple streams ../../gst/adder/.libs/libgstadder.so libgstadder.so - 0.10.31.4 + 0.10.32 LGPL gst-plugins-base - GStreamer Base Plug-ins prerelease + GStreamer Base Plug-ins source release Unknown package origin diff --git a/docs/plugins/inspect/plugin-alsa.xml b/docs/plugins/inspect/plugin-alsa.xml index 13a0c2594f..4f4dfc8db0 100644 --- a/docs/plugins/inspect/plugin-alsa.xml +++ b/docs/plugins/inspect/plugin-alsa.xml @@ -3,10 +3,10 @@ ALSA plugin library ../../ext/alsa/.libs/libgstalsa.so libgstalsa.so - 0.10.31.4 + 0.10.32 LGPL gst-plugins-base - GStreamer Base Plug-ins prerelease + GStreamer Base Plug-ins source release Unknown package origin diff --git a/docs/plugins/inspect/plugin-app.xml b/docs/plugins/inspect/plugin-app.xml index fd011b5001..6c6994cd85 100644 --- a/docs/plugins/inspect/plugin-app.xml +++ b/docs/plugins/inspect/plugin-app.xml @@ -3,10 +3,10 @@ Elements used to communicate with applications ../../gst/app/.libs/libgstapp.so libgstapp.so - 0.10.31.4 + 0.10.32 LGPL gst-plugins-base - GStreamer Base Plug-ins prerelease + GStreamer Base Plug-ins source release Unknown package origin diff --git a/docs/plugins/inspect/plugin-audioconvert.xml b/docs/plugins/inspect/plugin-audioconvert.xml index 023f3bfa2b..cbd4e58511 100644 --- a/docs/plugins/inspect/plugin-audioconvert.xml +++ b/docs/plugins/inspect/plugin-audioconvert.xml @@ -3,10 +3,10 @@ Convert audio to different formats ../../gst/audioconvert/.libs/libgstaudioconvert.so libgstaudioconvert.so - 0.10.31.4 + 0.10.32 LGPL gst-plugins-base - GStreamer Base Plug-ins prerelease + GStreamer Base Plug-ins source release Unknown package origin diff --git a/docs/plugins/inspect/plugin-audiorate.xml b/docs/plugins/inspect/plugin-audiorate.xml index d3038db415..b1a7bcd037 100644 --- a/docs/plugins/inspect/plugin-audiorate.xml +++ b/docs/plugins/inspect/plugin-audiorate.xml @@ -3,10 +3,10 @@ Adjusts audio frames ../../gst/audiorate/.libs/libgstaudiorate.so libgstaudiorate.so - 0.10.31.4 + 0.10.32 LGPL gst-plugins-base - GStreamer Base Plug-ins prerelease + GStreamer Base Plug-ins source release Unknown package origin diff --git a/docs/plugins/inspect/plugin-audioresample.xml b/docs/plugins/inspect/plugin-audioresample.xml index bf957b434c..88cacca692 100644 --- a/docs/plugins/inspect/plugin-audioresample.xml +++ b/docs/plugins/inspect/plugin-audioresample.xml @@ -3,10 +3,10 @@ Resamples audio ../../gst/audioresample/.libs/libgstaudioresample.so libgstaudioresample.so - 0.10.31.4 + 0.10.32 LGPL gst-plugins-base - GStreamer Base Plug-ins prerelease + GStreamer Base Plug-ins source release Unknown package origin diff --git a/docs/plugins/inspect/plugin-audiotestsrc.xml b/docs/plugins/inspect/plugin-audiotestsrc.xml index 19faa69a5d..e7705766b3 100644 --- a/docs/plugins/inspect/plugin-audiotestsrc.xml +++ b/docs/plugins/inspect/plugin-audiotestsrc.xml @@ -3,10 +3,10 @@ Creates audio test signals of given frequency and volume ../../gst/audiotestsrc/.libs/libgstaudiotestsrc.so libgstaudiotestsrc.so - 0.10.31.4 + 0.10.32 LGPL gst-plugins-base - GStreamer Base Plug-ins prerelease + GStreamer Base Plug-ins source release Unknown package origin diff --git a/docs/plugins/inspect/plugin-cdparanoia.xml b/docs/plugins/inspect/plugin-cdparanoia.xml index c5d4f00320..96cf3622c4 100644 --- a/docs/plugins/inspect/plugin-cdparanoia.xml +++ b/docs/plugins/inspect/plugin-cdparanoia.xml @@ -3,10 +3,10 @@ Read audio from CD in paranoid mode ../../ext/cdparanoia/.libs/libgstcdparanoia.so libgstcdparanoia.so - 0.10.31.4 + 0.10.32 LGPL gst-plugins-base - GStreamer Base Plug-ins prerelease + GStreamer Base Plug-ins source release Unknown package origin diff --git a/docs/plugins/inspect/plugin-decodebin.xml b/docs/plugins/inspect/plugin-decodebin.xml index a316cbd3fd..50bd54dbba 100644 --- a/docs/plugins/inspect/plugin-decodebin.xml +++ b/docs/plugins/inspect/plugin-decodebin.xml @@ -3,10 +3,10 @@ decoder bin ../../gst/playback/.libs/libgstdecodebin.so libgstdecodebin.so - 0.10.31.4 + 0.10.32 LGPL gst-plugins-base - GStreamer Base Plug-ins prerelease + GStreamer Base Plug-ins source release Unknown package origin diff --git a/docs/plugins/inspect/plugin-encoding.xml b/docs/plugins/inspect/plugin-encoding.xml index 83963edb3e..298921996d 100644 --- a/docs/plugins/inspect/plugin-encoding.xml +++ b/docs/plugins/inspect/plugin-encoding.xml @@ -3,10 +3,10 @@ various encoding-related elements ../../gst/encoding/.libs/libgstencodebin.so libgstencodebin.so - 0.10.31.4 + 0.10.32 LGPL gst-plugins-base - GStreamer Base Plug-ins prerelease + GStreamer Base Plug-ins source release Unknown package origin diff --git a/docs/plugins/inspect/plugin-ffmpegcolorspace.xml b/docs/plugins/inspect/plugin-ffmpegcolorspace.xml index b52980d107..bf46cb88fb 100644 --- a/docs/plugins/inspect/plugin-ffmpegcolorspace.xml +++ b/docs/plugins/inspect/plugin-ffmpegcolorspace.xml @@ -3,7 +3,7 @@ colorspace conversion copied from FFMpeg 0.4.9-pre1 ../../gst/ffmpegcolorspace/.libs/libgstffmpegcolorspace.so libgstffmpegcolorspace.so - 0.10.31.4 + 0.10.32 LGPL gst-plugins-base FFMpeg diff --git a/docs/plugins/inspect/plugin-gdp.xml b/docs/plugins/inspect/plugin-gdp.xml index 9ac43936db..5e1c917948 100644 --- a/docs/plugins/inspect/plugin-gdp.xml +++ b/docs/plugins/inspect/plugin-gdp.xml @@ -3,10 +3,10 @@ Payload/depayload GDP packets ../../gst/gdp/.libs/libgstgdp.so libgstgdp.so - 0.10.31.4 + 0.10.32 LGPL gst-plugins-base - GStreamer Base Plug-ins prerelease + GStreamer Base Plug-ins source release Unknown package origin diff --git a/docs/plugins/inspect/plugin-gio.xml b/docs/plugins/inspect/plugin-gio.xml index db0ee8b7a6..c3ce5c002d 100644 --- a/docs/plugins/inspect/plugin-gio.xml +++ b/docs/plugins/inspect/plugin-gio.xml @@ -3,10 +3,10 @@ GIO elements ../../ext/gio/.libs/libgstgio.so libgstgio.so - 0.10.31.4 + 0.10.32 LGPL gst-plugins-base - GStreamer Base Plug-ins prerelease + GStreamer Base Plug-ins source release Unknown package origin diff --git a/docs/plugins/inspect/plugin-gnomevfs.xml b/docs/plugins/inspect/plugin-gnomevfs.xml index e92b7cc9c4..2bf1663f58 100644 --- a/docs/plugins/inspect/plugin-gnomevfs.xml +++ b/docs/plugins/inspect/plugin-gnomevfs.xml @@ -3,10 +3,10 @@ elements to read from and write to Gnome-VFS uri's ../../ext/gnomevfs/.libs/libgstgnomevfs.so libgstgnomevfs.so - 0.10.31.4 + 0.10.32 LGPL gst-plugins-base - GStreamer Base Plug-ins prerelease + GStreamer Base Plug-ins source release Unknown package origin diff --git a/docs/plugins/inspect/plugin-libvisual.xml b/docs/plugins/inspect/plugin-libvisual.xml index 5ee4ddd914..3553cdec12 100644 --- a/docs/plugins/inspect/plugin-libvisual.xml +++ b/docs/plugins/inspect/plugin-libvisual.xml @@ -3,10 +3,10 @@ libvisual visualization plugins ../../ext/libvisual/.libs/libgstlibvisual.so libgstlibvisual.so - 0.10.31.4 + 0.10.32 LGPL gst-plugins-base - GStreamer Base Plug-ins prerelease + GStreamer Base Plug-ins source release Unknown package origin diff --git a/docs/plugins/inspect/plugin-ogg.xml b/docs/plugins/inspect/plugin-ogg.xml index f857ce6e59..e7e137f944 100644 --- a/docs/plugins/inspect/plugin-ogg.xml +++ b/docs/plugins/inspect/plugin-ogg.xml @@ -3,10 +3,10 @@ ogg stream manipulation (info about ogg: http://xiph.org) ../../ext/ogg/.libs/libgstogg.so libgstogg.so - 0.10.31.4 + 0.10.32 LGPL gst-plugins-base - GStreamer Base Plug-ins prerelease + GStreamer Base Plug-ins source release Unknown package origin diff --git a/docs/plugins/inspect/plugin-pango.xml b/docs/plugins/inspect/plugin-pango.xml index 32388269ef..f41c1ba9c6 100644 --- a/docs/plugins/inspect/plugin-pango.xml +++ b/docs/plugins/inspect/plugin-pango.xml @@ -3,10 +3,10 @@ Pango-based text rendering and overlay ../../ext/pango/.libs/libgstpango.so libgstpango.so - 0.10.31.4 + 0.10.32 LGPL gst-plugins-base - GStreamer Base Plug-ins prerelease + GStreamer Base Plug-ins source release Unknown package origin diff --git a/docs/plugins/inspect/plugin-playback.xml b/docs/plugins/inspect/plugin-playback.xml index b98913b1ba..234a72dc3f 100644 --- a/docs/plugins/inspect/plugin-playback.xml +++ b/docs/plugins/inspect/plugin-playback.xml @@ -3,10 +3,10 @@ various playback elements ../../gst/playback/.libs/libgstplaybin.so libgstplaybin.so - 0.10.31.4 + 0.10.32 LGPL gst-plugins-base - GStreamer Base Plug-ins prerelease + GStreamer Base Plug-ins source release Unknown package origin diff --git a/docs/plugins/inspect/plugin-subparse.xml b/docs/plugins/inspect/plugin-subparse.xml index a978ecb254..7557b7cc3b 100644 --- a/docs/plugins/inspect/plugin-subparse.xml +++ b/docs/plugins/inspect/plugin-subparse.xml @@ -3,10 +3,10 @@ Subtitle parsing ../../gst/subparse/.libs/libgstsubparse.so libgstsubparse.so - 0.10.31.4 + 0.10.32 LGPL gst-plugins-base - GStreamer Base Plug-ins prerelease + GStreamer Base Plug-ins source release Unknown package origin diff --git a/docs/plugins/inspect/plugin-tcp.xml b/docs/plugins/inspect/plugin-tcp.xml index c467234b8e..e4b1e8ec86 100644 --- a/docs/plugins/inspect/plugin-tcp.xml +++ b/docs/plugins/inspect/plugin-tcp.xml @@ -3,10 +3,10 @@ transfer data over the network via TCP ../../gst/tcp/.libs/libgsttcp.so libgsttcp.so - 0.10.31.4 + 0.10.32 LGPL gst-plugins-base - GStreamer Base Plug-ins prerelease + GStreamer Base Plug-ins source release Unknown package origin diff --git a/docs/plugins/inspect/plugin-theora.xml b/docs/plugins/inspect/plugin-theora.xml index 7aae9c3ead..8a8751e088 100644 --- a/docs/plugins/inspect/plugin-theora.xml +++ b/docs/plugins/inspect/plugin-theora.xml @@ -3,10 +3,10 @@ Theora plugin library ../../ext/theora/.libs/libgsttheora.so libgsttheora.so - 0.10.31.4 + 0.10.32 LGPL gst-plugins-base - GStreamer Base Plug-ins prerelease + GStreamer Base Plug-ins source release Unknown package origin diff --git a/docs/plugins/inspect/plugin-typefindfunctions.xml b/docs/plugins/inspect/plugin-typefindfunctions.xml index 68ed50101c..420a4d013d 100644 --- a/docs/plugins/inspect/plugin-typefindfunctions.xml +++ b/docs/plugins/inspect/plugin-typefindfunctions.xml @@ -3,10 +3,10 @@ default typefind functions ../../gst/typefind/.libs/libgsttypefindfunctions.so libgsttypefindfunctions.so - 0.10.31.4 + 0.10.32 LGPL gst-plugins-base - GStreamer Base Plug-ins prerelease + GStreamer Base Plug-ins source release Unknown package origin diff --git a/docs/plugins/inspect/plugin-uridecodebin.xml b/docs/plugins/inspect/plugin-uridecodebin.xml index 4d6c9b7a82..bc3452eb62 100644 --- a/docs/plugins/inspect/plugin-uridecodebin.xml +++ b/docs/plugins/inspect/plugin-uridecodebin.xml @@ -3,10 +3,10 @@ URI Decoder bin ../../gst/playback/.libs/libgstdecodebin2.so libgstdecodebin2.so - 0.10.31.4 + 0.10.32 LGPL gst-plugins-base - GStreamer Base Plug-ins prerelease + GStreamer Base Plug-ins source release Unknown package origin diff --git a/docs/plugins/inspect/plugin-video4linux.xml b/docs/plugins/inspect/plugin-video4linux.xml index 90a172e992..f4d68ddf9b 100644 --- a/docs/plugins/inspect/plugin-video4linux.xml +++ b/docs/plugins/inspect/plugin-video4linux.xml @@ -3,10 +3,10 @@ elements for Video 4 Linux ../../sys/v4l/.libs/libgstvideo4linux.so libgstvideo4linux.so - 0.10.31.4 + 0.10.32 LGPL gst-plugins-base - GStreamer Base Plug-ins prerelease + GStreamer Base Plug-ins source release Unknown package origin diff --git a/docs/plugins/inspect/plugin-videorate.xml b/docs/plugins/inspect/plugin-videorate.xml index bbd6c8e272..77b04e6f63 100644 --- a/docs/plugins/inspect/plugin-videorate.xml +++ b/docs/plugins/inspect/plugin-videorate.xml @@ -3,10 +3,10 @@ Adjusts video frames ../../gst/videorate/.libs/libgstvideorate.so libgstvideorate.so - 0.10.31.4 + 0.10.32 LGPL gst-plugins-base - GStreamer Base Plug-ins prerelease + GStreamer Base Plug-ins source release Unknown package origin diff --git a/docs/plugins/inspect/plugin-videoscale.xml b/docs/plugins/inspect/plugin-videoscale.xml index f0161a836f..4955792158 100644 --- a/docs/plugins/inspect/plugin-videoscale.xml +++ b/docs/plugins/inspect/plugin-videoscale.xml @@ -3,10 +3,10 @@ Resizes video ../../gst/videoscale/.libs/libgstvideoscale.so libgstvideoscale.so - 0.10.31.4 + 0.10.32 LGPL gst-plugins-base - GStreamer Base Plug-ins prerelease + GStreamer Base Plug-ins source release Unknown package origin diff --git a/docs/plugins/inspect/plugin-videotestsrc.xml b/docs/plugins/inspect/plugin-videotestsrc.xml index 4b61afaa3d..5f39f96a8e 100644 --- a/docs/plugins/inspect/plugin-videotestsrc.xml +++ b/docs/plugins/inspect/plugin-videotestsrc.xml @@ -3,10 +3,10 @@ Creates a test video stream ../../gst/videotestsrc/.libs/libgstvideotestsrc.so libgstvideotestsrc.so - 0.10.31.4 + 0.10.32 LGPL gst-plugins-base - GStreamer Base Plug-ins prerelease + GStreamer Base Plug-ins source release Unknown package origin diff --git a/docs/plugins/inspect/plugin-volume.xml b/docs/plugins/inspect/plugin-volume.xml index b8db2cf6a0..db1c008fde 100644 --- a/docs/plugins/inspect/plugin-volume.xml +++ b/docs/plugins/inspect/plugin-volume.xml @@ -3,10 +3,10 @@ plugin for controlling audio volume ../../gst/volume/.libs/libgstvolume.so libgstvolume.so - 0.10.31.4 + 0.10.32 LGPL gst-plugins-base - GStreamer Base Plug-ins prerelease + GStreamer Base Plug-ins source release Unknown package origin diff --git a/docs/plugins/inspect/plugin-vorbis.xml b/docs/plugins/inspect/plugin-vorbis.xml index 62dab2c737..43c5408e87 100644 --- a/docs/plugins/inspect/plugin-vorbis.xml +++ b/docs/plugins/inspect/plugin-vorbis.xml @@ -3,10 +3,10 @@ Vorbis plugin library ../../ext/vorbis/.libs/libgstvorbis.so libgstvorbis.so - 0.10.31.4 + 0.10.32 LGPL gst-plugins-base - GStreamer Base Plug-ins prerelease + GStreamer Base Plug-ins source release Unknown package origin diff --git a/docs/plugins/inspect/plugin-ximagesink.xml b/docs/plugins/inspect/plugin-ximagesink.xml index f72e084e48..d780da94b8 100644 --- a/docs/plugins/inspect/plugin-ximagesink.xml +++ b/docs/plugins/inspect/plugin-ximagesink.xml @@ -3,10 +3,10 @@ X11 video output element based on standard Xlib calls ../../sys/ximage/.libs/libgstximagesink.so libgstximagesink.so - 0.10.31.4 + 0.10.32 LGPL gst-plugins-base - GStreamer Base Plug-ins prerelease + GStreamer Base Plug-ins source release Unknown package origin diff --git a/docs/plugins/inspect/plugin-xvimagesink.xml b/docs/plugins/inspect/plugin-xvimagesink.xml index 735a111f97..ec4a24f9fe 100644 --- a/docs/plugins/inspect/plugin-xvimagesink.xml +++ b/docs/plugins/inspect/plugin-xvimagesink.xml @@ -3,10 +3,10 @@ XFree86 video output plugin using Xv extension ../../sys/xvimage/.libs/libgstxvimagesink.so libgstxvimagesink.so - 0.10.31.4 + 0.10.32 LGPL gst-plugins-base - GStreamer Base Plug-ins prerelease + GStreamer Base Plug-ins source release Unknown package origin diff --git a/gst-plugins-base.doap b/gst-plugins-base.doap index 3ea062fe95..ac4d649872 100644 --- a/gst-plugins-base.doap +++ b/gst-plugins-base.doap @@ -34,6 +34,17 @@ A wide range of video and audio decoders, encoders, and filters are included. + + + 0.10.32 + 0.10 + Your Life You Like It Well + 2011-01-21 + + + + + 0.10.31 diff --git a/win32/common/_stdint.h b/win32/common/_stdint.h index 25668c57e8..083fd25604 100644 --- a/win32/common/_stdint.h +++ b/win32/common/_stdint.h @@ -1,7 +1,7 @@ #ifndef _GST_PLUGINS_BASE__STDINT_H #define _GST_PLUGINS_BASE__STDINT_H 1 #ifndef _GENERATED_STDINT_H -#define _GENERATED_STDINT_H "gst-plugins-base 0.10.31.4" +#define _GENERATED_STDINT_H "gst-plugins-base 0.10.32" /* generated using gnu compiler gcc (Debian 4.4.5-10) 4.4.5 */ #define _STDINT_HAVE_STDINT_H 1 #include diff --git a/win32/common/config.h b/win32/common/config.h index 329bede4b9..61a4c08e85 100644 --- a/win32/common/config.h +++ b/win32/common/config.h @@ -75,13 +75,13 @@ #define GST_MAJORMINOR "0.10" /* package name in plugins */ -#define GST_PACKAGE_NAME "GStreamer Base Plug-ins prerelease" +#define GST_PACKAGE_NAME "GStreamer Base Plug-ins source release" /* package origin */ #define GST_PACKAGE_ORIGIN "Unknown package origin" /* GStreamer package release date/time for plugins as YYYY-MM-DD */ -#define GST_PACKAGE_RELEASE_DATETIME "2011-01-18T10:17Z" +#define GST_PACKAGE_RELEASE_DATETIME "2011-01-21" /* I know the API is subject to change. */ #undef G_UDEV_API_IS_SUBJECT_TO_CHANGE @@ -337,7 +337,7 @@ #define PACKAGE_NAME "GStreamer Base Plug-ins" /* Define to the full name and version of this package. */ -#define PACKAGE_STRING "GStreamer Base Plug-ins 0.10.31.4" +#define PACKAGE_STRING "GStreamer Base Plug-ins 0.10.32" /* Define to the one symbol short name of this package. */ #define PACKAGE_TARNAME "gst-plugins-base" @@ -346,7 +346,7 @@ #undef PACKAGE_URL /* Define to the version of this package. */ -#define PACKAGE_VERSION "0.10.31.4" +#define PACKAGE_VERSION "0.10.32" /* directory where plugins are located */ #ifdef _DEBUG @@ -374,7 +374,7 @@ #undef STDC_HEADERS /* Version number of package */ -#define VERSION "0.10.31.4" +#define VERSION "0.10.32" /* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most significant byte first (like Motorola and SPARC, unlike Intel). */ From 90847134921653a428624d16c6018d13748a8a4c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim-Philipp=20M=C3=BCller?= Date: Mon, 24 Jan 2011 00:00:27 +0000 Subject: [PATCH 156/254] Back to development --- configure.ac | 2 +- docs/plugins/gst-plugins-base-plugins.hierarchy | 1 - docs/plugins/inspect/plugin-adder.xml | 4 ++-- docs/plugins/inspect/plugin-alsa.xml | 4 ++-- docs/plugins/inspect/plugin-app.xml | 4 ++-- docs/plugins/inspect/plugin-audioconvert.xml | 4 ++-- docs/plugins/inspect/plugin-audiorate.xml | 4 ++-- docs/plugins/inspect/plugin-audioresample.xml | 4 ++-- docs/plugins/inspect/plugin-audiotestsrc.xml | 4 ++-- docs/plugins/inspect/plugin-cdparanoia.xml | 4 ++-- docs/plugins/inspect/plugin-decodebin.xml | 4 ++-- docs/plugins/inspect/plugin-encoding.xml | 4 ++-- docs/plugins/inspect/plugin-ffmpegcolorspace.xml | 2 +- docs/plugins/inspect/plugin-gdp.xml | 4 ++-- docs/plugins/inspect/plugin-gio.xml | 4 ++-- docs/plugins/inspect/plugin-gnomevfs.xml | 4 ++-- docs/plugins/inspect/plugin-libvisual.xml | 4 ++-- docs/plugins/inspect/plugin-ogg.xml | 4 ++-- docs/plugins/inspect/plugin-pango.xml | 4 ++-- docs/plugins/inspect/plugin-playback.xml | 4 ++-- docs/plugins/inspect/plugin-subparse.xml | 4 ++-- docs/plugins/inspect/plugin-tcp.xml | 4 ++-- docs/plugins/inspect/plugin-theora.xml | 4 ++-- docs/plugins/inspect/plugin-typefindfunctions.xml | 4 ++-- docs/plugins/inspect/plugin-uridecodebin.xml | 4 ++-- docs/plugins/inspect/plugin-video4linux.xml | 4 ++-- docs/plugins/inspect/plugin-videorate.xml | 4 ++-- docs/plugins/inspect/plugin-videoscale.xml | 4 ++-- docs/plugins/inspect/plugin-videotestsrc.xml | 4 ++-- docs/plugins/inspect/plugin-volume.xml | 4 ++-- docs/plugins/inspect/plugin-vorbis.xml | 4 ++-- docs/plugins/inspect/plugin-ximagesink.xml | 4 ++-- docs/plugins/inspect/plugin-xvimagesink.xml | 4 ++-- win32/common/_stdint.h | 2 +- win32/common/config.h | 10 +++++----- 35 files changed, 68 insertions(+), 69 deletions(-) diff --git a/configure.ac b/configure.ac index 3325abc63c..84664c707c 100644 --- a/configure.ac +++ b/configure.ac @@ -5,7 +5,7 @@ dnl please read gstreamer/docs/random/autotools before changing this file dnl initialize autoconf dnl releases only do -Wall, git and prerelease does -Werror too dnl use a three digit version number for releases, and four for git/prerelease -AC_INIT(GStreamer Base Plug-ins, 0.10.32, +AC_INIT(GStreamer Base Plug-ins, 0.10.32.1, http://bugzilla.gnome.org/enter_bug.cgi?product=GStreamer, gst-plugins-base) diff --git a/docs/plugins/gst-plugins-base-plugins.hierarchy b/docs/plugins/gst-plugins-base-plugins.hierarchy index d8f23638e4..0ada208196 100644 --- a/docs/plugins/gst-plugins-base-plugins.hierarchy +++ b/docs/plugins/gst-plugins-base-plugins.hierarchy @@ -3,7 +3,6 @@ GObject GOutputStream GstColorBalanceChannel GstMixerTrack - GstMixerOptions GstObject GstBus GstClock diff --git a/docs/plugins/inspect/plugin-adder.xml b/docs/plugins/inspect/plugin-adder.xml index 5085f65d28..616e5de3c5 100644 --- a/docs/plugins/inspect/plugin-adder.xml +++ b/docs/plugins/inspect/plugin-adder.xml @@ -3,10 +3,10 @@ Adds multiple streams ../../gst/adder/.libs/libgstadder.so libgstadder.so - 0.10.32 + 0.10.32.1 LGPL gst-plugins-base - GStreamer Base Plug-ins source release + GStreamer Base Plug-ins git Unknown package origin diff --git a/docs/plugins/inspect/plugin-alsa.xml b/docs/plugins/inspect/plugin-alsa.xml index 4f4dfc8db0..5cd1f5c6b4 100644 --- a/docs/plugins/inspect/plugin-alsa.xml +++ b/docs/plugins/inspect/plugin-alsa.xml @@ -3,10 +3,10 @@ ALSA plugin library ../../ext/alsa/.libs/libgstalsa.so libgstalsa.so - 0.10.32 + 0.10.32.1 LGPL gst-plugins-base - GStreamer Base Plug-ins source release + GStreamer Base Plug-ins git Unknown package origin diff --git a/docs/plugins/inspect/plugin-app.xml b/docs/plugins/inspect/plugin-app.xml index 6c6994cd85..4e63961fd3 100644 --- a/docs/plugins/inspect/plugin-app.xml +++ b/docs/plugins/inspect/plugin-app.xml @@ -3,10 +3,10 @@ Elements used to communicate with applications ../../gst/app/.libs/libgstapp.so libgstapp.so - 0.10.32 + 0.10.32.1 LGPL gst-plugins-base - GStreamer Base Plug-ins source release + GStreamer Base Plug-ins git Unknown package origin diff --git a/docs/plugins/inspect/plugin-audioconvert.xml b/docs/plugins/inspect/plugin-audioconvert.xml index cbd4e58511..215ee94ad1 100644 --- a/docs/plugins/inspect/plugin-audioconvert.xml +++ b/docs/plugins/inspect/plugin-audioconvert.xml @@ -3,10 +3,10 @@ Convert audio to different formats ../../gst/audioconvert/.libs/libgstaudioconvert.so libgstaudioconvert.so - 0.10.32 + 0.10.32.1 LGPL gst-plugins-base - GStreamer Base Plug-ins source release + GStreamer Base Plug-ins git Unknown package origin diff --git a/docs/plugins/inspect/plugin-audiorate.xml b/docs/plugins/inspect/plugin-audiorate.xml index b1a7bcd037..34ec1315da 100644 --- a/docs/plugins/inspect/plugin-audiorate.xml +++ b/docs/plugins/inspect/plugin-audiorate.xml @@ -3,10 +3,10 @@ Adjusts audio frames ../../gst/audiorate/.libs/libgstaudiorate.so libgstaudiorate.so - 0.10.32 + 0.10.32.1 LGPL gst-plugins-base - GStreamer Base Plug-ins source release + GStreamer Base Plug-ins git Unknown package origin diff --git a/docs/plugins/inspect/plugin-audioresample.xml b/docs/plugins/inspect/plugin-audioresample.xml index 88cacca692..9099a3ef22 100644 --- a/docs/plugins/inspect/plugin-audioresample.xml +++ b/docs/plugins/inspect/plugin-audioresample.xml @@ -3,10 +3,10 @@ Resamples audio ../../gst/audioresample/.libs/libgstaudioresample.so libgstaudioresample.so - 0.10.32 + 0.10.32.1 LGPL gst-plugins-base - GStreamer Base Plug-ins source release + GStreamer Base Plug-ins git Unknown package origin diff --git a/docs/plugins/inspect/plugin-audiotestsrc.xml b/docs/plugins/inspect/plugin-audiotestsrc.xml index e7705766b3..4ec1d419a4 100644 --- a/docs/plugins/inspect/plugin-audiotestsrc.xml +++ b/docs/plugins/inspect/plugin-audiotestsrc.xml @@ -3,10 +3,10 @@ Creates audio test signals of given frequency and volume ../../gst/audiotestsrc/.libs/libgstaudiotestsrc.so libgstaudiotestsrc.so - 0.10.32 + 0.10.32.1 LGPL gst-plugins-base - GStreamer Base Plug-ins source release + GStreamer Base Plug-ins git Unknown package origin diff --git a/docs/plugins/inspect/plugin-cdparanoia.xml b/docs/plugins/inspect/plugin-cdparanoia.xml index 96cf3622c4..095498dc43 100644 --- a/docs/plugins/inspect/plugin-cdparanoia.xml +++ b/docs/plugins/inspect/plugin-cdparanoia.xml @@ -3,10 +3,10 @@ Read audio from CD in paranoid mode ../../ext/cdparanoia/.libs/libgstcdparanoia.so libgstcdparanoia.so - 0.10.32 + 0.10.32.1 LGPL gst-plugins-base - GStreamer Base Plug-ins source release + GStreamer Base Plug-ins git Unknown package origin diff --git a/docs/plugins/inspect/plugin-decodebin.xml b/docs/plugins/inspect/plugin-decodebin.xml index 50bd54dbba..63292f82d0 100644 --- a/docs/plugins/inspect/plugin-decodebin.xml +++ b/docs/plugins/inspect/plugin-decodebin.xml @@ -3,10 +3,10 @@ decoder bin ../../gst/playback/.libs/libgstdecodebin.so libgstdecodebin.so - 0.10.32 + 0.10.32.1 LGPL gst-plugins-base - GStreamer Base Plug-ins source release + GStreamer Base Plug-ins git Unknown package origin diff --git a/docs/plugins/inspect/plugin-encoding.xml b/docs/plugins/inspect/plugin-encoding.xml index 298921996d..fa94055f54 100644 --- a/docs/plugins/inspect/plugin-encoding.xml +++ b/docs/plugins/inspect/plugin-encoding.xml @@ -3,10 +3,10 @@ various encoding-related elements ../../gst/encoding/.libs/libgstencodebin.so libgstencodebin.so - 0.10.32 + 0.10.32.1 LGPL gst-plugins-base - GStreamer Base Plug-ins source release + GStreamer Base Plug-ins git Unknown package origin diff --git a/docs/plugins/inspect/plugin-ffmpegcolorspace.xml b/docs/plugins/inspect/plugin-ffmpegcolorspace.xml index bf46cb88fb..e30774010b 100644 --- a/docs/plugins/inspect/plugin-ffmpegcolorspace.xml +++ b/docs/plugins/inspect/plugin-ffmpegcolorspace.xml @@ -3,7 +3,7 @@ colorspace conversion copied from FFMpeg 0.4.9-pre1 ../../gst/ffmpegcolorspace/.libs/libgstffmpegcolorspace.so libgstffmpegcolorspace.so - 0.10.32 + 0.10.32.1 LGPL gst-plugins-base FFMpeg diff --git a/docs/plugins/inspect/plugin-gdp.xml b/docs/plugins/inspect/plugin-gdp.xml index 5e1c917948..9c563d88ad 100644 --- a/docs/plugins/inspect/plugin-gdp.xml +++ b/docs/plugins/inspect/plugin-gdp.xml @@ -3,10 +3,10 @@ Payload/depayload GDP packets ../../gst/gdp/.libs/libgstgdp.so libgstgdp.so - 0.10.32 + 0.10.32.1 LGPL gst-plugins-base - GStreamer Base Plug-ins source release + GStreamer Base Plug-ins git Unknown package origin diff --git a/docs/plugins/inspect/plugin-gio.xml b/docs/plugins/inspect/plugin-gio.xml index c3ce5c002d..82dde14b8e 100644 --- a/docs/plugins/inspect/plugin-gio.xml +++ b/docs/plugins/inspect/plugin-gio.xml @@ -3,10 +3,10 @@ GIO elements ../../ext/gio/.libs/libgstgio.so libgstgio.so - 0.10.32 + 0.10.32.1 LGPL gst-plugins-base - GStreamer Base Plug-ins source release + GStreamer Base Plug-ins git Unknown package origin diff --git a/docs/plugins/inspect/plugin-gnomevfs.xml b/docs/plugins/inspect/plugin-gnomevfs.xml index 2bf1663f58..44a4a68cab 100644 --- a/docs/plugins/inspect/plugin-gnomevfs.xml +++ b/docs/plugins/inspect/plugin-gnomevfs.xml @@ -3,10 +3,10 @@ elements to read from and write to Gnome-VFS uri's ../../ext/gnomevfs/.libs/libgstgnomevfs.so libgstgnomevfs.so - 0.10.32 + 0.10.32.1 LGPL gst-plugins-base - GStreamer Base Plug-ins source release + GStreamer Base Plug-ins git Unknown package origin diff --git a/docs/plugins/inspect/plugin-libvisual.xml b/docs/plugins/inspect/plugin-libvisual.xml index 3553cdec12..2f20d8b1b4 100644 --- a/docs/plugins/inspect/plugin-libvisual.xml +++ b/docs/plugins/inspect/plugin-libvisual.xml @@ -3,10 +3,10 @@ libvisual visualization plugins ../../ext/libvisual/.libs/libgstlibvisual.so libgstlibvisual.so - 0.10.32 + 0.10.32.1 LGPL gst-plugins-base - GStreamer Base Plug-ins source release + GStreamer Base Plug-ins git Unknown package origin diff --git a/docs/plugins/inspect/plugin-ogg.xml b/docs/plugins/inspect/plugin-ogg.xml index e7e137f944..a1d0462e60 100644 --- a/docs/plugins/inspect/plugin-ogg.xml +++ b/docs/plugins/inspect/plugin-ogg.xml @@ -3,10 +3,10 @@ ogg stream manipulation (info about ogg: http://xiph.org) ../../ext/ogg/.libs/libgstogg.so libgstogg.so - 0.10.32 + 0.10.32.1 LGPL gst-plugins-base - GStreamer Base Plug-ins source release + GStreamer Base Plug-ins git Unknown package origin diff --git a/docs/plugins/inspect/plugin-pango.xml b/docs/plugins/inspect/plugin-pango.xml index f41c1ba9c6..aad3c8c3b7 100644 --- a/docs/plugins/inspect/plugin-pango.xml +++ b/docs/plugins/inspect/plugin-pango.xml @@ -3,10 +3,10 @@ Pango-based text rendering and overlay ../../ext/pango/.libs/libgstpango.so libgstpango.so - 0.10.32 + 0.10.32.1 LGPL gst-plugins-base - GStreamer Base Plug-ins source release + GStreamer Base Plug-ins git Unknown package origin diff --git a/docs/plugins/inspect/plugin-playback.xml b/docs/plugins/inspect/plugin-playback.xml index 234a72dc3f..19fe577faa 100644 --- a/docs/plugins/inspect/plugin-playback.xml +++ b/docs/plugins/inspect/plugin-playback.xml @@ -3,10 +3,10 @@ various playback elements ../../gst/playback/.libs/libgstplaybin.so libgstplaybin.so - 0.10.32 + 0.10.32.1 LGPL gst-plugins-base - GStreamer Base Plug-ins source release + GStreamer Base Plug-ins git Unknown package origin diff --git a/docs/plugins/inspect/plugin-subparse.xml b/docs/plugins/inspect/plugin-subparse.xml index 7557b7cc3b..69c61511cc 100644 --- a/docs/plugins/inspect/plugin-subparse.xml +++ b/docs/plugins/inspect/plugin-subparse.xml @@ -3,10 +3,10 @@ Subtitle parsing ../../gst/subparse/.libs/libgstsubparse.so libgstsubparse.so - 0.10.32 + 0.10.32.1 LGPL gst-plugins-base - GStreamer Base Plug-ins source release + GStreamer Base Plug-ins git Unknown package origin diff --git a/docs/plugins/inspect/plugin-tcp.xml b/docs/plugins/inspect/plugin-tcp.xml index e4b1e8ec86..cb539aab7b 100644 --- a/docs/plugins/inspect/plugin-tcp.xml +++ b/docs/plugins/inspect/plugin-tcp.xml @@ -3,10 +3,10 @@ transfer data over the network via TCP ../../gst/tcp/.libs/libgsttcp.so libgsttcp.so - 0.10.32 + 0.10.32.1 LGPL gst-plugins-base - GStreamer Base Plug-ins source release + GStreamer Base Plug-ins git Unknown package origin diff --git a/docs/plugins/inspect/plugin-theora.xml b/docs/plugins/inspect/plugin-theora.xml index 8a8751e088..989e1420f4 100644 --- a/docs/plugins/inspect/plugin-theora.xml +++ b/docs/plugins/inspect/plugin-theora.xml @@ -3,10 +3,10 @@ Theora plugin library ../../ext/theora/.libs/libgsttheora.so libgsttheora.so - 0.10.32 + 0.10.32.1 LGPL gst-plugins-base - GStreamer Base Plug-ins source release + GStreamer Base Plug-ins git Unknown package origin diff --git a/docs/plugins/inspect/plugin-typefindfunctions.xml b/docs/plugins/inspect/plugin-typefindfunctions.xml index 420a4d013d..d63b20de1c 100644 --- a/docs/plugins/inspect/plugin-typefindfunctions.xml +++ b/docs/plugins/inspect/plugin-typefindfunctions.xml @@ -3,10 +3,10 @@ default typefind functions ../../gst/typefind/.libs/libgsttypefindfunctions.so libgsttypefindfunctions.so - 0.10.32 + 0.10.32.1 LGPL gst-plugins-base - GStreamer Base Plug-ins source release + GStreamer Base Plug-ins git Unknown package origin diff --git a/docs/plugins/inspect/plugin-uridecodebin.xml b/docs/plugins/inspect/plugin-uridecodebin.xml index bc3452eb62..26f211d384 100644 --- a/docs/plugins/inspect/plugin-uridecodebin.xml +++ b/docs/plugins/inspect/plugin-uridecodebin.xml @@ -3,10 +3,10 @@ URI Decoder bin ../../gst/playback/.libs/libgstdecodebin2.so libgstdecodebin2.so - 0.10.32 + 0.10.32.1 LGPL gst-plugins-base - GStreamer Base Plug-ins source release + GStreamer Base Plug-ins git Unknown package origin diff --git a/docs/plugins/inspect/plugin-video4linux.xml b/docs/plugins/inspect/plugin-video4linux.xml index f4d68ddf9b..eddf4b1ef6 100644 --- a/docs/plugins/inspect/plugin-video4linux.xml +++ b/docs/plugins/inspect/plugin-video4linux.xml @@ -3,10 +3,10 @@ elements for Video 4 Linux ../../sys/v4l/.libs/libgstvideo4linux.so libgstvideo4linux.so - 0.10.32 + 0.10.32.1 LGPL gst-plugins-base - GStreamer Base Plug-ins source release + GStreamer Base Plug-ins git Unknown package origin diff --git a/docs/plugins/inspect/plugin-videorate.xml b/docs/plugins/inspect/plugin-videorate.xml index 77b04e6f63..7734630884 100644 --- a/docs/plugins/inspect/plugin-videorate.xml +++ b/docs/plugins/inspect/plugin-videorate.xml @@ -3,10 +3,10 @@ Adjusts video frames ../../gst/videorate/.libs/libgstvideorate.so libgstvideorate.so - 0.10.32 + 0.10.32.1 LGPL gst-plugins-base - GStreamer Base Plug-ins source release + GStreamer Base Plug-ins git Unknown package origin diff --git a/docs/plugins/inspect/plugin-videoscale.xml b/docs/plugins/inspect/plugin-videoscale.xml index 4955792158..101eef0243 100644 --- a/docs/plugins/inspect/plugin-videoscale.xml +++ b/docs/plugins/inspect/plugin-videoscale.xml @@ -3,10 +3,10 @@ Resizes video ../../gst/videoscale/.libs/libgstvideoscale.so libgstvideoscale.so - 0.10.32 + 0.10.32.1 LGPL gst-plugins-base - GStreamer Base Plug-ins source release + GStreamer Base Plug-ins git Unknown package origin diff --git a/docs/plugins/inspect/plugin-videotestsrc.xml b/docs/plugins/inspect/plugin-videotestsrc.xml index 5f39f96a8e..bc2f747d2f 100644 --- a/docs/plugins/inspect/plugin-videotestsrc.xml +++ b/docs/plugins/inspect/plugin-videotestsrc.xml @@ -3,10 +3,10 @@ Creates a test video stream ../../gst/videotestsrc/.libs/libgstvideotestsrc.so libgstvideotestsrc.so - 0.10.32 + 0.10.32.1 LGPL gst-plugins-base - GStreamer Base Plug-ins source release + GStreamer Base Plug-ins git Unknown package origin diff --git a/docs/plugins/inspect/plugin-volume.xml b/docs/plugins/inspect/plugin-volume.xml index db1c008fde..0978f0644e 100644 --- a/docs/plugins/inspect/plugin-volume.xml +++ b/docs/plugins/inspect/plugin-volume.xml @@ -3,10 +3,10 @@ plugin for controlling audio volume ../../gst/volume/.libs/libgstvolume.so libgstvolume.so - 0.10.32 + 0.10.32.1 LGPL gst-plugins-base - GStreamer Base Plug-ins source release + GStreamer Base Plug-ins git Unknown package origin diff --git a/docs/plugins/inspect/plugin-vorbis.xml b/docs/plugins/inspect/plugin-vorbis.xml index 43c5408e87..7f92050210 100644 --- a/docs/plugins/inspect/plugin-vorbis.xml +++ b/docs/plugins/inspect/plugin-vorbis.xml @@ -3,10 +3,10 @@ Vorbis plugin library ../../ext/vorbis/.libs/libgstvorbis.so libgstvorbis.so - 0.10.32 + 0.10.32.1 LGPL gst-plugins-base - GStreamer Base Plug-ins source release + GStreamer Base Plug-ins git Unknown package origin diff --git a/docs/plugins/inspect/plugin-ximagesink.xml b/docs/plugins/inspect/plugin-ximagesink.xml index d780da94b8..3e81de1d64 100644 --- a/docs/plugins/inspect/plugin-ximagesink.xml +++ b/docs/plugins/inspect/plugin-ximagesink.xml @@ -3,10 +3,10 @@ X11 video output element based on standard Xlib calls ../../sys/ximage/.libs/libgstximagesink.so libgstximagesink.so - 0.10.32 + 0.10.32.1 LGPL gst-plugins-base - GStreamer Base Plug-ins source release + GStreamer Base Plug-ins git Unknown package origin diff --git a/docs/plugins/inspect/plugin-xvimagesink.xml b/docs/plugins/inspect/plugin-xvimagesink.xml index ec4a24f9fe..2d7943ce7b 100644 --- a/docs/plugins/inspect/plugin-xvimagesink.xml +++ b/docs/plugins/inspect/plugin-xvimagesink.xml @@ -3,10 +3,10 @@ XFree86 video output plugin using Xv extension ../../sys/xvimage/.libs/libgstxvimagesink.so libgstxvimagesink.so - 0.10.32 + 0.10.32.1 LGPL gst-plugins-base - GStreamer Base Plug-ins source release + GStreamer Base Plug-ins git Unknown package origin diff --git a/win32/common/_stdint.h b/win32/common/_stdint.h index 083fd25604..86481efef1 100644 --- a/win32/common/_stdint.h +++ b/win32/common/_stdint.h @@ -1,7 +1,7 @@ #ifndef _GST_PLUGINS_BASE__STDINT_H #define _GST_PLUGINS_BASE__STDINT_H 1 #ifndef _GENERATED_STDINT_H -#define _GENERATED_STDINT_H "gst-plugins-base 0.10.32" +#define _GENERATED_STDINT_H "gst-plugins-base 0.10.32.1" /* generated using gnu compiler gcc (Debian 4.4.5-10) 4.4.5 */ #define _STDINT_HAVE_STDINT_H 1 #include diff --git a/win32/common/config.h b/win32/common/config.h index 61a4c08e85..c34d0325a6 100644 --- a/win32/common/config.h +++ b/win32/common/config.h @@ -75,13 +75,13 @@ #define GST_MAJORMINOR "0.10" /* package name in plugins */ -#define GST_PACKAGE_NAME "GStreamer Base Plug-ins source release" +#define GST_PACKAGE_NAME "GStreamer Base Plug-ins git" /* package origin */ #define GST_PACKAGE_ORIGIN "Unknown package origin" /* GStreamer package release date/time for plugins as YYYY-MM-DD */ -#define GST_PACKAGE_RELEASE_DATETIME "2011-01-21" +#define GST_PACKAGE_RELEASE_DATETIME "2011-01-23T23:47Z" /* I know the API is subject to change. */ #undef G_UDEV_API_IS_SUBJECT_TO_CHANGE @@ -337,7 +337,7 @@ #define PACKAGE_NAME "GStreamer Base Plug-ins" /* Define to the full name and version of this package. */ -#define PACKAGE_STRING "GStreamer Base Plug-ins 0.10.32" +#define PACKAGE_STRING "GStreamer Base Plug-ins 0.10.32.1" /* Define to the one symbol short name of this package. */ #define PACKAGE_TARNAME "gst-plugins-base" @@ -346,7 +346,7 @@ #undef PACKAGE_URL /* Define to the version of this package. */ -#define PACKAGE_VERSION "0.10.32" +#define PACKAGE_VERSION "0.10.32.1" /* directory where plugins are located */ #ifdef _DEBUG @@ -374,7 +374,7 @@ #undef STDC_HEADERS /* Version number of package */ -#define VERSION "0.10.32" +#define VERSION "0.10.32.1" /* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most significant byte first (like Motorola and SPARC, unlike Intel). */ From 7faf92511ac920380b94a4d91877f141064dbe39 Mon Sep 17 00:00:00 2001 From: Edward Hervey Date: Mon, 24 Jan 2011 18:27:30 +0100 Subject: [PATCH 157/254] riff: Add support for video/x-camstudio --- gst-libs/gst/riff/riff-media.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/gst-libs/gst/riff/riff-media.c b/gst-libs/gst/riff/riff-media.c index 9340b2c5df..40b2bf628c 100644 --- a/gst-libs/gst/riff/riff-media.c +++ b/gst-libs/gst/riff/riff-media.c @@ -717,6 +717,22 @@ gst_riff_create_video_caps (guint32 codec_fcc, break; } + case GST_MAKE_FOURCC ('C', 'S', 'C', 'D'): + { + if (strf) { + gint depth = (strf->bit_cnt != 0) ? (gint) strf->bit_cnt : 24; + + caps = gst_caps_new_simple ("video/x-camstudio", "depth", G_TYPE_INT, + depth, NULL); + } else { + /* template caps */ + caps = gst_caps_new_simple ("video/x-camstudio", NULL); + } + if (codec_name) + *codec_name = g_strdup ("Camstudio"); + break; + } + case GST_MAKE_FOURCC ('V', 'C', 'R', '1'): caps = gst_caps_new_simple ("video/x-ati-vcr", "vcrversion", G_TYPE_INT, 1, NULL); @@ -1737,6 +1753,7 @@ gst_riff_create_video_template_caps (void) GST_MAKE_FOURCC ('A', 'S', 'V', '1'), GST_MAKE_FOURCC ('A', 'S', 'V', '2'), GST_MAKE_FOURCC ('C', 'L', 'J', 'R'), + GST_MAKE_FOURCC ('C', 'S', 'C', 'D'), GST_MAKE_FOURCC ('C', 'Y', 'U', 'V'), GST_MAKE_FOURCC ('D', 'I', 'B', ' '), GST_MAKE_FOURCC ('D', 'I', 'V', '3'), From 254088344cf4588c32bb1ecabb94798ce0e229fe Mon Sep 17 00:00:00 2001 From: Thiago Santos Date: Mon, 24 Jan 2011 15:21:10 -0300 Subject: [PATCH 158/254] tag: xmp: Move static variable to local function Variable was being written to and could cause crashes if multiple elements were parsing xmp at the same time. Moving it to local scope solves the problem. --- gst-libs/gst/tag/gstxmptag.c | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/gst-libs/gst/tag/gstxmptag.c b/gst-libs/gst/tag/gstxmptag.c index 758b9776d2..2697f40fa3 100644 --- a/gst-libs/gst/tag/gstxmptag.c +++ b/gst-libs/gst/tag/gstxmptag.c @@ -957,15 +957,6 @@ struct _GstXmpNamespaceMap const gchar *original_ns; gchar *gstreamer_ns; }; -static GstXmpNamespaceMap ns_map[] = { - {"dc", NULL}, - {"exif", NULL}, - {"tiff", NULL}, - {"xap", NULL}, - {"photoshop", NULL}, - {"Iptc4xmpCore", NULL}, - {NULL, NULL} -}; /* parsing */ @@ -1153,6 +1144,16 @@ gst_tag_list_from_xmp_buffer (const GstBuffer * buffer) XmpTag *last_xmp_tag = NULL; GSList *pending_tags = NULL; + GstXmpNamespaceMap ns_map[] = { + {"dc", NULL}, + {"exif", NULL}, + {"tiff", NULL}, + {"xap", NULL}, + {"photoshop", NULL}, + {"Iptc4xmpCore", NULL}, + {NULL, NULL} + }; + xmp_tags_initialize (); g_return_val_if_fail (GST_IS_BUFFER (buffer), NULL); From 876bf233fb69903b393c8f5e02b49da4066eb333 Mon Sep 17 00:00:00 2001 From: Lane Brooks Date: Tue, 11 Jan 2011 18:18:34 +0100 Subject: [PATCH 159/254] textoverlay: Add support for vertical center alignment Fixes bug #639159. --- ext/pango/gsttextoverlay.c | 4 ++++ ext/pango/gsttextoverlay.h | 3 ++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/ext/pango/gsttextoverlay.c b/ext/pango/gsttextoverlay.c index 915a59c5fb..c09de831e6 100644 --- a/ext/pango/gsttextoverlay.c +++ b/ext/pango/gsttextoverlay.c @@ -216,6 +216,7 @@ gst_text_overlay_valign_get_type (void) {GST_TEXT_OVERLAY_VALIGN_BOTTOM, "bottom", "bottom"}, {GST_TEXT_OVERLAY_VALIGN_TOP, "top", "top"}, {GST_TEXT_OVERLAY_VALIGN_POS, "position", "position"}, + {GST_TEXT_OVERLAY_VALIGN_CENTER, "center", "center"}, {0, NULL, NULL}, }; @@ -1798,6 +1799,9 @@ gst_text_overlay_push_frame (GstTextOverlay * overlay, GstBuffer * video_frame) ypos = (gint) (overlay->height * overlay->ypos) - height / 2; ypos = CLAMP (ypos, 0, overlay->height - height); break; + case GST_TEXT_OVERLAY_VALIGN_CENTER: + ypos = (overlay->height - height) / 2; + break; default: ypos = overlay->ypad; break; diff --git a/ext/pango/gsttextoverlay.h b/ext/pango/gsttextoverlay.h index 5fddf3ad09..10dd9479e0 100644 --- a/ext/pango/gsttextoverlay.h +++ b/ext/pango/gsttextoverlay.h @@ -35,7 +35,8 @@ typedef enum { GST_TEXT_OVERLAY_VALIGN_BASELINE, GST_TEXT_OVERLAY_VALIGN_BOTTOM, GST_TEXT_OVERLAY_VALIGN_TOP, - GST_TEXT_OVERLAY_VALIGN_POS + GST_TEXT_OVERLAY_VALIGN_POS, + GST_TEXT_OVERLAY_VALIGN_CENTER } GstTextOverlayVAlign; /** From cb9607632f86a28ee7fe649efd279ca07edf4844 Mon Sep 17 00:00:00 2001 From: Yang Xichuan Date: Tue, 11 Jan 2011 15:10:42 +0800 Subject: [PATCH 160/254] oggparse: Make gst_ogg_parse_submit_buffer() safe By not passing zero-sized buffers to ogg_sync_buffer() and checking the return values of libogg functions. Fixes bug #639136. --- ext/ogg/gstoggparse.c | 34 +++++++++++++++++++++++----------- 1 file changed, 23 insertions(+), 11 deletions(-) diff --git a/ext/ogg/gstoggparse.c b/ext/ogg/gstoggparse.c index e05c0543ed..87eea1f95a 100644 --- a/ext/ogg/gstoggparse.c +++ b/ext/ogg/gstoggparse.c @@ -281,29 +281,41 @@ gst_ogg_parse_dispose (GObject * object) G_OBJECT_CLASS (parent_class)->dispose (object); } -/* submit the given buffer to the ogg sync. - * - * Returns the number of bytes submited. - */ -static gint +/* submit the given buffer to the ogg sync */ +static GstFlowReturn gst_ogg_parse_submit_buffer (GstOggParse * ogg, GstBuffer * buffer) { guint size; guint8 *data; gchar *oggbuffer; + GstFlowReturn ret = GST_FLOW_OK; size = GST_BUFFER_SIZE (buffer); data = GST_BUFFER_DATA (buffer); - /* We now have a buffer, submit it to the ogg sync layer */ - oggbuffer = ogg_sync_buffer (&ogg->sync, size); - memcpy (oggbuffer, data, size); - ogg_sync_wrote (&ogg->sync, size); + GST_DEBUG_OBJECT (ogg, "submitting %u bytes", size); + if (G_UNLIKELY (size == 0)) + goto done; - /* We've copied all the neccesary data, so we're done with the buffer */ + oggbuffer = ogg_sync_buffer (&ogg->sync, size); + if (G_UNLIKELY (oggbuffer == NULL)) { + GST_ELEMENT_ERROR (ogg, STREAM, DECODE, + (NULL), ("failed to get ogg sync buffer")); + ret = GST_FLOW_ERROR; + goto done; + } + + memcpy (oggbuffer, data, size); + if (G_UNLIKELY (ogg_sync_wrote (&ogg->sync, size) < 0)) { + GST_ELEMENT_ERROR (ogg, STREAM, DECODE, + (NULL), ("failed to write %d bytes to the sync buffer", size)); + ret = GST_FLOW_ERROR; + } + +done: gst_buffer_unref (buffer); - return size; + return ret; } static void From 7cfa18545c8ed361a8d89f308764e226d13e737f Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Mon, 17 Jan 2011 15:11:15 +0200 Subject: [PATCH 161/254] oggdemux: Remove dead code --- ext/ogg/gstoggdemux.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/ext/ogg/gstoggdemux.c b/ext/ogg/gstoggdemux.c index f25dbe30d7..c01166502d 100644 --- a/ext/ogg/gstoggdemux.c +++ b/ext/ogg/gstoggdemux.c @@ -1765,7 +1765,6 @@ gst_ogg_demux_activate_chain (GstOggDemux * ogg, GstOggChain * chain, /* first add the pads */ for (i = 0; i < chain->streams->len; i++) { GstOggPad *pad; - GstStructure *structure; pad = g_array_index (chain->streams, GstOggPad *, i); @@ -1783,8 +1782,6 @@ gst_ogg_demux_activate_chain (GstOggDemux * ogg, GstOggChain * chain, GST_DEBUG_OBJECT (ogg, "adding pad %" GST_PTR_FORMAT, pad); - structure = gst_caps_get_structure (GST_PAD_CAPS (pad), 0); - /* activate first */ gst_pad_set_active (GST_PAD_CAST (pad), TRUE); From 7caf9e5e81ab9846918729b32e6e653fb80c6e14 Mon Sep 17 00:00:00 2001 From: Vincent Penquerc'h Date: Mon, 24 Jan 2011 11:45:21 +0000 Subject: [PATCH 162/254] typefind: add detection for windows icon files to get them out of the way Some of them can otherwise be misdetected for MPEG audio. https://bugzilla.gnome.org/show_bug.cgi?id=620364 --- gst/typefind/gsttypefindfunctions.c | 44 +++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/gst/typefind/gsttypefindfunctions.c b/gst/typefind/gsttypefindfunctions.c index 373df083d6..afdff15c3c 100644 --- a/gst/typefind/gsttypefindfunctions.c +++ b/gst/typefind/gsttypefindfunctions.c @@ -3869,6 +3869,48 @@ xdgmime_typefind (GstTypeFind * find, gpointer user_data) } #endif /* USE_GIO */ +/*** Windows icon typefinder (to avoid false positives mostly) ***/ + +static void +windows_icon_typefind (GstTypeFind * find, gpointer user_data) +{ + guint8 *data; + gint64 datalen; + guint16 type, nimages; + gint32 size, offset; + + datalen = gst_type_find_get_length (find); + if ((data = gst_type_find_peek (find, 0, 6)) == NULL) + return; + + /* header - simple and not enough to rely on it alone */ + if (GST_READ_UINT16_LE (data) != 0) + return; + type = GST_READ_UINT16_LE (data + 2); + if (type != 1 && type != 2) + return; + nimages = GST_READ_UINT16_LE (data + 4); + if (nimages == 0) /* we can assume we can't have an empty image file ? */ + return; + + /* first image */ + if (data[6 + 3] != 0) + return; + if (type == 1) { + guint16 planes = GST_READ_UINT16_LE (data + 6 + 4); + if (planes > 1) + return; + } + size = GST_READ_UINT32_LE (data + 6 + 8); + offset = GST_READ_UINT32_LE (data + 6 + 12); + if (offset < 0 || size <= 0 || size >= datalen || offset >= datalen + || size + offset > datalen) + return; + + gst_type_find_suggest_simple (find, GST_TYPE_FIND_NEARLY_CERTAIN, + "image/vnd.microsoft.icon", NULL); +} + /*** generic typefind for streams that have some data at a specific position***/ typedef struct { @@ -4332,6 +4374,8 @@ plugin_init (GstPlugin * plugin) GST_TYPE_FIND_LIKELY); TYPE_FIND_REGISTER_START_WITH (plugin, "application/x-yuv4mpeg", GST_RANK_SECONDARY, y4m_exts, "YUV4MPEG2 ", 10, GST_TYPE_FIND_LIKELY); + TYPE_FIND_REGISTER (plugin, "image/vnd.microsoft.icon", GST_RANK_MARGINAL, + windows_icon_typefind, NULL, NULL, NULL, NULL); #ifdef USE_GIO TYPE_FIND_REGISTER (plugin, "xdgmime-base", GST_RANK_MARGINAL, From d144f7a3a56edd1588d094b7c7ef85eddc695b80 Mon Sep 17 00:00:00 2001 From: Vincent Penquerc'h Date: Fri, 21 Jan 2011 14:56:28 +0000 Subject: [PATCH 163/254] oggmux: cleanup Remove a pointless string concatentation, and fix an off-by-one in packetno in a log. https://bugzilla.gnome.org/show_bug.cgi?id=640189 --- ext/ogg/gstoggmux.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ext/ogg/gstoggmux.c b/ext/ogg/gstoggmux.c index bab9442a12..11a67920f7 100644 --- a/ext/ogg/gstoggmux.c +++ b/ext/ogg/gstoggmux.c @@ -781,7 +781,7 @@ gst_ogg_mux_queue_pads (GstOggMux * ogg_mux) buf = NULL; } else { GST_DEBUG_OBJECT (ogg_mux, - "got data buffer in control state, switching " "to data mode"); + "got data buffer in control state, switching to data mode"); /* this is a data buffer so switch to data state */ pad->state = GST_OGG_PAD_STATE_DATA; } @@ -1106,7 +1106,7 @@ gst_ogg_mux_send_headers (GstOggMux * mux) if (hwalk == NULL) { GST_LOG_OBJECT (mux, "flushing page as packet %" G_GUINT64_FORMAT " is first or " - "last packet", pad->packetno); + "last packet", packet.packetno); while (ogg_stream_flush (&pad->stream, &page)) { GstBuffer *hbuf = gst_ogg_mux_buffer_from_page (mux, &page, FALSE); From 2acdbdabaa3736ba66b1170e070b3a1bde37f35a Mon Sep 17 00:00:00 2001 From: Vincent Penquerc'h Date: Tue, 25 Jan 2011 13:39:25 +0000 Subject: [PATCH 164/254] typefind: add typefinder for DEGAS images This fixes at least one DEGAS image from being misdetected as DTS audio. https://bugzilla.gnome.org/show_bug.cgi?id=625129 --- gst/typefind/gsttypefindfunctions.c | 51 +++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) diff --git a/gst/typefind/gsttypefindfunctions.c b/gst/typefind/gsttypefindfunctions.c index afdff15c3c..6c3b1acb2a 100644 --- a/gst/typefind/gsttypefindfunctions.c +++ b/gst/typefind/gsttypefindfunctions.c @@ -3911,6 +3911,54 @@ windows_icon_typefind (GstTypeFind * find, gpointer user_data) "image/vnd.microsoft.icon", NULL); } + +/*** DEGAS Atari images (also to avoid false positives, see #625129) ***/ +static void +degas_type_find (GstTypeFind * tf, gpointer private) +{ + /* No magic, but it should have a fixed size and a few invalid values */ + /* http://www.fileformat.info/format/atari/spec/6ecf9f6eb5be494284a47feb8a214687/view.htm */ + gint64 len; + const guint8 *data; + guint16 resolution; + int n; + + len = gst_type_find_get_length (tf); + if (len < 34) /* smallest header of the lot */ + return; + data = gst_type_find_peek (tf, 0, 4); + resolution = GST_READ_UINT16_BE (data); + if (len == 32034) { + /* could be DEGAS */ + if (resolution <= 2) + gst_type_find_suggest_simple (tf, GST_TYPE_FIND_POSSIBLE + 5, + "image/x-degas", NULL); + } else if (len == 32066) { + /* could be DEGAS Elite */ + if (resolution <= 2) { + data = gst_type_find_peek (tf, len - 16, 8); + for (n = 0; n < 4; n++) { + if (GST_READ_UINT16_BE (data + n * 2) > 2) + return; + } + gst_type_find_suggest_simple (tf, GST_TYPE_FIND_POSSIBLE + 5, + "image/x-degas", NULL); + } + } else if (len >= 66 && len < 32066) { + /* could be compressed DEGAS Elite, but it's compressed and so we can't rely on size, + it does have 4 16 bytes values near the end that are 0-2 though. */ + if ((resolution & 0x8000) && (resolution & 0x7fff) <= 2) { + data = gst_type_find_peek (tf, len - 16, 8); + for (n = 0; n < 4; n++) { + if (GST_READ_UINT16_BE (data + n * 2) > 2) + return; + } + gst_type_find_suggest_simple (tf, GST_TYPE_FIND_POSSIBLE + 5, + "image/x-degas", NULL); + } + } +} + /*** generic typefind for streams that have some data at a specific position***/ typedef struct { @@ -4382,6 +4430,9 @@ plugin_init (GstPlugin * plugin) xdgmime_typefind, NULL, NULL, NULL, NULL); #endif + TYPE_FIND_REGISTER (plugin, "image/x-degas", GST_RANK_MARGINAL, + degas_type_find, NULL, NULL, NULL, NULL); + return TRUE; } From 682ca018c978310024511633c6078e29e6c7fd0b Mon Sep 17 00:00:00 2001 From: Stefan Kost Date: Wed, 12 Jan 2011 14:03:12 +0200 Subject: [PATCH 165/254] pbutils: add description for x-annodex --- gst-libs/gst/pbutils/descriptions.c | 1 + 1 file changed, 1 insertion(+) diff --git a/gst-libs/gst/pbutils/descriptions.c b/gst-libs/gst/pbutils/descriptions.c index cd67a6bd88..40ae1eaf5c 100644 --- a/gst-libs/gst/pbutils/descriptions.c +++ b/gst-libs/gst/pbutils/descriptions.c @@ -66,6 +66,7 @@ static const FormatInfo formats[] = { {"application/ogg", "Ogg", FLAG_CONTAINER}, {"application/mxf", "Material eXchange Format (MXF)", FLAG_CONTAINER}, {"application/vnd.rn-realmedia", "Realmedia", FLAG_CONTAINER}, + {"application/x-annodex", "Ogg", FLAG_CONTAINER}, {"application/x-id3", N_("ID3 tag"), FLAG_CONTAINER}, {"application/x-ape", N_("APE tag"), FLAG_CONTAINER}, {"application/x-apetag", N_("APE tag"), FLAG_CONTAINER}, From 69436bb8a6aef973a355b132da8ddb64ac40fab4 Mon Sep 17 00:00:00 2001 From: Stefan Kost Date: Tue, 25 Jan 2011 18:03:23 +0200 Subject: [PATCH 166/254] decodebin2: add comment and whitespace trimming --- gst/playback/gstdecodebin2.c | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/gst/playback/gstdecodebin2.c b/gst/playback/gstdecodebin2.c index bcf4731ab6..064d62e41e 100644 --- a/gst/playback/gstdecodebin2.c +++ b/gst/playback/gstdecodebin2.c @@ -667,11 +667,11 @@ gst_decode_bin_class_init (GstDecodeBinClass * klass) * * This function is emited when an array of possible factories for @caps on * @pad is needed. Decodebin2 will by default return an array with all - * compatible factories, sorted by rank. + * compatible factories, sorted by rank. * * If this function returns NULL, @pad will be exposed as a final caps. * - * If this function returns an empty array, the pad will be considered as + * If this function returns an empty array, the pad will be considered as * having an unhandled type media type. * * Returns: a #GValueArray* with a list of factories to try. The factories are @@ -867,7 +867,7 @@ gst_decode_bin_class_init (GstDecodeBinClass * klass) * If set to %FALSE, then only the streams that can be decoded to the final * caps (see 'caps' property) will have a pad exposed. Streams that do not * match those caps but could have been decoded will not have decoder plugged - * in internally and will not have a pad exposed. + * in internally and will not have a pad exposed. * * Since: 0.10.30 */ @@ -1362,6 +1362,8 @@ analyze_new_pad (GstDecodeBin * dbin, GstElement * src, GstPad * pad, GstDecodeGroup *group; GstDecodeChain *oldchain = chain; + /* we are adding a new pad for a demuxer (see is_demuxer_element(), + * start a new chain for it */ CHAIN_MUTEX_LOCK (oldchain); group = gst_decode_chain_get_current_group (chain); if (group) { @@ -1446,7 +1448,7 @@ analyze_new_pad (GstDecodeBin * dbin, GstElement * src, GstPad * pad, GST_DEBUG ("Checking if we can abort early"); /* 1.e Do an early check to see if the candidates are potential decoders, but - * due to the fact that they decode to a mediatype that is not final we don't + * due to the fact that they decode to a mediatype that is not final we don't * need them */ for (i = 0; i < factories->n_values && !dontuse; i++) { @@ -2150,7 +2152,7 @@ caps_notify_cb (GstPad * pad, GParamSpec * unused, GstDecodeChain * chain) gst_object_unref (element); } -/* Decide whether an element is a demuxer based on the +/* Decide whether an element is a demuxer based on the * klass and number/type of src pad templates it has */ static gboolean is_demuxer_element (GstElement * srcelement) @@ -2202,7 +2204,7 @@ is_demuxer_element (GstElement * srcelement) /* Returns TRUE if the caps are compatible with the caps specified in the 'caps' * property (which by default are the raw caps) - * + * * The decodebin_lock should be taken ! */ static gboolean @@ -2431,7 +2433,7 @@ gst_decode_chain_new (GstDecodeBin * dbin, GstDecodeGroup * parent, /* The overrun callback is used to expose groups that have not yet had their * no_more_pads called while the (large) multiqueue overflowed. When this * happens we must assume that the no_more_pads will not arrive anymore and we - * must expose the pads that we have. + * must expose the pads that we have. */ static void multi_queue_overrun_cb (GstElement * queue, GstDecodeGroup * group) @@ -2536,7 +2538,7 @@ gst_decode_group_free (GstDecodeGroup * group) * unrefed here. * * Can be called from streaming threads. - * + * * Not MT-safe, call with parent's chain lock! */ static void @@ -2760,7 +2762,7 @@ out: return complete; } -/* check if the group is drained, meaning all pads have seen an EOS +/* check if the group is drained, meaning all pads have seen an EOS * event. */ static void gst_decode_pad_handle_eos (GstDecodePad * pad) @@ -2773,7 +2775,7 @@ gst_decode_pad_handle_eos (GstDecodePad * pad) } /* gst_decode_chain_handle_eos: - * + * * Checks if there are next groups in any parent chain * to which we can switch or if everything is drained. * From 5075b891aa231694c4ea5948286d9249dcfbd413 Mon Sep 17 00:00:00 2001 From: Stefan Kost Date: Mon, 17 Jan 2011 23:13:29 +0200 Subject: [PATCH 167/254] snapshot: add a newline to the usage and error output --- tests/examples/snapshot/snapshot.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/examples/snapshot/snapshot.c b/tests/examples/snapshot/snapshot.c index b307111340..335c836b88 100644 --- a/tests/examples/snapshot/snapshot.c +++ b/tests/examples/snapshot/snapshot.c @@ -41,7 +41,7 @@ main (int argc, char *argv[]) gst_init (&argc, &argv); if (argc != 2) { - g_print ("usage: %s \n Writes snapshot.png in the current directory", + g_print ("usage: %s \n Writes snapshot.png in the current directory\n", argv[0]); exit (-1); } @@ -53,7 +53,7 @@ main (int argc, char *argv[]) pipeline = gst_parse_launch (descr, &error); if (error != NULL) { - g_print ("could not construct pipeline: %s", error->message); + g_print ("could not construct pipeline: %s\n", error->message); g_error_free (error); exit (-1); } From f6dad2e86858b62388c7bc2a76c329273d91ec71 Mon Sep 17 00:00:00 2001 From: Stefan Kost Date: Tue, 18 Jan 2011 10:20:29 +0200 Subject: [PATCH 168/254] snapshot: use a keyframe seek One would usualy get good quality snapshots quickly. The exact seek position does not really matter. --- tests/examples/snapshot/snapshot.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/examples/snapshot/snapshot.c b/tests/examples/snapshot/snapshot.c index 335c836b88..14f28093e4 100644 --- a/tests/examples/snapshot/snapshot.c +++ b/tests/examples/snapshot/snapshot.c @@ -99,8 +99,8 @@ main (int argc, char *argv[]) * by seeking to somewhere else we have a bigger chance of getting something * more interesting. An optimisation would be to detect black images and then * seek a little more */ - gst_element_seek_simple (pipeline, GST_FORMAT_TIME, GST_SEEK_FLAG_FLUSH, - position); + gst_element_seek_simple (pipeline, GST_FORMAT_TIME, + GST_SEEK_FLAG_KEY_UNIT | GST_SEEK_FLAG_FLUSH, position); /* get the preroll buffer from appsink, this block untils appsink really * prerolls */ From 11a1acfe88203829e7a70905d88a4cbbc36d010a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim-Philipp=20M=C3=BCller?= Date: Wed, 26 Jan 2011 09:06:10 +0000 Subject: [PATCH 169/254] typefinding: use image/x-icon as media type for ICON files That's what we've been using so far (e.g. gdkpixbufdec). --- gst/typefind/gsttypefindfunctions.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gst/typefind/gsttypefindfunctions.c b/gst/typefind/gsttypefindfunctions.c index 6c3b1acb2a..55af37f141 100644 --- a/gst/typefind/gsttypefindfunctions.c +++ b/gst/typefind/gsttypefindfunctions.c @@ -3908,7 +3908,7 @@ windows_icon_typefind (GstTypeFind * find, gpointer user_data) return; gst_type_find_suggest_simple (find, GST_TYPE_FIND_NEARLY_CERTAIN, - "image/vnd.microsoft.icon", NULL); + "image/x-icon", NULL); } @@ -4422,7 +4422,7 @@ plugin_init (GstPlugin * plugin) GST_TYPE_FIND_LIKELY); TYPE_FIND_REGISTER_START_WITH (plugin, "application/x-yuv4mpeg", GST_RANK_SECONDARY, y4m_exts, "YUV4MPEG2 ", 10, GST_TYPE_FIND_LIKELY); - TYPE_FIND_REGISTER (plugin, "image/vnd.microsoft.icon", GST_RANK_MARGINAL, + TYPE_FIND_REGISTER (plugin, "image/x-icon", GST_RANK_MARGINAL, windows_icon_typefind, NULL, NULL, NULL, NULL); #ifdef USE_GIO From e404beff5de7dca7f5ce2615e7cc61dba58c238c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim-Philipp=20M=C3=BCller?= Date: Wed, 26 Jan 2011 09:07:26 +0000 Subject: [PATCH 170/254] pbutils: add description for degas images --- gst-libs/gst/pbutils/descriptions.c | 1 + 1 file changed, 1 insertion(+) diff --git a/gst-libs/gst/pbutils/descriptions.c b/gst-libs/gst/pbutils/descriptions.c index 40ae1eaf5c..c32e3d92cd 100644 --- a/gst-libs/gst/pbutils/descriptions.c +++ b/gst-libs/gst/pbutils/descriptions.c @@ -217,6 +217,7 @@ static const FormatInfo formats[] = { {"image/svg+xml", "Scalable Vector Graphics (SVG)", 0}, {"image/tiff", "TIFF", 0}, {"image/x-cmu-raster", "CMU Raster Format", 0}, + {"image/x-degas", "DEGAS", 0}, {"image/x-icon", "ICO", 0}, {"image/x-j2c", "JPEG 2000", 0}, {"image/x-jpc", "JPEG 2000", 0}, From fc608d4dcd0257549c6018aac9ee5c2dec52bbee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim-Philipp=20M=C3=BCller?= Date: Wed, 26 Jan 2011 15:42:48 +0000 Subject: [PATCH 171/254] tests: don't run encodebin test if vorbis or theora plugins aren't available --- tests/check/Makefile.am | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/tests/check/Makefile.am b/tests/check/Makefile.am index 0cc03a4c37..f284716a10 100644 --- a/tests/check/Makefile.am +++ b/tests/check/Makefile.am @@ -77,6 +77,16 @@ else check_theora = endif +if USE_VORBIS +if USE_THEORA +check_encodebin = elements/encodebin +else +check_encodebin = +endif +else +check_encodebin = +endif + if USE_PLUGIN_SUBPARSE check_subparse = elements/subparse else @@ -106,7 +116,7 @@ check_PROGRAMS = \ elements/audiotestsrc \ elements/decodebin \ elements/decodebin2 \ - elements/encodebin \ + $(check_encodebin) \ elements/ffmpegcolorspace \ elements/gdpdepay \ elements/gdppay \ From b43db2f2a26973fa270a8d678a91d377ddffb846 Mon Sep 17 00:00:00 2001 From: Thiago Santos Date: Wed, 26 Jan 2011 12:16:58 -0300 Subject: [PATCH 172/254] streamsplitter: release pending events refs Unref pending events when disposing the streamsplitter. Also refactor a little to replace a for with a g_list_foreach --- gst/encoding/gststreamsplitter.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/gst/encoding/gststreamsplitter.c b/gst/encoding/gststreamsplitter.c index a2fa589f36..c473386e56 100644 --- a/gst/encoding/gststreamsplitter.c +++ b/gst/encoding/gststreamsplitter.c @@ -88,6 +88,11 @@ gst_stream_splitter_dispose (GObject * object) stream_splitter->lock = NULL; } + g_list_foreach (stream_splitter->pending_events, (GFunc) gst_event_unref, + NULL); + g_list_free (stream_splitter->pending_events); + stream_splitter->pending_events = NULL; + G_OBJECT_CLASS (gst_stream_splitter_parent_class)->dispose (object); } @@ -173,9 +178,8 @@ gst_stream_splitter_sink_event (GstPad * pad, GstEvent * event) } if (flushpending) { - GList *tmp; - for (tmp = stream_splitter->pending_events; tmp; tmp = tmp->next) - gst_event_unref ((GstEvent *) tmp->data); + g_list_foreach (stream_splitter->pending_events, (GFunc) gst_event_unref, + NULL); g_list_free (stream_splitter->pending_events); stream_splitter->pending_events = NULL; } From 749f541cc48b05c176f4d6eb78aba846c2f299ac Mon Sep 17 00:00:00 2001 From: Philippe Normand Date: Thu, 27 Jan 2011 12:32:35 +0100 Subject: [PATCH 173/254] typefinding: register H264 typefinder with H264 caps https://bugzilla.gnome.org/show_bug.cgi?id=640709 --- gst/typefind/gsttypefindfunctions.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gst/typefind/gsttypefindfunctions.c b/gst/typefind/gsttypefindfunctions.c index 55af37f141..6646944234 100644 --- a/gst/typefind/gsttypefindfunctions.c +++ b/gst/typefind/gsttypefindfunctions.c @@ -4228,7 +4228,7 @@ plugin_init (GstPlugin * plugin) TYPE_FIND_REGISTER (plugin, "video/mpeg4", GST_RANK_PRIMARY, mpeg4_video_type_find, m4v_exts, MPEG_VIDEO_CAPS, NULL, NULL); TYPE_FIND_REGISTER (plugin, "video/x-h264", GST_RANK_PRIMARY, - h264_video_type_find, h264_exts, MPEG_VIDEO_CAPS, NULL, NULL); + h264_video_type_find, h264_exts, H264_VIDEO_CAPS, NULL, NULL); TYPE_FIND_REGISTER (plugin, "video/x-nuv", GST_RANK_SECONDARY, nuv_type_find, nuv_exts, NUV_CAPS, NULL, NULL); From aa641a1aa8f937d0f8b917e47f125966b66d19d1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim-Philipp=20M=C3=BCller?= Date: Thu, 27 Jan 2011 15:26:25 +0000 Subject: [PATCH 174/254] win32: fix DEFAULT_AUDIOSINK, should be direct*sound*sink https://bugzilla.gnome.org/show_bug.cgi?id=640705 --- configure.ac | 2 +- win32/common/config.h | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/configure.ac b/configure.ac index 84664c707c..b84d0c5a30 100644 --- a/configure.ac +++ b/configure.ac @@ -1061,7 +1061,7 @@ sed \ -e 's/.* PLUGINDIR$/#ifdef _DEBUG\n# define PLUGINDIR PREFIX "\\\\debug\\\\lib\\\\gstreamer-0.10"\n#else\n# define PLUGINDIR PREFIX "\\\\lib\\\\gstreamer-0.10"\n#endif/' \ -e 's/.* USE_BINARY_REGISTRY$/#define USE_BINARY_REGISTRY/' \ -e 's/.* VERSION$/#define VERSION "'$VERSION'"/' \ - -e "s/.* DEFAULT_AUDIOSINK$/#define DEFAULT_AUDIOSINK \"directaudiosink\"/" \ + -e "s/.* DEFAULT_AUDIOSINK$/#define DEFAULT_AUDIOSINK \"directsoundsink\"/" \ -e "s/.* DEFAULT_VIDEOSINK$/#define DEFAULT_VIDEOSINK \"directdrawsink\"/" \ -e "s/.* DEFAULT_VISUALIZER$/#define DEFAULT_VISUALIZER \"goom\"/" \ config.h.in >win32/common/config.h-new diff --git a/win32/common/config.h b/win32/common/config.h index c34d0325a6..1b5ecec9e8 100644 --- a/win32/common/config.h +++ b/win32/common/config.h @@ -20,7 +20,7 @@ #undef CDPARANOIA_HEADERS_IN_DIR /* Default audio sink */ -#define DEFAULT_AUDIOSINK "directaudiosink" +#define DEFAULT_AUDIOSINK "directsoundsink" /* Default audio source */ #undef DEFAULT_AUDIOSRC @@ -81,7 +81,7 @@ #define GST_PACKAGE_ORIGIN "Unknown package origin" /* GStreamer package release date/time for plugins as YYYY-MM-DD */ -#define GST_PACKAGE_RELEASE_DATETIME "2011-01-23T23:47Z" +#define GST_PACKAGE_RELEASE_DATETIME "2011-01-27T15:23Z" /* I know the API is subject to change. */ #undef G_UDEV_API_IS_SUBJECT_TO_CHANGE From 21d1e2ded026c814f4b7bc9330d99abfc2ae9bc7 Mon Sep 17 00:00:00 2001 From: Felipe Contreras Date: Sun, 30 Jan 2011 15:40:53 +0200 Subject: [PATCH 175/254] baseaudiosink: trivial cleanups It seems these stuff was neglected from commmit d8942e2. Signed-off-by: Felipe Contreras --- gst-libs/gst/audio/gstbaseaudiosink.c | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/gst-libs/gst/audio/gstbaseaudiosink.c b/gst-libs/gst/audio/gstbaseaudiosink.c index 54ba77548d..b5c87b9fdf 100644 --- a/gst-libs/gst/audio/gstbaseaudiosink.c +++ b/gst-libs/gst/audio/gstbaseaudiosink.c @@ -71,15 +71,6 @@ enum LAST_SIGNAL }; -/* we tollerate half a second diff before we start resyncing. This - * should be enough to compensate for various rounding errors in the timestamp - * and sample offset position. - * This is an emergency resync fallback since buffers marked as DISCONT will - * always lock to the correct timestamp immediatly and buffers not marked as - * DISCONT are contiguous by definition. - */ -#define DIFF_TOLERANCE 2 - /* FIXME: 0.11, store the buffer_time and latency_time in nanoseconds */ #define DEFAULT_BUFFER_TIME ((200 * GST_MSECOND) / GST_USECOND) #define DEFAULT_LATENCY_TIME ((10 * GST_MSECOND) / GST_USECOND) @@ -89,7 +80,7 @@ enum /* FIXME, enable pull mode when clock slaving and trick modes are figured out */ #define DEFAULT_CAN_ACTIVATE_PULL FALSE -/* when timestamps or clock slaving drift for more than 20ms we resync. This is +/* when timestamps or clock slaving drift for more than 40ms we resync. This is * a reasonable default */ #define DEFAULT_DRIFT_TOLERANCE ((40 * GST_MSECOND) / GST_USECOND) From 1fb7c7e5dc9b7dae777ba0ea0a139e42c2354938 Mon Sep 17 00:00:00 2001 From: Wim Taymans Date: Thu, 20 Jan 2011 16:25:42 +0100 Subject: [PATCH 176/254] uridecodebin: also add https to buffer protocols HTTPS also needs buffering. --- gst/playback/gsturidecodebin.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/gst/playback/gsturidecodebin.c b/gst/playback/gsturidecodebin.c index 7151801397..a72c8f2c58 100644 --- a/gst/playback/gsturidecodebin.c +++ b/gst/playback/gsturidecodebin.c @@ -942,8 +942,9 @@ array_has_uri_value (const gchar * values[], const gchar * value) /* list of URIs that we consider to be streams and that need buffering. * We have no mechanism yet to figure this out with a query. */ -static const gchar *stream_uris[] = { "http://", "mms://", "mmsh://", - "mmsu://", "mmst://", "fd://", "myth://", "ssh://", "ftp://", "sftp://", +static const gchar *stream_uris[] = { "http://", "https://", "mms://", + "mmsh://", "mmsu://", "mmst://", "fd://", "myth://", "ssh://", + "ftp://", "sftp://", NULL }; From 71dec68cbab5f72f4cd7d884903cfdb19e27fda6 Mon Sep 17 00:00:00 2001 From: Cai Yuanqing Date: Wed, 26 Jan 2011 10:32:32 +0800 Subject: [PATCH 177/254] appsink: send new-buffer-list signal Send new-buffer-list signal when emit-signals is TRUE https://bugzilla.gnome.org/show_bug.cgi?id=640607 --- gst-libs/gst/app/gstappsink.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/gst-libs/gst/app/gstappsink.c b/gst-libs/gst/app/gstappsink.c index a6e8c3db0e..8f64aba69a 100644 --- a/gst-libs/gst/app/gstappsink.c +++ b/gst-libs/gst/app/gstappsink.c @@ -271,7 +271,8 @@ gst_app_sink_class_init (GstAppSinkClass * klass) g_object_class_install_property (gobject_class, PROP_EMIT_SIGNALS, g_param_spec_boolean ("emit-signals", "Emit signals", - "Emit new-preroll and new-buffer signals", DEFAULT_PROP_EMIT_SIGNALS, + "Emit new-preroll, new-buffer and new-buffer-list signals", + DEFAULT_PROP_EMIT_SIGNALS, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); g_object_class_install_property (gobject_class, PROP_MAX_BUFFERS, @@ -780,6 +781,8 @@ restart: if (is_list) { if (priv->callbacks.new_buffer_list) priv->callbacks.new_buffer_list (appsink, priv->user_data); + else if (emit) + g_signal_emit (appsink, gst_app_sink_signals[SIGNAL_NEW_BUFFER_LIST], 0); } else { if (priv->callbacks.new_buffer) priv->callbacks.new_buffer (appsink, priv->user_data); From 33a5e3e06f091afc31ef206a267c420ae4a5bb3a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim-Philipp=20M=C3=BCller?= Date: Mon, 31 Jan 2011 18:06:18 +0000 Subject: [PATCH 178/254] appsink: add buffer fallback in case the application doesn't handle buffer lists We shouldn't assume the application handles buffer lists, for ease-of-use reasons and for backwards compatibility reasons. --- gst-libs/gst/app/gstappsink.c | 62 +++++++++++++++++++++++- tests/check/elements/appsink.c | 87 ++++++++++++++++++++++++++++++++++ 2 files changed, 147 insertions(+), 2 deletions(-) diff --git a/gst-libs/gst/app/gstappsink.c b/gst-libs/gst/app/gstappsink.c index 8f64aba69a..07a3989c86 100644 --- a/gst-libs/gst/app/gstappsink.c +++ b/gst-libs/gst/app/gstappsink.c @@ -111,6 +111,8 @@ struct _GstAppSinkPrivate GstAppSinkCallbacks callbacks; gpointer user_data; GDestroyNotify notify; + + gboolean buffer_lists_supported; }; GST_DEBUG_CATEGORY_STATIC (app_sink_debug); @@ -623,6 +625,21 @@ gst_app_sink_flush_unlocked (GstAppSink * appsink) g_cond_signal (priv->cond); } +#define NEW_BUFFER_LIST_SIGID \ + gst_app_sink_signals[SIGNAL_NEW_BUFFER_LIST] + +static gboolean +gst_app_sink_check_buffer_lists_support (GstAppSink * appsink) +{ + gboolean ret; + + ret = (appsink->priv->callbacks.new_buffer_list != NULL) || + g_signal_has_handler_pending (appsink, NEW_BUFFER_LIST_SIGID, 0, FALSE); + + GST_INFO_OBJECT (appsink, "application supports buffer lists: %d", ret); + return ret; +} + static gboolean gst_app_sink_start (GstBaseSink * psink) { @@ -633,6 +650,8 @@ gst_app_sink_start (GstBaseSink * psink) GST_DEBUG_OBJECT (appsink, "starting"); priv->flushing = FALSE; priv->started = TRUE; + priv->buffer_lists_supported = + gst_app_sink_check_buffer_lists_support (appsink); g_mutex_unlock (priv->mutex); return TRUE; @@ -812,9 +831,46 @@ gst_app_sink_render (GstBaseSink * psink, GstBuffer * buffer) } static GstFlowReturn -gst_app_sink_render_list (GstBaseSink * psink, GstBufferList * list) +gst_app_sink_render_list (GstBaseSink * sink, GstBufferList * list) { - return gst_app_sink_render_common (psink, GST_MINI_OBJECT_CAST (list), TRUE); + GstBufferListIterator *it; + GstFlowReturn flow; + GstAppSink *appsink; + GstBuffer *group; + + appsink = GST_APP_SINK_CAST (sink); + + if (appsink->priv->buffer_lists_supported) + return gst_app_sink_render_common (sink, GST_MINI_OBJECT_CAST (list), TRUE); + + /* The application doesn't support buffer lists, extract individual buffers + * then and push them one-by-one */ + GST_INFO_OBJECT (sink, "chaining each group in list as a merged buffer"); + + it = gst_buffer_list_iterate (list); + + if (gst_buffer_list_iterator_next_group (it)) { + do { + group = gst_buffer_list_iterator_merge_group (it); + if (group == NULL) { + group = gst_buffer_new (); + GST_DEBUG_OBJECT (sink, "chaining empty group"); + } else { + GST_DEBUG_OBJECT (sink, "chaining group"); + } + flow = gst_app_sink_render (sink, group); + gst_buffer_unref (group); + } while (flow == GST_FLOW_OK && gst_buffer_list_iterator_next_group (it)); + } else { + GST_DEBUG_OBJECT (sink, "chaining empty group"); + group = gst_buffer_new (); + flow = gst_app_sink_render (sink, group); + gst_buffer_unref (group); + } + + gst_buffer_list_iterator_free (it); + + return flow; } static GstCaps * @@ -1335,6 +1391,8 @@ gst_app_sink_set_callbacks (GstAppSink * appsink, priv->callbacks = *callbacks; priv->user_data = user_data; priv->notify = notify; + priv->buffer_lists_supported = + gst_app_sink_check_buffer_lists_support (appsink); GST_OBJECT_UNLOCK (appsink); } diff --git a/tests/check/elements/appsink.c b/tests/check/elements/appsink.c index 3d03439338..34982ef933 100644 --- a/tests/check/elements/appsink.c +++ b/tests/check/elements/appsink.c @@ -317,6 +317,91 @@ GST_START_TEST (test_buffer_list) GST_END_TEST; +static GstFlowReturn +callback_function_buffer (GstAppSink * appsink, gpointer p_counter) +{ + GstBuffer *buf; + gint *p_int_counter = p_counter; + + buf = gst_app_sink_pull_buffer (appsink); + fail_unless (GST_IS_BUFFER (buf)); + + /* buffer list has 3 buffers in two groups */ + switch (*p_int_counter) { + case 0: + fail_unless_equals_int (GST_BUFFER_SIZE (buf), sizeof (gint)); + fail_unless_equals_int ((((gint *) GST_BUFFER_DATA (buf))[0]), 1); + break; + case 1: + fail_unless_equals_int (GST_BUFFER_SIZE (buf), 2 * sizeof (gint)); + fail_unless_equals_int ((((gint *) GST_BUFFER_DATA (buf))[0]), 2); + fail_unless_equals_int ((((gint *) GST_BUFFER_DATA (buf))[1]), 4); + break; + default: + g_warn_if_reached (); + break; + } + + gst_buffer_unref (buf); + + *p_int_counter += 1; + + return GST_FLOW_OK; +} + +GST_START_TEST (test_buffer_list_fallback) +{ + GstElement *sink; + GstBufferList *list; + GstAppSinkCallbacks callbacks = { NULL }; + gint counter = 0; + + sink = setup_appsink (); + + callbacks.new_buffer = callback_function_buffer; + + gst_app_sink_set_callbacks (GST_APP_SINK (sink), &callbacks, &counter, NULL); + + ASSERT_SET_STATE (sink, GST_STATE_PLAYING, GST_STATE_CHANGE_ASYNC); + + list = create_buffer_list (); + fail_unless (gst_pad_push_list (mysrcpad, list) == GST_FLOW_OK); + + fail_unless_equals_int (counter, 2); + + ASSERT_SET_STATE (sink, GST_STATE_NULL, GST_STATE_CHANGE_SUCCESS); + cleanup_appsink (sink); +} + +GST_END_TEST; + +GST_START_TEST (test_buffer_list_fallback_signal) +{ + GstElement *sink; + GstBufferList *list; + gint counter = 0; + + sink = setup_appsink (); + + /* C calling convention to the rescue.. */ + g_signal_connect (sink, "new-buffer", G_CALLBACK (callback_function_buffer), + &counter); + + g_object_set (sink, "emit-signals", TRUE, NULL); + + ASSERT_SET_STATE (sink, GST_STATE_PLAYING, GST_STATE_CHANGE_ASYNC); + + list = create_buffer_list (); + fail_unless (gst_pad_push_list (mysrcpad, list) == GST_FLOW_OK); + + fail_unless_equals_int (counter, 2); + + ASSERT_SET_STATE (sink, GST_STATE_NULL, GST_STATE_CHANGE_SUCCESS); + cleanup_appsink (sink); +} + +GST_END_TEST; + static Suite * appsink_suite (void) { @@ -329,6 +414,8 @@ appsink_suite (void) tcase_add_test (tc_chain, test_notify0); tcase_add_test (tc_chain, test_notify1); tcase_add_test (tc_chain, test_buffer_list); + tcase_add_test (tc_chain, test_buffer_list_fallback); + tcase_add_test (tc_chain, test_buffer_list_fallback_signal); return s; } From 505fa27159156aaf59a32646b660ee56408ab306 Mon Sep 17 00:00:00 2001 From: Mark Nauwelaerts Date: Sat, 29 Jan 2011 19:40:23 +0100 Subject: [PATCH 179/254] xmptag: cast argument to isdigit to int ... as that is the specification and fixes compilation on Cygwin: gstxmptaag.c: In function 'read_one_tag': gstxmptag.c:1015: error: array subscript has type 'char' --- gst-libs/gst/tag/gstxmptag.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gst-libs/gst/tag/gstxmptag.c b/gst-libs/gst/tag/gstxmptag.c index 2697f40fa3..c3bc6360e8 100644 --- a/gst-libs/gst/tag/gstxmptag.c +++ b/gst-libs/gst/tag/gstxmptag.c @@ -1012,7 +1012,7 @@ read_one_tag (GstTagList * list, const gchar * tag, XmpTag * xmptag, gint num_digits = 0; /* find the number of digits */ - while (isdigit (usec_str[num_digits++]) && num_digits < 6); + while (isdigit ((gint) usec_str[num_digits++]) && num_digits < 6); if (num_digits > 0) { /* fill up to 6 digits with 0 */ From e5e09844ea6134f8a8fe851e6b572d968a2ecc44 Mon Sep 17 00:00:00 2001 From: Mark Nauwelaerts Date: Sat, 29 Jan 2011 20:43:08 +0100 Subject: [PATCH 180/254] tcp: use socklen_t where appropriate rather than specific type In particular, fixes Cygwin build where socklen_t is defined as int in line with native win32 api definition. --- gst/tcp/gsttcpserversink.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gst/tcp/gsttcpserversink.c b/gst/tcp/gsttcpserversink.c index c0cb95f73d..fdca0ec755 100644 --- a/gst/tcp/gsttcpserversink.c +++ b/gst/tcp/gsttcpserversink.c @@ -149,7 +149,7 @@ gst_tcp_server_sink_handle_server_read (GstTCPServerSink * sink) /* new client */ int client_sock_fd; struct sockaddr_in client_address; - unsigned int client_address_len; + socklen_t client_address_len; /* For some stupid reason, client_address and client_address_len has to be * zeroed */ From c36a3e46f5151d6f8b0c723f9e12d1f19fcca4b5 Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Thu, 19 Aug 2010 22:31:07 +0300 Subject: [PATCH 181/254] id3tag: map the ID3v2 TENC frame to GST_TAG_ENCODED_BY https://bugzilla.gnome.org/show_bug.cgi?id=627268 --- configure.ac | 2 +- gst-libs/gst/tag/gstid3tag.c | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index b84d0c5a30..5b08865c7e 100644 --- a/configure.ac +++ b/configure.ac @@ -60,7 +60,7 @@ AC_LIBTOOL_WIN32_DLL AM_PROG_LIBTOOL dnl *** required versions of GStreamer stuff *** -GST_REQ=0.10.32 +GST_REQ=0.10.32.1 dnl *** autotools stuff **** diff --git a/gst-libs/gst/tag/gstid3tag.c b/gst-libs/gst/tag/gstid3tag.c index fc13fb2c5a..8c9b352643 100644 --- a/gst-libs/gst/tag/gstid3tag.c +++ b/gst-libs/gst/tag/gstid3tag.c @@ -201,6 +201,7 @@ static const GstTagEntryMatch tag_matches[] = { {GST_TAG_COMPOSER, "TCOM"}, {GST_TAG_COPYRIGHT, "TCOP"}, {GST_TAG_COPYRIGHT_URI, "WCOP"}, + {GST_TAG_ENCODED_BY, "TENC"}, {GST_TAG_GENRE, "TCON"}, {GST_TAG_DATE, "TDRC"}, {GST_TAG_COMMENT, "COMM"}, From 9805bdfcc8874e3673f09b0913bdc62f5ea2d614 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim-Philipp=20M=C3=BCller?= Date: Tue, 1 Feb 2011 15:57:14 +0000 Subject: [PATCH 182/254] theoraenc: clean up property descriptions Remove "This property requires libtheora version >= 1.1" qualifiers from property descriptions. They aren't needed any longer now that we require libtheora >= 1.1. --- ext/theora/gsttheoraenc.c | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) diff --git a/ext/theora/gsttheoraenc.c b/ext/theora/gsttheoraenc.c index 8ccfa93cc0..d31485bfd8 100644 --- a/ext/theora/gsttheoraenc.c +++ b/ext/theora/gsttheoraenc.c @@ -302,39 +302,33 @@ gst_theora_enc_class_init (GstTheoraEncClass * klass) g_object_class_install_property (gobject_class, PROP_SPEEDLEVEL, g_param_spec_int ("speed-level", "Speed level", "Controls the amount of motion vector searching done while " - "encoding. This property requires libtheora version >= 1.0", - 0, 3, THEORA_DEF_SPEEDLEVEL, + "encoding", 0, 3, THEORA_DEF_SPEEDLEVEL, (GParamFlags) G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); g_object_class_install_property (gobject_class, PROP_VP3_COMPATIBLE, g_param_spec_boolean ("vp3-compatible", "VP3 Compatible", - "Disables non-VP3 compatible features." - " This property requires libtheora version >= 1.1", + "Disables non-VP3 compatible features", THEORA_DEF_VP3_COMPATIBLE, (GParamFlags) G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); g_object_class_install_property (gobject_class, PROP_DROP_FRAMES, g_param_spec_boolean ("drop-frames", "VP3 Compatible", - "Allow or disallow frame dropping." - " This property requires libtheora version >= 1.1", + "Allow or disallow frame dropping", THEORA_DEF_DROP_FRAMES, (GParamFlags) G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); g_object_class_install_property (gobject_class, PROP_CAP_OVERFLOW, g_param_spec_boolean ("cap-overflow", "VP3 Compatible", - "Enable capping of bit reservoir overflows." - " This property requires libtheora version >= 1.1", + "Enable capping of bit reservoir overflows", THEORA_DEF_CAP_OVERFLOW, (GParamFlags) G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); g_object_class_install_property (gobject_class, PROP_CAP_UNDERFLOW, g_param_spec_boolean ("cap-underflow", "VP3 Compatible", - "Enable capping of bit reservoir underflows." - " This property requires libtheora version >= 1.1", + "Enable capping of bit reservoir underflows", THEORA_DEF_CAP_UNDERFLOW, (GParamFlags) G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); g_object_class_install_property (gobject_class, PROP_RATE_BUFFER, g_param_spec_int ("rate-buffer", "Rate Control Buffer", "Sets the size of the rate control buffer, in units of frames. " "The default value of 0 instructs the encoder to automatically " - "select an appropriate value." - " This property requires libtheora version >= 1.1", + "select an appropriate value", 0, 1000, THEORA_DEF_RATE_BUFFER, (GParamFlags) G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); g_object_class_install_property (gobject_class, PROP_MULTIPASS_CACHE_FILE, From b7664eae716a7e0026c3d4d7ca10897a30f6a45e Mon Sep 17 00:00:00 2001 From: Vincent Penquerc'h Date: Fri, 21 Jan 2011 10:56:00 +0000 Subject: [PATCH 183/254] oggmux: do not skip a pageno at start Discontinuities are automatically signalled by oggdemux at the start of a new stream. When oggmux is yet to output actual data pages, do not signal these discontinuities in the ogg stream. This patch may miss some actual discontinuities at the very start of a stream, but avoids the spurious missing pages when encoding happens normally. A better fix might involve finding a way to distinguish between actual data discontinuities and discontinuities merely marking the start of a new stream. Fixes an issue with ogg page numbering (would skip a number for no reason, which then looks like a packet was lost somewhere) when re-muxing an ogg stream, e.g. when re-tagging in rhythmbox. https://bugzilla.gnome.org/show_bug.cgi?id=629196 --- ext/ogg/gstoggmux.c | 17 ++++++++++++----- ext/ogg/gstoggmux.h | 1 + 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/ext/ogg/gstoggmux.c b/ext/ogg/gstoggmux.c index 11a67920f7..c36b4fb585 100644 --- a/ext/ogg/gstoggmux.c +++ b/ext/ogg/gstoggmux.c @@ -394,6 +394,7 @@ gst_ogg_mux_request_new_pad (GstElement * element, oggpad->new_page = TRUE; oggpad->first_delta = FALSE; oggpad->prev_delta = FALSE; + oggpad->data_pushed = FALSE; oggpad->pagebuffers = g_queue_new (); oggpad->collect_event = (GstPadEventFunction) GST_PAD_EVENTFUNC (newpad); @@ -1306,11 +1307,15 @@ gst_ogg_mux_process_best_pad (GstOggMux * ogg_mux, GstOggPadData * best) } if (GST_BUFFER_IS_DISCONT (buf)) { - GST_LOG_OBJECT (pad->collect.pad, "got discont"); - packet.packetno++; - /* No public API for this; hack things in */ - pad->stream.pageno++; - force_flush = TRUE; + if (pad->data_pushed) { + GST_LOG_OBJECT (pad->collect.pad, "got discont"); + packet.packetno++; + /* No public API for this; hack things in */ + pad->stream.pageno++; + force_flush = TRUE; + } else { + GST_LOG_OBJECT (pad->collect.pad, "discont at stream start"); + } } /* flush the currently built page if necessary */ @@ -1364,6 +1369,7 @@ gst_ogg_mux_process_best_pad (GstOggMux * ogg_mux, GstOggPadData * best) GST_DEBUG_OBJECT (pad->collect.pad, "swapping in BOS packet"); ogg_stream_packetin (&pad->stream, &packet); + pad->data_pushed = TRUE; gp_time = GST_BUFFER_OFFSET (pad->buffer); granulepos = GST_BUFFER_OFFSET_END (pad->buffer); @@ -1607,6 +1613,7 @@ gst_ogg_mux_init_collectpads (GstCollectPads * collect) oggpad->new_page = TRUE; oggpad->first_delta = FALSE; oggpad->prev_delta = FALSE; + oggpad->data_pushed = FALSE; oggpad->pagebuffers = g_queue_new (); walk = g_slist_next (walk); diff --git a/ext/ogg/gstoggmux.h b/ext/ogg/gstoggmux.h index 6134d5ed2f..37b1fae091 100644 --- a/ext/ogg/gstoggmux.h +++ b/ext/ogg/gstoggmux.h @@ -78,6 +78,7 @@ typedef struct gboolean new_page; /* starting a new page */ gboolean first_delta; /* was the first packet in the page a delta */ gboolean prev_delta; /* was the previous buffer a delta frame */ + gboolean data_pushed; /* whether we pushed data already */ GstPadEventFunction collect_event; From 2c017d2a70d49bf3a9cd40ba203b383e4a54fe59 Mon Sep 17 00:00:00 2001 From: Mark Nauwelaerts Date: Wed, 2 Feb 2011 15:33:36 +0100 Subject: [PATCH 184/254] uridecodebin: fix copy-and-paste typo in property docs --- gst/playback/gsturidecodebin.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gst/playback/gsturidecodebin.c b/gst/playback/gsturidecodebin.c index a72c8f2c58..d36fff9754 100644 --- a/gst/playback/gsturidecodebin.c +++ b/gst/playback/gsturidecodebin.c @@ -407,7 +407,7 @@ gst_uri_decode_bin_class_init (GstURIDecodeBinClass * klass) G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); /** - * GstQueue2:ring-buffer-max-size + * GstURIDecodeBin::ring-buffer-max-size * * The maximum size of the ring buffer in kilobytes. If set to 0, the ring * buffer is disabled. Default is 0. From 440002a137640db2c5d6613d9bf56dfff997eb07 Mon Sep 17 00:00:00 2001 From: Vincent Penquerc'h Date: Fri, 21 Jan 2011 16:05:46 +0000 Subject: [PATCH 185/254] oggmux: use oggstream for less brittleness in recognizing headers Using the IN_CAPS flag for this is brittle, and will fail if either vorbisparse or vorbistag (which is itself based on vorbisparse) is inserted between oggdemux and oggmux. Possibly other elements too (eg, theoraparse, etc). Using oggstream ensures we Get It Right More Often Than Not. https://bugzilla.gnome.org/show_bug.cgi?id=629196 --- ext/ogg/gstoggmux.c | 80 ++++++++++++++++++++++++++++----------------- ext/ogg/gstoggmux.h | 8 ++--- 2 files changed, 54 insertions(+), 34 deletions(-) diff --git a/ext/ogg/gstoggmux.c b/ext/ogg/gstoggmux.c index c36b4fb585..984b890356 100644 --- a/ext/ogg/gstoggmux.c +++ b/ext/ogg/gstoggmux.c @@ -282,7 +282,7 @@ gst_ogg_mux_ogg_pad_destroy_notify (GstCollectData * data) GstOggPadData *oggpad = (GstOggPadData *) data; GstBuffer *buf; - ogg_stream_clear (&oggpad->stream); + ogg_stream_clear (&oggpad->map.stream); if (oggpad->pagebuffers) { while ((buf = g_queue_pop_head (oggpad->pagebuffers)) != NULL) { @@ -384,8 +384,8 @@ gst_ogg_mux_request_new_pad (GstElement * element, sizeof (GstOggPadData), gst_ogg_mux_ogg_pad_destroy_notify); ogg_mux->active_pads++; - oggpad->serial = serial; - ogg_stream_init (&oggpad->stream, serial); + oggpad->map.serialno = serial; + ogg_stream_init (&oggpad->map.stream, oggpad->map.serialno); oggpad->packetno = 0; oggpad->pageno = 0; oggpad->eos = FALSE; @@ -396,6 +396,8 @@ gst_ogg_mux_request_new_pad (GstElement * element, oggpad->prev_delta = FALSE; oggpad->data_pushed = FALSE; oggpad->pagebuffers = g_queue_new (); + oggpad->map.headers = NULL; + oggpad->map.queued = NULL; oggpad->collect_event = (GstPadEventFunction) GST_PAD_EVENTFUNC (newpad); gst_pad_set_event_function (newpad, @@ -751,7 +753,6 @@ gst_ogg_mux_queue_pads (GstOggMux * ogg_mux) /* try to get a new buffer for this pad if needed and possible */ if (pad->buffer == NULL) { GstBuffer *buf; - gboolean incaps; /* shift the buffer along if needed (it's okay if next_buffer is NULL) */ if (pad->buffer == NULL) { @@ -770,13 +771,31 @@ gst_ogg_mux_queue_pads (GstOggMux * ogg_mux) GST_BUFFER_FLAG_IS_SET (buf, GST_BUFFER_FLAG_DELTA_UNIT)) ogg_mux->delta_pad = pad; - incaps = GST_BUFFER_FLAG_IS_SET (buf, GST_BUFFER_FLAG_IN_CAPS); /* if we need headers */ if (pad->state == GST_OGG_PAD_STATE_CONTROL) { /* and we have one */ - if (incaps) { + ogg_packet packet; + packet.packet = GST_BUFFER_DATA (buf); + packet.bytes = GST_BUFFER_SIZE (buf); + packet.granulepos = GST_BUFFER_OFFSET_END (buf); + if (packet.granulepos == -1) + packet.granulepos = 0; + + /* if we're not yet in data mode, ensure we're setup on the first packet */ + if (!pad->have_type) { + pad->have_type = gst_ogg_stream_setup_map (&pad->map, &packet); + if (!pad->have_type) { + pad->map.caps = + gst_caps_new_simple ("application/x-unknown", NULL); + } + GST_DEBUG_OBJECT (ogg_mux, "New pad has caps: %s", + gst_caps_to_string (pad->map.caps)); + } + + + if (gst_ogg_stream_packet_is_header (&pad->map, &packet)) { GST_DEBUG_OBJECT (ogg_mux, - "got incaps buffer in control state, ignoring"); + "got header buffer in control state, ignoring"); /* just ignore */ gst_buffer_unref (buf); buf = NULL; @@ -799,7 +818,7 @@ gst_ogg_mux_queue_pads (GstOggMux * ogg_mux) /* Just gone to EOS. Flush existing page(s) */ pad->eos = TRUE; - while (ogg_stream_flush (&pad->stream, &page)) { + while (ogg_stream_flush (&pad->map.stream, &page)) { /* Place page into the per-pad queue */ ret = gst_ogg_mux_pad_queue_page (ogg_mux, pad, &page, pad->first_delta); @@ -974,7 +993,7 @@ gst_ogg_mux_send_headers (GstOggMux * mux) continue; /* now figure out the headers */ - pad->headers = gst_ogg_mux_get_headers (pad); + pad->map.headers = gst_ogg_mux_get_headers (pad); } GST_LOG_OBJECT (mux, "creating BOS pages"); @@ -1000,9 +1019,9 @@ gst_ogg_mux_send_headers (GstOggMux * mux) GST_LOG_OBJECT (thepad, "looping over headers"); - if (pad->headers) { - buf = GST_BUFFER (pad->headers->data); - pad->headers = g_list_remove (pad->headers, buf); + if (pad->map.headers) { + buf = GST_BUFFER (pad->map.headers->data); + pad->map.headers = g_list_remove (pad->map.headers, buf); } else if (pad->buffer) { buf = pad->buffer; gst_buffer_ref (buf); @@ -1031,11 +1050,11 @@ gst_ogg_mux_send_headers (GstOggMux * mux) packet.e_o_s = 0; /* swap the packet in */ - ogg_stream_packetin (&pad->stream, &packet); + ogg_stream_packetin (&pad->map.stream, &packet); gst_buffer_unref (buf); GST_LOG_OBJECT (thepad, "flushing out BOS page"); - if (!ogg_stream_flush (&pad->stream, &page)) + if (!ogg_stream_flush (&pad->map.stream, &page)) g_critical ("Could not flush BOS page"); hbuf = gst_ogg_mux_buffer_from_page (mux, &page, FALSE); @@ -1079,7 +1098,7 @@ gst_ogg_mux_send_headers (GstOggMux * mux) GST_LOG_OBJECT (mux, "looping over headers for pad %s:%s", GST_DEBUG_PAD_NAME (thepad)); - hwalk = pad->headers; + hwalk = pad->map.headers; while (hwalk) { GstBuffer *buf = GST_BUFFER (hwalk->data); ogg_packet packet; @@ -1100,7 +1119,7 @@ gst_ogg_mux_send_headers (GstOggMux * mux) packet.e_o_s = 0; /* swap the packet in */ - ogg_stream_packetin (&pad->stream, &packet); + ogg_stream_packetin (&pad->map.stream, &packet); gst_buffer_unref (buf); /* if last header, flush page */ @@ -1108,7 +1127,7 @@ gst_ogg_mux_send_headers (GstOggMux * mux) GST_LOG_OBJECT (mux, "flushing page as packet %" G_GUINT64_FORMAT " is first or " "last packet", packet.packetno); - while (ogg_stream_flush (&pad->stream, &page)) { + while (ogg_stream_flush (&pad->map.stream, &page)) { GstBuffer *hbuf = gst_ogg_mux_buffer_from_page (mux, &page, FALSE); GST_LOG_OBJECT (mux, "swapped out page"); @@ -1117,7 +1136,7 @@ gst_ogg_mux_send_headers (GstOggMux * mux) } else { GST_LOG_OBJECT (mux, "try to swap out page"); /* just try to swap out a page then */ - while (ogg_stream_pageout (&pad->stream, &page) > 0) { + while (ogg_stream_pageout (&pad->map.stream, &page) > 0) { GstBuffer *hbuf = gst_ogg_mux_buffer_from_page (mux, &page, FALSE); GST_LOG_OBJECT (mux, "swapped out page"); @@ -1125,8 +1144,8 @@ gst_ogg_mux_send_headers (GstOggMux * mux) } } } - g_list_free (pad->headers); - pad->headers = NULL; + g_list_free (pad->map.headers); + pad->map.headers = NULL; } /* hbufs holds all buffers for the headers now */ @@ -1207,9 +1226,10 @@ gst_ogg_mux_process_best_pad (GstOggMux * ogg_mux, GstOggPadData * best) GST_LOG_OBJECT (pad->collect.pad, GST_GP_FORMAT " stored packet %" G_GINT64_FORMAT " will make page too long, flushing", - GST_BUFFER_OFFSET_END (pad->buffer), (gint64) pad->stream.packetno); + GST_BUFFER_OFFSET_END (pad->buffer), + (gint64) pad->map.stream.packetno); - while (ogg_stream_flush (&pad->stream, &page)) { + while (ogg_stream_flush (&pad->map.stream, &page)) { /* end time of this page is the timestamp of the next buffer */ ogg_mux->pulling->timestamp_end = GST_BUFFER_TIMESTAMP (pad->buffer); /* Place page into the per-pad queue */ @@ -1311,7 +1331,7 @@ gst_ogg_mux_process_best_pad (GstOggMux * ogg_mux, GstOggPadData * best) GST_LOG_OBJECT (pad->collect.pad, "got discont"); packet.packetno++; /* No public API for this; hack things in */ - pad->stream.pageno++; + pad->map.stream.pageno++; force_flush = TRUE; } else { GST_LOG_OBJECT (pad->collect.pad, "discont at stream start"); @@ -1323,7 +1343,7 @@ gst_ogg_mux_process_best_pad (GstOggMux * ogg_mux, GstOggPadData * best) GST_LOG_OBJECT (pad->collect.pad, GST_GP_FORMAT " forced flush of page before this packet", GST_BUFFER_OFFSET_END (pad->buffer)); - while (ogg_stream_flush (&pad->stream, &page)) { + while (ogg_stream_flush (&pad->map.stream, &page)) { /* end time of this page is the timestamp of the next buffer */ ogg_mux->pulling->timestamp_end = GST_BUFFER_TIMESTAMP (pad->buffer); ret = gst_ogg_mux_pad_queue_page (ogg_mux, pad, &page, @@ -1368,7 +1388,7 @@ gst_ogg_mux_process_best_pad (GstOggMux * ogg_mux, GstOggPadData * best) if (packet.b_o_s == 1) GST_DEBUG_OBJECT (pad->collect.pad, "swapping in BOS packet"); - ogg_stream_packetin (&pad->stream, &packet); + ogg_stream_packetin (&pad->map.stream, &packet); pad->data_pushed = TRUE; gp_time = GST_BUFFER_OFFSET (pad->buffer); @@ -1387,7 +1407,7 @@ gst_ogg_mux_process_best_pad (GstOggMux * ogg_mux, GstOggPadData * best) /* let ogg write out the pages now. The packet we got could end * up in more than one page so we need to write them all */ - if (ogg_stream_pageout (&pad->stream, &page) > 0) { + if (ogg_stream_pageout (&pad->map.stream, &page) > 0) { /* we have a new page, so we need to timestamp it correctly. * if this fresh packet ends on this page, then the page's granulepos * comes from that packet, and we should set this buffer's timestamp */ @@ -1398,7 +1418,7 @@ gst_ogg_mux_process_best_pad (GstOggMux * ogg_mux, GstOggPadData * best) granulepos, (gint64) packet.packetno, GST_TIME_ARGS (timestamp)); GST_LOG_OBJECT (pad->collect.pad, GST_GP_FORMAT " new page %ld", - GST_GP_CAST (ogg_page_granulepos (&page)), pad->stream.pageno); + GST_GP_CAST (ogg_page_granulepos (&page)), pad->map.stream.pageno); if (ogg_page_granulepos (&page) == granulepos) { /* the packet we streamed in finishes on the current page, @@ -1427,7 +1447,7 @@ gst_ogg_mux_process_best_pad (GstOggMux * ogg_mux, GstOggPadData * best) /* use an inner loop here to flush the remaining pages and * mark them as delta frames as well */ - while (ogg_stream_pageout (&pad->stream, &page) > 0) { + while (ogg_stream_pageout (&pad->map.stream, &page) > 0) { if (ogg_page_granulepos (&page) == granulepos) { /* the page has taken up the new packet completely, which means * the packet ends the page and we can update the gp time @@ -1604,7 +1624,7 @@ gst_ogg_mux_init_collectpads (GstCollectPads * collect) while (walk) { GstOggPadData *oggpad = (GstOggPadData *) walk->data; - ogg_stream_init (&oggpad->stream, oggpad->serial); + ogg_stream_init (&oggpad->map.stream, oggpad->map.serialno); oggpad->packetno = 0; oggpad->pageno = 0; oggpad->eos = FALSE; @@ -1630,7 +1650,7 @@ gst_ogg_mux_clear_collectpads (GstCollectPads * collect) GstOggPadData *oggpad = (GstOggPadData *) walk->data; GstBuffer *buf; - ogg_stream_clear (&oggpad->stream); + ogg_stream_clear (&oggpad->map.stream); while ((buf = g_queue_pop_head (oggpad->pagebuffers)) != NULL) { gst_buffer_unref (buf); diff --git a/ext/ogg/gstoggmux.h b/ext/ogg/gstoggmux.h index 37b1fae091..6812f82ca2 100644 --- a/ext/ogg/gstoggmux.h +++ b/ext/ogg/gstoggmux.h @@ -25,6 +25,7 @@ #include #include +#include "gstoggstream.h" G_BEGIN_DECLS @@ -49,13 +50,14 @@ typedef struct { GstCollectData collect; /* we extend the CollectData */ + GstOggStream map; + gboolean have_type; + /* These two buffers make a very simple queue - they enter as 'next_buffer' * and (usually) leave as 'buffer', except at EOS, when buffer will be NULL */ GstBuffer *buffer; /* the first waiting buffer for the pad */ GstBuffer *next_buffer; /* the second waiting buffer for the pad */ - gint serial; - ogg_stream_state stream; gint64 packetno; /* number of next packet */ gint64 pageno; /* number of next page */ guint64 duration; /* duration of current page */ @@ -71,8 +73,6 @@ typedef struct GstOggPadState state; /* state of the pad */ - GList *headers; - GQueue *pagebuffers; /* List of pages in buffers ready for pushing */ gboolean new_page; /* starting a new page */ From 2eac43bd73ff405c6883c1c2476a90a123b52159 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim-Philipp=20M=C3=BCller?= Date: Wed, 2 Feb 2011 17:23:43 +0000 Subject: [PATCH 186/254] oggmux: keep IN_CAPS flag check for header buffers as fallback In case the ogg mapper doesn't handle all the accepted input formats (although it really should). Saves us error handling for that case though. Also log caps properly. https://bugzilla.gnome.org/show_bug.cgi?id=629196 --- ext/ogg/gstoggmux.c | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/ext/ogg/gstoggmux.c b/ext/ogg/gstoggmux.c index 984b890356..6dfbf612c3 100644 --- a/ext/ogg/gstoggmux.c +++ b/ext/ogg/gstoggmux.c @@ -775,25 +775,34 @@ gst_ogg_mux_queue_pads (GstOggMux * ogg_mux) if (pad->state == GST_OGG_PAD_STATE_CONTROL) { /* and we have one */ ogg_packet packet; + gboolean is_header; + packet.packet = GST_BUFFER_DATA (buf); packet.bytes = GST_BUFFER_SIZE (buf); - packet.granulepos = GST_BUFFER_OFFSET_END (buf); - if (packet.granulepos == -1) + + if (GST_BUFFER_OFFSET_END_IS_VALID (buf)) + packet.granulepos = GST_BUFFER_OFFSET_END (buf); + else packet.granulepos = 0; /* if we're not yet in data mode, ensure we're setup on the first packet */ if (!pad->have_type) { pad->have_type = gst_ogg_stream_setup_map (&pad->map, &packet); if (!pad->have_type) { - pad->map.caps = - gst_caps_new_simple ("application/x-unknown", NULL); + GST_ERROR_OBJECT (pad, "mapper didn't recognise input stream " + "(pad caps: %" GST_PTR_FORMAT ")", GST_PAD_CAPS (pad)); + } else { + GST_DEBUG_OBJECT (pad, "caps detected: %" GST_PTR_FORMAT, + pad->map.caps); } - GST_DEBUG_OBJECT (ogg_mux, "New pad has caps: %s", - gst_caps_to_string (pad->map.caps)); } + if (pad->have_type) + is_header = gst_ogg_stream_packet_is_header (&pad->map, &packet); + else /* fallback (FIXME 0.11: remove IN_CAPS hack) */ + is_header = GST_BUFFER_FLAG_IS_SET (buf, GST_BUFFER_FLAG_IN_CAPS); - if (gst_ogg_stream_packet_is_header (&pad->map, &packet)) { + if (is_header) { GST_DEBUG_OBJECT (ogg_mux, "got header buffer in control state, ignoring"); /* just ignore */ From 54c19ba6def4f9cead7e18a893c981e425f9405c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim-Philipp=20M=C3=BCller?= Date: Wed, 2 Feb 2011 17:30:15 +0000 Subject: [PATCH 187/254] oggmux: free stream map caps when done --- ext/ogg/gstoggmux.c | 1 + 1 file changed, 1 insertion(+) diff --git a/ext/ogg/gstoggmux.c b/ext/ogg/gstoggmux.c index 6dfbf612c3..3329824b5d 100644 --- a/ext/ogg/gstoggmux.c +++ b/ext/ogg/gstoggmux.c @@ -283,6 +283,7 @@ gst_ogg_mux_ogg_pad_destroy_notify (GstCollectData * data) GstBuffer *buf; ogg_stream_clear (&oggpad->map.stream); + gst_caps_replace (&oggpad->map.caps, NULL); if (oggpad->pagebuffers) { while ((buf = g_queue_pop_head (oggpad->pagebuffers)) != NULL) { From 96a1a9dec6676826dd808d6c35a5ae3f7f276212 Mon Sep 17 00:00:00 2001 From: Vincent Penquerc'h Date: Fri, 21 Jan 2011 18:10:29 +0000 Subject: [PATCH 188/254] oggmux: ensure serialnos are unique We do that by checking a newly generated one is not already used in an existing stream, and doing it again if it is. https://bugzilla.gnome.org/show_bug.cgi?id=640211 --- ext/ogg/gstoggmux.c | 30 +++++++++++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/ext/ogg/gstoggmux.c b/ext/ogg/gstoggmux.c index 3329824b5d..c6ed67c72a 100644 --- a/ext/ogg/gstoggmux.c +++ b/ext/ogg/gstoggmux.c @@ -337,6 +337,34 @@ gst_ogg_mux_sink_event (GstPad * pad, GstEvent * event) return ret; } +static gboolean +gst_ogg_mux_is_serialno_present (GstOggMux * ogg_mux, guint32 serialno) +{ + GSList *walk; + + walk = ogg_mux->collect->data; + while (walk) { + GstOggPadData *pad = (GstOggPadData *) walk->data; + if (pad->map.serialno == serialno) + return TRUE; + walk = walk->next; + } + + return FALSE; +} + +static guint32 +gst_ogg_mux_generate_serialno (GstOggMux * ogg_mux) +{ + guint32 serialno; + + do { + serialno = g_random_int_range (0, G_MAXINT32); + } while (gst_ogg_mux_is_serialno_present (ogg_mux, serialno)); + + return serialno; +} + static GstPad * gst_ogg_mux_request_new_pad (GstElement * element, GstPadTemplate * templ, const gchar * req_name) @@ -364,7 +392,7 @@ gst_ogg_mux_request_new_pad (GstElement * element, if (req_name == NULL || strlen (req_name) < 6) { /* no name given when requesting the pad, use random serial number */ - serial = rand (); + serial = gst_ogg_mux_generate_serialno (ogg_mux); } else { /* parse serial number from requested padname */ serial = atoi (&req_name[5]); From b2389c2108b6f643e4c0879d22059530d4d734c5 Mon Sep 17 00:00:00 2001 From: Mark Nauwelaerts Date: Wed, 2 Feb 2011 16:49:04 +0100 Subject: [PATCH 189/254] tagdemux: also push cached events downstream when operating in pull mode Otherwise, having 2 tagdemux in a row followed by an element operating in pull mode will make the second tagdemux implictly eat the first tagdemux' tag event(s). Fixes (part of) #641047. --- gst-libs/gst/tag/gsttagdemux.c | 41 +++++++++++++++++++++++----------- 1 file changed, 28 insertions(+), 13 deletions(-) diff --git a/gst-libs/gst/tag/gsttagdemux.c b/gst-libs/gst/tag/gsttagdemux.c index fdc09b83ce..8bb331434e 100644 --- a/gst-libs/gst/tag/gsttagdemux.c +++ b/gst-libs/gst/tag/gsttagdemux.c @@ -156,6 +156,7 @@ static GstStateChangeReturn gst_tag_demux_change_state (GstElement * element, static gboolean gst_tag_demux_pad_query (GstPad * pad, GstQuery * query); static const GstQueryType *gst_tag_demux_get_query_types (GstPad * pad); static gboolean gst_tag_demux_get_upstream_size (GstTagDemux * tagdemux); +static void gst_tag_demux_send_pending_events (GstTagDemux * tagdemux); static void gst_tag_demux_send_tag_event (GstTagDemux * tagdemux); static gboolean gst_tag_demux_send_new_segment (GstTagDemux * tagdemux); @@ -668,8 +669,6 @@ gst_tag_demux_chain (GstPad * pad, GstBuffer * buf) return GST_FLOW_UNEXPECTED; } if (outbuf) { - GList *events; - if (G_UNLIKELY (demux->priv->srcpad == NULL)) { gst_buffer_unref (outbuf); return GST_FLOW_ERROR; @@ -685,17 +684,7 @@ gst_tag_demux_chain (GstPad * pad, GstBuffer * buf) } /* send any pending events we cached */ - GST_OBJECT_LOCK (demux); - events = demux->priv->pending_events; - demux->priv->pending_events = NULL; - GST_OBJECT_UNLOCK (demux); - - while (events != NULL) { - GST_DEBUG_OBJECT (demux->priv->srcpad, "sending cached %s event: %" - GST_PTR_FORMAT, GST_EVENT_TYPE_NAME (events->data), events->data); - gst_pad_push_event (demux->priv->srcpad, GST_EVENT (events->data)); - events = g_list_delete_link (events, events); - } + gst_tag_demux_send_pending_events (demux); /* Send our own pending tag event */ if (demux->priv->send_tag_event) { @@ -1333,6 +1322,13 @@ gst_tag_demux_src_getrange (GstPad * srcpad, { GstTagDemux *demux = GST_TAG_DEMUX (GST_PAD_PARENT (srcpad)); + /* downstream in pull mode won't miss a newsegment event, + * but it likely appreciates other (tag) events */ + if (demux->priv->need_newseg) { + gst_tag_demux_send_pending_events (demux); + demux->priv->need_newseg = FALSE; + } + if (demux->priv->send_tag_event) { gst_tag_demux_send_tag_event (demux); demux->priv->send_tag_event = FALSE; @@ -1418,6 +1414,25 @@ gst_tag_demux_get_query_types (GstPad * pad) return types; } +static void +gst_tag_demux_send_pending_events (GstTagDemux * demux) +{ + GList *events; + + /* send any pending events we cached */ + GST_OBJECT_LOCK (demux); + events = demux->priv->pending_events; + demux->priv->pending_events = NULL; + GST_OBJECT_UNLOCK (demux); + + while (events != NULL) { + GST_DEBUG_OBJECT (demux->priv->srcpad, "sending cached %s event: %" + GST_PTR_FORMAT, GST_EVENT_TYPE_NAME (events->data), events->data); + gst_pad_push_event (demux->priv->srcpad, GST_EVENT (events->data)); + events = g_list_delete_link (events, events); + } +} + static void gst_tag_demux_send_tag_event (GstTagDemux * demux) { From fe59f50468b8fc4f22b5c29487d64ed1b0026e76 Mon Sep 17 00:00:00 2001 From: Stefan Kost Date: Tue, 8 Feb 2011 12:31:34 +0200 Subject: [PATCH 190/254] decodebin2: caps can be NULL Don't use and unref NULL caps. --- gst/playback/gstdecodebin2.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/gst/playback/gstdecodebin2.c b/gst/playback/gstdecodebin2.c index 064d62e41e..673e9b4434 100644 --- a/gst/playback/gstdecodebin2.c +++ b/gst/playback/gstdecodebin2.c @@ -3064,13 +3064,15 @@ gst_decode_chain_get_topology (GstDecodeChain * chain) for (; l && l->next; l = l->next) { GstCaps *caps = _gst_element_get_linked_caps (l->next->data, l->data); - s = gst_structure_id_empty_new (topology_structure_name); - gst_structure_id_set (u, topology_caps, GST_TYPE_CAPS, caps, NULL); - gst_caps_unref (caps); + if (caps) { + s = gst_structure_id_empty_new (topology_structure_name); + gst_structure_id_set (u, topology_caps, GST_TYPE_CAPS, caps, NULL); + gst_caps_unref (caps); - gst_structure_id_set (s, topology_next, GST_TYPE_STRUCTURE, u, NULL); - gst_structure_free (u); - u = s; + gst_structure_id_set (s, topology_next, GST_TYPE_STRUCTURE, u, NULL); + gst_structure_free (u); + u = s; + } } /* Caps that resulted in this chain */ From e9ff48376b04a5c3bd73c37bd37171a63282d6aa Mon Sep 17 00:00:00 2001 From: Arun Raghavan Date: Tue, 8 Feb 2011 23:58:56 +0530 Subject: [PATCH 191/254] discoverer: Use nominal bitrate if bitrate tag is unavailable If the bitrate tag is unavailable, this falls back to the nominal bitrate tag instead, if that is present. https://bugzilla.gnome.org/show_bug.cgi?id=641860 --- gst-libs/gst/pbutils/gstdiscoverer.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/gst-libs/gst/pbutils/gstdiscoverer.c b/gst-libs/gst/pbutils/gstdiscoverer.c index 8422d8f10b..854fd46def 100644 --- a/gst-libs/gst/pbutils/gstdiscoverer.c +++ b/gst-libs/gst/pbutils/gstdiscoverer.c @@ -598,7 +598,8 @@ collect_information (GstDiscoverer * dc, const GstStructure * st, if (gst_structure_id_has_field (st, _TAGS_QUARK)) { gst_structure_id_get (st, _TAGS_QUARK, GST_TYPE_STRUCTURE, &tags_st, NULL); - if (gst_structure_get_uint (tags_st, GST_TAG_BITRATE, &utmp)) + if (gst_structure_get_uint (tags_st, GST_TAG_BITRATE, &utmp) || + gst_structure_get_uint (tags_st, GST_TAG_NOMINAL_BITRATE, &utmp)) info->bitrate = utmp; if (gst_structure_get_uint (tags_st, GST_TAG_MAXIMUM_BITRATE, &utmp)) @@ -650,7 +651,8 @@ collect_information (GstDiscoverer * dc, const GstStructure * st, if (gst_structure_id_has_field (st, _TAGS_QUARK)) { gst_structure_id_get (st, _TAGS_QUARK, GST_TYPE_STRUCTURE, &tags_st, NULL); - if (gst_structure_get_uint (tags_st, GST_TAG_BITRATE, &utmp)) + if (gst_structure_get_uint (tags_st, GST_TAG_BITRATE, &utmp) || + gst_structure_get_uint (tags_st, GST_TAG_NOMINAL_BITRATE, &utmp)) info->bitrate = utmp; if (gst_structure_get_uint (tags_st, GST_TAG_MAXIMUM_BITRATE, &utmp)) From c6578dd3ce57d2a8b2975d82095e967ed4119e62 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim-Philipp=20M=C3=BCller?= Date: Thu, 10 Feb 2011 23:44:43 +0000 Subject: [PATCH 192/254] doap: update mailing list location --- gst-plugins-base.doap | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gst-plugins-base.doap b/gst-plugins-base.doap index ac4d649872..f0dcb1470e 100644 --- a/gst-plugins-base.doap +++ b/gst-plugins-base.doap @@ -22,7 +22,7 @@ A wide range of video and audio decoders, encoders, and filters are included. - + C From f481a983fdd8b907301bd25a6ca5c6e79df46c02 Mon Sep 17 00:00:00 2001 From: Stefan Kost Date: Mon, 14 Feb 2011 12:52:59 +0200 Subject: [PATCH 193/254] Automatic update of common submodule From f94d739 to 1de7f6a --- common | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common b/common index f94d739915..1de7f6ab2d 160000 --- a/common +++ b/common @@ -1 +1 @@ -Subproject commit f94d73991563ea2dcae2218b4847e32998f06816 +Subproject commit 1de7f6ab2d4bc1af69f06079cf0f4e2cbbfdc178 From f7dbec909163ad197cf152fd8214a9ad4a58ae9a Mon Sep 17 00:00:00 2001 From: Andoni Morales Alastruey Date: Wed, 9 Feb 2011 12:45:23 +0100 Subject: [PATCH 194/254] gdppay: ensure buffer's metadata is writable before setting caps --- gst/gdp/gstgdppay.c | 1 + 1 file changed, 1 insertion(+) diff --git a/gst/gdp/gstgdppay.c b/gst/gdp/gstgdppay.c index f9e27da1e0..6da4967f7a 100644 --- a/gst/gdp/gstgdppay.c +++ b/gst/gdp/gstgdppay.c @@ -474,6 +474,7 @@ gst_gdp_pay_reset_streamheader (GstGDPPay * this) GST_DEBUG_OBJECT (this, "Setting caps on src pad %" GST_PTR_FORMAT, caps); gst_pad_set_caps (this->srcpad, caps); + this->caps_buf = gst_buffer_make_metadata_writable (this->caps_buf); gst_buffer_set_caps (this->caps_buf, caps); this->new_segment_buf = gst_buffer_make_metadata_writable (this->new_segment_buf); From 46f3e7c6fd9148677e97e01c5a29f07f59a132b3 Mon Sep 17 00:00:00 2001 From: Sjoerd Simons Date: Sun, 13 Feb 2011 14:42:14 +0000 Subject: [PATCH 195/254] theoraenc: Don't reset the video quality setting the bitrate libtheora has two encoding modes, CBR, where it tries to hit a target bitrate and VBR where it tries to achieve a target quality. Internally if the target bitrate is set to anything other then 0 the encoding-mode is CBR. This means that the gstreamer element can leave the video_quality setting alone as long as the user is tweaking the bitrate. Which has the nice side-effect that if the user explicitely sets the bitrate to 0 (which is actually the default), the quality value doesn't get reset and one ends up encoding VBR at quality-level 0... --- ext/theora/gsttheoraenc.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/ext/theora/gsttheoraenc.c b/ext/theora/gsttheoraenc.c index d31485bfd8..03acef80bc 100644 --- a/ext/theora/gsttheoraenc.c +++ b/ext/theora/gsttheoraenc.c @@ -1372,13 +1372,12 @@ theora_enc_set_property (GObject * object, guint prop_id, case PROP_BITRATE: GST_OBJECT_LOCK (enc); enc->video_bitrate = g_value_get_int (value) * 1000; - enc->video_quality = 0; enc->bitrate_changed = TRUE; GST_OBJECT_UNLOCK (enc); break; case PROP_QUALITY: GST_OBJECT_LOCK (enc); - if (GST_STATE (enc) >= GST_STATE_PAUSED && enc->video_quality == 0) { + if (GST_STATE (enc) >= GST_STATE_PAUSED && enc->video_bitrate > 0) { GST_WARNING_OBJECT (object, "Can't change from bitrate to quality mode" " while playing"); } else { From fbf972979561676507d6083ef16c986df1394cd7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= Date: Tue, 15 Feb 2011 17:01:13 +0100 Subject: [PATCH 196/254] decodebin2: Don't leak elements that fail to go to PAUSED after being autoplugged Fixes bug #642381. --- gst/playback/gstdecodebin2.c | 1 + 1 file changed, 1 insertion(+) diff --git a/gst/playback/gstdecodebin2.c b/gst/playback/gstdecodebin2.c index 673e9b4434..ebcf51df33 100644 --- a/gst/playback/gstdecodebin2.c +++ b/gst/playback/gstdecodebin2.c @@ -1761,6 +1761,7 @@ connect_pad (GstDecodeBin * dbin, GstElement * src, GstDecodePad * dpad, tmp = chain->elements->data; gst_element_set_state (tmp, GST_STATE_NULL); gst_bin_remove (GST_BIN (dbin), tmp); + gst_object_unref (tmp); chain->elements = g_list_delete_link (chain->elements, chain->elements); } while (tmp != element); CHAIN_MUTEX_UNLOCK (chain); From 555e33800867d68bfed0e27546448e738acabf35 Mon Sep 17 00:00:00 2001 From: Akihiro Tsukada Date: Tue, 15 Feb 2011 17:24:28 +0100 Subject: [PATCH 197/254] playbin2: Fix handling of non-raw custom sinks When autoplugging elements in decodebin2, check if the caps are supported by one of the sink before continuing autoplugging. Fixes bug #642174. --- gst/playback/gstplaybin2.c | 56 ++++++++++++++++++++++++++++++++------ 1 file changed, 48 insertions(+), 8 deletions(-) diff --git a/gst/playback/gstplaybin2.c b/gst/playback/gstplaybin2.c index aa5aa35364..5fce8abeba 100644 --- a/gst/playback/gstplaybin2.c +++ b/gst/playback/gstplaybin2.c @@ -2930,7 +2930,7 @@ static gboolean autoplug_continue_cb (GstElement * element, GstPad * pad, GstCaps * caps, GstSourceGroup * group) { - GstCaps *subcaps = NULL; + GstCaps *stopcaps = NULL; gboolean ret = FALSE; GstElement *text_sink; GstPad *text_sinkpad = NULL; @@ -2942,26 +2942,66 @@ autoplug_continue_cb (GstElement * element, GstPad * pad, GstCaps * caps, text_sinkpad = gst_element_get_static_pad (text_sink, "sink"); if (text_sinkpad) { - subcaps = gst_pad_get_caps_reffed (text_sinkpad); + stopcaps = gst_pad_get_caps_reffed (text_sinkpad); gst_object_unref (text_sinkpad); /* If the textsink claims to support ANY subcaps, * go the save way and only use the plaintext caps */ - if (gst_caps_is_any (subcaps)) { + if (gst_caps_is_any (stopcaps)) { GST_WARNING_OBJECT (group->playbin, "Text sink '%s' accepts ANY caps", GST_OBJECT_NAME (text_sink)); - gst_caps_unref (subcaps); - subcaps = gst_static_caps_get (&sub_plaintext_caps); + gst_caps_unref (stopcaps); + stopcaps = gst_static_caps_get (&sub_plaintext_caps); } } else { - subcaps = gst_subtitle_overlay_create_factory_caps (); + stopcaps = gst_subtitle_overlay_create_factory_caps (); } if (text_sink) gst_object_unref (text_sink); - ret = !gst_caps_can_intersect (subcaps, caps); - gst_caps_unref (subcaps); + GST_PLAY_BIN_LOCK (group->playbin); + GST_SOURCE_GROUP_LOCK (group); + if (group->playbin->audio_sink) { + GstCaps *audio_sinkcaps; + GstPad *audio_sinkpad = NULL; + + audio_sinkpad = + gst_element_get_static_pad (group->playbin->audio_sink, "sink"); + if (audio_sinkpad) { + audio_sinkcaps = gst_pad_get_caps (audio_sinkpad); + gst_object_unref (audio_sinkpad); + + stopcaps = gst_caps_make_writable (stopcaps); + if (!gst_caps_is_any (audio_sinkcaps)) + gst_caps_merge (stopcaps, audio_sinkcaps); + else + gst_caps_unref (audio_sinkcaps); + } + } + + if (group->playbin->video_sink) { + GstCaps *video_sinkcaps; + GstPad *video_sinkpad = NULL; + + video_sinkpad = + gst_element_get_static_pad (group->playbin->video_sink, "sink"); + if (video_sinkpad) { + video_sinkcaps = gst_pad_get_caps (video_sinkpad); + gst_object_unref (video_sinkpad); + + stopcaps = gst_caps_make_writable (stopcaps); + if (!gst_caps_is_any (video_sinkcaps)) + gst_caps_merge (stopcaps, video_sinkcaps); + else + gst_caps_unref (video_sinkcaps); + } + } + GST_SOURCE_GROUP_UNLOCK (group); + GST_PLAY_BIN_UNLOCK (group->playbin); + + ret = !gst_caps_can_intersect (stopcaps, caps); + gst_caps_unref (stopcaps); GST_DEBUG_OBJECT (group->playbin, "continue autoplugging group %p for %s:%s, %" GST_PTR_FORMAT ": %d", From 140dca43f35d5438d8c5300bd150e9fb69beea59 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= Date: Tue, 15 Feb 2011 17:46:22 +0100 Subject: [PATCH 198/254] playbin2: Optimize autoplug-continue handler a bit Don't build merge the caps of all sinks but check them one-by-one until one supports the caps. Also get reffed caps from the sinkpads instead of a writable copy and add debug output if a sink claims to support ANY caps. --- gst/playback/gstplaybin2.c | 125 ++++++++++++++++++++----------------- 1 file changed, 67 insertions(+), 58 deletions(-) diff --git a/gst/playback/gstplaybin2.c b/gst/playback/gstplaybin2.c index 5fce8abeba..54b9c1d3e6 100644 --- a/gst/playback/gstplaybin2.c +++ b/gst/playback/gstplaybin2.c @@ -2930,79 +2930,88 @@ static gboolean autoplug_continue_cb (GstElement * element, GstPad * pad, GstCaps * caps, GstSourceGroup * group) { - GstCaps *stopcaps = NULL; gboolean ret = FALSE; - GstElement *text_sink; - GstPad *text_sinkpad = NULL; - - text_sink = - (group->playbin->text_sink) ? gst_object_ref (group-> - playbin->text_sink) : NULL; - if (text_sink) - text_sinkpad = gst_element_get_static_pad (text_sink, "sink"); - - if (text_sinkpad) { - stopcaps = gst_pad_get_caps_reffed (text_sinkpad); - gst_object_unref (text_sinkpad); - - /* If the textsink claims to support ANY subcaps, - * go the save way and only use the plaintext caps */ - if (gst_caps_is_any (stopcaps)) { - GST_WARNING_OBJECT (group->playbin, "Text sink '%s' accepts ANY caps", - GST_OBJECT_NAME (text_sink)); - gst_caps_unref (stopcaps); - stopcaps = gst_static_caps_get (&sub_plaintext_caps); - } - } else { - stopcaps = gst_subtitle_overlay_create_factory_caps (); - } - - if (text_sink) - gst_object_unref (text_sink); + GstElement *sink; + GstPad *sinkpad = NULL; + GstCaps *sinkcaps = NULL; GST_PLAY_BIN_LOCK (group->playbin); GST_SOURCE_GROUP_LOCK (group); - if (group->playbin->audio_sink) { - GstCaps *audio_sinkcaps; - GstPad *audio_sinkpad = NULL; - audio_sinkpad = - gst_element_get_static_pad (group->playbin->audio_sink, "sink"); - if (audio_sinkpad) { - audio_sinkcaps = gst_pad_get_caps (audio_sinkpad); - gst_object_unref (audio_sinkpad); + if ((sink = group->playbin->text_sink)) + sinkpad = gst_element_get_static_pad (sink, "sink"); + if (sinkpad) { + sinkcaps = gst_pad_get_caps_reffed (sinkpad); + gst_object_unref (sinkpad); - stopcaps = gst_caps_make_writable (stopcaps); - if (!gst_caps_is_any (audio_sinkcaps)) - gst_caps_merge (stopcaps, audio_sinkcaps); - else - gst_caps_unref (audio_sinkcaps); + /* If the textsink claims to support ANY subcaps, + * go the safe way and only use the plaintext caps */ + if (gst_caps_is_any (sinkcaps)) { + GST_WARNING_OBJECT (group->playbin, "Text sink '%s' accepts ANY caps", + GST_OBJECT_NAME (sink)); + gst_caps_unref (sinkcaps); + sinkcaps = gst_static_caps_get (&sub_plaintext_caps); + } + } else { + sinkcaps = gst_subtitle_overlay_create_factory_caps (); + } + ret = !gst_caps_can_intersect (caps, sinkcaps); + gst_caps_unref (sinkcaps); + sinkcaps = NULL; + if (!ret) + goto done; + + if ((sink = group->playbin->audio_sink)) { + sinkpad = gst_element_get_static_pad (sink, "sink"); + if (sinkpad) { + sinkcaps = gst_pad_get_caps_reffed (sinkpad); + gst_object_unref (sinkpad); + + /* If the audio sink claims to support ANY caps go + * the safe way and only use the raw audio caps + * that decodebin2 already has */ + if (gst_caps_is_any (sinkcaps)) { + GST_WARNING_OBJECT (group->playbin, "Audio sink '%s' accepts ANY caps", + GST_OBJECT_NAME (sink)); + gst_caps_unref (sinkcaps); + sinkcaps = NULL; + } } } + if (sinkcaps) { + ret = !gst_caps_can_intersect (caps, sinkcaps); + gst_caps_unref (sinkcaps); + sinkcaps = NULL; + } + if (!ret) + goto done; - if (group->playbin->video_sink) { - GstCaps *video_sinkcaps; - GstPad *video_sinkpad = NULL; + if ((sink = group->playbin->video_sink)) { + sinkpad = gst_element_get_static_pad (sink, "sink"); + if (sinkpad) { + sinkcaps = gst_pad_get_caps_reffed (sinkpad); + gst_object_unref (sinkpad); - video_sinkpad = - gst_element_get_static_pad (group->playbin->video_sink, "sink"); - if (video_sinkpad) { - video_sinkcaps = gst_pad_get_caps (video_sinkpad); - gst_object_unref (video_sinkpad); - - stopcaps = gst_caps_make_writable (stopcaps); - if (!gst_caps_is_any (video_sinkcaps)) - gst_caps_merge (stopcaps, video_sinkcaps); - else - gst_caps_unref (video_sinkcaps); + /* If the video sink claims to support ANY caps go + * the safe way and only use the raw video caps + * that decodebin2 already has */ + if (gst_caps_is_any (sinkcaps)) { + GST_WARNING_OBJECT (group->playbin, "Video sink '%s' accepts ANY caps", + GST_OBJECT_NAME (sink)); + gst_caps_unref (sinkcaps); + sinkcaps = NULL; + } } } + if (sinkcaps) { + ret = !gst_caps_can_intersect (caps, sinkcaps); + gst_caps_unref (sinkcaps); + } + +done: GST_SOURCE_GROUP_UNLOCK (group); GST_PLAY_BIN_UNLOCK (group->playbin); - ret = !gst_caps_can_intersect (stopcaps, caps); - gst_caps_unref (stopcaps); - GST_DEBUG_OBJECT (group->playbin, "continue autoplugging group %p for %s:%s, %" GST_PTR_FORMAT ": %d", group, GST_DEBUG_PAD_NAME (pad), caps, ret); From c201ff3de3ce36dfc658b13dc4f637c923e3a01d Mon Sep 17 00:00:00 2001 From: Stefan Kost Date: Wed, 16 Feb 2011 11:56:16 +0200 Subject: [PATCH 199/254] discoverer: improve logging (and reindent) Add more logging for the tag merging and use the _OBJECT flavour more. --- gst-libs/gst/pbutils/gstdiscoverer.c | 38 ++++++++++++++++++---------- 1 file changed, 25 insertions(+), 13 deletions(-) diff --git a/gst-libs/gst/pbutils/gstdiscoverer.c b/gst-libs/gst/pbutils/gstdiscoverer.c index 854fd46def..2a019c0ea5 100644 --- a/gst-libs/gst/pbutils/gstdiscoverer.c +++ b/gst-libs/gst/pbutils/gstdiscoverer.c @@ -36,7 +36,7 @@ * asks for the discovery to begin (through gst_discoverer_start()). * * All the information is returned in a #GstDiscovererInfo structure. - * + * * Since: 0.10.31 */ @@ -396,12 +396,16 @@ _event_probe (GstPad * pad, GstEvent * event, PrivateStream * ps) /* If preroll is complete, drop these tags - the collected information is * possibly already being processed and adding more tags would be racy */ if (G_LIKELY (ps->dc->priv->processing)) { + GST_DEBUG_OBJECT (pad, "private stream %p old tags %" GST_PTR_FORMAT, ps, + ps->tags); tmp = gst_tag_list_merge (ps->tags, tl, GST_TAG_MERGE_APPEND); if (ps->tags) gst_tag_list_free (ps->tags); ps->tags = tmp; + GST_DEBUG_OBJECT (pad, "private stream %p new tags %" GST_PTR_FORMAT, ps, + tmp); } else - GST_DEBUG_OBJECT (ps->dc, "Dropping tags since preroll is done"); + GST_DEBUG_OBJECT (pad, "Dropping tags since preroll is done"); DISCO_UNLOCK (ps->dc); } @@ -844,10 +848,14 @@ parse_stream_topology (GstDiscoverer * dc, const GstStructure * topology, if (gst_structure_id_has_field (topology, _TAGS_QUARK)) { gst_structure_id_get (topology, _TAGS_QUARK, GST_TYPE_STRUCTURE, &tags, NULL); + + GST_DEBUG ("Merge tags %" GST_PTR_FORMAT, tags); + cont->parent.tags = gst_tag_list_merge (cont->parent.tags, (GstTagList *) tags, GST_TAG_MERGE_APPEND); gst_tag_list_free (tags); + GST_DEBUG ("Container info tags %" GST_PTR_FORMAT, tmp); } for (i = 0; i < len; i++) { @@ -965,7 +973,8 @@ handle_message (GstDiscoverer * dc, GstMessage * msg) { gboolean done = FALSE; - GST_DEBUG ("got a %s message", GST_MESSAGE_TYPE_NAME (msg)); + GST_DEBUG_OBJECT (GST_MESSAGE_SRC (msg), "got a %s message", + GST_MESSAGE_TYPE_NAME (msg)); switch (GST_MESSAGE_TYPE (msg)) { case GST_MESSAGE_ERROR:{ @@ -973,8 +982,8 @@ handle_message (GstDiscoverer * dc, GstMessage * msg) gchar *debug; gst_message_parse_error (msg, &gerr, &debug); - GST_WARNING ("Got an error [debug:%s]", debug); - GST_WARNING ("Got an error [message:%s]", gerr->message); + GST_WARNING_OBJECT (GST_MESSAGE_SRC (msg), + "Got an error [debug:%s], [message:%s]", debug, gerr->message); dc->priv->current_error = gerr; g_free (debug); @@ -1005,7 +1014,8 @@ handle_message (GstDiscoverer * dc, GstMessage * msg) GST_DEBUG_OBJECT (GST_MESSAGE_SRC (msg), "structure %" GST_PTR_FORMAT, msg->structure); if (sttype == _MISSING_PLUGIN_QUARK) { - GST_DEBUG ("Setting result to MISSING_PLUGINS"); + GST_DEBUG_OBJECT (GST_MESSAGE_SRC (msg), + "Setting result to MISSING_PLUGINS"); dc->priv->current_info->result = GST_DISCOVERER_MISSING_PLUGINS; dc->priv->current_info->misc = gst_structure_copy (msg->structure); } else if (sttype == _STREAM_TOPOLOGY_QUARK) { @@ -1019,7 +1029,7 @@ handle_message (GstDiscoverer * dc, GstMessage * msg) GstTagList *tl, *tmp; gst_message_parse_tag (msg, &tl); - GST_DEBUG ("Got tags %" GST_PTR_FORMAT, tl); + GST_DEBUG_OBJECT (GST_MESSAGE_SRC (msg), "Got tags %" GST_PTR_FORMAT, tl); /* Merge with current tags */ tmp = gst_tag_list_merge (dc->priv->current_info->tags, tl, @@ -1028,6 +1038,8 @@ handle_message (GstDiscoverer * dc, GstMessage * msg) if (dc->priv->current_info->tags) gst_tag_list_free (dc->priv->current_info->tags); dc->priv->current_info->tags = tmp; + GST_DEBUG_OBJECT (GST_MESSAGE_SRC (msg), "Current info %p, tags %" + GST_PTR_FORMAT, dc->priv->current_info, tmp); } break; @@ -1221,11 +1233,11 @@ beach: /** * gst_discoverer_start: * @discoverer: A #GstDiscoverer - * + * * Allow asynchronous discovering of URIs to take place. * A #GMainLoop must be available for #GstDiscoverer to properly work in * asynchronous mode. - * + * * Since: 0.10.31 */ void @@ -1267,7 +1279,7 @@ gst_discoverer_start (GstDiscoverer * discoverer) * * Stop the discovery of any pending URIs and clears the list of * pending URIS (if any). - * + * * Since: 0.10.31 */ void @@ -1331,7 +1343,7 @@ gst_discoverer_stop (GstDiscoverer * discoverer) * * Returns: %TRUE if the @uri was succesfully appended to the list of pending * uris, else %FALSE - * + * * Since: 0.10.31 */ gboolean @@ -1369,7 +1381,7 @@ gst_discoverer_discover_uri_async (GstDiscoverer * discoverer, * * Returns: (transfer full): the result of the scanning. Can be %NULL if an * error occurred. - * + * * Since: 0.10.31 */ GstDiscovererInfo * @@ -1424,7 +1436,7 @@ gst_discoverer_discover_uri (GstDiscoverer * discoverer, const gchar * uri, * If an error occurred when creating the discoverer, @err will be set * accordingly and %NULL will be returned. If @err is set, the caller must * free it when no longer needed using g_error_free(). - * + * * Since: 0.10.31 */ GstDiscoverer * From 7e06d3525072d5eab79053bb032dd5b810a2ab3f Mon Sep 17 00:00:00 2001 From: Stefan Kost Date: Wed, 16 Feb 2011 11:57:31 +0200 Subject: [PATCH 200/254] discoverer: don't leak parent tags --- gst-libs/gst/pbutils/gstdiscoverer.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/gst-libs/gst/pbutils/gstdiscoverer.c b/gst-libs/gst/pbutils/gstdiscoverer.c index 2a019c0ea5..dede0b3bf5 100644 --- a/gst-libs/gst/pbutils/gstdiscoverer.c +++ b/gst-libs/gst/pbutils/gstdiscoverer.c @@ -846,15 +846,20 @@ parse_stream_topology (GstDiscoverer * dc, const GstStructure * topology, res = (GstDiscovererStreamInfo *) cont; if (gst_structure_id_has_field (topology, _TAGS_QUARK)) { + GstTagList *tmp; + gst_structure_id_get (topology, _TAGS_QUARK, GST_TYPE_STRUCTURE, &tags, NULL); GST_DEBUG ("Merge tags %" GST_PTR_FORMAT, tags); - cont->parent.tags = + tmp = gst_tag_list_merge (cont->parent.tags, (GstTagList *) tags, GST_TAG_MERGE_APPEND); gst_tag_list_free (tags); + if (cont->parent.tags) + gst_tag_list_free (cont->parent.tags); + cont->parent.tags = tmp; GST_DEBUG ("Container info tags %" GST_PTR_FORMAT, tmp); } From d467eb708af0d4b36f8b8d64dc20959a5033e79a Mon Sep 17 00:00:00 2001 From: Ralph Giles Date: Thu, 13 Jan 2011 15:12:53 -0800 Subject: [PATCH 201/254] Set the theoraenc speed-level property from libtheora's defaults. The speed-level property, which allows callers to trade of encoding quality for speed in the libtheora api, has a version-dependent maximum and default values. Instead of hardcoding the acceptable range for the theoraenc element's presentation of this setting, we query the library directly at class initialization time and set the maximum and default values from that. If the query fails, we fall back to the previous default setting. To keep the values reported by gst-inspect (which I'm told use the spec values from the class) with those available on an\ instantiated element, we remove to setting of enc->speed_level from the initializer and instead pass G_PARAM_CONSTRUCT to the property spec flags, asking g_object to set this property when theoraenc objects are constructed. NB in theory the maximum speed-level could depend on the actual video caps. If later versions of libtheoraenc do this, a second call will need to be made from theora_enc_reset to update the property, since this function is mostly useful for realtime adjustment of performance while the pipeline is running. --- ext/theora/gsttheoraenc.c | 76 ++++++++++++++++++++++++++++++++++++--- 1 file changed, 72 insertions(+), 4 deletions(-) diff --git a/ext/theora/gsttheoraenc.c b/ext/theora/gsttheoraenc.c index 03acef80bc..fe7f1b7bf1 100644 --- a/ext/theora/gsttheoraenc.c +++ b/ext/theora/gsttheoraenc.c @@ -175,6 +175,57 @@ granulepos_to_timestamp (GstTheoraEnc * theoraenc, ogg_int64_t granulepos) theoraenc->info.fps_numerator); } +/* Generate a dummy encoder context for use in th_encode_ctl queries + Release with th_encode_free() + This and the next routine from theora/examples/libtheora_info.c */ +static th_enc_ctx * +dummy_encode_ctx (void) +{ + th_enc_ctx *ctx; + th_info info; + + /* set the minimal video parameters */ + th_info_init (&info); + info.frame_width = 320; + info.frame_height = 240; + info.fps_numerator = 1; + info.fps_denominator = 1; + + /* allocate and initialize a context object */ + ctx = th_encode_alloc (&info); + if (!ctx) + GST_WARNING ("Failed to allocate dummy encoder context."); + + /* clear the info struct */ + th_info_clear (&info); + + return ctx; +} + +/* Query the current and maximum values for the 'speed level' setting. + This can be used to ask the encoder to trade off encoding quality + vs. performance cost, for example to adapt to realtime constraints. */ +static int +check_speed_level (th_enc_ctx * ctx, int *current, int *max) +{ + int ret; + + /* query the current speed level */ + ret = th_encode_ctl (ctx, TH_ENCCTL_GET_SPLEVEL, current, sizeof (int)); + if (ret) { + GST_WARNING ("Error %d getting current speed level.", ret); + return ret; + } + /* query the maximum speed level, which varies by encoder version */ + ret = th_encode_ctl (ctx, TH_ENCCTL_GET_SPLEVEL_MAX, max, sizeof (int)); + if (ret) { + GST_WARNING ("Error %d getting maximum speed level.", ret); + return ret; + } + + return 0; +} + static GstStaticPadTemplate theora_enc_sink_factory = GST_STATIC_PAD_TEMPLATE ("sink", GST_PAD_SINK, @@ -242,6 +293,19 @@ gst_theora_enc_class_init (GstTheoraEncClass * klass) GObjectClass *gobject_class = (GObjectClass *) klass; GstElementClass *gstelement_class = GST_ELEMENT_CLASS (klass); + /* query runtime encoder properties */ + th_enc_ctx *th_ctx; + int default_speed_level = THEORA_DEF_SPEEDLEVEL; + int max_speed_level = default_speed_level; + + th_ctx = dummy_encode_ctx (); + if (th_ctx) { + if (!check_speed_level (th_ctx, &default_speed_level, &max_speed_level)) + GST_WARNING + ("Failed to determine settings for the speed-level property."); + th_encode_free (th_ctx); + } + gobject_class->set_property = theora_enc_set_property; gobject_class->get_property = theora_enc_get_property; gobject_class->finalize = theora_enc_finalize; @@ -301,9 +365,13 @@ gst_theora_enc_class_init (GstTheoraEncClass * klass) (GParamFlags) G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); g_object_class_install_property (gobject_class, PROP_SPEEDLEVEL, g_param_spec_int ("speed-level", "Speed level", - "Controls the amount of motion vector searching done while " - "encoding", 0, 3, THEORA_DEF_SPEEDLEVEL, - (GParamFlags) G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + "Controls the amount of analysis performed when encoding." + " Higher values trade compression quality for speed." + " This property requires libtheora version >= 1.0" + ", and the maximum value may vary based on encoder version.", + 0, max_speed_level, default_speed_level, + (GParamFlags) G_PARAM_READWRITE | G_PARAM_CONSTRUCT | + G_PARAM_STATIC_STRINGS)); g_object_class_install_property (gobject_class, PROP_VP3_COMPATIBLE, g_param_spec_boolean ("vp3-compatible", "VP3 Compatible", "Disables non-VP3 compatible features", @@ -371,7 +439,7 @@ gst_theora_enc_init (GstTheoraEnc * enc, GstTheoraEncClass * g_class) enc->expected_ts = GST_CLOCK_TIME_NONE; - enc->speed_level = THEORA_DEF_SPEEDLEVEL; + /* enc->speed_level is set to the libtheora default by the constructor */ enc->vp3_compatible = THEORA_DEF_VP3_COMPATIBLE; enc->drop_frames = THEORA_DEF_DROP_FRAMES; enc->cap_overflow = THEORA_DEF_CAP_OVERFLOW; From f499810bdc6ff5015524415447af3234c3207283 Mon Sep 17 00:00:00 2001 From: David Schleef Date: Sat, 15 Jan 2011 18:21:28 -0800 Subject: [PATCH 202/254] theoraenc: Set speed level while running --- ext/theora/gsttheoraenc.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/ext/theora/gsttheoraenc.c b/ext/theora/gsttheoraenc.c index fe7f1b7bf1..a6a8640541 100644 --- a/ext/theora/gsttheoraenc.c +++ b/ext/theora/gsttheoraenc.c @@ -1466,6 +1466,10 @@ theora_enc_set_property (GObject * object, guint prop_id, break; case PROP_SPEEDLEVEL: enc->speed_level = g_value_get_int (value); + if (enc->encoder) { + th_encode_ctl (enc->encoder, TH_ENCCTL_SET_SPLEVEL, &enc->speed_level, + sizeof (enc->speed_level)); + } break; case PROP_VP3_COMPATIBLE: enc->vp3_compatible = g_value_get_boolean (value); From 15e23414d369fa762c62a701d6480b0dee0a2ca2 Mon Sep 17 00:00:00 2001 From: David Schleef Date: Thu, 3 Feb 2011 22:41:23 -0800 Subject: [PATCH 203/254] oggparse: better detection of delta unit flag --- ext/ogg/gstoggparse.c | 47 ++++++++++++++++++++++++++++++++---------- ext/ogg/gstoggstream.h | 1 + 2 files changed, 37 insertions(+), 11 deletions(-) diff --git a/ext/ogg/gstoggparse.c b/ext/ogg/gstoggparse.c index 87eea1f95a..ffbba865a1 100644 --- a/ext/ogg/gstoggparse.c +++ b/ext/ogg/gstoggparse.c @@ -115,6 +115,7 @@ free_stream (GstOggStream * stream) { g_list_foreach (stream->headers, (GFunc) gst_mini_object_unref, NULL); g_list_foreach (stream->unknown_pages, (GFunc) gst_mini_object_unref, NULL); + g_list_foreach (stream->stored_buffers, (GFunc) gst_mini_object_unref, NULL); g_free (stream); } @@ -362,7 +363,7 @@ gst_ogg_parse_is_header (GstOggParse * ogg, GstOggStream * stream, static GstBuffer * gst_ogg_parse_buffer_from_page (ogg_page * page, - guint64 offset, gboolean keyframe, GstClockTime timestamp) + guint64 offset, GstClockTime timestamp) { int size = page->header_len + page->body_len; GstBuffer *buf = gst_buffer_new_and_alloc (size); @@ -373,9 +374,6 @@ gst_ogg_parse_buffer_from_page (ogg_page * page, GST_BUFFER_TIMESTAMP (buf) = timestamp; GST_BUFFER_OFFSET (buf) = offset; GST_BUFFER_OFFSET_END (buf) = offset + size; - if (!keyframe) { - GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_DELTA_UNIT); - } return buf; } @@ -447,7 +445,7 @@ gst_ogg_parse_chain (GstPad * pad, GstBuffer * buffer) keyframe = TRUE; } pagebuffer = gst_ogg_parse_buffer_from_page (&page, startoffset, - keyframe, buffertimestamp); + buffertimestamp); /* We read out 'ret' bytes, so we set the next offset appropriately */ ogg->offset += ret; @@ -659,15 +657,42 @@ gst_ogg_parse_chain (GstPad * pad, GstBuffer * buffer) g_list_free (stream->unknown_pages); stream->unknown_pages = NULL; } + } - gst_buffer_set_caps (pagebuffer, caps); - - result = gst_pad_push (ogg->srcpad, GST_BUFFER (pagebuffer)); - if (result != GST_FLOW_OK) - return result; + if (granule == -1) { + stream->stored_buffers = g_list_append (stream->stored_buffers, + pagebuffer); } else { - /* Normal data page, submit buffer */ + if (stream->stored_buffers) { + int j; + + for (j = 0; j < g_list_length (stream->stored_buffers); j++) { + GstBuffer *buf = + GST_BUFFER (g_list_nth_data (stream->stored_buffers, j)); + + gst_buffer_set_caps (buf, ogg->caps); + GST_BUFFER_TIMESTAMP (buf) = buffertimestamp; + if (!keyframe) { + GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_DELTA_UNIT); + } else { + keyframe = FALSE; + } + + result = gst_pad_push (ogg->srcpad, buf); + if (result != GST_FLOW_OK) + return result; + } + g_list_free (stream->stored_buffers); + stream->stored_buffers = NULL; + } + gst_buffer_set_caps (pagebuffer, ogg->caps); + if (!keyframe) { + GST_BUFFER_FLAG_SET (pagebuffer, GST_BUFFER_FLAG_DELTA_UNIT); + } else { + keyframe = FALSE; + } + result = gst_pad_push (ogg->srcpad, GST_BUFFER (pagebuffer)); if (result != GST_FLOW_OK) return result; diff --git a/ext/ogg/gstoggstream.h b/ext/ogg/gstoggstream.h index 974ad89b50..94c8f05504 100644 --- a/ext/ogg/gstoggstream.h +++ b/ext/ogg/gstoggstream.h @@ -53,6 +53,7 @@ struct _GstOggStream /* for oggparse */ gboolean in_headers; GList *unknown_pages; + GList *stored_buffers; gint map; gboolean is_skeleton; From 9745a41ea397da25bef78e849608066679716e9a Mon Sep 17 00:00:00 2001 From: David Schleef Date: Fri, 4 Feb 2011 17:36:40 -0800 Subject: [PATCH 204/254] theoraenc: move debug category init earlier --- ext/theora/gsttheoraenc.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/ext/theora/gsttheoraenc.c b/ext/theora/gsttheoraenc.c index a6a8640541..6a09c2cf3e 100644 --- a/ext/theora/gsttheoraenc.c +++ b/ext/theora/gsttheoraenc.c @@ -298,6 +298,8 @@ gst_theora_enc_class_init (GstTheoraEncClass * klass) int default_speed_level = THEORA_DEF_SPEEDLEVEL; int max_speed_level = default_speed_level; + GST_DEBUG_CATEGORY_INIT (theoraenc_debug, "theoraenc", 0, "Theora encoder"); + th_ctx = dummy_encode_ctx (); if (th_ctx) { if (!check_speed_level (th_ctx, &default_speed_level, &max_speed_level)) @@ -410,7 +412,6 @@ gst_theora_enc_class_init (GstTheoraEncClass * klass) (GParamFlags) G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); gstelement_class->change_state = theora_enc_change_state; - GST_DEBUG_CATEGORY_INIT (theoraenc_debug, "theoraenc", 0, "Theora encoder"); } static void From 7902e13df5e8e9499bd149ba043de1cd0fb0e1ce Mon Sep 17 00:00:00 2001 From: David Schleef Date: Tue, 15 Feb 2011 19:23:48 -0800 Subject: [PATCH 205/254] typefind: Fix mpeg TS detection --- gst/typefind/gsttypefindfunctions.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gst/typefind/gsttypefindfunctions.c b/gst/typefind/gsttypefindfunctions.c index 6646944234..1180930ce3 100644 --- a/gst/typefind/gsttypefindfunctions.c +++ b/gst/typefind/gsttypefindfunctions.c @@ -1896,7 +1896,7 @@ static GstStaticCaps mpegts_caps = GST_STATIC_CAPS ("video/mpegts, " /* Check for sync byte, error_indicator == 0 and packet has payload */ #define IS_MPEGTS_HEADER(data) (((data)[0] == 0x47) && \ (((data)[1] & 0x80) == 0x00) && \ - (((data)[3] & 0x10) == 0x10)) + (((data)[3] & 0x30) != 0x00)) /* Helper function to search ahead at intervals of packet_size for mpegts * headers */ From 6ca5bb72a404913e9d9eeed62fa1f84577197409 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= Date: Fri, 18 Feb 2011 09:36:34 +0100 Subject: [PATCH 206/254] decodebin2: Disconnect signal handlers when removing a failed element This prevents crashes later if one of the signals is emitted after the element was removed from decodebin2 already, which can happen in discoverer. --- gst/playback/gstdecodebin2.c | 33 ++++++++++++++++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) diff --git a/gst/playback/gstdecodebin2.c b/gst/playback/gstdecodebin2.c index ebcf51df33..e435789c35 100644 --- a/gst/playback/gstdecodebin2.c +++ b/gst/playback/gstdecodebin2.c @@ -1758,9 +1758,40 @@ connect_pad (GstDecodeBin * dbin, GstElement * src, GstDecodePad * dpad, * other thread could've added elements in the meantime */ CHAIN_MUTEX_LOCK (chain); do { + GList *l; + tmp = chain->elements->data; - gst_element_set_state (tmp, GST_STATE_NULL); + + /* Disconnect any signal handlers that might be connected + * in connect_element() or analyze_pad() */ + g_signal_handlers_disconnect_by_func (tmp, pad_added_cb, chain); + g_signal_handlers_disconnect_by_func (tmp, pad_removed_cb, chain); + g_signal_handlers_disconnect_by_func (tmp, no_more_pads_cb, chain); + + for (l = chain->pending_pads; l;) { + GstPendingPad *pp = l->data; + GList *n; + + if (GST_PAD_PARENT (pp->pad) != tmp) { + l = l->next; + continue; + } + + g_signal_handlers_disconnect_by_func (pp->pad, caps_notify_cb, chain); + gst_pad_remove_event_probe (pp->pad, pp->event_probe_id); + gst_object_unref (pp->pad); + g_slice_free (GstPendingPad, pp); + + /* Remove element from the list, update list head and go to the + * next element in the list */ + n = l->next; + chain->pending_pads = g_list_delete_link (chain->pending_pads, l); + l = n; + } + gst_bin_remove (GST_BIN (dbin), tmp); + gst_element_set_state (tmp, GST_STATE_NULL); + gst_object_unref (tmp); chain->elements = g_list_delete_link (chain->elements, chain->elements); } while (tmp != element); From 1351597381760f6c99c84d5ac97dcaaca1b93191 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= Date: Fri, 18 Feb 2011 10:57:40 +0100 Subject: [PATCH 207/254] playbin2: Use a recursive mutex for the playbin lock This lock is taken when activating a group, which could result in calling the autoplug-continue callback, which also needs this lock to access the sinks. See bug #642174. --- gst/playback/gstplaybin2.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/gst/playback/gstplaybin2.c b/gst/playback/gstplaybin2.c index 54b9c1d3e6..94ee770d76 100644 --- a/gst/playback/gstplaybin2.c +++ b/gst/playback/gstplaybin2.c @@ -322,9 +322,9 @@ struct _GstSourceGroup GstSourceSelect selector[GST_PLAY_SINK_TYPE_LAST]; }; -#define GST_PLAY_BIN_GET_LOCK(bin) (((GstPlayBin*)(bin))->lock) -#define GST_PLAY_BIN_LOCK(bin) (g_mutex_lock (GST_PLAY_BIN_GET_LOCK(bin))) -#define GST_PLAY_BIN_UNLOCK(bin) (g_mutex_unlock (GST_PLAY_BIN_GET_LOCK(bin))) +#define GST_PLAY_BIN_GET_LOCK(bin) (&((GstPlayBin*)(bin))->lock) +#define GST_PLAY_BIN_LOCK(bin) (g_static_rec_mutex_lock (GST_PLAY_BIN_GET_LOCK(bin))) +#define GST_PLAY_BIN_UNLOCK(bin) (g_static_rec_mutex_unlock (GST_PLAY_BIN_GET_LOCK(bin))) /* lock to protect dynamic callbacks, like no-more-pads */ #define GST_PLAY_BIN_DYN_LOCK(bin) g_mutex_lock ((bin)->dyn_lock) @@ -355,7 +355,7 @@ struct _GstPlayBin { GstPipeline parent; - GMutex *lock; /* to protect group switching */ + GStaticRecMutex lock; /* to protect group switching */ /* the groups, we use a double buffer to switch between current and next */ GstSourceGroup groups[2]; /* array with group info */ @@ -1174,7 +1174,7 @@ gst_play_bin_update_elements_list (GstPlayBin * playbin) static void gst_play_bin_init (GstPlayBin * playbin) { - playbin->lock = g_mutex_new (); + g_static_rec_mutex_init (&playbin->lock); playbin->dyn_lock = g_mutex_new (); /* assume we can create a selector */ @@ -1229,7 +1229,8 @@ gst_play_bin_finalize (GObject * object) if (playbin->elements) gst_plugin_feature_list_free (playbin->elements); - g_mutex_free (playbin->lock); + + g_static_rec_mutex_free (&playbin->lock); g_mutex_free (playbin->dyn_lock); g_mutex_free (playbin->elements_lock); From 0641eabeb2da1fa161eeeb70647ea1c49519f4ac Mon Sep 17 00:00:00 2001 From: "tskd2@yahoo.co.jp" Date: Wed, 16 Feb 2011 20:14:25 +0900 Subject: [PATCH 208/254] uridecodebin: expose "autoplug-sort" signal It is a proxy of the decodebin2's one, and was missing in the previous code. See bug #642433. --- gst/playback/gsturidecodebin.c | 76 ++++++++++++++++++++++++++++++++++ 1 file changed, 76 insertions(+) diff --git a/gst/playback/gsturidecodebin.c b/gst/playback/gsturidecodebin.c index d36fff9754..035b4d1030 100644 --- a/gst/playback/gsturidecodebin.c +++ b/gst/playback/gsturidecodebin.c @@ -119,6 +119,9 @@ struct _GstURIDecodeBinClass /* signal fired to get a list of factories to try to autoplug */ GValueArray *(*autoplug_factories) (GstElement * element, GstPad * pad, GstCaps * caps); + /* signal fired to sort the factories */ + GValueArray *(*autoplug_sort) (GstElement * element, GstPad * pad, + GstCaps * caps, GValueArray * factories); /* signal fired to select from the proposed list of factories */ GstAutoplugSelectResult (*autoplug_select) (GstElement * element, GstPad * pad, GstCaps * caps, GValueArray * factories); @@ -145,6 +148,7 @@ enum SIGNAL_AUTOPLUG_FACTORIES, SIGNAL_AUTOPLUG_SELECT, SIGNAL_DRAINED, + SIGNAL_AUTOPLUG_SORT, LAST_SIGNAL }; @@ -250,6 +254,22 @@ _gst_select_accumulator (GSignalInvocationHint * ihint, return FALSE; } +static gboolean +_gst_array_hasvalue_accumulator (GSignalInvocationHint * ihint, + GValue * return_accu, const GValue * handler_return, gpointer dummy) +{ + gpointer array; + + array = g_value_get_boxed (handler_return); + if (!(ihint->run_type & G_SIGNAL_RUN_CLEANUP)) + g_value_set_boxed (return_accu, array); + + if (array != NULL) + return FALSE; + + return TRUE; +} + static gboolean gst_uri_decode_bin_autoplug_continue (GstElement * element, GstPad * pad, GstCaps * caps) @@ -309,6 +329,19 @@ gst_uri_decode_bin_autoplug_factories (GstElement * element, GstPad * pad, return result; } +static GValueArray * +gst_uri_decode_bin_autoplug_sort (GstElement * element, GstPad * pad, + GstCaps * caps, GValueArray * factories) +{ + GValueArray *result; + + result = g_value_array_copy (factories); + + GST_DEBUG_OBJECT (element, "autoplug-sort returns %p", result); + + /* return input */ + return result; +} static void gst_uri_decode_bin_class_init (GstURIDecodeBinClass * klass) @@ -484,6 +517,31 @@ gst_uri_decode_bin_class_init (GstURIDecodeBinClass * klass) gst_play_marshal_BOXED__OBJECT_BOXED, G_TYPE_VALUE_ARRAY, 2, GST_TYPE_PAD, GST_TYPE_CAPS); + /** + * GstURIDecodeBin::autoplug-sort: + * @bin: The decodebin + * @pad: The #GstPad. + * @caps: The #GstCaps. + * @factories: A #GValueArray of possible #GstElementFactory to use. + * + * Once decodebin2 has found the possible #GstElementFactory objects to try + * for @caps on @pad, this signal is emited. The purpose of the signal is for + * the application to perform additional sorting or filtering on the element + * factory array. + * + * The callee should copy and modify @factories. + * + * Returns: A new sorted array of #GstElementFactory objects. + * + * Since: 0.10.33 + */ + gst_uri_decode_bin_signals[SIGNAL_AUTOPLUG_SORT] = + g_signal_new ("autoplug-sort", G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstURIDecodeBinClass, autoplug_sort), + _gst_array_hasvalue_accumulator, NULL, + gst_play_marshal_BOXED__OBJECT_BOXED_BOXED, G_TYPE_VALUE_ARRAY, 3, + GST_TYPE_PAD, GST_TYPE_CAPS, G_TYPE_VALUE_ARRAY); + /** * GstURIDecodeBin::autoplug-select: * @pad: The #GstPad. @@ -539,6 +597,7 @@ gst_uri_decode_bin_class_init (GstURIDecodeBinClass * klass) GST_DEBUG_FUNCPTR (gst_uri_decode_bin_autoplug_continue); klass->autoplug_factories = GST_DEBUG_FUNCPTR (gst_uri_decode_bin_autoplug_factories); + klass->autoplug_sort = GST_DEBUG_FUNCPTR (gst_uri_decode_bin_autoplug_sort); } static void @@ -1369,6 +1428,21 @@ proxy_autoplug_factories_signal (GstElement * element, GstPad * pad, return result; } +static GValueArray * +proxy_autoplug_sort_signal (GstElement * element, GstPad * pad, + GstCaps * caps, GValueArray * factories, GstURIDecodeBin * dec) +{ + GValueArray *result; + + g_signal_emit (dec, + gst_uri_decode_bin_signals[SIGNAL_AUTOPLUG_SORT], 0, pad, caps, + factories, &result); + + GST_DEBUG_OBJECT (dec, "autoplug-sort returned %p", result); + + return result; +} + static GstAutoplugSelectResult proxy_autoplug_select_signal (GstElement * element, GstPad * pad, GstCaps * caps, GstElementFactory * factory, GstURIDecodeBin * dec) @@ -1420,6 +1494,8 @@ make_decoder (GstURIDecodeBin * decoder) G_CALLBACK (proxy_autoplug_continue_signal), decoder); g_signal_connect (decodebin, "autoplug-factories", G_CALLBACK (proxy_autoplug_factories_signal), decoder); + g_signal_connect (decodebin, "autoplug-sort", + G_CALLBACK (proxy_autoplug_sort_signal), decoder); g_signal_connect (decodebin, "autoplug-select", G_CALLBACK (proxy_autoplug_select_signal), decoder); g_signal_connect (decodebin, "drained", From 785f35a48e46ff99a7db1715e5edd182301e3555 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= Date: Fri, 18 Feb 2011 11:57:12 +0100 Subject: [PATCH 209/254] decodebin2: Keep the original factory list if the sort signal handlers returned NULL --- gst/playback/gstdecodebin2.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/gst/playback/gstdecodebin2.c b/gst/playback/gstdecodebin2.c index e435789c35..7d762a2918 100644 --- a/gst/playback/gstdecodebin2.c +++ b/gst/playback/gstdecodebin2.c @@ -1434,8 +1434,10 @@ analyze_new_pad (GstDecodeBin * dbin, GstElement * src, GstPad * pad, g_signal_emit (G_OBJECT (dbin), gst_decode_bin_signals[SIGNAL_AUTOPLUG_SORT], 0, dpad, caps, factories, &result); - g_value_array_free (factories); - factories = result; + if (result) { + g_value_array_free (factories); + factories = result; + } /* At this point we have a potential decoder, but we might not need it * if it doesn't match the output caps */ From ef5f73206dd3ad515abea7e2c1a8e24a3fcc2814 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= Date: Fri, 18 Feb 2011 11:58:44 +0100 Subject: [PATCH 210/254] decodebin2: Update documentation of the autoplug-* signals Add notes about the behaviour if multiple signal handlers are connected. For most autoplug-* signals only the first signal handler will ever be invoked. Also add to the autoplug-sort docs that the signal handler can return NULL to specify that the order should change and other handlers get the chance to sort the array. --- gst/playback/gstdecodebin2.c | 51 +++++++++++++++++++++++++++--------- 1 file changed, 39 insertions(+), 12 deletions(-) diff --git a/gst/playback/gstdecodebin2.c b/gst/playback/gstdecodebin2.c index 7d762a2918..f28ff4a70c 100644 --- a/gst/playback/gstdecodebin2.c +++ b/gst/playback/gstdecodebin2.c @@ -590,8 +590,8 @@ gst_decode_bin_class_init (GstDecodeBinClass * klass) /** * GstDecodeBin2::new-decoded-pad: - * @bin: The decodebin - * @pad: The newly created pad + * @bin: The decodebin. + * @pad: The newly created pad. * @islast: #TRUE if this is the last pad to be added. Deprecated. * * This signal gets emitted as soon as a new pad of the same type as one of @@ -609,8 +609,8 @@ gst_decode_bin_class_init (GstDecodeBinClass * klass) /** * GstDecodeBin2::removed-decoded-pad: - * @bin: The decodebin - * @pad: The pad that was removed + * @bin: The decodebin. + * @pad: The pad that was removed. * * This signal is emitted when a 'final' caps pad has been removed. * @@ -625,7 +625,7 @@ gst_decode_bin_class_init (GstDecodeBinClass * klass) /** * GstDecodeBin2::unknown-type: - * @bin: The decodebin + * @bin: The decodebin. * @pad: The new pad containing caps that cannot be resolved to a 'final' * stream type. * @caps: The #GstCaps of the pad that cannot be resolved. @@ -641,13 +641,19 @@ gst_decode_bin_class_init (GstDecodeBinClass * klass) /** * GstDecodeBin2::autoplug-continue: - * @bin: The decodebin + * @bin: The decodebin. * @pad: The #GstPad. * @caps: The #GstCaps found. * * This signal is emitted whenever decodebin2 finds a new stream. It is * emitted before looking for any elements that can handle that stream. * + * + * Invocation of signal handlers stops after the first signal handler + * returns #FALSE. Signal handlers are invoked in the order they were + * connected in. + * + * * Returns: #TRUE if you wish decodebin2 to look for elements that can * handle the given @caps. If #FALSE, those caps will be considered as * final and the pad will be exposed as such (see 'new-decoded-pad' @@ -661,7 +667,7 @@ gst_decode_bin_class_init (GstDecodeBinClass * klass) /** * GstDecodeBin2::autoplug-factories: - * @bin: The decodebin + * @bin: The decodebin. * @pad: The #GstPad. * @caps: The #GstCaps found. * @@ -672,7 +678,13 @@ gst_decode_bin_class_init (GstDecodeBinClass * klass) * If this function returns NULL, @pad will be exposed as a final caps. * * If this function returns an empty array, the pad will be considered as - * having an unhandled type media type. + * having an unhandled type media type. + * + * + * Only the signal handler that is connected first will ever by invoked. + * Don't connect signal handlers with the #G_CONNECT_AFTER flag to this + * signal, they will never be invoked! + * * * Returns: a #GValueArray* with a list of factories to try. The factories are * by default tried in the returned order or based on the index returned by @@ -687,7 +699,7 @@ gst_decode_bin_class_init (GstDecodeBinClass * klass) /** * GstDecodeBin2::autoplug-sort: - * @bin: The decodebin + * @bin: The decodebin. * @pad: The #GstPad. * @caps: The #GstCaps. * @factories: A #GValueArray of possible #GstElementFactory to use. @@ -697,7 +709,16 @@ gst_decode_bin_class_init (GstDecodeBinClass * klass) * the application to perform additional sorting or filtering on the element * factory array. * - * The callee should copy and modify @factories. + * The callee should copy and modify @factories or return #NULL if the + * order should not change. + * + * + * Invocation of signal handlers stops after one signal handler has + * returned something else than #NULL. Signal handlers are invoked in + * the order they were connected in. + * Don't connect signal handlers with the #G_CONNECT_AFTER flag to this + * signal, they will never be invoked! + * * * Returns: A new sorted array of #GstElementFactory objects. */ @@ -710,10 +731,10 @@ gst_decode_bin_class_init (GstDecodeBinClass * klass) /** * GstDecodeBin2::autoplug-select: - * @bin: The decodebin + * @bin: The decodebin. * @pad: The #GstPad. * @caps: The #GstCaps. - * @factory: A #GstElementFactory to use + * @factory: A #GstElementFactory to use. * * This signal is emitted once decodebin2 has found all the possible * #GstElementFactory that can be used to handle the given @caps. For each of @@ -731,6 +752,12 @@ gst_decode_bin_class_init (GstDecodeBinClass * klass) * A value of #GST_AUTOPLUG_SELECT_SKIP will skip @factory and move to the * next factory. * + * + * Only the signal handler that is connected first will ever by invoked. + * Don't connect signal handlers with the #G_CONNECT_AFTER flag to this + * signal, they will never be invoked! + * + * * Returns: a #GST_TYPE_AUTOPLUG_SELECT_RESULT that indicates the required * operation. the default handler will always return * #GST_AUTOPLUG_SELECT_TRY. From da4b5bf9f9cfa06241c8f85a8b5e1f7f2c67aac3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= Date: Fri, 18 Feb 2011 12:00:34 +0100 Subject: [PATCH 211/254] uridecodebin: Update autoplug-* signal docs from decodebin2 uridecodebin proxies these signals. --- gst/playback/gsturidecodebin.c | 42 ++++++++++++++++++++++++++++------ 1 file changed, 35 insertions(+), 7 deletions(-) diff --git a/gst/playback/gsturidecodebin.c b/gst/playback/gsturidecodebin.c index 035b4d1030..c20fbfef05 100644 --- a/gst/playback/gsturidecodebin.c +++ b/gst/playback/gsturidecodebin.c @@ -456,8 +456,8 @@ gst_uri_decode_bin_class_init (GstURIDecodeBinClass * klass) /** * GstURIDecodeBin::unknown-type: - * @bin: The uridecodebin - * @pad: the new pad containing caps that cannot be resolved to a 'final' + * @bin: The uridecodebin. + * @pad: the new pad containing caps that cannot be resolved to a 'final'. * stream type. * @caps: the #GstCaps of the pad that cannot be resolved. * @@ -472,13 +472,19 @@ gst_uri_decode_bin_class_init (GstURIDecodeBinClass * klass) /** * GstURIDecodeBin::autoplug-continue: - * @bin: The uridecodebin + * @bin: The uridecodebin. * @pad: The #GstPad. * @caps: The #GstCaps found. * * This signal is emitted whenever uridecodebin finds a new stream. It is * emitted before looking for any elements that can handle that stream. * + * + * Invocation of signal handlers stops after the first signal handler + * returns #FALSE. Signal handlers are invoked in the order they were + * connected in. + * + * * Returns: #TRUE if you wish uridecodebin to look for elements that can * handle the given @caps. If #FALSE, those caps will be considered as * final and the pad will be exposed as such (see 'new-decoded-pad' @@ -493,7 +499,7 @@ gst_uri_decode_bin_class_init (GstURIDecodeBinClass * klass) /** * GstURIDecodeBin::autoplug-factories: - * @bin: The decodebin + * @bin: The uridecodebin. * @pad: The #GstPad. * @caps: The #GstCaps found. * @@ -506,6 +512,12 @@ gst_uri_decode_bin_class_init (GstURIDecodeBinClass * klass) * If this function returns an empty array, the pad will be considered as * having an unhandled type media type. * + * + * Only the signal handler that is connected first will ever by invoked. + * Don't connect signal handlers with the #G_CONNECT_AFTER flag to this + * signal, they will never be invoked! + * + * * Returns: a #GValueArray* with a list of factories to try. The factories are * by default tried in the returned order or based on the index returned by * "autoplug-select". @@ -519,7 +531,7 @@ gst_uri_decode_bin_class_init (GstURIDecodeBinClass * klass) /** * GstURIDecodeBin::autoplug-sort: - * @bin: The decodebin + * @bin: The uridecodebin. * @pad: The #GstPad. * @caps: The #GstCaps. * @factories: A #GValueArray of possible #GstElementFactory to use. @@ -529,7 +541,16 @@ gst_uri_decode_bin_class_init (GstURIDecodeBinClass * klass) * the application to perform additional sorting or filtering on the element * factory array. * - * The callee should copy and modify @factories. + * The callee should copy and modify @factories or return #NULL if the + * order should not change. + * + * + * Invocation of signal handlers stops after one signal handler has + * returned something else than #NULL. Signal handlers are invoked in + * the order they were connected in. + * Don't connect signal handlers with the #G_CONNECT_AFTER flag to this + * signal, they will never be invoked! + * * * Returns: A new sorted array of #GstElementFactory objects. * @@ -544,9 +565,10 @@ gst_uri_decode_bin_class_init (GstURIDecodeBinClass * klass) /** * GstURIDecodeBin::autoplug-select: + * @bin: The uridecodebin. * @pad: The #GstPad. * @caps: The #GstCaps. - * @factory: A #GstElementFactory to use + * @factory: A #GstElementFactory to use. * * This signal is emitted once uridecodebin has found all the possible * #GstElementFactory that can be used to handle the given @caps. For each of @@ -564,6 +586,12 @@ gst_uri_decode_bin_class_init (GstURIDecodeBinClass * klass) * A value of #GST_AUTOPLUG_SELECT_SKIP will skip @factory and move to the * next factory. * + * + * Only the signal handler that is connected first will ever by invoked. + * Don't connect signal handlers with the #G_CONNECT_AFTER flag to this + * signal, they will never be invoked! + * + * * Returns: a #GST_TYPE_AUTOPLUG_SELECT_RESULT that indicates the required * operation. The default handler will always return * #GST_AUTOPLUG_SELECT_TRY. From 2a6602d994268b77e7135d28ff9d5b04c23aafb0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= Date: Fri, 18 Feb 2011 12:01:05 +0100 Subject: [PATCH 212/254] decodebin2: Return NULL from the default autoplug-sort handler ...instead of copying the array. Returning NULL will result in the original factories array to be used and prevents a useless array copy in most use cases. --- gst/playback/gstdecodebin2.c | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/gst/playback/gstdecodebin2.c b/gst/playback/gstdecodebin2.c index f28ff4a70c..9e9d5e2723 100644 --- a/gst/playback/gstdecodebin2.c +++ b/gst/playback/gstdecodebin2.c @@ -1308,14 +1308,7 @@ static GValueArray * gst_decode_bin_autoplug_sort (GstElement * element, GstPad * pad, GstCaps * caps, GValueArray * factories) { - GValueArray *result; - - result = g_value_array_copy (factories); - - GST_DEBUG_OBJECT (element, "autoplug-sort returns %p", result); - - /* return input */ - return result; + return NULL; } static GstAutoplugSelectResult From 91122e4efc2d2a6306f09b13b36583efe93c2c40 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= Date: Fri, 18 Feb 2011 12:02:07 +0100 Subject: [PATCH 213/254] uridecodebin: Return NULL from the default autoplug-sort handler ...instead of copying the array. Returning NULL will result in the original factories array to be used and prevents a useless array copy in most use cases. --- gst/playback/gsturidecodebin.c | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/gst/playback/gsturidecodebin.c b/gst/playback/gsturidecodebin.c index c20fbfef05..ddd322a948 100644 --- a/gst/playback/gsturidecodebin.c +++ b/gst/playback/gsturidecodebin.c @@ -333,14 +333,7 @@ static GValueArray * gst_uri_decode_bin_autoplug_sort (GstElement * element, GstPad * pad, GstCaps * caps, GValueArray * factories) { - GValueArray *result; - - result = g_value_array_copy (factories); - - GST_DEBUG_OBJECT (element, "autoplug-sort returns %p", result); - - /* return input */ - return result; + return NULL; } static void From 09750a01326cf42a4c0752d8cee3134cd1216f64 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= Date: Fri, 18 Feb 2011 12:06:30 +0100 Subject: [PATCH 214/254] uridecodebin: Add default handler for autoplug-select uridecodebin proxies this signal and only the first signal handler will ever be called from decodebin2, which is uridecodebin's proxy signal handler. --- gst/playback/gsturidecodebin.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/gst/playback/gsturidecodebin.c b/gst/playback/gsturidecodebin.c index ddd322a948..af2d3dd52d 100644 --- a/gst/playback/gsturidecodebin.c +++ b/gst/playback/gsturidecodebin.c @@ -124,7 +124,7 @@ struct _GstURIDecodeBinClass GstCaps * caps, GValueArray * factories); /* signal fired to select from the proposed list of factories */ GstAutoplugSelectResult (*autoplug_select) (GstElement * element, - GstPad * pad, GstCaps * caps, GValueArray * factories); + GstPad * pad, GstCaps * caps, GstElementFactory * factory); /* emited when all data is decoded */ void (*drained) (GstElement * element); @@ -336,6 +336,16 @@ gst_uri_decode_bin_autoplug_sort (GstElement * element, GstPad * pad, return NULL; } +static GstAutoplugSelectResult +gst_uri_decode_bin_autoplug_select (GstElement * element, GstPad * pad, + GstCaps * caps, GstElementFactory * factory) +{ + GST_DEBUG_OBJECT (element, "default autoplug-select returns TRY"); + + /* Try factory. */ + return GST_AUTOPLUG_SELECT_TRY; +} + static void gst_uri_decode_bin_class_init (GstURIDecodeBinClass * klass) { @@ -619,6 +629,8 @@ gst_uri_decode_bin_class_init (GstURIDecodeBinClass * klass) klass->autoplug_factories = GST_DEBUG_FUNCPTR (gst_uri_decode_bin_autoplug_factories); klass->autoplug_sort = GST_DEBUG_FUNCPTR (gst_uri_decode_bin_autoplug_sort); + klass->autoplug_select = + GST_DEBUG_FUNCPTR (gst_uri_decode_bin_autoplug_select); } static void From 2fc70442a7b65798223548005e5aa391dd32607d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= Date: Fri, 18 Feb 2011 14:04:38 +0100 Subject: [PATCH 215/254] playbin2: Use gst_pad_accept_caps() instead of intersecting with the getcaps caps This might be faster and more accurate in some cases to detect if a sink supports a format and autoplugging can be stopped. --- gst/playback/gstplaybin2.c | 57 +++++--------------------------------- 1 file changed, 7 insertions(+), 50 deletions(-) diff --git a/gst/playback/gstplaybin2.c b/gst/playback/gstplaybin2.c index 94ee770d76..5eaae69a7d 100644 --- a/gst/playback/gstplaybin2.c +++ b/gst/playback/gstplaybin2.c @@ -2921,9 +2921,6 @@ autoplug_factories_cb (GstElement * decodebin, GstPad * pad, return result; } -static GstStaticCaps sub_plaintext_caps = - GST_STATIC_CAPS ("text/x-pango-markup; text/plain"); - /* autoplug-continue decides, if a pad has raw caps that can be exposed * directly or if further decoding is necessary. We use this to expose * supported subtitles directly */ @@ -2931,10 +2928,9 @@ static gboolean autoplug_continue_cb (GstElement * element, GstPad * pad, GstCaps * caps, GstSourceGroup * group) { - gboolean ret = FALSE; + gboolean ret = TRUE; GstElement *sink; GstPad *sinkpad = NULL; - GstCaps *sinkcaps = NULL; GST_PLAY_BIN_LOCK (group->playbin); GST_SOURCE_GROUP_LOCK (group); @@ -2942,72 +2938,33 @@ autoplug_continue_cb (GstElement * element, GstPad * pad, GstCaps * caps, if ((sink = group->playbin->text_sink)) sinkpad = gst_element_get_static_pad (sink, "sink"); if (sinkpad) { - sinkcaps = gst_pad_get_caps_reffed (sinkpad); + ret = !gst_pad_accept_caps (sinkpad, caps); gst_object_unref (sinkpad); - - /* If the textsink claims to support ANY subcaps, - * go the safe way and only use the plaintext caps */ - if (gst_caps_is_any (sinkcaps)) { - GST_WARNING_OBJECT (group->playbin, "Text sink '%s' accepts ANY caps", - GST_OBJECT_NAME (sink)); - gst_caps_unref (sinkcaps); - sinkcaps = gst_static_caps_get (&sub_plaintext_caps); - } } else { - sinkcaps = gst_subtitle_overlay_create_factory_caps (); + GstCaps *subcaps = gst_subtitle_overlay_create_factory_caps (); + ret = !gst_caps_can_intersect (caps, subcaps); + gst_caps_unref (subcaps); } - ret = !gst_caps_can_intersect (caps, sinkcaps); - gst_caps_unref (sinkcaps); - sinkcaps = NULL; if (!ret) goto done; if ((sink = group->playbin->audio_sink)) { sinkpad = gst_element_get_static_pad (sink, "sink"); if (sinkpad) { - sinkcaps = gst_pad_get_caps_reffed (sinkpad); + ret = !gst_pad_accept_caps (sinkpad, caps); gst_object_unref (sinkpad); - - /* If the audio sink claims to support ANY caps go - * the safe way and only use the raw audio caps - * that decodebin2 already has */ - if (gst_caps_is_any (sinkcaps)) { - GST_WARNING_OBJECT (group->playbin, "Audio sink '%s' accepts ANY caps", - GST_OBJECT_NAME (sink)); - gst_caps_unref (sinkcaps); - sinkcaps = NULL; - } } } - if (sinkcaps) { - ret = !gst_caps_can_intersect (caps, sinkcaps); - gst_caps_unref (sinkcaps); - sinkcaps = NULL; - } if (!ret) goto done; if ((sink = group->playbin->video_sink)) { sinkpad = gst_element_get_static_pad (sink, "sink"); if (sinkpad) { - sinkcaps = gst_pad_get_caps_reffed (sinkpad); + ret = !gst_pad_accept_caps (sinkpad, caps); gst_object_unref (sinkpad); - - /* If the video sink claims to support ANY caps go - * the safe way and only use the raw video caps - * that decodebin2 already has */ - if (gst_caps_is_any (sinkcaps)) { - GST_WARNING_OBJECT (group->playbin, "Video sink '%s' accepts ANY caps", - GST_OBJECT_NAME (sink)); - gst_caps_unref (sinkcaps); - sinkcaps = NULL; - } } } - if (sinkcaps) { - ret = !gst_caps_can_intersect (caps, sinkcaps); - gst_caps_unref (sinkcaps); - } done: GST_SOURCE_GROUP_UNLOCK (group); From 4c68f3b597f9eec7247808b98f8a6ea78da06dc3 Mon Sep 17 00:00:00 2001 From: Edward Hervey Date: Thu, 17 Feb 2011 18:11:10 +0100 Subject: [PATCH 216/254] encodebin: Add a audioconverter after the audio resampler. This allows handling non-native-endianness conversion properly. --- gst/encoding/gstencodebin.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/gst/encoding/gstencodebin.c b/gst/encoding/gstencodebin.c index ada95f8f5f..0ca3981f20 100644 --- a/gst/encoding/gstencodebin.c +++ b/gst/encoding/gstencodebin.c @@ -1203,26 +1203,30 @@ _create_stream_group (GstEncodeBin * ebin, GstEncodingProfile * sprof, last = cspace; } else if (GST_IS_ENCODING_AUDIO_PROFILE (sprof)) { - GstElement *aconv, *ares, *arate; + GstElement *aconv, *ares, *arate, *aconv2; GST_LOG ("Adding conversion elements for audio stream"); arate = gst_element_factory_make ("audiorate", NULL); g_object_set (arate, "tolerance", (guint64) ebin->tolerance, NULL); aconv = gst_element_factory_make ("audioconvert", NULL); + aconv2 = gst_element_factory_make ("audioconvert", NULL); ares = gst_element_factory_make ("audioresample", NULL); - gst_bin_add_many ((GstBin *) ebin, arate, aconv, ares, NULL); + gst_bin_add_many ((GstBin *) ebin, arate, aconv, ares, aconv2, NULL); tosync = g_list_append (tosync, arate); tosync = g_list_append (tosync, aconv); tosync = g_list_append (tosync, ares); + tosync = g_list_append (tosync, aconv2); if (!fast_element_link (arate, aconv) || - !fast_element_link (aconv, ares) || !fast_element_link (ares, last)) + !fast_element_link (aconv, ares) || + !fast_element_link (ares, aconv2) || !fast_element_link (aconv2, last)) goto converter_link_failure; sgroup->converters = g_list_prepend (sgroup->converters, arate); sgroup->converters = g_list_prepend (sgroup->converters, aconv); sgroup->converters = g_list_prepend (sgroup->converters, ares); + sgroup->converters = g_list_prepend (sgroup->converters, aconv2); last = arate; } From 0e3c32ac72c2dd62de05c815ce90e38b4a484b5f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= Date: Fri, 18 Feb 2011 17:26:53 +0100 Subject: [PATCH 217/254] playbin2: If a sink claims to support ANY caps assume that it only supports the usual raw formats This should be changed again in 0.11, if a sink really claims to support ANY caps it should support everything or provide correct caps. --- gst/playback/gstplaybin2.c | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/gst/playback/gstplaybin2.c b/gst/playback/gstplaybin2.c index 5eaae69a7d..2f2a42eb9b 100644 --- a/gst/playback/gstplaybin2.c +++ b/gst/playback/gstplaybin2.c @@ -2924,6 +2924,10 @@ autoplug_factories_cb (GstElement * decodebin, GstPad * pad, /* autoplug-continue decides, if a pad has raw caps that can be exposed * directly or if further decoding is necessary. We use this to expose * supported subtitles directly */ + +/* FIXME 0.11: Remove the checks for ANY caps, a sink should specify + * explicitely the caps it supports and if it claims to support ANY + * caps it really should support everything */ static gboolean autoplug_continue_cb (GstElement * element, GstPad * pad, GstCaps * caps, GstSourceGroup * group) @@ -2938,7 +2942,11 @@ autoplug_continue_cb (GstElement * element, GstPad * pad, GstCaps * caps, if ((sink = group->playbin->text_sink)) sinkpad = gst_element_get_static_pad (sink, "sink"); if (sinkpad) { - ret = !gst_pad_accept_caps (sinkpad, caps); + GstCaps *sinkcaps = gst_pad_get_caps_reffed (sinkpad); + + if (!gst_caps_is_any (sinkcaps)) + ret = !gst_pad_accept_caps (sinkpad, caps); + gst_caps_unref (sinkcaps); gst_object_unref (sinkpad); } else { GstCaps *subcaps = gst_subtitle_overlay_create_factory_caps (); @@ -2951,7 +2959,11 @@ autoplug_continue_cb (GstElement * element, GstPad * pad, GstCaps * caps, if ((sink = group->playbin->audio_sink)) { sinkpad = gst_element_get_static_pad (sink, "sink"); if (sinkpad) { - ret = !gst_pad_accept_caps (sinkpad, caps); + GstCaps *sinkcaps = gst_pad_get_caps_reffed (sinkpad); + + if (!gst_caps_is_any (sinkcaps)) + ret = !gst_pad_accept_caps (sinkpad, caps); + gst_caps_unref (sinkcaps); gst_object_unref (sinkpad); } } @@ -2961,7 +2973,11 @@ autoplug_continue_cb (GstElement * element, GstPad * pad, GstCaps * caps, if ((sink = group->playbin->video_sink)) { sinkpad = gst_element_get_static_pad (sink, "sink"); if (sinkpad) { - ret = !gst_pad_accept_caps (sinkpad, caps); + GstCaps *sinkcaps = gst_pad_get_caps_reffed (sinkpad); + + if (!gst_caps_is_any (sinkcaps)) + ret = !gst_pad_accept_caps (sinkpad, caps); + gst_caps_unref (sinkcaps); gst_object_unref (sinkpad); } } From 82199c581506a6ef3f21144c6a7f48aea0f22240 Mon Sep 17 00:00:00 2001 From: Leo Singer Date: Fri, 18 Feb 2011 13:27:23 -0800 Subject: [PATCH 218/254] audiotestsrc: each element gets its own instance of GRand, if needed As a result, pipelines that contain multiple instances of audiotestsrc with the 'wave' property set to 'white-noise', 'pink-noise', or 'gaussian-noise' will run much faster, since they won't be competing for access to the global, lock-protected instance of GRand. Fixes bug #642720. --- gst/audiotestsrc/gstaudiotestsrc.c | 40 ++++++++++++++++++++++++------ gst/audiotestsrc/gstaudiotestsrc.h | 1 + 2 files changed, 34 insertions(+), 7 deletions(-) diff --git a/gst/audiotestsrc/gstaudiotestsrc.c b/gst/audiotestsrc/gstaudiotestsrc.c index 5b689713fb..ecbb2fbb07 100644 --- a/gst/audiotestsrc/gstaudiotestsrc.c +++ b/gst/audiotestsrc/gstaudiotestsrc.c @@ -140,6 +140,8 @@ gst_audiostestsrc_wave_get_type (void) return audiostestsrc_wave_type; } +static void gst_audio_test_src_finalize (GObject * object); + static void gst_audio_test_src_set_property (GObject * object, guint prop_id, const GValue * value, GParamSpec * pspec); static void gst_audio_test_src_get_property (GObject * object, @@ -190,6 +192,7 @@ gst_audio_test_src_class_init (GstAudioTestSrcClass * klass) gobject_class->set_property = gst_audio_test_src_set_property; gobject_class->get_property = gst_audio_test_src_get_property; + gobject_class->finalize = gst_audio_test_src_finalize; g_object_class_install_property (gobject_class, PROP_SAMPLES_PER_BUFFER, g_param_spec_int ("samplesperbuffer", "Samples per buffer", @@ -263,10 +266,24 @@ gst_audio_test_src_init (GstAudioTestSrc * src, GstAudioTestSrcClass * g_class) src->timestamp_offset = DEFAULT_TIMESTAMP_OFFSET; src->can_activate_pull = DEFAULT_CAN_ACTIVATE_PULL; + src->gen = NULL; + src->wave = DEFAULT_WAVE; gst_base_src_set_blocksize (GST_BASE_SRC (src), -1); } +static void +gst_audio_test_src_finalize (GObject * object) +{ + GstAudioTestSrc *src = GST_AUDIO_TEST_SRC (object); + + if (src->gen) + g_rand_free (src->gen); + src->gen = NULL; + + G_OBJECT_CLASS (parent_class)->finalize (object); +} + static void gst_audio_test_src_src_fixate (GstPad * pad, GstCaps * caps) { @@ -584,7 +601,7 @@ gst_audio_test_src_create_white_noise_##type (GstAudioTestSrc * src, g##type * s i = 0; \ while (i < (src->generate_samples_per_buffer * src->channels)) { \ for (c = 0; c < src->channels; ++c) \ - samples[i++] = (g##type) (amp * g_random_double_range (-1.0, 1.0)); \ + samples[i++] = (g##type) (amp * g_rand_double_range (src->gen, -1.0, 1.0)); \ } \ } @@ -626,8 +643,9 @@ gst_audio_test_src_init_pink_noise (GstAudioTestSrc * src) /* Generate Pink noise values between -1.0 and +1.0 */ static gdouble -gst_audio_test_src_generate_pink_noise_value (GstPinkNoise * pink) +gst_audio_test_src_generate_pink_noise_value (GstAudioTestSrc * src) { + GstPinkNoise *pink = &src->pink; glong new_random; glong sum; @@ -651,13 +669,15 @@ gst_audio_test_src_generate_pink_noise_value (GstPinkNoise * pink) * values together. Only one changes each time. */ pink->running_sum -= pink->rows[num_zeros]; - new_random = 32768.0 - (65536.0 * (gulong) rand () / (RAND_MAX + 1.0)); + new_random = 32768.0 - (65536.0 * (gulong) g_rand_int (src->gen) + / (G_MAXUINT32 + 1.0)); pink->running_sum += new_random; pink->rows[num_zeros] = new_random; } /* Add extra white noise value. */ - new_random = 32768.0 - (65536.0 * (gulong) rand () / (RAND_MAX + 1.0)); + new_random = 32768.0 - (65536.0 * (gulong) g_rand_int (src->gen) + / (G_MAXUINT32 + 1.0)); sum = pink->running_sum + new_random; /* Scale to range of -1.0 to 0.9999. */ @@ -677,7 +697,7 @@ gst_audio_test_src_create_pink_noise_##type (GstAudioTestSrc * src, g##type * sa while (i < (src->generate_samples_per_buffer * src->channels)) { \ for (c = 0; c < src->channels; ++c) { \ samples[i++] = \ - (g##type) (gst_audio_test_src_generate_pink_noise_value (&src->pink) * \ + (g##type) (gst_audio_test_src_generate_pink_noise_value (src) * \ amp); \ } \ } \ @@ -794,8 +814,8 @@ gst_audio_test_src_create_gaussian_white_noise_##type (GstAudioTestSrc * src, g# \ for (i = 0; i < src->generate_samples_per_buffer * src->channels; ) { \ for (c = 0; c < src->channels; ++c) { \ - gdouble mag = sqrt (-2 * log (1.0 - g_random_double ())); \ - gdouble phs = g_random_double_range (0.0, M_PI_M2); \ + gdouble mag = sqrt (-2 * log (1.0 - g_rand_double (src->gen))); \ + gdouble phs = g_rand_double_range (src->gen, 0.0, M_PI_M2); \ \ samples[i++] = (g##type) (amp * mag * cos (phs)); \ if (++c >= src->channels) \ @@ -846,9 +866,13 @@ gst_audio_test_src_change_wave (GstAudioTestSrc * src) src->process = silence_funcs[src->format]; break; case GST_AUDIO_TEST_SRC_WAVE_WHITE_NOISE: + if (!(src->gen)) + src->gen = g_rand_new (); src->process = white_noise_funcs[src->format]; break; case GST_AUDIO_TEST_SRC_WAVE_PINK_NOISE: + if (!(src->gen)) + src->gen = g_rand_new (); gst_audio_test_src_init_pink_noise (src); src->process = pink_noise_funcs[src->format]; break; @@ -861,6 +885,8 @@ gst_audio_test_src_change_wave (GstAudioTestSrc * src) src->process = tick_funcs[src->format]; break; case GST_AUDIO_TEST_SRC_WAVE_GAUSSIAN_WHITE_NOISE: + if (!(src->gen)) + src->gen = g_rand_new (); src->process = gaussian_white_noise_funcs[src->format]; break; default: diff --git a/gst/audiotestsrc/gstaudiotestsrc.h b/gst/audiotestsrc/gstaudiotestsrc.h index 860c5c01b1..8c76594822 100644 --- a/gst/audiotestsrc/gstaudiotestsrc.h +++ b/gst/audiotestsrc/gstaudiotestsrc.h @@ -127,6 +127,7 @@ struct _GstAudioTestSrc { gboolean reverse; /* play backwards */ /* waveform specific context data */ + GRand *gen; /* random number generator */ gdouble accumulator; /* phase angle */ GstPinkNoise pink; gdouble wave_table[1024]; From 7a24e3ea4e73af4e72d529909b80f651bec44f05 Mon Sep 17 00:00:00 2001 From: David Schleef Date: Fri, 18 Feb 2011 16:26:59 -0800 Subject: [PATCH 219/254] video: Add gst_video_format_get_component_depth() --- gst-libs/gst/video/video.c | 67 ++++++++++++++++++++++++++++++++++++++ gst-libs/gst/video/video.h | 1 + 2 files changed, 68 insertions(+) diff --git a/gst-libs/gst/video/video.c b/gst-libs/gst/video/video.c index d9fa50b229..dc43e7e890 100644 --- a/gst-libs/gst/video/video.c +++ b/gst-libs/gst/video/video.c @@ -1163,6 +1163,73 @@ gst_video_format_has_alpha (GstVideoFormat format) } } +/** + * gst_video_format_get_component_depth: + * @format: a #GstVideoFormat + * + * Returns the number of bits used to encode an individual pixel of + * a given component. Typically this is 8, although higher and lower + * values are possible for some formats. + * + * Since: 0.10.33 + * + * Returns: depth of component + */ +int +gst_video_format_get_component_depth (GstVideoFormat format, int component) +{ + if (component == 3 && !gst_video_format_has_alpha (format)) + return 0; + + switch (format) { + case GST_VIDEO_FORMAT_RGB16: + case GST_VIDEO_FORMAT_BGR16: + if (component == 1) + return 6; + return 5; + case GST_VIDEO_FORMAT_RGB15: + case GST_VIDEO_FORMAT_BGR15: + return 5; + case GST_VIDEO_FORMAT_I420: + case GST_VIDEO_FORMAT_YV12: + case GST_VIDEO_FORMAT_YUY2: + case GST_VIDEO_FORMAT_YVYU: + case GST_VIDEO_FORMAT_UYVY: + case GST_VIDEO_FORMAT_Y41B: + case GST_VIDEO_FORMAT_Y42B: + case GST_VIDEO_FORMAT_Y444: + case GST_VIDEO_FORMAT_NV12: + case GST_VIDEO_FORMAT_NV21: + case GST_VIDEO_FORMAT_v308: + case GST_VIDEO_FORMAT_Y800: + case GST_VIDEO_FORMAT_YUV9: + case GST_VIDEO_FORMAT_YVU9: + case GST_VIDEO_FORMAT_IYU1: + case GST_VIDEO_FORMAT_AYUV: + case GST_VIDEO_FORMAT_RGBA: + case GST_VIDEO_FORMAT_BGRA: + case GST_VIDEO_FORMAT_ARGB: + case GST_VIDEO_FORMAT_ABGR: + case GST_VIDEO_FORMAT_A420: + case GST_VIDEO_FORMAT_RGB8_PALETTED: + case GST_VIDEO_FORMAT_RGBx: + case GST_VIDEO_FORMAT_BGRx: + case GST_VIDEO_FORMAT_xRGB: + case GST_VIDEO_FORMAT_xBGR: + case GST_VIDEO_FORMAT_RGB: + case GST_VIDEO_FORMAT_BGR: + default: + return 8; + case GST_VIDEO_FORMAT_v210: + case GST_VIDEO_FORMAT_UYVP: + return 10; + case GST_VIDEO_FORMAT_Y16: + case GST_VIDEO_FORMAT_v216: + return 16; + } + +} + /** * gst_video_format_get_row_stride: * @format: a #GstVideoFormat diff --git a/gst-libs/gst/video/video.h b/gst-libs/gst/video/video.h index 96c5a85d9d..8ad56764be 100644 --- a/gst-libs/gst/video/video.h +++ b/gst-libs/gst/video/video.h @@ -421,6 +421,7 @@ gboolean gst_video_format_is_rgb (GstVideoFormat format); gboolean gst_video_format_is_yuv (GstVideoFormat format); gboolean gst_video_format_is_gray (GstVideoFormat format); gboolean gst_video_format_has_alpha (GstVideoFormat format); +int gst_video_format_get_component_depth (GstVideoFormat format, int component); int gst_video_format_get_row_stride (GstVideoFormat format, int component, int width); int gst_video_format_get_pixel_stride (GstVideoFormat format, int component); From 0ed72c29596338e53079e978c4af7bba5a859baf Mon Sep 17 00:00:00 2001 From: David Schleef Date: Sat, 19 Feb 2011 12:03:17 -0800 Subject: [PATCH 220/254] video: Add ARGB64 and AYUV64 16-bit per channel formats. --- gst-libs/gst/video/video.c | 52 +++++++++++++++++++++++++++++++++++++- gst-libs/gst/video/video.h | 24 +++++++++++++++++- 2 files changed, 74 insertions(+), 2 deletions(-) diff --git a/gst-libs/gst/video/video.c b/gst-libs/gst/video/video.c index dc43e7e890..a9d856616e 100644 --- a/gst-libs/gst/video/video.c +++ b/gst-libs/gst/video/video.c @@ -395,6 +395,15 @@ gst_video_format_parse_caps (GstCaps * caps, GstVideoFormat * format, } } else if (depth == 8 && bpp == 8) { *format = GST_VIDEO_FORMAT_RGB8_PALETTED; + } else if (depth == 64 && bpp == 64) { + *format = gst_video_format_from_rgba32_masks (red_mask, green_mask, + blue_mask, alpha_mask); + if (*format == GST_VIDEO_FORMAT_ARGB) { + *format = GST_VIDEO_FORMAT_ARGB64; + } else { + *format = GST_VIDEO_FORMAT_UNKNOWN; + ok = FALSE; + } } else { ok = FALSE; } @@ -615,10 +624,15 @@ gst_video_format_new_caps (GstVideoFormat format, int width, depth = 8; have_alpha = FALSE; break; + case GST_VIDEO_FORMAT_ARGB64: + bpp = 64; + depth = 64; + have_alpha = TRUE; + break; default: return NULL; } - if (bpp == 32 || bpp == 24) { + if (bpp == 32 || bpp == 24 || bpp == 64) { if (bpp == 32) { mask = 0xff000000; } else { @@ -797,6 +811,8 @@ gst_video_format_from_fourcc (guint32 fourcc) return GST_VIDEO_FORMAT_YVU9; case GST_MAKE_FOURCC ('I', 'Y', 'U', '1'): return GST_VIDEO_FORMAT_IYU1; + case GST_MAKE_FOURCC ('A', 'Y', '6', '4'): + return GST_VIDEO_FORMAT_AYUV64; default: return GST_VIDEO_FORMAT_UNKNOWN; } @@ -862,6 +878,8 @@ gst_video_format_to_fourcc (GstVideoFormat format) return GST_MAKE_FOURCC ('Y', 'V', 'U', '9'); case GST_VIDEO_FORMAT_IYU1: return GST_MAKE_FOURCC ('I', 'Y', 'U', '1'); + case GST_VIDEO_FORMAT_AYUV64: + return GST_MAKE_FOURCC ('A', 'Y', '6', '4'); default: return 0; } @@ -1000,6 +1018,7 @@ gst_video_format_is_rgb (GstVideoFormat format) case GST_VIDEO_FORMAT_YUV9: case GST_VIDEO_FORMAT_YVU9: case GST_VIDEO_FORMAT_IYU1: + case GST_VIDEO_FORMAT_AYUV64: return FALSE; case GST_VIDEO_FORMAT_RGBx: case GST_VIDEO_FORMAT_BGRx: @@ -1016,6 +1035,7 @@ gst_video_format_is_rgb (GstVideoFormat format) case GST_VIDEO_FORMAT_RGB15: case GST_VIDEO_FORMAT_BGR15: case GST_VIDEO_FORMAT_RGB8_PALETTED: + case GST_VIDEO_FORMAT_ARGB64: return TRUE; default: return FALSE; @@ -1057,6 +1077,7 @@ gst_video_format_is_yuv (GstVideoFormat format) case GST_VIDEO_FORMAT_YUV9: case GST_VIDEO_FORMAT_YVU9: case GST_VIDEO_FORMAT_IYU1: + case GST_VIDEO_FORMAT_AYUV64: return TRUE; case GST_VIDEO_FORMAT_RGBx: case GST_VIDEO_FORMAT_BGRx: @@ -1073,6 +1094,7 @@ gst_video_format_is_yuv (GstVideoFormat format) case GST_VIDEO_FORMAT_RGB15: case GST_VIDEO_FORMAT_BGR15: case GST_VIDEO_FORMAT_RGB8_PALETTED: + case GST_VIDEO_FORMAT_ARGB64: return FALSE; default: return FALSE; @@ -1146,6 +1168,8 @@ gst_video_format_has_alpha (GstVideoFormat format) case GST_VIDEO_FORMAT_ABGR: case GST_VIDEO_FORMAT_A420: case GST_VIDEO_FORMAT_RGB8_PALETTED: + case GST_VIDEO_FORMAT_ARGB64: + case GST_VIDEO_FORMAT_AYUV64: return TRUE; case GST_VIDEO_FORMAT_RGBx: case GST_VIDEO_FORMAT_BGRx: @@ -1225,6 +1249,8 @@ gst_video_format_get_component_depth (GstVideoFormat format, int component) return 10; case GST_VIDEO_FORMAT_Y16: case GST_VIDEO_FORMAT_v216: + case GST_VIDEO_FORMAT_ARGB64: + case GST_VIDEO_FORMAT_AYUV64: return 16; } @@ -1335,6 +1361,9 @@ gst_video_format_get_row_stride (GstVideoFormat format, int component, case GST_VIDEO_FORMAT_IYU1: return GST_ROUND_UP_4 (GST_ROUND_UP_4 (width) + GST_ROUND_UP_4 (width) / 2); + case GST_VIDEO_FORMAT_ARGB64: + case GST_VIDEO_FORMAT_AYUV64: + return width * 8; default: return 0; } @@ -1429,6 +1458,9 @@ gst_video_format_get_pixel_stride (GstVideoFormat format, int component) return 0; case GST_VIDEO_FORMAT_RGB8_PALETTED: return 1; + case GST_VIDEO_FORMAT_ARGB64: + case GST_VIDEO_FORMAT_AYUV64: + return 8; default: return 0; } @@ -1505,6 +1537,8 @@ gst_video_format_get_component_width (GstVideoFormat format, case GST_VIDEO_FORMAT_Y800: case GST_VIDEO_FORMAT_Y16: case GST_VIDEO_FORMAT_RGB8_PALETTED: + case GST_VIDEO_FORMAT_ARGB64: + case GST_VIDEO_FORMAT_AYUV64: return width; case GST_VIDEO_FORMAT_A420: if (component == 0 || component == 3) { @@ -1581,6 +1615,8 @@ gst_video_format_get_component_height (GstVideoFormat format, case GST_VIDEO_FORMAT_UYVP: case GST_VIDEO_FORMAT_RGB8_PALETTED: case GST_VIDEO_FORMAT_IYU1: + case GST_VIDEO_FORMAT_ARGB64: + case GST_VIDEO_FORMAT_AYUV64: return height; case GST_VIDEO_FORMAT_A420: if (component == 0 || component == 3) { @@ -1843,6 +1879,17 @@ gst_video_format_get_component_offset (GstVideoFormat format, return 0; if (component == 2) return 4; + case GST_VIDEO_FORMAT_ARGB64: + case GST_VIDEO_FORMAT_AYUV64: + if (component == 0) + return 2; + if (component == 1) + return 4; + if (component == 2) + return 6; + if (component == 3) + return 0; + return 0; default: return 0; } @@ -1938,6 +1985,9 @@ gst_video_format_get_size (GstVideoFormat format, int width, int height) size += GST_ROUND_UP_4 (GST_ROUND_UP_4 (width) / 4) * (GST_ROUND_UP_4 (height) / 4) * 2; return size; + case GST_VIDEO_FORMAT_ARGB64: + case GST_VIDEO_FORMAT_AYUV64: + return width * 8 * height; default: return 0; } diff --git a/gst-libs/gst/video/video.h b/gst-libs/gst/video/video.h index 8ad56764be..e78f74c660 100644 --- a/gst-libs/gst/video/video.h +++ b/gst-libs/gst/video/video.h @@ -69,6 +69,8 @@ G_BEGIN_DECLS * @GST_VIDEO_FORMAT_YUV9: planar 4:1:0 YUV (Since: 0.10.32) * @GST_VIDEO_FORMAT_YVU9: planar 4:1:0 YUV (like YUV9 but UV planes swapped) (Since: 0.10.32) * @GST_VIDEO_FORMAT_IYU1: packed 4:1:1 YUV (Cb-Y0-Y1-Cr-Y2-Y3 ...) (Since: 0.10.32) + * @GST_VIDEO_FORMAT_ARGB64: rgb with alpha channel first, 16 bits per channel (Since: 0.10.33) + * @GST_VIDEO_FORMAT_AY64: packed 4:4:4 YUV with alpha channel, 16 bits per channel (A0-Y0-U0-V0 ...) (Since: 0.10.33) * * Enum value describing the most common video formats. */ @@ -112,7 +114,9 @@ typedef enum { GST_VIDEO_FORMAT_RGB8_PALETTED, GST_VIDEO_FORMAT_YUV9, GST_VIDEO_FORMAT_YVU9, - GST_VIDEO_FORMAT_IYU1 + GST_VIDEO_FORMAT_IYU1, + GST_VIDEO_FORMAT_ARGB64, + GST_VIDEO_FORMAT_AYUV64 } GstVideoFormat; #define GST_VIDEO_BYTE1_MASK_32 "0xFF000000" @@ -232,6 +236,19 @@ typedef enum { "height = " GST_VIDEO_SIZE_RANGE ", " \ "framerate = " GST_VIDEO_FPS_RANGE +#define __GST_VIDEO_CAPS_MAKE_64A(R, G, B, A) \ + "video/x-raw-rgb, " \ + "bpp = (int) 64, " \ + "depth = (int) 64, " \ + "endianness = (int) BIG_ENDIAN, " \ + "red_mask = (int) " GST_VIDEO_BYTE ## R ## _MASK_32 ", " \ + "green_mask = (int) " GST_VIDEO_BYTE ## G ## _MASK_32 ", " \ + "blue_mask = (int) " GST_VIDEO_BYTE ## B ## _MASK_32 ", " \ + "alpha_mask = (int) " GST_VIDEO_BYTE ## A ## _MASK_32 ", " \ + "width = " GST_VIDEO_SIZE_RANGE ", " \ + "height = " GST_VIDEO_SIZE_RANGE ", " \ + "framerate = " GST_VIDEO_FPS_RANGE + /* 24 bit */ @@ -296,6 +313,11 @@ typedef enum { #define GST_VIDEO_CAPS_BGR_15 \ __GST_VIDEO_CAPS_MAKE_15 (3, 2, 1) +/* 64 bit alpha */ + +#define GST_VIDEO_CAPS_ARGB_64 \ + __GST_VIDEO_CAPS_MAKE_64A (2, 3, 4, 1) + /** * GST_VIDEO_CAPS_RGB8_PALETTED: * From 99d83392895abf45273e159533d9fdce54a295ed Mon Sep 17 00:00:00 2001 From: David Schleef Date: Sat, 19 Feb 2011 16:41:43 -0800 Subject: [PATCH 221/254] videotestsrc: Add 16-bit-per-channel formats --- gst/videotestsrc/videotestsrc.c | 73 +++++++++++++++++++++++++++++++-- 1 file changed, 70 insertions(+), 3 deletions(-) diff --git a/gst/videotestsrc/videotestsrc.c b/gst/videotestsrc/videotestsrc.c index c06b35369e..99735075d2 100644 --- a/gst/videotestsrc/videotestsrc.c +++ b/gst/videotestsrc/videotestsrc.c @@ -32,6 +32,9 @@ #include #include +#define TO_16(x) (((x)<<8) | (x)) +#define TO_10(x) (((x)<<2) | ((x)>>6)) + static void paint_tmpline_ARGB (paintinfo * p, int x, int w); static void paint_tmpline_AYUV (paintinfo * p, int x, int w); @@ -144,6 +147,7 @@ static void paint_setup_v410 (paintinfo * p, unsigned char *dest); static void paint_setup_v216 (paintinfo * p, unsigned char *dest); static void paint_setup_v210 (paintinfo * p, unsigned char *dest); static void paint_setup_UYVP (paintinfo * p, unsigned char *dest); +static void paint_setup_AY64 (paintinfo * p, unsigned char *dest); static void paint_setup_YUV9 (paintinfo * p, unsigned char *dest); static void paint_setup_YVU9 (paintinfo * p, unsigned char *dest); @@ -159,6 +163,7 @@ static void paint_setup_RGB888 (paintinfo * p, unsigned char *dest); static void paint_setup_BGR888 (paintinfo * p, unsigned char *dest); static void paint_setup_RGB565 (paintinfo * p, unsigned char *dest); static void paint_setup_xRGB1555 (paintinfo * p, unsigned char *dest); +static void paint_setup_ARGB64 (paintinfo * p, unsigned char *dest); static void paint_setup_bayer_bggr (paintinfo * p, unsigned char *dest); static void paint_setup_bayer_rggb (paintinfo * p, unsigned char *dest); @@ -184,9 +189,11 @@ static void convert_hline_v410 (paintinfo * p, int y); static void convert_hline_v216 (paintinfo * p, int y); static void convert_hline_v210 (paintinfo * p, int y); static void convert_hline_UYVP (paintinfo * p, int y); +static void convert_hline_AY64 (paintinfo * p, int y); static void convert_hline_YUV9 (paintinfo * p, int y); static void convert_hline_astr4 (paintinfo * p, int y); +static void convert_hline_astr8 (paintinfo * p, int y); static void convert_hline_str4 (paintinfo * p, int y); static void convert_hline_str3 (paintinfo * p, int y); static void convert_hline_RGB565 (paintinfo * p, int y); @@ -216,6 +223,7 @@ struct fourcc_list_struct fourcc_list[] = { {VTS_YUV, "v210", "v210", 21, paint_setup_v210, convert_hline_v210}, {VTS_YUV, "v216", "v216", 32, paint_setup_v216, convert_hline_v216}, {VTS_YUV, "UYVP", "UYVP", 20, paint_setup_UYVP, convert_hline_UYVP}, + {VTS_YUV, "AY64", "AY64", 64, paint_setup_AY64, convert_hline_AY64}, #ifdef disabled {VTS_YUV, "IYU2", "IYU2", 24, paint_setup_IYU2, convert_hline_IYU2}, @@ -283,6 +291,9 @@ struct fourcc_list_struct fourcc_list[] = { convert_hline_xRGB1555, 15, 0x00007c00, 0x000003e0, 0x0000001f}, + {VTS_RGB, "RGB ", "ARGB8888", 64, paint_setup_ARGB64, convert_hline_astr8, + 64, + 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000}, {VTS_BAYER, "bggr", "Bayer", 8, paint_setup_bayer_bggr, convert_hline_bayer}, {VTS_BAYER, "rggb", "Bayer", 8, paint_setup_bayer_rggb, convert_hline_bayer}, @@ -1838,6 +1849,19 @@ paint_setup_YVYU (paintinfo * p, unsigned char *dest) p->endptr = dest + p->ystride * p->height; } +static void +paint_setup_AY64 (paintinfo * p, unsigned char *dest) +{ + p->ap = dest; + p->yp = dest + 2; + p->up = dest + 4; + p->vp = dest + 6; + p->ystride = p->width * 8; + p->ustride = p->width * 8; + p->vstride = p->width * 8; + p->endptr = dest + p->ystride * p->height; +} + static void convert_hline_v308 (paintinfo * p, int y) { @@ -1872,9 +1896,6 @@ convert_hline_AYUV (paintinfo * p, int y) } } -#define TO_16(x) (((x)<<8) | (x)) -#define TO_10(x) (((x)<<2) | ((x)>>6)) - static void convert_hline_v216 (paintinfo * p, int y) { @@ -2005,6 +2026,21 @@ convert_hline_YUY2 (paintinfo * p, int y) } } +static void +convert_hline_AY64 (paintinfo * p, int y) +{ + int i; + guint16 *ayuv16 = (guint16 *) (p->ap + y * p->ystride); + guint8 *ayuv = p->tmpline; + + for (i = 0; i < p->width; i++) { + GST_WRITE_UINT16_LE (ayuv16 + i * 4 + 0, TO_16 (ayuv[4 * i + 0])); + GST_WRITE_UINT16_LE (ayuv16 + i * 4 + 1, TO_16 (ayuv[4 * i + 1])); + GST_WRITE_UINT16_LE (ayuv16 + i * 4 + 2, TO_16 (ayuv[4 * i + 2])); + GST_WRITE_UINT16_LE (ayuv16 + i * 4 + 3, TO_16 (ayuv[4 * i + 3])); + } +} + #ifdef disabled static void paint_setup_IYU2 (paintinfo * p, unsigned char *dest) @@ -2294,6 +2330,19 @@ paint_setup_BGR888 (paintinfo * p, unsigned char *dest) p->endptr = p->dest + p->ystride * p->height; } +static void +paint_setup_ARGB64 (paintinfo * p, unsigned char *dest) +{ + p->yp = dest + 2; + p->up = dest + 4; + p->vp = dest + 6; + p->ap = dest; + p->ystride = p->width * 8; + p->ustride = p->width * 8; + p->vstride = p->width * 8; + p->endptr = p->dest + p->ystride * p->height; +} + static void convert_hline_str4 (paintinfo * p, int y) { @@ -2330,6 +2379,24 @@ convert_hline_astr4 (paintinfo * p, int y) } } +static void +convert_hline_astr8 (paintinfo * p, int y) +{ + int i; + guint16 *A = (guint16 *) (p->ap + y * p->ystride); + guint16 *R = (guint16 *) (p->yp + y * p->ystride); + guint16 *G = (guint16 *) (p->up + y * p->ustride); + guint16 *B = (guint16 *) (p->vp + y * p->vstride); + guint8 *argb = p->tmpline; + + for (i = 0; i < p->width; i++) { + A[4 * i] = TO_16 (argb[4 * i + 0]); + R[4 * i] = TO_16 (argb[4 * i + 1]); + G[4 * i] = TO_16 (argb[4 * i + 2]); + B[4 * i] = TO_16 (argb[4 * i + 3]); + } +} + static void convert_hline_str3 (paintinfo * p, int y) { From e1149f52c12559696dbba8d2adb4a7b85240d368 Mon Sep 17 00:00:00 2001 From: David Schleef Date: Sat, 19 Feb 2011 18:50:37 -0800 Subject: [PATCH 222/254] videoscale: Add 16-bit-channel support --- gst/videoscale/gstvideoscale.c | 28 +++++- gst/videoscale/gstvideoscaleorc-dist.c | 103 +++++++++++++++++++- gst/videoscale/gstvideoscaleorc-dist.h | 2 + gst/videoscale/gstvideoscaleorc.orc | 7 ++ gst/videoscale/vs_4tap.c | 125 +++++++++++++++++++++++++ gst/videoscale/vs_4tap.h | 7 ++ gst/videoscale/vs_fill_borders.c | 41 ++++++++ gst/videoscale/vs_fill_borders.h | 1 + gst/videoscale/vs_image.c | 118 +++++++++++++++++++++++ gst/videoscale/vs_image.h | 10 ++ gst/videoscale/vs_scanline.c | 66 +++++++++++++ gst/videoscale/vs_scanline.h | 5 + 12 files changed, 505 insertions(+), 8 deletions(-) diff --git a/gst/videoscale/gstvideoscale.c b/gst/videoscale/gstvideoscale.c index af5ea8db5f..aaf104bd42 100644 --- a/gst/videoscale/gstvideoscale.c +++ b/gst/videoscale/gstvideoscale.c @@ -129,7 +129,9 @@ static GstStaticCaps gst_video_scale_format_caps[] = { GST_STATIC_CAPS (GST_VIDEO_CAPS_GRAY8), GST_STATIC_CAPS (GST_VIDEO_CAPS_YUV ("Y800")), GST_STATIC_CAPS (GST_VIDEO_CAPS_YUV ("Y8 ")), - GST_STATIC_CAPS (GST_VIDEO_CAPS_YUV ("GREY")) + GST_STATIC_CAPS (GST_VIDEO_CAPS_YUV ("GREY")), + GST_STATIC_CAPS (GST_VIDEO_CAPS_YUV ("AY64")), + GST_STATIC_CAPS (GST_VIDEO_CAPS_ARGB_64) }; #define GST_TYPE_VIDEO_SCALE_METHOD (gst_video_scale_method_get_type()) @@ -422,9 +424,7 @@ gst_video_scale_set_caps (GstBaseTransform * trans, GstCaps * in, GstCaps * out) if (videoscale->tmp_buf) g_free (videoscale->tmp_buf); - videoscale->tmp_buf = - g_malloc (gst_video_format_get_row_stride (videoscale->format, 0, - videoscale->to_width) * 4); + videoscale->tmp_buf = g_malloc (videoscale->to_width * 8 * 4); gst_base_transform_set_passthrough (trans, (videoscale->from_width == videoscale->to_width @@ -960,6 +960,7 @@ _get_black_for_format (GstVideoFormat format) case GST_VIDEO_FORMAT_ABGR: case GST_VIDEO_FORMAT_xRGB: case GST_VIDEO_FORMAT_xBGR: + case GST_VIDEO_FORMAT_ARGB64: return black[0]; case GST_VIDEO_FORMAT_RGBA: case GST_VIDEO_FORMAT_BGRA: @@ -967,6 +968,7 @@ _get_black_for_format (GstVideoFormat format) case GST_VIDEO_FORMAT_BGRx: return black[1]; case GST_VIDEO_FORMAT_AYUV: + case GST_VIDEO_FORMAT_AYUV64: return black[2]; case GST_VIDEO_FORMAT_RGB: case GST_VIDEO_FORMAT_BGR: @@ -1072,6 +1074,24 @@ gst_video_scale_transform (GstBaseTransform * trans, GstBuffer * in, goto unknown_mode; } break; + case GST_VIDEO_FORMAT_ARGB64: + case GST_VIDEO_FORMAT_AYUV64: + if (add_borders) + vs_fill_borders_AYUV64 (&dest, black); + switch (method) { + case GST_VIDEO_SCALE_NEAREST: + vs_image_scale_nearest_AYUV64 (&dest, &src, videoscale->tmp_buf); + break; + case GST_VIDEO_SCALE_BILINEAR: + vs_image_scale_linear_AYUV64 (&dest, &src, videoscale->tmp_buf); + break; + case GST_VIDEO_SCALE_4TAP: + vs_image_scale_4tap_AYUV64 (&dest, &src, videoscale->tmp_buf); + break; + default: + goto unknown_mode; + } + break; case GST_VIDEO_FORMAT_RGB: case GST_VIDEO_FORMAT_BGR: case GST_VIDEO_FORMAT_v308: diff --git a/gst/videoscale/gstvideoscaleorc-dist.c b/gst/videoscale/gstvideoscaleorc-dist.c index d65ccbca44..d62e29ff44 100644 --- a/gst/videoscale/gstvideoscaleorc-dist.c +++ b/gst/videoscale/gstvideoscaleorc-dist.c @@ -32,6 +32,7 @@ typedef unsigned __int16 orc_uint16; typedef unsigned __int32 orc_uint32; typedef unsigned __int64 orc_uint64; #define ORC_UINT64_C(x) (x##Ui64) +#define inline __inline #else #include typedef signed char orc_int8; @@ -78,6 +79,7 @@ void orc_merge_linear_u16 (orc_uint16 * d1, const orc_uint16 * s1, const orc_uint16 * s2, int p1, int p2, int n); void orc_splat_u16 (orc_uint16 * d1, int p1, int n); void orc_splat_u32 (orc_uint32 * d1, int p1, int n); +void orc_splat_u64 (orc_uint64 * d1, orc_int64 p1, int n); void orc_downsample_u8 (guint8 * d1, const guint8 * s1, int n); void orc_downsample_u16 (guint16 * d1, const guint16 * s1, int n); void gst_videoscale_orc_downsample_u32 (guint8 * d1, const guint8 * s1, int n); @@ -171,7 +173,7 @@ orc_merge_linear_u8 (orc_uint8 * d1, const orc_uint8 * s1, const orc_uint8 * s2, /* 6: loadpw */ var38.i = p1; /* 8: loadpw */ - var39.i = 0x00000080; /* 128 or 6.32404e-322f */ + var39.i = (int) 0x00000080; /* 128 or 6.32404e-322f */ for (i = 0; i < n; i++) { /* 0: loadb */ @@ -229,7 +231,7 @@ _backup_orc_merge_linear_u8 (OrcExecutor * ORC_RESTRICT ex) /* 6: loadpw */ var38.i = ex->params[24]; /* 8: loadpw */ - var39.i = 0x00000080; /* 128 or 6.32404e-322f */ + var39.i = (int) 0x00000080; /* 128 or 6.32404e-322f */ for (i = 0; i < n; i++) { /* 0: loadb */ @@ -540,6 +542,81 @@ orc_splat_u32 (orc_uint32 * d1, int p1, int n) #endif +/* orc_splat_u64 */ +#ifdef DISABLE_ORC +void +orc_splat_u64 (orc_uint64 * d1, orc_int64 p1, int n) +{ + int i; + orc_union64 *ORC_RESTRICT ptr0; + orc_union64 var32; + orc_union64 var33; + + ptr0 = (orc_union64 *) d1; + + /* 0: loadpq */ + var32.i = p1; + + for (i = 0; i < n; i++) { + /* 1: copyq */ + var33.i = var32.i; + /* 2: storeq */ + ptr0[i] = var33; + } + +} + +#else +static void +_backup_orc_splat_u64 (OrcExecutor * ORC_RESTRICT ex) +{ + int i; + int n = ex->n; + orc_union64 *ORC_RESTRICT ptr0; + orc_union64 var32; + orc_union64 var33; + + ptr0 = (orc_union64 *) ex->arrays[0]; + + /* 0: loadpq */ + var32.i = + (ex->params[24] & 0xffffffff) | ((orc_uint64) (ex->params[24 + + (ORC_VAR_T1 - ORC_VAR_P1)]) << 32); + + for (i = 0; i < n; i++) { + /* 1: copyq */ + var33.i = var32.i; + /* 2: storeq */ + ptr0[i] = var33; + } + +} + +static OrcProgram *_orc_program_orc_splat_u64; +void +orc_splat_u64 (orc_uint64 * d1, orc_int64 p1, int n) +{ + OrcExecutor _ex, *ex = &_ex; + OrcProgram *p = _orc_program_orc_splat_u64; + void (*func) (OrcExecutor *); + + ex->program = p; + + ex->n = n; + ex->arrays[ORC_VAR_D1] = d1; + { + orc_union64 tmp; + tmp.i = p1; + ex->params[ORC_VAR_P1] = tmp.x2[0]; + ex->params[ORC_VAR_T1] = tmp.x2[1]; + } + + func = p->code_exec; + func (ex); +} +#endif + + /* orc_downsample_u8 */ #ifdef DISABLE_ORC void @@ -1510,7 +1587,7 @@ gst_videoscale_orc_merge_bicubic_u8 (guint8 * d1, const guint8 * s1, /* 12: loadpb */ var41 = p4; /* 15: loadpw */ - var42.i = 0x00000020; /* 32 or 1.58101e-322f */ + var42.i = (int) 0x00000020; /* 32 or 1.58101e-322f */ for (i = 0; i < n; i++) { /* 0: loadb */ @@ -1593,7 +1670,7 @@ _backup_gst_videoscale_orc_merge_bicubic_u8 (OrcExecutor * ORC_RESTRICT ex) /* 12: loadpb */ var41 = ex->params[27]; /* 15: loadpw */ - var42.i = 0x00000020; /* 32 or 1.58101e-322f */ + var42.i = (int) 0x00000020; /* 32 or 1.58101e-322f */ for (i = 0; i < n; i++) { /* 0: loadb */ @@ -1770,6 +1847,24 @@ gst_videoscale_orc_init (void) _orc_program_orc_splat_u32 = p; } + { + /* orc_splat_u64 */ + OrcProgram *p; + OrcCompileResult result; + + p = orc_program_new (); + orc_program_set_name (p, "orc_splat_u64"); + orc_program_set_backup_function (p, _backup_orc_splat_u64); + orc_program_add_destination (p, 8, "d1"); + orc_program_add_parameter_int64 (p, 8, "p1"); + + orc_program_append_2 (p, "copyq", 0, ORC_VAR_D1, ORC_VAR_P1, ORC_VAR_D1, + ORC_VAR_D1); + + result = orc_program_compile (p); + + _orc_program_orc_splat_u64 = p; + } { /* orc_downsample_u8 */ OrcProgram *p; diff --git a/gst/videoscale/gstvideoscaleorc-dist.h b/gst/videoscale/gstvideoscaleorc-dist.h index df1de1d2b6..93157f09cb 100644 --- a/gst/videoscale/gstvideoscaleorc-dist.h +++ b/gst/videoscale/gstvideoscaleorc-dist.h @@ -37,6 +37,7 @@ typedef unsigned __int16 orc_uint16; typedef unsigned __int32 orc_uint32; typedef unsigned __int64 orc_uint64; #define ORC_UINT64_C(x) (x##Ui64) +#define inline __inline #else #include typedef signed char orc_int8; @@ -63,6 +64,7 @@ void orc_merge_linear_u8 (orc_uint8 * d1, const orc_uint8 * s1, const orc_uint8 void orc_merge_linear_u16 (orc_uint16 * d1, const orc_uint16 * s1, const orc_uint16 * s2, int p1, int p2, int n); void orc_splat_u16 (orc_uint16 * d1, int p1, int n); void orc_splat_u32 (orc_uint32 * d1, int p1, int n); +void orc_splat_u64 (orc_uint64 * d1, orc_int64 p1, int n); void orc_downsample_u8 (guint8 * d1, const guint8 * s1, int n); void orc_downsample_u16 (guint16 * d1, const guint16 * s1, int n); void gst_videoscale_orc_downsample_u32 (guint8 * d1, const guint8 * s1, int n); diff --git a/gst/videoscale/gstvideoscaleorc.orc b/gst/videoscale/gstvideoscaleorc.orc index 17d9687101..81623e231b 100644 --- a/gst/videoscale/gstvideoscaleorc.orc +++ b/gst/videoscale/gstvideoscaleorc.orc @@ -54,6 +54,13 @@ copyw d1, p1 copyl d1, p1 +.function orc_splat_u64 +.dest 8 d1 +.longparam 8 p1 + +copyq d1, p1 + + .function orc_downsample_u8 .dest 1 d1 guint8 .source 2 s1 guint8 diff --git a/gst/videoscale/vs_4tap.c b/gst/videoscale/vs_4tap.c index a210371d8c..e582f7c304 100644 --- a/gst/videoscale/vs_4tap.c +++ b/gst/videoscale/vs_4tap.c @@ -1324,3 +1324,128 @@ vs_image_scale_4tap_RGB555 (const VSImage * dest, const VSImage * src, yacc += y_increment; } } + +void +vs_scanline_resample_4tap_AYUV64 (uint16_t * dest, uint16_t * src, + int n, int src_width, int *xacc, int increment) +{ + int i; + int j; + int acc; + int x; + int y; + int off; + + acc = *xacc; + for (i = 0; i < n; i++) { + j = acc >> 16; + x = (acc & 0xffff) >> 8; + + for (off = 0; off < 4; off++) { + if (j - 1 >= 0 && j + 2 < src_width) { + y = vs_4tap_taps[x][0] * src[MAX ((j - 1) * 4 + off, 0)]; + y += vs_4tap_taps[x][1] * src[j * 4 + off]; + y += vs_4tap_taps[x][2] * src[(j + 1) * 4 + off]; + y += vs_4tap_taps[x][3] * src[(j + 2) * 4 + off]; + } else { + y = vs_4tap_taps[x][0] * src[CLAMP ((j - 1) * 4 + off, 0, + 4 * (src_width - 1) + off)]; + y += vs_4tap_taps[x][1] * src[CLAMP (j * 4 + off, 0, + 4 * (src_width - 1) + off)]; + y += vs_4tap_taps[x][2] * src[CLAMP ((j + 1) * 4 + off, 0, + 4 * (src_width - 1) + off)]; + y += vs_4tap_taps[x][3] * src[CLAMP ((j + 2) * 4 + off, 0, + 4 * (src_width - 1) + off)]; + } + y += (1 << (SHIFT - 1)); + dest[i * 4 + off] = CLAMP (y >> SHIFT, 0, 255); + } + acc += increment; + } + *xacc = acc; +} + +void +vs_scanline_merge_4tap_AYUV64 (uint16_t * dest, uint16_t * src1, + uint16_t * src2, uint16_t * src3, uint16_t * src4, int n, int acc) +{ + int i; + int y; + int off; + int a, b, c, d; + + acc = (acc >> 8) & 0xff; + a = vs_4tap_taps[acc][0]; + b = vs_4tap_taps[acc][1]; + c = vs_4tap_taps[acc][2]; + d = vs_4tap_taps[acc][3]; + for (i = 0; i < n; i++) { + for (off = 0; off < 4; off++) { + y = a * src1[i * 4 + off]; + y += b * src2[i * 4 + off]; + y += c * src3[i * 4 + off]; + y += d * src4[i * 4 + off]; + y += (1 << (SHIFT - 1)); + dest[i * 4 + off] = CLAMP (y >> SHIFT, 0, 65535); + } + } +} + +void +vs_image_scale_4tap_AYUV64 (const VSImage * dest, const VSImage * src, + uint8_t * tmpbuf8) +{ + int yacc; + int y_increment; + int x_increment; + int i; + int j; + int xacc; + int k; + guint16 *tmpbuf = (guint16 *) tmpbuf8; + + if (dest->height == 1) + y_increment = 0; + else + y_increment = ((src->height - 1) << 16) / (dest->height - 1); + + if (dest->width == 1) + x_increment = 0; + else + x_increment = ((src->width - 1) << 16) / (dest->width - 1); + + k = 0; + for (i = 0; i < 4; i++) { + xacc = 0; + vs_scanline_resample_4tap_AYUV64 ((guint16 *) (tmpbuf + i * dest->stride), + (guint16 *) (src->pixels + i * src->stride), dest->width, src->width, + &xacc, x_increment); + } + + yacc = 0; + for (i = 0; i < dest->height; i++) { + uint16_t *t0, *t1, *t2, *t3; + + j = yacc >> 16; + + while (j > k) { + k++; + if (k + 3 < src->height) { + xacc = 0; + vs_scanline_resample_4tap_AYUV64 ((guint16 *) (tmpbuf + ((k + + 3) & 3) * dest->stride), + (guint16 *) (src->pixels + (k + 3) * src->stride), dest->width, + src->width, &xacc, x_increment); + } + } + + t0 = tmpbuf + (CLAMP (j - 1, 0, src->height - 1) & 3) * dest->stride; + t1 = tmpbuf + (CLAMP (j, 0, src->height - 1) & 3) * dest->stride; + t2 = tmpbuf + (CLAMP (j + 1, 0, src->height - 1) & 3) * dest->stride; + t3 = tmpbuf + (CLAMP (j + 2, 0, src->height - 1) & 3) * dest->stride; + vs_scanline_merge_4tap_AYUV64 ((guint16 *) (dest->pixels + + i * dest->stride), t0, t1, t2, t3, dest->width, yacc & 0xffff); + + yacc += y_increment; + } +} diff --git a/gst/videoscale/vs_4tap.h b/gst/videoscale/vs_4tap.h index ba1ffee7ee..6b51b52e5e 100644 --- a/gst/videoscale/vs_4tap.h +++ b/gst/videoscale/vs_4tap.h @@ -88,5 +88,12 @@ void vs_scanline_merge_4tap_Y16 (uint8_t *dest, uint8_t *src1, uint8_t *src2, void vs_image_scale_4tap_Y16 (const VSImage * dest, const VSImage * src, uint8_t * tmpbuf); +void vs_scanline_resample_4tap_AYUV64 (uint16_t *dest, uint16_t *src, + int n, int src_width, int *xacc, int increment); +void vs_scanline_merge_4tap_AYUV64 (uint16_t *dest, uint16_t *src1, uint16_t *src2, + uint16_t *src3, uint16_t *src4, int n, int acc); +void vs_image_scale_4tap_AYUV64 (const VSImage * dest, const VSImage * src, + uint8_t * tmpbuf); + #endif diff --git a/gst/videoscale/vs_fill_borders.c b/gst/videoscale/vs_fill_borders.c index b796031dcd..160e137de1 100644 --- a/gst/videoscale/vs_fill_borders.c +++ b/gst/videoscale/vs_fill_borders.c @@ -379,3 +379,44 @@ vs_fill_borders_RGB555 (const VSImage * dest, const uint8_t * val) data += stride; } } + +void +vs_fill_borders_AYUV64 (const VSImage * dest, const uint8_t * val) +{ + int i; + int top = dest->border_top, bottom = dest->border_bottom; + int left = dest->border_left, right = dest->border_right; + int width = dest->width; + int height = dest->height; + int real_width = dest->real_width; + int stride = dest->stride; + int tmp, tmp2; + uint8_t *data; + uint64_t v; + + v = (val[0] << 8) | (val[1] << 24) | (((guint64) val[2]) << 40) | (((guint64) + val[3]) << 56); + + data = dest->real_pixels; + for (i = 0; i < top; i++) { + orc_splat_u64 ((uint64_t *) data, v, real_width); + data += stride; + } + + if (left || right) { + tmp = height; + tmp2 = (left + width) * 8; + for (i = 0; i < tmp; i++) { + orc_splat_u64 ((uint64_t *) data, v, left); + orc_splat_u64 ((uint64_t *) (data + tmp2), v, right); + data += stride; + } + } else { + data += stride * height; + } + + for (i = 0; i < bottom; i++) { + orc_splat_u64 ((uint64_t *) data, v, real_width); + data += stride; + } +} diff --git a/gst/videoscale/vs_fill_borders.h b/gst/videoscale/vs_fill_borders.h index 84d0be32cd..faf00db6c3 100644 --- a/gst/videoscale/vs_fill_borders.h +++ b/gst/videoscale/vs_fill_borders.h @@ -39,5 +39,6 @@ void vs_fill_borders_Y (const VSImage *dest, const uint8_t *val); void vs_fill_borders_Y16 (const VSImage *dest, const uint16_t val); void vs_fill_borders_RGB565 (const VSImage *dest, const uint8_t *val); void vs_fill_borders_RGB555 (const VSImage *dest, const uint8_t *val); +void vs_fill_borders_AYUV64 (const VSImage *dest, const uint8_t *val); #endif /* __VS_FILL_BORDERS_H__ */ diff --git a/gst/videoscale/vs_image.c b/gst/videoscale/vs_image.c index 1cc2211141..bff8ac767c 100644 --- a/gst/videoscale/vs_image.c +++ b/gst/videoscale/vs_image.c @@ -1047,3 +1047,121 @@ vs_image_scale_linear_RGB555 (const VSImage * dest, const VSImage * src, acc += y_increment; } } + +void +vs_image_scale_nearest_AYUV64 (const VSImage * dest, const VSImage * src, + uint8_t * tmpbuf8) +{ + int acc; + int y_increment; + int x_increment; + int i; + int j; + int prev_j; + + if (dest->height == 1) + y_increment = 0; + else + y_increment = ((src->height - 1) << 16) / (dest->height - 1); + + if (dest->width == 1) + x_increment = 0; + else + x_increment = ((src->width - 1) << 16) / (dest->width - 1); + + + acc = 0; + prev_j = -1; + for (i = 0; i < dest->height; i++) { + j = acc >> 16; + + if (j == prev_j) { + memcpy (dest->pixels + i * dest->stride, + dest->pixels + (i - 1) * dest->stride, dest->width * 8); + } else { + int xacc = 0; + vs_scanline_resample_nearest_AYUV64 (dest->pixels + i * dest->stride, + src->pixels + j * src->stride, src->width, dest->width, &xacc, + x_increment); + } + + prev_j = j; + acc += y_increment; + } +} + +void +vs_image_scale_linear_AYUV64 (const VSImage * dest, const VSImage * src, + uint8_t * tmpbuf) +{ + int acc; + int y_increment; + int x_increment; + int y1; + int y2; + int i; + int j; + int x; + int dest_size; + int xacc; + + if (dest->height == 1) + y_increment = 0; + else + y_increment = ((src->height - 1) << 16) / (dest->height - 1); + + if (dest->width == 1) + x_increment = 0; + else + x_increment = ((src->width - 1) << 16) / (dest->width - 1); + + dest_size = dest->width * 8; + +#undef LINE +#define LINE(x) ((guint16 *)((tmpbuf) + (dest_size)*((x)&1))) + + acc = 0; + y2 = -1; + //gst_videoscale_orc_resample_bilinear_u64 (LINE (0), src->pixels, + // 0, x_increment, dest->width); + xacc = 0; + vs_scanline_resample_linear_AYUV64 ((guint8 *) LINE (0), + src->pixels, src->width, dest->width, &xacc, x_increment); + y1 = 0; + for (i = 0; i < dest->height; i++) { + j = acc >> 16; + x = acc & 0xffff; + + if (x == 0) { + memcpy (dest->pixels + i * dest->stride, LINE (j), dest_size); + } else { + if (j > y1) { + xacc = 0; + vs_scanline_resample_linear_AYUV64 ((guint8 *) LINE (j), + src->pixels + j * src->stride, src->width, dest->width, &xacc, + x_increment); + //gst_videoscale_orc_resample_bilinear_u64 (LINE (j), + // src->pixels + j * src->stride, 0, x_increment, dest->width); + y1++; + } + if (j >= y1) { + xacc = 0; + vs_scanline_resample_linear_AYUV64 ((guint8 *) LINE (j + 1), + src->pixels + (j + 1) * src->stride, src->width, dest->width, &xacc, + x_increment); + orc_merge_linear_u16 ((guint16 *) (dest->pixels + i * dest->stride), + LINE (j), LINE (j + 1), 65536 - x, x, dest->width * 4); + //gst_videoscale_orc_resample_merge_bilinear_u64 (dest->pixels + + // i * dest->stride, LINE (j + 1), LINE (j), + // src->pixels + (j + 1) * src->stride, (x >> 8), 0, x_increment, + // dest->width); + y1++; + } else { + orc_merge_linear_u16 ((guint16 *) (dest->pixels + i * dest->stride), + LINE (j), LINE (j + 1), 65536 - x, x, dest->width * 4); + } + } + + acc += y_increment; + } +} diff --git a/gst/videoscale/vs_image.h b/gst/videoscale/vs_image.h index 23f12805c9..3a23dd44f5 100644 --- a/gst/videoscale/vs_image.h +++ b/gst/videoscale/vs_image.h @@ -84,5 +84,15 @@ void vs_image_scale_nearest_Y16 (const VSImage *dest, const VSImage *src, void vs_image_scale_linear_Y16 (const VSImage *dest, const VSImage *src, uint8_t *tmpbuf); +void vs_image_scale_nearest_AYUV16 (const VSImage *dest, const VSImage *src, + uint8_t *tmpbuf); +void vs_image_scale_linear_AYUV16 (const VSImage *dest, const VSImage *src, + uint8_t *tmpbuf); + +void vs_image_scale_nearest_AYUV64 (const VSImage * dest, const VSImage * src, + uint8_t * tmpbuf8); +void vs_image_scale_linear_AYUV64 (const VSImage * dest, const VSImage * src, + uint8_t * tmpbuf8); + #endif diff --git a/gst/videoscale/vs_scanline.c b/gst/videoscale/vs_scanline.c index cfe02b63a9..822a6b6600 100644 --- a/gst/videoscale/vs_scanline.c +++ b/gst/videoscale/vs_scanline.c @@ -713,3 +713,69 @@ vs_scanline_merge_linear_RGB555 (uint8_t * dest_u8, uint8_t * src1_u8, (RGB555_B (src1[i]) * (65536 - x) + RGB555_B (src2[i]) * x) >> 16); } } + +void +vs_scanline_resample_nearest_AYUV64 (uint8_t * dest8, uint8_t * src8, + int src_width, int n, int *accumulator, int increment) +{ + guint16 *dest = (guint16 *) dest8; + guint16 *src = (guint16 *) src8; + int acc = *accumulator; + int i; + int j; + int x; + + for (i = 0; i < n; i++) { + j = acc >> 16; + x = acc & 0xffff; + dest[i * 4 + 0] = (x < 32768 + || j + 1 >= src_width) ? src[j * 4 + 0] : src[j * 4 + 4]; + dest[i * 4 + 1] = (x < 32768 + || j + 1 >= src_width) ? src[j * 4 + 1] : src[j * 4 + 5]; + dest[i * 4 + 2] = (x < 32768 + || j + 1 >= src_width) ? src[j * 4 + 2] : src[j * 4 + 6]; + dest[i * 4 + 3] = (x < 32768 + || j + 1 >= src_width) ? src[j * 4 + 3] : src[j * 4 + 7]; + + acc += increment; + } + + *accumulator = acc; +} + +void +vs_scanline_resample_linear_AYUV64 (uint8_t * dest8, uint8_t * src8, + int src_width, int n, int *accumulator, int increment) +{ + guint16 *dest = (guint16 *) dest8; + guint16 *src = (guint16 *) src8; + int acc = *accumulator; + int i; + int j; + int x; + + for (i = 0; i < n; i++) { + j = acc >> 16; + x = (acc & 0xffff) >> 1; + + if (j + 1 < src_width) { + dest[i * 4 + 0] = + (src[j * 3 + 0] * (32768 - x) + src[j * 4 + 4] * x) >> 15; + dest[i * 4 + 1] = + (src[j * 4 + 1] * (32768 - x) + src[j * 4 + 5] * x) >> 15; + dest[i * 4 + 2] = + (src[j * 4 + 2] * (32768 - x) + src[j * 4 + 6] * x) >> 15; + dest[i * 4 + 3] = + (src[j * 4 + 3] * (32768 - x) + src[j * 4 + 7] * x) >> 15; + } else { + dest[i * 4 + 0] = src[j * 4 + 0]; + dest[i * 4 + 1] = src[j * 4 + 1]; + dest[i * 4 + 2] = src[j * 4 + 2]; + dest[i * 4 + 3] = src[j * 4 + 3]; + } + + acc += increment; + } + + *accumulator = acc; +} diff --git a/gst/videoscale/vs_scanline.h b/gst/videoscale/vs_scanline.h index e3589696c3..387fc9511b 100644 --- a/gst/videoscale/vs_scanline.h +++ b/gst/videoscale/vs_scanline.h @@ -70,5 +70,10 @@ void vs_scanline_resample_nearest_Y16 (uint8_t *dest, uint8_t *src, int n, int s void vs_scanline_resample_linear_Y16 (uint8_t *dest, uint8_t *src, int n, int src_width, int *accumulator, int increment); void vs_scanline_merge_linear_Y16 (uint8_t *dest, uint8_t *src1, uint8_t *src2, int n, int x); +void vs_scanline_resample_nearest_AYUV64 (uint8_t * dest, uint8_t * src, + int src_width, int n, int *accumulator, int increment); +void vs_scanline_resample_linear_AYUV64 (uint8_t * dest, uint8_t * src, + int src_width, int n, int *accumulator, int increment); + #endif From 6d150873e8b4c23d694b0351570de323b1576d76 Mon Sep 17 00:00:00 2001 From: David Schleef Date: Sun, 20 Feb 2011 23:49:54 -0800 Subject: [PATCH 223/254] oggmux,adder: Check if collectpads has been freed Core now calls release_pad in finalize, which is usually after the collectpads has been unreffed. --- ext/ogg/gstoggmux.c | 4 +++- gst/adder/gstadder.c | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/ext/ogg/gstoggmux.c b/ext/ogg/gstoggmux.c index c6ed67c72a..35e4448000 100644 --- a/ext/ogg/gstoggmux.c +++ b/ext/ogg/gstoggmux.c @@ -462,7 +462,9 @@ gst_ogg_mux_release_pad (GstElement * element, GstPad * pad) ogg_mux = GST_OGG_MUX (gst_pad_get_parent (pad)); - gst_collect_pads_remove_pad (ogg_mux->collect, pad); + if (ogg_mux->collect) { + gst_collect_pads_remove_pad (ogg_mux->collect, pad); + } gst_element_remove_pad (element, pad); gst_object_unref (ogg_mux); diff --git a/gst/adder/gstadder.c b/gst/adder/gstadder.c index ab2abd7022..987adbd287 100644 --- a/gst/adder/gstadder.c +++ b/gst/adder/gstadder.c @@ -991,7 +991,9 @@ gst_adder_release_pad (GstElement * element, GstPad * pad) GST_DEBUG_OBJECT (adder, "release pad %s:%s", GST_DEBUG_PAD_NAME (pad)); - gst_collect_pads_remove_pad (adder->collect, pad); + if (adder->collect) { + gst_collect_pads_remove_pad (adder->collect, pad); + } gst_element_remove_pad (element, pad); } From 3fe2777b546acd9bf510d5098b3a8b4a8f2430d5 Mon Sep 17 00:00:00 2001 From: Edward Hervey Date: Mon, 21 Feb 2011 12:04:09 +0100 Subject: [PATCH 224/254] Revert "oggmux,adder: Check if collectpads has been freed" This reverts commit 6d150873e8b4c23d694b0351570de323b1576d76. Depends on a core commit that was reverted. --- ext/ogg/gstoggmux.c | 4 +--- gst/adder/gstadder.c | 4 +--- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/ext/ogg/gstoggmux.c b/ext/ogg/gstoggmux.c index 35e4448000..c6ed67c72a 100644 --- a/ext/ogg/gstoggmux.c +++ b/ext/ogg/gstoggmux.c @@ -462,9 +462,7 @@ gst_ogg_mux_release_pad (GstElement * element, GstPad * pad) ogg_mux = GST_OGG_MUX (gst_pad_get_parent (pad)); - if (ogg_mux->collect) { - gst_collect_pads_remove_pad (ogg_mux->collect, pad); - } + gst_collect_pads_remove_pad (ogg_mux->collect, pad); gst_element_remove_pad (element, pad); gst_object_unref (ogg_mux); diff --git a/gst/adder/gstadder.c b/gst/adder/gstadder.c index 987adbd287..ab2abd7022 100644 --- a/gst/adder/gstadder.c +++ b/gst/adder/gstadder.c @@ -991,9 +991,7 @@ gst_adder_release_pad (GstElement * element, GstPad * pad) GST_DEBUG_OBJECT (adder, "release pad %s:%s", GST_DEBUG_PAD_NAME (pad)); - if (adder->collect) { - gst_collect_pads_remove_pad (adder->collect, pad); - } + gst_collect_pads_remove_pad (adder->collect, pad); gst_element_remove_pad (element, pad); } From bb0dc56114eac01f4f09c4c58cdf9243a3947928 Mon Sep 17 00:00:00 2001 From: Mark Nauwelaerts Date: Mon, 21 Feb 2011 12:27:17 +0100 Subject: [PATCH 225/254] videorate: fix skip-to-first ts setup ... such as avoiding arithmetic mixing counts and ts, although latter would typically be 0 so far. --- gst/videorate/gstvideorate.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/gst/videorate/gstvideorate.c b/gst/videorate/gstvideorate.c index a0642c210c..2797d8ab47 100644 --- a/gst/videorate/gstvideorate.c +++ b/gst/videorate/gstvideorate.c @@ -795,11 +795,9 @@ gst_video_rate_chain (GstPad * pad, GstBuffer * buffer) /* new buffer, we expect to output a buffer that matches the first * timestamp in the segment */ if (videorate->skip_to_first) { - videorate->next_ts = in_ts; - videorate->out_frame_count = gst_util_uint64_scale (in_ts, - videorate->to_rate_numerator, - videorate->to_rate_denominator * GST_SECOND) - - (videorate->segment.accum + videorate->segment.start); + videorate->next_ts = intime; + videorate->base_ts = in_ts - videorate->segment.start; + videorate->out_frame_count = 0; } else { videorate->next_ts = videorate->segment.start + videorate->segment.accum; From d17c4c28d53b17986118a8d12aa926892fe86b1c Mon Sep 17 00:00:00 2001 From: Mark Nauwelaerts Date: Mon, 21 Feb 2011 12:40:36 +0100 Subject: [PATCH 226/254] audiorate: add skip-to-first property API: GstAudioRate::skip-to-first --- gst/audiorate/gstaudiorate.c | 31 ++++++++++++++++++++++++++++++- gst/audiorate/gstaudiorate.h | 1 + 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/gst/audiorate/gstaudiorate.c b/gst/audiorate/gstaudiorate.c index 057115d823..40d3467a94 100644 --- a/gst/audiorate/gstaudiorate.c +++ b/gst/audiorate/gstaudiorate.c @@ -78,6 +78,7 @@ enum #define DEFAULT_SILENT TRUE #define DEFAULT_TOLERANCE 0 +#define DEFAULT_SKIP_TO_FIRST FALSE enum { @@ -88,7 +89,7 @@ enum ARG_DROP, ARG_SILENT, ARG_TOLERANCE, - /* FILL ME */ + ARG_SKIP_TO_FIRST }; static GstStaticPadTemplate gst_audio_rate_src_template = @@ -212,6 +213,18 @@ gst_audio_rate_class_init (GstAudioRateClass * klass) 0, G_MAXUINT64, DEFAULT_TOLERANCE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + /** + * GstAudioRate:skip-to-first: + * + * Don't produce buffers before the first one we receive. + * + * Since: 0.10.33 + **/ + g_object_class_install_property (object_class, ARG_SKIP_TO_FIRST, + g_param_spec_boolean ("skip-to-first", "Skip to first buffer", + "Don't produce buffers before the first one we receive", + DEFAULT_SKIP_TO_FIRST, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + element_class->change_state = gst_audio_rate_change_state; } @@ -556,6 +569,16 @@ gst_audio_rate_chain (GstPad * pad, GstBuffer * buf) audiorate->next_offset = pos; audiorate->next_ts = gst_util_uint64_scale_int (audiorate->next_offset, GST_SECOND, audiorate->rate); + + if (audiorate->skip_to_first && GST_BUFFER_TIMESTAMP_IS_VALID (buf)) { + GST_DEBUG_OBJECT (audiorate, "but skipping to first buffer instead"); + pos = gst_util_uint64_scale_int (GST_BUFFER_TIMESTAMP (buf), + audiorate->rate, GST_SECOND); + GST_DEBUG_OBJECT (audiorate, "so resync to offset %" G_GINT64_FORMAT, + pos); + audiorate->next_offset = pos; + audiorate->next_ts = GST_BUFFER_TIMESTAMP (buf); + } } audiorate->in++; @@ -768,6 +791,9 @@ gst_audio_rate_set_property (GObject * object, case ARG_TOLERANCE: audiorate->tolerance = g_value_get_uint64 (value); break; + case ARG_SKIP_TO_FIRST: + audiorate->skip_to_first = g_value_get_boolean (value); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -799,6 +825,9 @@ gst_audio_rate_get_property (GObject * object, case ARG_TOLERANCE: g_value_set_uint64 (value, audiorate->tolerance); break; + case ARG_SKIP_TO_FIRST: + g_value_set_boolean (value, audiorate->skip_to_first); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; diff --git a/gst/audiorate/gstaudiorate.h b/gst/audiorate/gstaudiorate.h index bcc087bda3..e55bbcfc79 100644 --- a/gst/audiorate/gstaudiorate.h +++ b/gst/audiorate/gstaudiorate.h @@ -58,6 +58,7 @@ struct _GstAudioRate guint64 in, out, add, drop; gboolean silent; guint64 tolerance; + gboolean skip_to_first; /* audio state */ guint64 next_offset; From 6213f1f3b1d2edfeb923e77a18c5977eba39fa5d Mon Sep 17 00:00:00 2001 From: Benjamin Otte Date: Mon, 21 Feb 2011 18:00:02 +0100 Subject: [PATCH 227/254] rtsp: Fix copy/paste error in inrospection part of Makefile --- gst-libs/gst/rtsp/Makefile.am | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gst-libs/gst/rtsp/Makefile.am b/gst-libs/gst/rtsp/Makefile.am index 87a2ecd7fd..a26b527dad 100644 --- a/gst-libs/gst/rtsp/Makefile.am +++ b/gst-libs/gst/rtsp/Makefile.am @@ -56,8 +56,8 @@ gir_headers=$(patsubst %,$(srcdir)/%, $(libgstrtspinclude_HEADERS)) gir_headers+=$(patsubst %,$(builddir)/%, $(nodist_libgstrtspinclude_HEADERS)) gir_sources=$(patsubst %,$(srcdir)/%, $(libgstrtsp_@GST_MAJORMINOR@_la_SOURCES)) gir_sources+=$(patsubst %,$(builddir)/%, $(nodist_libgstrtsp_@GST_MAJORMINOR@_la_SOURCES)) -gir_cincludes=$(patsubst %,--c-include='gst/audio/%',$(libgstrtspinclude_HEADERS)) -gir_cincludes+=$(patsubst %,--c-include='gst/audio/%',$(nodist_libgstrtspinclude_HEADERS)) +gir_cincludes=$(patsubst %,--c-include='gst/rtsp/%',$(libgstrtspinclude_HEADERS)) +gir_cincludes+=$(patsubst %,--c-include='gst/rtsp/%',$(nodist_libgstrtspinclude_HEADERS)) GstRtsp-@GST_MAJORMINOR@.gir: $(INTROSPECTION_SCANNER) libgstrtsp-@GST_MAJORMINOR@.la $(AM_V_GEN)PKG_CONFIG_PATH="$(GST_PKG_CONFIG_PATH)" \ From 11f7e808ac683527fd4003cee2669683e35e3a3a Mon Sep 17 00:00:00 2001 From: Benjamin Otte Date: Mon, 21 Feb 2011 18:00:36 +0100 Subject: [PATCH 228/254] tag: Fix copy/paste error in inrospection part of Makefile --- gst-libs/gst/tag/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gst-libs/gst/tag/Makefile.am b/gst-libs/gst/tag/Makefile.am index 9e82463703..15263dd49e 100644 --- a/gst-libs/gst/tag/Makefile.am +++ b/gst-libs/gst/tag/Makefile.am @@ -23,7 +23,7 @@ BUILT_GIRSOURCES = GstTag-@GST_MAJORMINOR@.gir gir_headers=$(patsubst %,$(srcdir)/%, $(libgsttaginclude_HEADERS)) gir_sources=$(patsubst %,$(srcdir)/%, $(libgsttag_@GST_MAJORMINOR@_la_SOURCES)) -gir_cincludes=$(patsubst %,--c-include='gst/audio/%',$(libgsttainclude_HEADERS)) +gir_cincludes=$(patsubst %,--c-include='gst/tag/%',$(libgsttaginclude_HEADERS)) GstTag-@GST_MAJORMINOR@.gir: $(INTROSPECTION_SCANNER) libgsttag-@GST_MAJORMINOR@.la $(AM_V_GEN)PKG_CONFIG_PATH="$(GST_PKG_CONFIG_PATH)" \ From 2cc48b62fe95c13377f172e7519908285e507999 Mon Sep 17 00:00:00 2001 From: Benjamin Otte Date: Mon, 21 Feb 2011 18:01:04 +0100 Subject: [PATCH 229/254] sdp: Fix copy/paste error in inrospection part of Makefile --- gst-libs/gst/sdp/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gst-libs/gst/sdp/Makefile.am b/gst-libs/gst/sdp/Makefile.am index fd8017e98a..55480ebb22 100644 --- a/gst-libs/gst/sdp/Makefile.am +++ b/gst-libs/gst/sdp/Makefile.am @@ -16,7 +16,7 @@ BUILT_GIRSOURCES = GstSdp-@GST_MAJORMINOR@.gir gir_headers=$(patsubst %,$(srcdir)/%, $(libgstsdpinclude_HEADERS)) gir_sources=$(patsubst %,$(srcdir)/%, $(libgstsdp_@GST_MAJORMINOR@_la_SOURCES)) -gir_cincludes=$(patsubst %,--c-include='gst/audio/%',$(libgstsdpinclude_HEADERS)) +gir_cincludes=$(patsubst %,--c-include='gst/sdp/%',$(libgstsdpinclude_HEADERS)) GstSdp-@GST_MAJORMINOR@.gir: $(INTROSPECTION_SCANNER) libgstsdp-@GST_MAJORMINOR@.la $(AM_V_GEN)PKG_CONFIG_PATH="$(GST_PKG_CONFIG_PATH)" \ From 01168b83cfd2f73e5f93d24fd5ab25b8dee7e7e1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim-Philipp=20M=C3=BCller?= Date: Mon, 21 Feb 2011 17:55:04 +0000 Subject: [PATCH 230/254] tests: fix videoscale test by ignoring newly-added 64-bit formats They probably fail because ffmpegcolorspace can't handle those formats. --- tests/check/elements/videoscale.c | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/tests/check/elements/videoscale.c b/tests/check/elements/videoscale.c index f8a38eb510..75f16dfdca 100644 --- a/tests/check/elements/videoscale.c +++ b/tests/check/elements/videoscale.c @@ -68,6 +68,24 @@ on_sink_handoff (GstElement * element, GstBuffer * buffer, GstPad * pad, *n_buffers = *n_buffers + 1; } +static gboolean +caps_are_64bpp (const GstCaps * caps) +{ + GstVideoFormat fmt; + GstCaps *fmt_caps; + + /* need fixed caps for _parse_caps */ + fmt_caps = gst_caps_copy (caps); + gst_structure_remove_field (gst_caps_get_structure (fmt_caps, 0), "width"); + gst_structure_remove_field (gst_caps_get_structure (fmt_caps, 0), "height"); + gst_structure_remove_field (gst_caps_get_structure (fmt_caps, 0), + "framerate"); + + fail_unless (gst_video_format_parse_caps (fmt_caps, &fmt, NULL, NULL)); + gst_caps_unref (fmt_caps); + return (fmt == GST_VIDEO_FORMAT_ARGB64 || fmt == GST_VIDEO_FORMAT_AYUV64); +} + static void run_test (const GstCaps * caps, gint src_width, gint src_height, gint dest_width, gint dest_height, gint method, @@ -82,6 +100,10 @@ run_test (const GstCaps * caps, gint src_width, gint src_height, GstCaps *copy; guint n_buffers = 0; + /* skip formats that ffmpegcolorspace can't handle */ + if (caps_are_64bpp (caps)) + return; + pipeline = gst_element_factory_make ("pipeline", "pipeline"); fail_unless (pipeline != NULL); @@ -198,6 +220,10 @@ GST_START_TEST (test_passthrough) GstCaps *caps = *p; for (method = 0; method < 3; method++) { + /* skip formats that ffmpegcolorspace can't handle */ + if (caps_are_64bpp (caps)) + continue; + GST_DEBUG ("Running test for caps '%" GST_PTR_FORMAT "'" " from %dx%u to %dx%d with method %d", caps, src_width, src_height, dest_width, dest_height, method); @@ -251,7 +277,6 @@ GST_START_TEST (name) \ run_test (caps, src_width, src_height, \ dest_width, dest_height, method, \ NULL, NULL, NULL, NULL); \ - \ gst_caps_unref (caps); \ p++; \ } \ @@ -787,6 +812,7 @@ videoscale_suite (void) tcase_add_test (tc_chain, test_negotiation); tcase_add_test (tc_chain, test_reverse_negotiation); + GST_ERROR ("FIXME: test 64-bpp formats as well"); return s; } From 17fddc13d2bded11bb52e7698230c69e514a8345 Mon Sep 17 00:00:00 2001 From: Teemu Katajisto Date: Mon, 21 Feb 2011 15:58:16 +0200 Subject: [PATCH 231/254] pbutils: encoding-target: fix error checking in target file loading https://bugzilla.gnome.org/show_bug.cgi?id=642949 --- gst-libs/gst/pbutils/encoding-target.c | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/gst-libs/gst/pbutils/encoding-target.c b/gst-libs/gst/pbutils/encoding-target.c index 2e92173863..b7e7ad545b 100644 --- a/gst-libs/gst/pbutils/encoding-target.c +++ b/gst-libs/gst/pbutils/encoding-target.c @@ -707,6 +707,9 @@ load_file_and_read_header (const gchar * path, gchar ** targetname, { GKeyFile *in; gboolean res; + GError *key_error = NULL; + + g_return_val_if_fail (error == NULL || *error == NULL, NULL); in = g_key_file_new (); @@ -714,12 +717,13 @@ load_file_and_read_header (const gchar * path, gchar ** targetname, res = g_key_file_load_from_file (in, path, - G_KEY_FILE_KEEP_COMMENTS | G_KEY_FILE_KEEP_TRANSLATIONS, error); - if (!res || error != NULL) + G_KEY_FILE_KEEP_COMMENTS | G_KEY_FILE_KEEP_TRANSLATIONS, &key_error); + if (!res || key_error != NULL) goto load_error; + key_error = NULL; *targetname = - g_key_file_get_value (in, GST_ENCODING_TARGET_HEADER, "name", error); + g_key_file_get_value (in, GST_ENCODING_TARGET_HEADER, "name", &key_error); if (!*targetname) goto empty_name; @@ -734,14 +738,16 @@ load_file_and_read_header (const gchar * path, gchar ** targetname, load_error: { GST_WARNING ("Unable to read GstEncodingTarget file %s: %s", - path, (*error)->message); + path, key_error->message); + g_propagate_error (error, key_error); g_key_file_free (in); return NULL; } empty_name: { - GST_WARNING ("Wrong header in file %s: %s", path, (*error)->message); + GST_WARNING ("Wrong header in file %s: %s", path, key_error->message); + g_propagate_error (error, key_error); g_key_file_free (in); return NULL; } From 0ebc34adf94caf2476a18d7188341a903a4b2227 Mon Sep 17 00:00:00 2001 From: Parthasarathi Susarla Date: Thu, 10 Feb 2011 03:22:42 +1100 Subject: [PATCH 232/254] typefinding: detect raw h.263 https://bugzilla.gnome.org/show_bug.cgi?id=623846 --- gst/typefind/gsttypefindfunctions.c | 56 +++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) diff --git a/gst/typefind/gsttypefindfunctions.c b/gst/typefind/gsttypefindfunctions.c index 1180930ce3..2b35330f52 100644 --- a/gst/typefind/gsttypefindfunctions.c +++ b/gst/typefind/gsttypefindfunctions.c @@ -2125,6 +2125,59 @@ mpeg4_video_type_find (GstTypeFind * tf, gpointer unused) } } +/*** video/x-h263 H263 video stream ***/ +static GstStaticCaps h263_video_caps = GST_STATIC_CAPS ("video/x-h263"); + +#define H263_VIDEO_CAPS gst_static_caps_get(&h263_video_caps) + +#define H263_MAX_PROBE_LENGTH (128 * 1024) + +static void +h263_video_type_find (GstTypeFind * tf, gpointer unused) +{ + DataScanCtx c = { 0, NULL, 0 }; + guint64 data = 0; + guint64 psc = 0; + guint8 tr = 0; + guint format; + guint good = 0; + guint bad = 0; + + while (c.offset < H263_MAX_PROBE_LENGTH) { + if (G_UNLIKELY (!data_scan_ctx_ensure_data (tf, &c, 4))) + break; + + /* Find the picture start code */ + data = (data << 8) + c.data[0]; + psc = data & 0xfffffc0000; + if (psc == 0x800000) { + /* Found PSC */ + /* TR */ + tr = (data & 0x3fc) >> 2; + /* Source Format */ + format = tr & 0x07; + + /* Now that we have a Valid PSC, check if we also have a valid PTYPE and + the Source Format, which should range between 1 and 5 */ + if (((tr >> 6) == 0x2) && (format > 0 && format < 6)) + good++; + else + bad++; + + /* FIXME: maybe bail out early if we get mostly bad syncs ? */ + } + + data_scan_ctx_advance (tf, &c, 1); + } + + if (good > 0 && bad == 0) + gst_type_find_suggest (tf, GST_TYPE_FIND_LIKELY, H263_VIDEO_CAPS); + else if (good > 2 * bad) + gst_type_find_suggest (tf, GST_TYPE_FIND_POSSIBLE, H263_VIDEO_CAPS); + + return; +} + /*** video/x-h264 H264 elementary video stream ***/ static GstStaticCaps h264_video_caps = @@ -4140,6 +4193,7 @@ plugin_init (GstPlugin * plugin) }; static const gchar *flv_exts[] = { "flv", NULL }; static const gchar *m4v_exts[] = { "m4v", NULL }; + static const gchar *h263_exts[] = { "h263", "263", NULL }; static const gchar *h264_exts[] = { "h264", "x264", "264", NULL }; static const gchar *nuv_exts[] = { "nuv", NULL }; static const gchar *vivo_exts[] = { "viv", NULL }; @@ -4227,6 +4281,8 @@ plugin_init (GstPlugin * plugin) NULL); TYPE_FIND_REGISTER (plugin, "video/mpeg4", GST_RANK_PRIMARY, mpeg4_video_type_find, m4v_exts, MPEG_VIDEO_CAPS, NULL, NULL); + TYPE_FIND_REGISTER (plugin, "video/x-h263", GST_RANK_SECONDARY, + h263_video_type_find, h263_exts, H263_VIDEO_CAPS, NULL, NULL); TYPE_FIND_REGISTER (plugin, "video/x-h264", GST_RANK_PRIMARY, h264_video_type_find, h264_exts, H264_VIDEO_CAPS, NULL, NULL); TYPE_FIND_REGISTER (plugin, "video/x-nuv", GST_RANK_SECONDARY, nuv_type_find, From 40c4fe8fbe23cc3e3293c737969fc274dfb6c4f1 Mon Sep 17 00:00:00 2001 From: Arun Raghavan Date: Mon, 7 Feb 2011 13:57:39 +0530 Subject: [PATCH 233/254] discoverer: Use g_signal_connect_object instead of g_signal_connect We want to make sure the discoverer object passed to the various callbacks doesn't become invalid if a callback is pending and the object is free'd in the mean time. https://bugzilla.gnome.org/show_bug.cgi?id=641706 --- gst-libs/gst/pbutils/gstdiscoverer.c | 39 ++++++++++++++++++++++------ 1 file changed, 31 insertions(+), 8 deletions(-) diff --git a/gst-libs/gst/pbutils/gstdiscoverer.c b/gst-libs/gst/pbutils/gstdiscoverer.c index dede0b3bf5..954b732d35 100644 --- a/gst-libs/gst/pbutils/gstdiscoverer.c +++ b/gst-libs/gst/pbutils/gstdiscoverer.c @@ -108,6 +108,12 @@ struct _GstDiscovererPrivate /* reusable queries */ GstQuery *seeking_query; + + /* Handler ids for various callbacks */ + gulong pad_added_id; + gulong pad_remove_id; + gulong element_added_id; + gulong bus_cb_id; }; #define DISCO_LOCK(dc) g_mutex_lock (dc->priv->lock); @@ -267,24 +273,28 @@ gst_discoverer_init (GstDiscoverer * dc) GST_LOG_OBJECT (dc, "Adding uridecodebin to pipeline"); gst_bin_add (dc->priv->pipeline, dc->priv->uridecodebin); - g_signal_connect (dc->priv->uridecodebin, "pad-added", - G_CALLBACK (uridecodebin_pad_added_cb), dc); - g_signal_connect (dc->priv->uridecodebin, "pad-removed", - G_CALLBACK (uridecodebin_pad_removed_cb), dc); + dc->priv->pad_added_id = + g_signal_connect_object (dc->priv->uridecodebin, "pad-added", + G_CALLBACK (uridecodebin_pad_added_cb), dc, 0); + dc->priv->pad_remove_id = + g_signal_connect_object (dc->priv->uridecodebin, "pad-removed", + G_CALLBACK (uridecodebin_pad_removed_cb), dc, 0); GST_LOG_OBJECT (dc, "Getting pipeline bus"); dc->priv->bus = gst_pipeline_get_bus ((GstPipeline *) dc->priv->pipeline); - g_signal_connect (dc->priv->bus, "message", G_CALLBACK (discoverer_bus_cb), - dc); + dc->priv->bus_cb_id = + g_signal_connect_object (dc->priv->bus, "message", + G_CALLBACK (discoverer_bus_cb), dc, 0); GST_DEBUG_OBJECT (dc, "Done initializing Discoverer"); /* This is ugly. We get the GType of decodebin2 so we can quickly detect * when a decodebin2 is added to uridecodebin so we can set the * post-stream-topology setting to TRUE */ - g_signal_connect (dc->priv->uridecodebin, "element-added", - G_CALLBACK (uridecodebin_element_added_cb), dc); + dc->priv->element_added_id = + g_signal_connect_object (dc->priv->uridecodebin, "element-added", + G_CALLBACK (uridecodebin_element_added_cb), dc, 0); tmp = gst_element_factory_make ("decodebin2", NULL); dc->priv->decodebin2_type = G_OBJECT_TYPE (tmp); gst_object_unref (tmp); @@ -308,6 +318,12 @@ discoverer_reset (GstDiscoverer * dc) gst_element_set_state ((GstElement *) dc->priv->pipeline, GST_STATE_NULL); } +#define DISCONNECT_SIGNAL(o,i) G_STMT_START{ \ + if ((i) && g_signal_handler_is_connected ((o), (i))) \ + g_signal_handler_disconnect ((o), (i)); \ + (i) = 0; \ +}G_STMT_END + static void gst_discoverer_dispose (GObject * obj) { @@ -318,9 +334,16 @@ gst_discoverer_dispose (GObject * obj) discoverer_reset (dc); if (G_LIKELY (dc->priv->pipeline)) { + /* Workaround for bug #118536 */ + DISCONNECT_SIGNAL (dc->priv->uridecodebin, dc->priv->pad_added_id); + DISCONNECT_SIGNAL (dc->priv->uridecodebin, dc->priv->pad_remove_id); + DISCONNECT_SIGNAL (dc->priv->uridecodebin, dc->priv->element_added_id); + DISCONNECT_SIGNAL (dc->priv->bus, dc->priv->bus_cb_id); + /* pipeline was set to NULL in _reset */ gst_object_unref (dc->priv->pipeline); gst_object_unref (dc->priv->bus); + dc->priv->pipeline = NULL; dc->priv->uridecodebin = NULL; dc->priv->bus = NULL; From 8d2b69384a2674873975b5414f7bb3635ff2014b Mon Sep 17 00:00:00 2001 From: Arun Raghavan Date: Mon, 7 Feb 2011 13:04:55 +0530 Subject: [PATCH 234/254] discoverer: Keep a ref for the async timeout callback This makes sure we maintain a ref on the discoverer object while the async timeout callback is alive to prevent a potential crash if the object is freed while the callback is pending. https://bugzilla.gnome.org/show_bug.cgi?id=641706 --- gst-libs/gst/pbutils/gstdiscoverer.c | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/gst-libs/gst/pbutils/gstdiscoverer.c b/gst-libs/gst/pbutils/gstdiscoverer.c index 954b732d35..66953c7bc0 100644 --- a/gst-libs/gst/pbutils/gstdiscoverer.c +++ b/gst-libs/gst/pbutils/gstdiscoverer.c @@ -982,14 +982,34 @@ discoverer_collect (GstDiscoverer * dc) } } +static void +get_async_cb (gpointer cb_data, GSource * source, GSourceFunc * func, + gpointer * data) +{ + *func = (GSourceFunc) async_timeout_cb; + *data = cb_data; +} + +/* Wrapper since GSourceCallbackFuncs don't expect a return value from ref() */ +static void +_void_g_object_ref (gpointer object) +{ + g_object_ref (G_OBJECT (object)); +} + static void handle_current_async (GstDiscoverer * dc) { GSource *source; + static GSourceCallbackFuncs cb_funcs = { + .ref = _void_g_object_ref, + .unref = g_object_unref, + .get = get_async_cb, + }; /* Attach a timeout to the main context */ source = g_timeout_source_new (dc->priv->timeout / GST_MSECOND); - g_source_set_callback (source, (GSourceFunc) async_timeout_cb, dc, NULL); + g_source_set_callback_indirect (source, g_object_ref (dc), &cb_funcs); dc->priv->timeoutid = g_source_attach (source, dc->priv->ctx); g_source_unref (source); } From 8fc424bcbf017d9ccb4aa3aedb2c9c17ab7dc495 Mon Sep 17 00:00:00 2001 From: Arun Raghavan Date: Tue, 8 Feb 2011 12:42:32 +0530 Subject: [PATCH 235/254] discoverer: Chain dispose() up to parent class --- gst-libs/gst/pbutils/gstdiscoverer.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/gst-libs/gst/pbutils/gstdiscoverer.c b/gst-libs/gst/pbutils/gstdiscoverer.c index 66953c7bc0..4a7d72d27d 100644 --- a/gst-libs/gst/pbutils/gstdiscoverer.c +++ b/gst-libs/gst/pbutils/gstdiscoverer.c @@ -360,6 +360,8 @@ gst_discoverer_dispose (GObject * obj) gst_query_unref (dc->priv->seeking_query); dc->priv->seeking_query = NULL; } + + G_OBJECT_CLASS (gst_discoverer_parent_class)->dispose (obj); } static void From 399f528a332cdcfbdef9f00db4c8c4605e302aa8 Mon Sep 17 00:00:00 2001 From: Stefan Kost Date: Tue, 22 Feb 2011 16:41:54 +0200 Subject: [PATCH 236/254] discoverer: handle desc==NULL It would otherwise be printed as (null) and mess up indentation (no \n). --- tools/gst-discoverer.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/tools/gst-discoverer.c b/tools/gst-discoverer.c index c68721b1bc..00d2d0f415 100644 --- a/tools/gst-discoverer.c +++ b/tools/gst-discoverer.c @@ -204,8 +204,10 @@ print_stream_info (GstDiscovererStreamInfo * info, void *depth) desc = gst_stream_video_information_to_string (info, GPOINTER_TO_INT (depth) + 1); - g_print ("%s", desc); - g_free (desc); + if (desc) { + g_print ("%s", desc); + g_free (desc); + } } } From eae16a78b9a643e62e43ac98139a7b8c64322d7d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim-Philipp=20M=C3=BCller?= Date: Tue, 22 Feb 2011 15:26:14 +0000 Subject: [PATCH 237/254] win32: update .def file for new libgstvideo API --- win32/common/libgstvideo.def | 1 + 1 file changed, 1 insertion(+) diff --git a/win32/common/libgstvideo.def b/win32/common/libgstvideo.def index a2340291d0..ef663d2f0e 100644 --- a/win32/common/libgstvideo.def +++ b/win32/common/libgstvideo.def @@ -7,6 +7,7 @@ EXPORTS gst_video_filter_get_type gst_video_format_convert gst_video_format_from_fourcc + gst_video_format_get_component_depth gst_video_format_get_component_height gst_video_format_get_component_offset gst_video_format_get_component_width From 948e4d50a6c6f43ede5ba32758e43c759cf007d8 Mon Sep 17 00:00:00 2001 From: Mark Nauwelaerts Date: Wed, 23 Feb 2011 10:32:08 +0100 Subject: [PATCH 238/254] playsink: avoid crashing on the way out when needed chain missing --- gst/playback/gstplaysink.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/gst/playback/gstplaysink.c b/gst/playback/gstplaysink.c index bb41a036a8..76c6e677cb 100644 --- a/gst/playback/gstplaysink.c +++ b/gst/playback/gstplaysink.c @@ -2217,6 +2217,8 @@ gst_play_sink_reconfigure (GstPlaySink * playsink) if (!playsink->videochain) playsink->videochain = gen_video_chain (playsink, raw, async); + if (!playsink->videochain) + goto no_chain; if (!playsink->video_sinkpad_stream_synchronizer) { GstIterator *it; @@ -2241,6 +2243,8 @@ gst_play_sink_reconfigure (GstPlaySink * playsink) if (!playsink->videodeinterlacechain) playsink->videodeinterlacechain = gen_video_deinterlace_chain (playsink); + if (!playsink->videodeinterlacechain) + goto no_chain; GST_DEBUG_OBJECT (playsink, "adding video deinterlace chain"); @@ -2574,6 +2578,15 @@ gst_play_sink_reconfigure (GstPlaySink * playsink) GST_PLAY_SINK_UNLOCK (playsink); return TRUE; + + /* ERRORS */ +no_chain: + { + /* gen_ chain already posted error */ + GST_DEBUG_OBJECT (playsink, "failed to setup chain"); + GST_PLAY_SINK_UNLOCK (playsink); + return FALSE; + } } /** From 102b4feddf4f519515b5d33873f8aee776bdabfa Mon Sep 17 00:00:00 2001 From: Mark Nauwelaerts Date: Wed, 23 Feb 2011 14:29:03 +0100 Subject: [PATCH 239/254] playsink: undo state change side effect on error way out ... to avoid subsequent cleanup disposing an element not in NULL state. --- gst/playback/gstplaysink.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/gst/playback/gstplaysink.c b/gst/playback/gstplaysink.c index 76c6e677cb..14d6882178 100644 --- a/gst/playback/gstplaysink.c +++ b/gst/playback/gstplaysink.c @@ -1961,6 +1961,8 @@ setup_audio_chain (GstPlaySink * playsink, gboolean raw) * re-generate the chain */ if (chain->volume == NULL) { GST_DEBUG_OBJECT (playsink, "no existing volume element to re-use"); + /* undo background state change done earlier */ + gst_element_set_state (chain->sink, GST_STATE_NULL); return FALSE; } From 19052a847d43c489e6bfd249d4e63ba31e630fe1 Mon Sep 17 00:00:00 2001 From: Mark Nauwelaerts Date: Wed, 23 Feb 2011 14:31:13 +0100 Subject: [PATCH 240/254] playsink: release all chains when going to NULL Also fixes #642466. --- gst/playback/gstplaysink.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/gst/playback/gstplaysink.c b/gst/playback/gstplaysink.c index 14d6882178..5ba637ac40 100644 --- a/gst/playback/gstplaysink.c +++ b/gst/playback/gstplaysink.c @@ -3271,6 +3271,21 @@ gst_play_sink_change_state (GstElement * element, GstStateChange transition) add_chain (GST_PLAY_CHAIN (playsink->textchain), FALSE); } do_async_done (playsink); + /* when going to READY, keep elements around as long as possible, + * so they may be re-used faster next time/url around. + * when really going to NULL, clean up everything completely. */ + if (transition == GST_STATE_CHANGE_READY_TO_NULL) { + free_chain ((GstPlayChain *) playsink->videodeinterlacechain); + playsink->videodeinterlacechain = NULL; + free_chain ((GstPlayChain *) playsink->videochain); + playsink->videochain = NULL; + free_chain ((GstPlayChain *) playsink->audiochain); + playsink->audiochain = NULL; + free_chain ((GstPlayChain *) playsink->vischain); + playsink->vischain = NULL; + free_chain ((GstPlayChain *) playsink->textchain); + playsink->textchain = NULL; + } break; default: break; From 27178f7aff309132ce32bba1d995ab59d2466eeb Mon Sep 17 00:00:00 2001 From: Leo Singer Date: Mon, 21 Feb 2011 20:34:41 -0800 Subject: [PATCH 241/254] adder: Fill in offset_end field of outgoing buffers ... rather than leave it as GST_BUFFER_OFFSET_NONE Fix bug #642942. --- gst/adder/gstadder.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/gst/adder/gstadder.c b/gst/adder/gstadder.c index ab2abd7022..fca3eb2325 100644 --- a/gst/adder/gstadder.c +++ b/gst/adder/gstadder.c @@ -1208,10 +1208,12 @@ gst_adder_collected (GstCollectPads * pads, gpointer user_data) if (adder->segment_rate > 0.0) { GST_BUFFER_TIMESTAMP (outbuf) = adder->timestamp; GST_BUFFER_OFFSET (outbuf) = adder->offset; + GST_BUFFER_OFFSET_END (outbuf) = next_offset; GST_BUFFER_DURATION (outbuf) = next_timestamp - adder->timestamp; } else { GST_BUFFER_TIMESTAMP (outbuf) = next_timestamp; GST_BUFFER_OFFSET (outbuf) = next_offset; + GST_BUFFER_OFFSET_END (outbuf) = adder->offset; GST_BUFFER_DURATION (outbuf) = adder->timestamp - next_timestamp; } From 8067bcc54f4f0565d82a1c47081fc59c42a42ba5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= Date: Thu, 24 Feb 2011 15:55:00 +0100 Subject: [PATCH 242/254] encodebin: Return a new reference of the pad for the "request-pad" signal The GObject signal code assumes that the signal handlers return a new reference or copy. Fixes bug #641927. --- gst/encoding/gstencodebin.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/gst/encoding/gstencodebin.c b/gst/encoding/gstencodebin.c index 0ca3981f20..c1a0e8bbc0 100644 --- a/gst/encoding/gstencodebin.c +++ b/gst/encoding/gstencodebin.c @@ -670,7 +670,9 @@ gst_encode_bin_request_new_pad (GstElement * element, static GstPad * gst_encode_bin_request_pad_signal (GstEncodeBin * encodebin, GstCaps * caps) { - return request_pad_for_stream (encodebin, G_TYPE_NONE, NULL, caps); + GstPad *pad = request_pad_for_stream (encodebin, G_TYPE_NONE, NULL, caps); + + return pad ? GST_PAD_CAST (gst_object_ref (pad)) : NULL; } static inline StreamGroup * From dc87e8698ed900c161312830ddf87ba436ba055e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= Date: Thu, 24 Feb 2011 16:02:50 +0100 Subject: [PATCH 243/254] encodebin: Fix memory leaks related to request pads Request pads have to be released by the caller and must be unreffed after releasing them. --- tests/check/elements/encodebin.c | 74 +++++++++++++++++++------------- 1 file changed, 44 insertions(+), 30 deletions(-) diff --git a/tests/check/elements/encodebin.c b/tests/check/elements/encodebin.c index 424b89d87e..a910cebd2b 100644 --- a/tests/check/elements/encodebin.c +++ b/tests/check/elements/encodebin.c @@ -110,7 +110,7 @@ GST_START_TEST (test_encodebin_states) /* At this point, the ghostpad has *NO* target */ target = gst_ghost_pad_get_target (GST_GHOST_PAD (srcpad)); fail_unless (target == NULL); - g_object_unref (srcpad); + gst_object_unref (srcpad); /* No profile, * switching to READY should succeed, @@ -146,8 +146,8 @@ GST_START_TEST (test_encodebin_states) fail_unless (srcpad != NULL); target = gst_ghost_pad_get_target (GST_GHOST_PAD (srcpad)); fail_unless (target != NULL); - g_object_unref (target); - g_object_unref (srcpad); + gst_object_unref (target); + gst_object_unref (srcpad); /* Set back to NULL */ @@ -183,12 +183,12 @@ GST_START_TEST (test_encodebin_sink_pads_static) /* Check if the source pad was properly created */ srcpad = gst_element_get_static_pad (ebin, "src"); fail_unless (srcpad != NULL); - g_object_unref (srcpad); + gst_object_unref (srcpad); /* Check if the audio sink pad was properly created */ sinkpad = gst_element_get_static_pad (ebin, "audio_0"); fail_unless (sinkpad != NULL); - g_object_unref (sinkpad); + gst_object_unref (sinkpad); /* Set back to NULL */ fail_unless_equals_int (gst_element_set_state (ebin, GST_STATE_NULL), @@ -251,12 +251,13 @@ GST_START_TEST (test_encodebin_sink_pads_dynamic) /* Check if the source pad was properly created */ srcpad = gst_element_get_static_pad (ebin, "src"); fail_unless (srcpad != NULL); - g_object_unref (srcpad); + gst_object_unref (srcpad); /* Check if the audio sink pad can be requested */ sinkpad = gst_element_get_request_pad (ebin, "audio_0"); fail_unless (sinkpad != NULL); gst_element_release_request_pad (ebin, sinkpad); + gst_object_unref (sinkpad); sinkpad = NULL; /* Check again with the 'request-pad' signal */ @@ -265,6 +266,8 @@ GST_START_TEST (test_encodebin_sink_pads_dynamic) gst_caps_unref (sinkcaps); fail_unless (sinkpad != NULL); gst_element_release_request_pad (ebin, sinkpad); + gst_object_unref (sinkpad); + sinkpad = NULL; fail_unless_equals_int (gst_element_set_state (ebin, GST_STATE_PAUSED), GST_STATE_CHANGE_SUCCESS); @@ -301,17 +304,17 @@ GST_START_TEST (test_encodebin_sink_pads_multiple_static) /* Check if the source pad was properly created */ srcpad = gst_element_get_static_pad (ebin, "src"); fail_unless (srcpad != NULL); - g_object_unref (srcpad); + gst_object_unref (srcpad); /* Check if the audio sink pad was properly created */ sinkpadvorbis = gst_element_get_static_pad (ebin, "audio_0"); fail_unless (sinkpadvorbis != NULL); - g_object_unref (sinkpadvorbis); + gst_object_unref (sinkpadvorbis); /* Check if the video sink pad was properly created */ sinkpadtheora = gst_element_get_static_pad (ebin, "video_1"); fail_unless (sinkpadtheora != NULL); - g_object_unref (sinkpadtheora); + gst_object_unref (sinkpadtheora); /* Set back to NULL */ fail_unless_equals_int (gst_element_set_state (ebin, GST_STATE_NULL), @@ -343,21 +346,26 @@ GST_START_TEST (test_encodebin_sink_pads_multiple_dynamic) /* Check if the source pad was properly created */ srcpad = gst_element_get_static_pad (ebin, "src"); fail_unless (srcpad != NULL); - g_object_unref (srcpad); + gst_object_unref (srcpad); /* Check if the audio sink pad was properly created */ sinkpadvorbis = gst_element_get_request_pad (ebin, "audio_0"); fail_unless (sinkpadvorbis != NULL); - g_object_unref (sinkpadvorbis); + gst_object_unref (sinkpadvorbis); /* Check if the video sink pad was properly created */ sinkpadtheora = gst_element_get_request_pad (ebin, "video_1"); fail_unless (sinkpadtheora != NULL); - g_object_unref (sinkpadtheora); + gst_object_unref (sinkpadtheora); fail_unless_equals_int (gst_element_set_state (ebin, GST_STATE_PAUSED), GST_STATE_CHANGE_SUCCESS); + gst_element_release_request_pad (GST_ELEMENT (ebin), sinkpadvorbis); + gst_object_unref (sinkpadvorbis); + gst_element_release_request_pad (GST_ELEMENT (ebin), sinkpadtheora); + gst_object_unref (sinkpadtheora); + /* Set back to NULL */ fail_unless_equals_int (gst_element_set_state (ebin, GST_STATE_NULL), GST_STATE_CHANGE_SUCCESS); @@ -389,7 +397,7 @@ GST_START_TEST (test_encodebin_sink_pads_dynamic_encoder) /* Check if the source pad was properly created */ srcpad = gst_element_get_static_pad (ebin, "src"); fail_unless (srcpad != NULL); - g_object_unref (srcpad); + gst_object_unref (srcpad); /* Check if the audio sink pad was properly created */ vorbiscaps = gst_caps_from_string ("audio/x-vorbis,channels=2,rate=44100"); @@ -397,6 +405,7 @@ GST_START_TEST (test_encodebin_sink_pads_dynamic_encoder) gst_caps_unref (vorbiscaps); fail_unless (sinkpad != NULL); gst_element_release_request_pad (ebin, sinkpad); + gst_object_unref (sinkpad); fail_unless_equals_int (gst_element_set_state (ebin, GST_STATE_PAUSED), GST_STATE_CHANGE_SUCCESS); @@ -462,7 +471,7 @@ GST_START_TEST (test_encodebin_render_audio_static) fail_unless_equals_int (gst_element_set_state (pipeline, GST_STATE_NULL), GST_STATE_CHANGE_SUCCESS); - g_object_unref (bus); + gst_object_unref (bus); gst_object_unref (pipeline); } @@ -530,7 +539,7 @@ GST_START_TEST (test_encodebin_render_audio_only_static) fail_unless_equals_int (gst_element_set_state (pipeline, GST_STATE_NULL), GST_STATE_CHANGE_SUCCESS); - g_object_unref (bus); + gst_object_unref (bus); gst_object_unref (pipeline); } @@ -569,8 +578,7 @@ GST_START_TEST (test_encodebin_render_audio_dynamic) fail_unless_equals_int (gst_pad_link (srcpad, sinkpad), GST_PAD_LINK_OK); - g_object_unref (srcpad); - g_object_unref (sinkpad); + gst_object_unref (srcpad); fail_unless (gst_element_link (ebin, fakesink)); @@ -597,11 +605,14 @@ GST_START_TEST (test_encodebin_render_audio_dynamic) } } + gst_element_release_request_pad (GST_ELEMENT (ebin), sinkpad); + gst_object_unref (sinkpad); + /* Set back to NULL */ fail_unless_equals_int (gst_element_set_state (pipeline, GST_STATE_NULL), GST_STATE_CHANGE_SUCCESS); - g_object_unref (bus); + gst_object_unref (bus); gst_object_unref (pipeline); } @@ -664,7 +675,7 @@ GST_START_TEST (test_encodebin_render_audio_video_static) fail_unless_equals_int (gst_element_set_state (pipeline, GST_STATE_NULL), GST_STATE_CHANGE_SUCCESS); - g_object_unref (bus); + gst_object_unref (bus); gst_object_unref (pipeline); } @@ -677,7 +688,7 @@ GST_START_TEST (test_encodebin_render_audio_video_dynamic) GstEncodingProfile *prof; GstBus *bus; gboolean done = FALSE; - GstPad *sinkpad, *srcpad; + GstPad *sinkpad1, *sinkpad2, *srcpad; /* Create an encodebin and render 5s of vorbis/ogg */ @@ -701,18 +712,16 @@ GST_START_TEST (test_encodebin_render_audio_video_dynamic) fail_unless (gst_element_link (ebin, fakesink)); srcpad = gst_element_get_static_pad (audiotestsrc, "src"); - sinkpad = gst_element_get_request_pad (ebin, "audio_0"); + sinkpad1 = gst_element_get_request_pad (ebin, "audio_0"); fail_unless (srcpad != NULL); - fail_unless (sinkpad != NULL); - fail_unless_equals_int (gst_pad_link (srcpad, sinkpad), GST_PAD_LINK_OK); - g_object_unref (srcpad); - g_object_unref (sinkpad); + fail_unless (sinkpad1 != NULL); + fail_unless_equals_int (gst_pad_link (srcpad, sinkpad1), GST_PAD_LINK_OK); + gst_object_unref (srcpad); srcpad = gst_element_get_static_pad (videotestsrc, "src"); - sinkpad = gst_element_get_request_pad (ebin, "video_1"); - fail_unless_equals_int (gst_pad_link (srcpad, sinkpad), GST_PAD_LINK_OK); - g_object_unref (srcpad); - g_object_unref (sinkpad); + sinkpad2 = gst_element_get_request_pad (ebin, "video_1"); + fail_unless_equals_int (gst_pad_link (srcpad, sinkpad2), GST_PAD_LINK_OK); + gst_object_unref (srcpad); fail_unless_equals_int (gst_element_set_state (pipeline, GST_STATE_PLAYING), GST_STATE_CHANGE_ASYNC); @@ -737,11 +746,16 @@ GST_START_TEST (test_encodebin_render_audio_video_dynamic) } } + gst_element_release_request_pad (GST_ELEMENT (ebin), sinkpad1); + gst_object_unref (sinkpad1); + gst_element_release_request_pad (GST_ELEMENT (ebin), sinkpad2); + gst_object_unref (sinkpad2); + /* Set back to NULL */ fail_unless_equals_int (gst_element_set_state (pipeline, GST_STATE_NULL), GST_STATE_CHANGE_SUCCESS); - g_object_unref (bus); + gst_object_unref (bus); gst_object_unref (pipeline); } From 461d9f2f2c3eaeb17233d4f0d0d6677bba7a5a80 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= Date: Thu, 24 Feb 2011 16:22:53 +0100 Subject: [PATCH 244/254] oggmux: Don't handle GstCollectData as GstObject, use the pad instead --- ext/ogg/gstoggmux.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ext/ogg/gstoggmux.c b/ext/ogg/gstoggmux.c index c6ed67c72a..9016102d2e 100644 --- a/ext/ogg/gstoggmux.c +++ b/ext/ogg/gstoggmux.c @@ -1068,10 +1068,10 @@ gst_ogg_mux_send_headers (GstOggMux * mux) gst_buffer_ref (buf); } else { /* fixme -- should be caught in the previous list traversal. */ - GST_OBJECT_LOCK (pad); + GST_OBJECT_LOCK (thepad); g_critical ("No headers or buffers on pad %s:%s", - GST_DEBUG_PAD_NAME (pad)); - GST_OBJECT_UNLOCK (pad); + GST_DEBUG_PAD_NAME (thepad)); + GST_OBJECT_UNLOCK (thepad); continue; } From c48c193b56480d286935a6d97071ad8caa19b99e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim-Philipp=20M=C3=BCller?= Date: Tue, 22 Feb 2011 12:56:48 +0000 Subject: [PATCH 245/254] playbin2, uridecodebin: add "source-setup" signal Add "source-setup" signal for convenience and discoverability. No need to figure out "notify::source", look up the notify callback signature, then do an g_object_get() to get the source element.. https://bugzilla.gnome.org/show_bug.cgi?id=626152 --- gst/playback/gstplaybin2.c | 22 ++++++++++++++++++++++ gst/playback/gsturidecodebin.c | 22 ++++++++++++++++++++++ 2 files changed, 44 insertions(+) diff --git a/gst/playback/gstplaybin2.c b/gst/playback/gstplaybin2.c index 2f2a42eb9b..30aa71618b 100644 --- a/gst/playback/gstplaybin2.c +++ b/gst/playback/gstplaybin2.c @@ -509,6 +509,7 @@ enum SIGNAL_GET_VIDEO_PAD, SIGNAL_GET_AUDIO_PAD, SIGNAL_GET_TEXT_PAD, + SIGNAL_SOURCE_SETUP, LAST_SIGNAL }; @@ -910,6 +911,24 @@ gst_play_bin_class_init (GstPlayBinClass * klass) G_STRUCT_OFFSET (GstPlayBinClass, text_tags_changed), NULL, NULL, gst_marshal_VOID__INT, G_TYPE_NONE, 1, G_TYPE_INT); + /** + * GstPlayBin2::source-setup: + * @playbin: a #GstPlayBin2 + * @source: source element + * + * This signal is emitted after the source element has been created, so + * it can be configured by setting additional properties (e.g. set a + * proxy server for an http source, or set the device and read speed for + * an audio cd source). This is functionally equivalent to connecting to + * the notify::source signal, but more convenient. + * + * Since: 0.10.33 + */ + gst_play_bin_signals[SIGNAL_SOURCE_SETUP] = + g_signal_new ("source-setup", G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST, 0, NULL, NULL, + gst_marshal_VOID__OBJECT, G_TYPE_NONE, 1, GST_TYPE_ELEMENT); + /** * GstPlayBin2::get-video-tags * @playbin: a #GstPlayBin2 @@ -3121,6 +3140,9 @@ notify_source_cb (GstElement * uridecodebin, GParamSpec * pspec, GST_OBJECT_UNLOCK (playbin); g_object_notify (G_OBJECT (playbin), "source"); + + g_signal_emit (playbin, gst_play_bin_signals[SIGNAL_SOURCE_SETUP], + 0, playbin->source); } /* must be called with the group lock */ diff --git a/gst/playback/gsturidecodebin.c b/gst/playback/gsturidecodebin.c index af2d3dd52d..f4551e3b4f 100644 --- a/gst/playback/gsturidecodebin.c +++ b/gst/playback/gsturidecodebin.c @@ -149,6 +149,7 @@ enum SIGNAL_AUTOPLUG_SELECT, SIGNAL_DRAINED, SIGNAL_AUTOPLUG_SORT, + SIGNAL_SOURCE_SETUP, LAST_SIGNAL }; @@ -618,6 +619,24 @@ gst_uri_decode_bin_class_init (GstURIDecodeBinClass * klass) G_STRUCT_OFFSET (GstURIDecodeBinClass, drained), NULL, NULL, gst_marshal_VOID__VOID, G_TYPE_NONE, 0, G_TYPE_NONE); + /** + * GstURIDecodeBin::source-setup: + * @bin: the uridecodebin. + * @source: source element + * + * This signal is emitted after the source element has been created, so + * it can be configured by setting additional properties (e.g. set a + * proxy server for an http source, or set the device and read speed for + * an audio cd source). This is functionally equivalent to connecting to + * the notify::source signal, but more convenient. + * + * Since: 0.10.33 + */ + gst_uri_decode_bin_signals[SIGNAL_SOURCE_SETUP] = + g_signal_new ("source-setup", G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST, 0, NULL, NULL, + gst_marshal_VOID__OBJECT, G_TYPE_NONE, 1, GST_TYPE_ELEMENT); + gstelement_class->query = GST_DEBUG_FUNCPTR (gst_uri_decode_bin_query); gstelement_class->change_state = GST_DEBUG_FUNCPTR (gst_uri_decode_bin_change_state); @@ -1877,6 +1896,9 @@ setup_source (GstURIDecodeBin * decoder) /* notify of the new source used */ g_object_notify (G_OBJECT (decoder), "source"); + g_signal_emit (decoder, gst_uri_decode_bin_signals[SIGNAL_SOURCE_SETUP], + 0, decoder->source); + /* remove the old decoders now, if any */ remove_decoders (decoder, FALSE); From 2835a9e45c6d9a7a3a9339aba65e3fc319535a50 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim-Philipp=20M=C3=BCller?= Date: Tue, 22 Feb 2011 14:54:55 +0000 Subject: [PATCH 246/254] checks: add a simple unit test for the source-setup signal --- tests/check/elements/playbin2.c | 44 +++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/tests/check/elements/playbin2.c b/tests/check/elements/playbin2.c index c7281dd5fb..aef9272bbd 100644 --- a/tests/check/elements/playbin2.c +++ b/tests/check/elements/playbin2.c @@ -464,6 +464,49 @@ GST_START_TEST (test_refcount) GST_END_TEST; +static void +source_setup (GstElement * playbin, GstElement * source, GstElement ** p_src) +{ + GST_LOG ("source-setup called, source = %s", G_OBJECT_TYPE_NAME (source)); + *p_src = gst_object_ref (source); + GST_LOG ("here"); +} + +GST_START_TEST (test_source_setup) +{ + GstElement *playbin, *videosink; + GstElement *src = NULL; + + if (!gst_default_registry_check_feature_version ("redvideosrc", 0, 10, 0)) { + fail_unless (gst_element_register (NULL, "redvideosrc", GST_RANK_PRIMARY, + gst_red_video_src_get_type ())); + } + + playbin = gst_element_factory_make ("playbin2", NULL); + g_object_set (playbin, "uri", "redvideo://", NULL); + + videosink = gst_element_factory_make ("fakesink", "myvideosink"); + g_object_set (playbin, "video-sink", videosink, NULL); + + g_signal_connect (playbin, "source-setup", G_CALLBACK (source_setup), &src); + + fail_unless_equals_int (gst_element_set_state (playbin, GST_STATE_PAUSED), + GST_STATE_CHANGE_ASYNC); + fail_unless_equals_int (gst_element_get_state (playbin, NULL, NULL, + GST_CLOCK_TIME_NONE), GST_STATE_CHANGE_SUCCESS); + + fail_unless (src != NULL); + fail_unless (G_OBJECT_TYPE (src) == gst_red_video_src_get_type ()); + + fail_unless_equals_int (gst_element_set_state (playbin, GST_STATE_NULL), + GST_STATE_CHANGE_SUCCESS); + + gst_object_unref (playbin); + gst_object_unref (src); +} + +GST_END_TEST; + /*** redvideo:// source ***/ static GstURIType @@ -696,6 +739,7 @@ playbin2_suite (void) tcase_add_test (tc_chain, test_missing_suburisource_handler); tcase_add_test (tc_chain, test_missing_primary_decoder); tcase_add_test (tc_chain, test_refcount); + tcase_add_test (tc_chain, test_source_setup); /* one day we might also want to have the following checks: * tcase_add_test (tc_chain, test_missing_secondary_decoder_one_fatal); From eb91fe7162c35d7298fb96fd15884ee38e886b15 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= Date: Thu, 24 Feb 2011 20:59:48 +0100 Subject: [PATCH 247/254] encodebin: Fix double unref in unit test --- tests/check/elements/encodebin.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/tests/check/elements/encodebin.c b/tests/check/elements/encodebin.c index a910cebd2b..3b5d66ad82 100644 --- a/tests/check/elements/encodebin.c +++ b/tests/check/elements/encodebin.c @@ -351,12 +351,10 @@ GST_START_TEST (test_encodebin_sink_pads_multiple_dynamic) /* Check if the audio sink pad was properly created */ sinkpadvorbis = gst_element_get_request_pad (ebin, "audio_0"); fail_unless (sinkpadvorbis != NULL); - gst_object_unref (sinkpadvorbis); /* Check if the video sink pad was properly created */ sinkpadtheora = gst_element_get_request_pad (ebin, "video_1"); fail_unless (sinkpadtheora != NULL); - gst_object_unref (sinkpadtheora); fail_unless_equals_int (gst_element_set_state (ebin, GST_STATE_PAUSED), GST_STATE_CHANGE_SUCCESS); From e0a658a664429fd75a54a62939d4f607079d67d8 Mon Sep 17 00:00:00 2001 From: Robert Swain Date: Mon, 3 Jan 2011 11:41:56 +0100 Subject: [PATCH 248/254] gstvideo: Add GST_VIDEO_BUFFER_PROGRESSIVE flag Maps to GST_BUFFER_FLAG_MEDIA4. The purpose is to explicitly indicate whether a telecined buffer is progressive or not without having to make assumptions based on previous buffers. --- gst-libs/gst/video/video.h | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/gst-libs/gst/video/video.h b/gst-libs/gst/video/video.h index e78f74c660..2adf387ffa 100644 --- a/gst-libs/gst/video/video.h +++ b/gst-libs/gst/video/video.h @@ -410,6 +410,16 @@ typedef enum { */ #define GST_VIDEO_BUFFER_ONEFIELD GST_BUFFER_FLAG_MEDIA3 +/** + * GST_VIDEO_BUFFER_PROGRESSIVE: + * + * If the #GstBuffer is telecined, then the buffer is progressive if the + * %GST_VIDEO_BUFFER_PROGRESSIVE flag is set, else it is telecine mixed. + * + * Since: 0.10.33 + */ +#define GST_VIDEO_BUFFER_PROGRESSIVE GST_BUFFER_FLAG_MEDIA4 + /* functions */ const GValue *gst_video_frame_rate (GstPad *pad); gboolean gst_video_get_size (GstPad *pad, From 1265a421246a7b33af39197808e2aeafd0033e83 Mon Sep 17 00:00:00 2001 From: David Schleef Date: Fri, 25 Feb 2011 19:37:07 -0800 Subject: [PATCH 249/254] video: Add support for r210 --- gst-libs/gst/video/video.c | 26 ++++++++++++++++++++++++-- gst-libs/gst/video/video.h | 17 ++++++++++++++++- 2 files changed, 40 insertions(+), 3 deletions(-) diff --git a/gst-libs/gst/video/video.c b/gst-libs/gst/video/video.c index a9d856616e..d9569a4e8c 100644 --- a/gst-libs/gst/video/video.c +++ b/gst-libs/gst/video/video.c @@ -367,7 +367,9 @@ gst_video_format_parse_caps (GstCaps * caps, GstVideoFormat * format, } have_alpha = gst_structure_get_int (structure, "alpha_mask", &alpha_mask); - if (depth == 24 && bpp == 32 && endianness == G_BIG_ENDIAN) { + if (depth == 30 && bpp == 32 && endianness == G_BIG_ENDIAN) { + *format = GST_VIDEO_FORMAT_r210; + } else if (depth == 24 && bpp == 32 && endianness == G_BIG_ENDIAN) { *format = gst_video_format_from_rgb32_masks (red_mask, green_mask, blue_mask); if (*format == GST_VIDEO_FORMAT_UNKNOWN) { @@ -629,10 +631,20 @@ gst_video_format_new_caps (GstVideoFormat format, int width, depth = 64; have_alpha = TRUE; break; + case GST_VIDEO_FORMAT_r210: + bpp = 32; + depth = 30; + have_alpha = FALSE; + break; default: return NULL; } - if (bpp == 32 || bpp == 24 || bpp == 64) { + if (bpp == 32 && depth == 30) { + red_mask = 0x3ff00000; + green_mask = 0x000ffc00; + blue_mask = 0x000003ff; + have_alpha = FALSE; + } else if (bpp == 32 || bpp == 24 || bpp == 64) { if (bpp == 32) { mask = 0xff000000; } else { @@ -1036,6 +1048,7 @@ gst_video_format_is_rgb (GstVideoFormat format) case GST_VIDEO_FORMAT_BGR15: case GST_VIDEO_FORMAT_RGB8_PALETTED: case GST_VIDEO_FORMAT_ARGB64: + case GST_VIDEO_FORMAT_r210: return TRUE; default: return FALSE; @@ -1095,6 +1108,7 @@ gst_video_format_is_yuv (GstVideoFormat format) case GST_VIDEO_FORMAT_BGR15: case GST_VIDEO_FORMAT_RGB8_PALETTED: case GST_VIDEO_FORMAT_ARGB64: + case GST_VIDEO_FORMAT_r210: return FALSE; default: return FALSE; @@ -1181,6 +1195,7 @@ gst_video_format_has_alpha (GstVideoFormat format) case GST_VIDEO_FORMAT_BGR16: case GST_VIDEO_FORMAT_RGB15: case GST_VIDEO_FORMAT_BGR15: + case GST_VIDEO_FORMAT_r210: return FALSE; default: return FALSE; @@ -1246,6 +1261,7 @@ gst_video_format_get_component_depth (GstVideoFormat format, int component) return 8; case GST_VIDEO_FORMAT_v210: case GST_VIDEO_FORMAT_UYVP: + case GST_VIDEO_FORMAT_r210: return 10; case GST_VIDEO_FORMAT_Y16: case GST_VIDEO_FORMAT_v216: @@ -1303,6 +1319,7 @@ gst_video_format_get_row_stride (GstVideoFormat format, int component, case GST_VIDEO_FORMAT_BGRA: case GST_VIDEO_FORMAT_ARGB: case GST_VIDEO_FORMAT_ABGR: + case GST_VIDEO_FORMAT_r210: return width * 4; case GST_VIDEO_FORMAT_RGB16: case GST_VIDEO_FORMAT_BGR16: @@ -1420,6 +1437,7 @@ gst_video_format_get_pixel_stride (GstVideoFormat format, int component) case GST_VIDEO_FORMAT_BGRA: case GST_VIDEO_FORMAT_ARGB: case GST_VIDEO_FORMAT_ABGR: + case GST_VIDEO_FORMAT_r210: return 4; case GST_VIDEO_FORMAT_RGB16: case GST_VIDEO_FORMAT_BGR16: @@ -1539,6 +1557,7 @@ gst_video_format_get_component_width (GstVideoFormat format, case GST_VIDEO_FORMAT_RGB8_PALETTED: case GST_VIDEO_FORMAT_ARGB64: case GST_VIDEO_FORMAT_AYUV64: + case GST_VIDEO_FORMAT_r210: return width; case GST_VIDEO_FORMAT_A420: if (component == 0 || component == 3) { @@ -1617,6 +1636,7 @@ gst_video_format_get_component_height (GstVideoFormat format, case GST_VIDEO_FORMAT_IYU1: case GST_VIDEO_FORMAT_ARGB64: case GST_VIDEO_FORMAT_AYUV64: + case GST_VIDEO_FORMAT_r210: return height; case GST_VIDEO_FORMAT_A420: if (component == 0 || component == 3) { @@ -1800,6 +1820,7 @@ gst_video_format_get_component_offset (GstVideoFormat format, case GST_VIDEO_FORMAT_Y444: return GST_ROUND_UP_4 (width) * height * component; case GST_VIDEO_FORMAT_v210: + case GST_VIDEO_FORMAT_r210: /* v210 is bit-packed, so this doesn't make sense */ return 0; case GST_VIDEO_FORMAT_v216: @@ -1939,6 +1960,7 @@ gst_video_format_get_size (GstVideoFormat format, int width, int height) case GST_VIDEO_FORMAT_BGRA: case GST_VIDEO_FORMAT_ARGB: case GST_VIDEO_FORMAT_ABGR: + case GST_VIDEO_FORMAT_r210: return width * 4 * height; case GST_VIDEO_FORMAT_RGB16: case GST_VIDEO_FORMAT_BGR16: diff --git a/gst-libs/gst/video/video.h b/gst-libs/gst/video/video.h index 2adf387ffa..969cb05072 100644 --- a/gst-libs/gst/video/video.h +++ b/gst-libs/gst/video/video.h @@ -71,6 +71,7 @@ G_BEGIN_DECLS * @GST_VIDEO_FORMAT_IYU1: packed 4:1:1 YUV (Cb-Y0-Y1-Cr-Y2-Y3 ...) (Since: 0.10.32) * @GST_VIDEO_FORMAT_ARGB64: rgb with alpha channel first, 16 bits per channel (Since: 0.10.33) * @GST_VIDEO_FORMAT_AY64: packed 4:4:4 YUV with alpha channel, 16 bits per channel (A0-Y0-U0-V0 ...) (Since: 0.10.33) + * @GST_VIDEO_FORMAT_r210: packed 4:4:4 RGB, 10 bits per channel (Since: 0.10.33) * * Enum value describing the most common video formats. */ @@ -116,7 +117,8 @@ typedef enum { GST_VIDEO_FORMAT_YVU9, GST_VIDEO_FORMAT_IYU1, GST_VIDEO_FORMAT_ARGB64, - GST_VIDEO_FORMAT_AYUV64 + GST_VIDEO_FORMAT_AYUV64, + GST_VIDEO_FORMAT_r210 } GstVideoFormat; #define GST_VIDEO_BYTE1_MASK_32 "0xFF000000" @@ -313,6 +315,19 @@ typedef enum { #define GST_VIDEO_CAPS_BGR_15 \ __GST_VIDEO_CAPS_MAKE_15 (3, 2, 1) +/* 30 bit */ +#define GST_VIDEO_CAPS_r210 \ + "video/x-raw-rgb, " \ + "bpp = (int) 32, " \ + "depth = (int) 30, " \ + "endianness = (int) BIG_ENDIAN, " \ + "red_mask = (int) 0x3ff00000, " \ + "green_mask = (int) 0x000ffc00, " \ + "blue_mask = (int) 0x000003ff, " \ + "width = " GST_VIDEO_SIZE_RANGE ", " \ + "height = " GST_VIDEO_SIZE_RANGE ", " \ + "framerate = " GST_VIDEO_FPS_RANGE + /* 64 bit alpha */ #define GST_VIDEO_CAPS_ARGB_64 \ From 32c30b88ff2bf94aed04dbfc540502b2b987b073 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= Date: Sat, 26 Feb 2011 23:20:42 +0100 Subject: [PATCH 250/254] decodebin2: Improve detection of raw caps in expose-all-streams=false mode Previously we only checked against the raw caps but we should also check against the return value of autoplug-continue. Additionally fix a thread-safety issue with accessing the raw caps. --- gst/playback/gstdecodebin2.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/gst/playback/gstdecodebin2.c b/gst/playback/gstdecodebin2.c index 9e9d5e2723..caa3c42799 100644 --- a/gst/playback/gstdecodebin2.c +++ b/gst/playback/gstdecodebin2.c @@ -1463,7 +1463,6 @@ analyze_new_pad (GstDecodeBin * dbin, GstElement * src, GstPad * pad, * if it doesn't match the output caps */ if (!dbin->expose_allstreams) { guint i; - GstCaps *rawcaps = gst_static_caps_get (&default_raw_caps); const GList *tmps; gboolean dontuse = FALSE; @@ -1492,13 +1491,21 @@ analyze_new_pad (GstDecodeBin * dbin, GstElement * src, GstPad * pad, if (st->direction != GST_PAD_SRC) continue; tcaps = gst_static_pad_template_get_caps (st); - if (!gst_caps_can_intersect (tcaps, dbin->caps)) + + apcontinue = TRUE; + + /* Emit autoplug-continue to see if the caps are considered to be raw caps */ + g_signal_emit (G_OBJECT (dbin), + gst_decode_bin_signals[SIGNAL_AUTOPLUG_CONTINUE], 0, dpad, tcaps, + &apcontinue); + + /* If autoplug-continue returns TRUE and the caps are not final, don't use them */ + if (apcontinue && !are_final_caps (dbin, tcaps)) dontuse = TRUE; gst_caps_unref (tcaps); } } } - gst_caps_unref (rawcaps); if (dontuse) { gst_object_unref (dpad); From 5058f792263e4214f4655c5ed5956ebfbeb17c99 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= Date: Sat, 26 Feb 2011 23:39:03 +0100 Subject: [PATCH 251/254] decodebin2: Don't use the same element multiple times in the same chain This is going to lead to an infinite loop of this element and can easily happen with parsers that accept their own src caps on the sinkpad. --- gst/playback/gstdecodebin2.c | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/gst/playback/gstdecodebin2.c b/gst/playback/gstdecodebin2.c index caa3c42799..339ec91ba6 100644 --- a/gst/playback/gstdecodebin2.c +++ b/gst/playback/gstdecodebin2.c @@ -1667,6 +1667,8 @@ connect_pad (GstDecodeBin * dbin, GstElement * src, GstDecodePad * dpad, GstElement *element; GstPad *sinkpad; gboolean subtitle; + gboolean skip = FALSE; + GList *l; /* Set dpad target to pad again, it might've been unset * below but we came back here because something failed @@ -1678,6 +1680,29 @@ connect_pad (GstDecodeBin * dbin, GstElement * src, GstDecodePad * dpad, /* Remove selected factory from the list. */ g_value_array_remove (factories, 0); + /* First check if this is a factory for which we have already + * created an element in this chain. If we have, we skip this + * factory because it will lead to an infinite loop. Examples + * for this are parsers that accept their own src caps on the + * sinkpad again. + */ + CHAIN_MUTEX_LOCK (chain); + for (l = chain->elements; l; l = l->next) { + GstElement *otherelement = GST_ELEMENT_CAST (l->data); + + if (gst_element_get_factory (otherelement) == factory) { + skip = TRUE; + continue; + } + } + CHAIN_MUTEX_UNLOCK (chain); + if (skip) { + GST_DEBUG_OBJECT (dbin, + "Skipping factory '%s' because it was already used in this chain", + gst_plugin_feature_get_name (GST_PLUGIN_FEATURE_CAST (factory))); + continue; + } + /* emit autoplug-select to see what we should do with it. */ g_signal_emit (G_OBJECT (dbin), gst_decode_bin_signals[SIGNAL_AUTOPLUG_SELECT], From c7f52902477f0288f31b7645fbe637b5b2dd678a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= Date: Sat, 26 Feb 2011 23:43:39 +0100 Subject: [PATCH 252/254] decodebin2: Break the double-factory checking loop immediately if the factory was used already --- gst/playback/gstdecodebin2.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gst/playback/gstdecodebin2.c b/gst/playback/gstdecodebin2.c index 339ec91ba6..7b8fbc2eff 100644 --- a/gst/playback/gstdecodebin2.c +++ b/gst/playback/gstdecodebin2.c @@ -1692,7 +1692,7 @@ connect_pad (GstDecodeBin * dbin, GstElement * src, GstDecodePad * dpad, if (gst_element_get_factory (otherelement) == factory) { skip = TRUE; - continue; + break; } } CHAIN_MUTEX_UNLOCK (chain); From 4ac6f5ff831fe1ee9b7005c707c6ea1527240ddb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= Date: Sun, 27 Feb 2011 09:32:55 +0100 Subject: [PATCH 253/254] decodebin2: Only prevent to autoplug the same parser multiple times for the same chain Parsers are the only element class that are not changing the data and could lead to an infinite loop. Other element classes like demuxers, e.g. id3demux, can be used multiple times in a row and sometimes are. --- gst/playback/gstdecodebin2.c | 46 ++++++++++++++++++++---------------- 1 file changed, 26 insertions(+), 20 deletions(-) diff --git a/gst/playback/gstdecodebin2.c b/gst/playback/gstdecodebin2.c index 7b8fbc2eff..882d53f804 100644 --- a/gst/playback/gstdecodebin2.c +++ b/gst/playback/gstdecodebin2.c @@ -1667,8 +1667,6 @@ connect_pad (GstDecodeBin * dbin, GstElement * src, GstDecodePad * dpad, GstElement *element; GstPad *sinkpad; gboolean subtitle; - gboolean skip = FALSE; - GList *l; /* Set dpad target to pad again, it might've been unset * below but we came back here because something failed @@ -1680,27 +1678,35 @@ connect_pad (GstDecodeBin * dbin, GstElement * src, GstDecodePad * dpad, /* Remove selected factory from the list. */ g_value_array_remove (factories, 0); - /* First check if this is a factory for which we have already - * created an element in this chain. If we have, we skip this - * factory because it will lead to an infinite loop. Examples - * for this are parsers that accept their own src caps on the - * sinkpad again. + /* If the factory is for a parser we first check if the factory + * was already used for the current chain. If it was used already + * we would otherwise create an infinite loop here because the + * parser apparently accepts its own output as input. + * This is only done for parsers because it's perfectly valid + * to have other element classes after each other because a + * parser is the only one that does not change the data. A + * valid example for this would be multiple id3demux in a row. */ - CHAIN_MUTEX_LOCK (chain); - for (l = chain->elements; l; l = l->next) { - GstElement *otherelement = GST_ELEMENT_CAST (l->data); + if (strstr (gst_element_factory_get_klass (factory), "Parser")) { + gboolean skip = FALSE; + GList *l; - if (gst_element_get_factory (otherelement) == factory) { - skip = TRUE; - break; + CHAIN_MUTEX_LOCK (chain); + for (l = chain->elements; l; l = l->next) { + GstElement *otherelement = GST_ELEMENT_CAST (l->data); + + if (gst_element_get_factory (otherelement) == factory) { + skip = TRUE; + break; + } + } + CHAIN_MUTEX_UNLOCK (chain); + if (skip) { + GST_DEBUG_OBJECT (dbin, + "Skipping factory '%s' because it was already used in this chain", + gst_plugin_feature_get_name (GST_PLUGIN_FEATURE_CAST (factory))); + continue; } - } - CHAIN_MUTEX_UNLOCK (chain); - if (skip) { - GST_DEBUG_OBJECT (dbin, - "Skipping factory '%s' because it was already used in this chain", - gst_plugin_feature_get_name (GST_PLUGIN_FEATURE_CAST (factory))); - continue; } /* emit autoplug-select to see what we should do with it. */ From fa300aee2006b1771c7dd77c8cfd5730296ab5f1 Mon Sep 17 00:00:00 2001 From: Stefan Kost Date: Mon, 28 Feb 2011 10:10:22 +0200 Subject: [PATCH 254/254] tests: add ABI test suite for libs --- tests/check/Makefile.am | 36 ++++++++++- tests/check/libs/libsabi.c | 112 +++++++++++++++++++++++++++++++++ tests/check/libs/struct_i386.h | 100 +++++++++++++++++++++++++++++ 3 files changed, 245 insertions(+), 3 deletions(-) create mode 100644 tests/check/libs/libsabi.c create mode 100644 tests/check/libs/struct_i386.h diff --git a/tests/check/Makefile.am b/tests/check/Makefile.am index f284716a10..f496787d35 100644 --- a/tests/check/Makefile.am +++ b/tests/check/Makefile.am @@ -37,7 +37,7 @@ endif if USE_GNOME_VFS check_gnomevfs = elements/gnomevfssink else -check_gnomevfs = +check_gnomevfs = endif if USE_GIO @@ -55,13 +55,13 @@ endif if USE_OGG check_ogg = pipelines/oggmux else -check_ogg = +check_ogg = endif if USE_PANGO check_pango = elements/textoverlay else -check_pango = +check_pango = endif if USE_VORBIS @@ -131,6 +131,7 @@ check_PROGRAMS = \ generic/clock-selection \ generic/states \ gst/typefindfunctions \ + libs/libsabi \ libs/audio \ libs/cddabasesrc \ libs/fft \ @@ -160,6 +161,15 @@ VALGRIND_TO_FIX = \ # these tests don't even pass noinst_PROGRAMS = $(check_libvisual) +noinst_HEADERS = \ + libs/struct_i386.h +# libs/struct_arm.h \ +# libs/struct_hppa.h \ +# libs/struct_ppc32.h \ +# libs/struct_ppc64.h \ +# libs/struct_sparc.h \ +# libs/struct_x86_64.h + AM_CFLAGS = $(GST_CFLAGS) $(GST_CHECK_CFLAGS) \ -DGST_TEST_FILES_PATH="\"$(TEST_FILES_DIRECTORY)\"" \ -UG_DISABLE_ASSERT -UG_DISABLE_CAST_CHECKS @@ -170,6 +180,26 @@ VALGRIND_TESTS_DISABLE = $(VALGRIND_TO_FIX) SUPPRESSIONS = $(top_srcdir)/common/gst.supp $(srcdir)/gst-plugins-base.supp +libs_libsabi_CFLAGS = \ + $(GST_PLUGINS_BASE_CFLAGS) \ + $(GST_BASE_CFLAGS) \ + $(AM_CFLAGS) + +libs_libsabi_LDADD = \ + $(top_builddir)/gst-libs/gst/app/libgstapp-@GST_MAJORMINOR@.la \ + $(top_builddir)/gst-libs/gst/audio/libgstaudio-@GST_MAJORMINOR@.la \ + $(top_builddir)/gst-libs/gst/cdda/libgstcdda-@GST_MAJORMINOR@.la \ + $(top_builddir)/gst-libs/gst/fft/libgstfft-@GST_MAJORMINOR@.la \ + $(top_builddir)/gst-libs/gst/interfaces/libgstinterfaces-@GST_MAJORMINOR@.la \ + $(top_builddir)/gst-libs/gst/netbuffer/libgstnetbuffer-@GST_MAJORMINOR@.la \ + $(top_builddir)/gst-libs/gst/pbutils/libgstpbutils-@GST_MAJORMINOR@.la \ + $(top_builddir)/gst-libs/gst/rtp/libgstrtp-@GST_MAJORMINOR@.la \ + $(top_builddir)/gst-libs/gst/rtsp/libgstrtsp-@GST_MAJORMINOR@.la \ + $(top_builddir)/gst-libs/gst/tag/libgsttag-@GST_MAJORMINOR@.la \ + $(top_builddir)/gst-libs/gst/video/libgstvideo-@GST_MAJORMINOR@.la \ + $(GST_BASE_LIBS) \ + $(LDADD) + libs_audio_CFLAGS = \ $(GST_PLUGINS_BASE_CFLAGS) \ $(GST_BASE_CFLAGS) \ diff --git a/tests/check/libs/libsabi.c b/tests/check/libs/libsabi.c new file mode 100644 index 0000000000..5202d921e2 --- /dev/null +++ b/tests/check/libs/libsabi.c @@ -0,0 +1,112 @@ +/* GStreamer + * Copyright (C) 2005 Wim Taymans + * 2011 Stefan Kost + * + * libsabi.c: Unit test for ABI compatibility + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* initial version of the file was generated using: + * grep -A1 "" ../../docs/libs/gst-plugins-base-libs-decl.txt | \ + * grep "" | grep -v "Private" | sort | \ + * sed -e 's/\(.*\)<\/NAME>/\ {\"\1\", sizeof (\1), 0\},/' + * + * it needs a bit of editing to remove opaque structs + */ + +#ifdef HAVE_CPU_I386 +#include "struct_i386.h" +#define HAVE_ABI_SIZES TRUE +#else +/* in case someone wants to generate a new arch */ +#include "struct_i386.h" +#define HAVE_ABI_SIZES FALSE +#endif + +GST_START_TEST (test_ABI) +{ + gst_check_abi_list (list, HAVE_ABI_SIZES); +} + +GST_END_TEST; + +static Suite * +libsabi_suite (void) +{ + Suite *s = suite_create ("LibsABI"); + TCase *tc_chain = tcase_create ("size check"); + + tcase_set_timeout (tc_chain, 0); + + suite_add_tcase (s, tc_chain); + tcase_add_test (tc_chain, test_ABI); + return s; +} + +GST_CHECK_MAIN (libsabi); diff --git a/tests/check/libs/struct_i386.h b/tests/check/libs/struct_i386.h new file mode 100644 index 0000000000..6f504adefa --- /dev/null +++ b/tests/check/libs/struct_i386.h @@ -0,0 +1,100 @@ + +GstCheckABIStruct list[] = { + {"GstAppBufferClass", sizeof (GstAppBufferClass), 16}, + {"GstAppBuffer", sizeof (GstAppBuffer), 88}, + {"GstAppSinkCallbacks", sizeof (GstAppSinkCallbacks), 28}, + {"GstAppSinkClass", sizeof (GstAppSinkClass), 404}, + {"GstAppSink", sizeof (GstAppSink), 404}, + {"GstAppSrcCallbacks", sizeof (GstAppSrcCallbacks), 28}, + {"GstAppSrcClass", sizeof (GstAppSrcClass), 412}, + {"GstAppSrc", sizeof (GstAppSrc), 396}, + {"GstAudioClockClass", sizeof (GstAudioClockClass), 192}, + {"GstAudioClock", sizeof (GstAudioClock), 228}, + {"GstAudioFilterClass", sizeof (GstAudioFilterClass), 396}, + {"GstAudioFilter", sizeof (GstAudioFilter), 480}, + {"GstAudioSinkClass", sizeof (GstAudioSinkClass), 432}, + {"GstAudioSink", sizeof (GstAudioSink), 456}, + {"GstAudioSrcClass", sizeof (GstAudioSrcClass), 460}, + {"GstAudioSrc", sizeof (GstAudioSrc), 460}, + {"GstBaseAudioSinkClass", sizeof (GstBaseAudioSinkClass), 388}, + {"GstBaseAudioSink", sizeof (GstBaseAudioSink), 436}, + {"GstBaseAudioSrcClass", sizeof (GstBaseAudioSrcClass), 416}, + {"GstBaseAudioSrc", sizeof (GstBaseAudioSrc), 440}, + {"GstBaseRTPAudioPayloadClass", sizeof (GstBaseRTPAudioPayloadClass), 288}, + {"GstBaseRTPAudioPayload", sizeof (GstBaseRTPAudioPayload), 364}, + {"GstBaseRTPDepayloadClass", sizeof (GstBaseRTPDepayloadClass), 280}, + {"GstBaseRTPDepayload", sizeof (GstBaseRTPDepayload), 304}, + {"GstBaseRTPPayloadClass", sizeof (GstBaseRTPPayloadClass), 272}, + {"GstBaseRTPPayload", sizeof (GstBaseRTPPayload), 324}, + {"GstCddaBaseSrcClass", sizeof (GstCddaBaseSrcClass), 432}, + {"GstCddaBaseSrc", sizeof (GstCddaBaseSrc), 508}, + {"GstCddaBaseSrcTrack", sizeof (GstCddaBaseSrcTrack), 36}, + {"GstColorBalanceChannelClass", sizeof (GstColorBalanceChannelClass), 88}, + {"GstColorBalanceChannel", sizeof (GstColorBalanceChannel), 24}, + {"GstColorBalanceClass", sizeof (GstColorBalanceClass), 44}, + {"GstDiscovererClass", sizeof (GstDiscovererClass), 96}, + {"GstDiscoverer", sizeof (GstDiscoverer), 32}, + {"GstFFTF32Complex", sizeof (GstFFTF32Complex), 8}, + {"GstFFTF32", sizeof (GstFFTF32), 28}, + {"GstFFTF64Complex", sizeof (GstFFTF64Complex), 16}, + {"GstFFTF64", sizeof (GstFFTF64), 28}, + {"GstFFTS16Complex", sizeof (GstFFTS16Complex), 4}, + {"GstFFTS16", sizeof (GstFFTS16), 28}, + {"GstFFTS32Complex", sizeof (GstFFTS32Complex), 8}, + {"GstFFTS32", sizeof (GstFFTS32), 28}, + {"GstMixerClass", sizeof (GstMixerClass), 72}, + {"GstMixerOptionsClass", sizeof (GstMixerOptionsClass), 100}, + {"GstMixerOptions", sizeof (GstMixerOptions), 52}, + {"GstMixerTrackClass", sizeof (GstMixerTrackClass), 84}, + {"GstMixerTrack", sizeof (GstMixerTrack), 32}, + {"GstNavigationInterface", sizeof (GstNavigationInterface), 28}, + {"GstNetAddress", sizeof (GstNetAddress), 40}, + {"GstNetBufferClass", sizeof (GstNetBufferClass), 32}, + {"GstNetBuffer", sizeof (GstNetBuffer), 176}, + {"GstPropertyProbeInterface", sizeof (GstPropertyProbeInterface), 44}, + {"gst_riff_acid", sizeof (gst_riff_acid), 24}, + {"gst_riff_dmlh", sizeof (gst_riff_dmlh), 4}, + {"gst_riff_index_entry", sizeof (gst_riff_index_entry), 16}, + {"gst_riff_strf_auds", sizeof (gst_riff_strf_auds), 16}, + {"gst_riff_strf_iavs", sizeof (gst_riff_strf_iavs), 32}, + {"gst_riff_strf_vids", sizeof (gst_riff_strf_vids), 40}, + {"gst_riff_strh", sizeof (gst_riff_strh), 48}, + {"GstRingBufferClass", sizeof (GstRingBufferClass), 172}, + {"GstRingBuffer", sizeof (GstRingBuffer), 220}, + {"GstRingBufferSpec", sizeof (GstRingBufferSpec), 112}, + {"GstRTCPPacket", sizeof (GstRTCPPacket), 36}, + {"GstRTPPayloadInfo", sizeof (GstRTPPayloadInfo), 24}, + {"GstRTSPExtensionInterface", sizeof (GstRTSPExtensionInterface), 60}, + {"GstRTSPMessage", sizeof (GstRTSPMessage), 28}, + {"GstRTSPRange", sizeof (GstRTSPRange), 8}, + {"GstRTSPTime", sizeof (GstRTSPTime), 12}, + {"GstRTSPTimeRange", sizeof (GstRTSPTimeRange), 28}, + {"GstRTSPTransport", sizeof (GstRTSPTransport), 76}, + {"GstRTSPUrl", sizeof (GstRTSPUrl), 32}, + {"GstRTSPWatchFuncs", sizeof (GstRTSPWatchFuncs), 40}, + {"GstSDPAttribute", sizeof (GstSDPAttribute), 8}, + {"GstSDPBandwidth", sizeof (GstSDPBandwidth), 8}, + {"GstSDPConnection", sizeof (GstSDPConnection), 20}, + {"GstSDPKey", sizeof (GstSDPKey), 8}, + {"GstSDPMedia", sizeof (GstSDPMedia), 44}, + {"GstSDPMessage", sizeof (GstSDPMessage), 96}, + {"GstSDPOrigin", sizeof (GstSDPOrigin), 24}, + {"GstSDPTime", sizeof (GstSDPTime), 12}, + {"GstSDPZone", sizeof (GstSDPZone), 8}, + {"GstStreamVolumeInterface", sizeof (GstStreamVolumeInterface), 24}, + {"GstTagDemuxClass", sizeof (GstTagDemuxClass), 284}, + {"GstTagDemux", sizeof (GstTagDemux), 148}, + {"GstTunerChannelClass", sizeof (GstTunerChannelClass), 92}, + {"GstTunerChannel", sizeof (GstTunerChannel), 40}, + {"GstTunerClass", sizeof (GstTunerClass), 76}, + {"GstTunerNormClass", sizeof (GstTunerNormClass), 84}, + {"GstTunerNorm", sizeof (GstTunerNorm), 36}, + {"GstVideoFilterClass", sizeof (GstVideoFilterClass), 376}, + {"GstVideoFilter", sizeof (GstVideoFilter), 356}, + {"GstVideoOrientationInterface", sizeof (GstVideoOrientationInterface), 56}, + {"GstVideoRectangle", sizeof (GstVideoRectangle), 16}, + {"GstVideoSinkClass", sizeof (GstVideoSinkClass), 384}, + {"GstVideoSink", sizeof (GstVideoSink), 408}, + {"GstXOverlayClass", sizeof (GstXOverlayClass), 32}, + {NULL, 0, 0} +};