diff --git a/configure.ac b/configure.ac index 51e39821f5..84c2819ae8 100644 --- a/configure.ac +++ b/configure.ac @@ -259,7 +259,7 @@ AC_CHECK_FUNC(gethostbyname,,[AC_CHECK_LIB(nsl,gethostbyname)]) dnl *** checks for dependency libraries *** dnl GLib is required -AG_GST_GLIB_CHECK([2.22]) +AG_GST_GLIB_CHECK([2.24]) ORC_CHECK([0.4.11]) diff --git a/ext/gnomevfs/gstgnomevfssrc.c b/ext/gnomevfs/gstgnomevfssrc.c index e0ae5da401..59c261317a 100644 --- a/ext/gnomevfs/gstgnomevfssrc.c +++ b/ext/gnomevfs/gstgnomevfssrc.c @@ -70,6 +70,7 @@ #include "gst/gst-i18n-plugin.h" #include "gstgnomevfssrc.h" +#include #include #include @@ -128,6 +129,8 @@ static void gst_gnome_vfs_src_get_property (GObject * object, guint prop_id, static gboolean gst_gnome_vfs_src_stop (GstBaseSrc * src); static gboolean gst_gnome_vfs_src_start (GstBaseSrc * src); static gboolean gst_gnome_vfs_src_is_seekable (GstBaseSrc * src); +static gboolean gst_gnome_vfs_src_unlock (GstBaseSrc * basesrc); +static gboolean gst_gnome_vfs_src_unlock_stop (GstBaseSrc * basesrc); static gboolean gst_gnome_vfs_src_get_size (GstBaseSrc * src, guint64 * size); static GstFlowReturn gst_gnome_vfs_src_create (GstBaseSrc * basesrc, guint64 offset, guint size, GstBuffer ** buffer); @@ -202,6 +205,9 @@ gst_gnome_vfs_src_class_init (GstGnomeVFSSrcClass * klass) gstbasesrc_class->start = GST_DEBUG_FUNCPTR (gst_gnome_vfs_src_start); gstbasesrc_class->stop = GST_DEBUG_FUNCPTR (gst_gnome_vfs_src_stop); + gstbasesrc_class->unlock = GST_DEBUG_FUNCPTR (gst_gnome_vfs_src_unlock); + gstbasesrc_class->unlock_stop = + GST_DEBUG_FUNCPTR (gst_gnome_vfs_src_unlock_stop); gstbasesrc_class->get_size = GST_DEBUG_FUNCPTR (gst_gnome_vfs_src_get_size); gstbasesrc_class->is_seekable = GST_DEBUG_FUNCPTR (gst_gnome_vfs_src_is_seekable); @@ -214,7 +220,9 @@ gst_gnome_vfs_src_init (GstGnomeVFSSrc * gnomevfssrc) { gnomevfssrc->uri = NULL; gnomevfssrc->uri_name = NULL; + gnomevfssrc->context = NULL; gnomevfssrc->handle = NULL; + gnomevfssrc->interrupted = FALSE; gnomevfssrc->curoffset = 0; gnomevfssrc->seekable = FALSE; @@ -563,6 +571,7 @@ gst_gnome_vfs_src_create (GstBaseSrc * basesrc, guint64 offset, guint size, guint8 *data, *ptr; gsize todo; GstGnomeVFSSrc *src; + gboolean interrupted = FALSE; src = GST_GNOME_VFS_SRC (basesrc); @@ -593,9 +602,21 @@ gst_gnome_vfs_src_create (GstBaseSrc * basesrc, guint64 offset, guint size, ptr = data; todo = size; - while (todo > 0) { + while (!src->interrupted && todo > 0) { /* this can return less that we ask for */ - res = gnome_vfs_read (src->handle, ptr, todo, &readbytes); + res = + gnome_vfs_read_cancellable (src->handle, data, todo, &readbytes, + src->context); + + if (G_UNLIKELY (res == GNOME_VFS_ERROR_CANCELLED)) { + GST_DEBUG_OBJECT (src, "interrupted"); + + /* Just take what we've so far gotten and return */ + size = size - todo; + todo = 0; + interrupted = TRUE; + break; + } if (G_UNLIKELY (res == GNOME_VFS_ERROR_EOF || (res == GNOME_VFS_OK && readbytes == 0))) @@ -614,6 +635,9 @@ gst_gnome_vfs_src_create (GstBaseSrc * basesrc, guint64 offset, guint size, } gst_buffer_unmap (buf, data, size); + if (interrupted) + goto interrupted; + GST_BUFFER_OFFSET (buf) = src->curoffset; src->curoffset += size; @@ -644,6 +668,11 @@ read_failed: ("Failed to read data: %s", gnome_vfs_result_to_string (res))); return GST_FLOW_ERROR; } +interrupted: + { + gst_buffer_unref (buf); + return GST_FLOW_WRONG_STATE; + } eos: { gst_buffer_unmap (buf, data, size); @@ -733,6 +762,37 @@ gst_gnome_vfs_src_query (GstBaseSrc * basesrc, GstQuery * query) return ret; } +/* Interrupt a blocking request. */ +static gboolean +gst_gnome_vfs_src_unlock (GstBaseSrc * basesrc) +{ + GstGnomeVFSSrc *src; + + src = GST_GNOME_VFS_SRC (basesrc); + GST_DEBUG_OBJECT (src, "unlock()"); + src->interrupted = TRUE; + if (src->context) { + GnomeVFSCancellation *cancel = + gnome_vfs_context_get_cancellation (src->context); + if (cancel) + gnome_vfs_cancellation_cancel (cancel); + } + return TRUE; +} + +/* Interrupt interrupt. */ +static gboolean +gst_gnome_vfs_src_unlock_stop (GstBaseSrc * basesrc) +{ + GstGnomeVFSSrc *src; + + src = GST_GNOME_VFS_SRC (basesrc); + GST_DEBUG_OBJECT (src, "unlock_stop()"); + + src->interrupted = FALSE; + return TRUE; +} + static gboolean gst_gnome_vfs_src_get_size (GstBaseSrc * basesrc, guint64 * size) { @@ -786,6 +846,7 @@ gst_gnome_vfs_src_start (GstBaseSrc * basesrc) gst_gnome_vfs_src_push_callbacks (src); + src->context = gnome_vfs_context_new (); if (src->uri != NULL) { GnomeVFSOpenMode mode = GNOME_VFS_OPEN_READ; @@ -857,6 +918,9 @@ gst_gnome_vfs_src_stop (GstBaseSrc * basesrc) src->handle = NULL; } src->curoffset = 0; + src->interrupted = FALSE; + gnome_vfs_context_free (src->context); + src->context = NULL; return TRUE; } diff --git a/ext/gnomevfs/gstgnomevfssrc.h b/ext/gnomevfs/gstgnomevfssrc.h index 31c1f65caa..e8c228d9b7 100644 --- a/ext/gnomevfs/gstgnomevfssrc.h +++ b/ext/gnomevfs/gstgnomevfssrc.h @@ -58,8 +58,10 @@ struct _GstGnomeVFSSrc /* uri, file, ... */ GnomeVFSURI *uri; gchar *uri_name; + GnomeVFSContext *context; GnomeVFSHandle *handle; gboolean own_handle; + gboolean interrupted; GnomeVFSFileOffset curoffset; /* current offset in file */ gboolean seekable; diff --git a/ext/pango/gstbasetextoverlay.c b/ext/pango/gstbasetextoverlay.c index 25f913cc45..d437ac1644 100644 --- a/ext/pango/gstbasetextoverlay.c +++ b/ext/pango/gstbasetextoverlay.c @@ -114,6 +114,7 @@ GST_DEBUG_CATEGORY (pango_debug); #define DEFAULT_PROP_AUTO_ADJUST_SIZE TRUE #define DEFAULT_PROP_VERTICAL_RENDER FALSE #define DEFAULT_PROP_COLOR 0xffffffff +#define DEFAULT_PROP_OUTLINE_COLOR 0xff000000 /* make a property of me */ #define DEFAULT_SHADING_VALUE -80 @@ -186,6 +187,8 @@ enum PROP_AUTO_ADJUST_SIZE, PROP_VERTICAL_RENDER, PROP_COLOR, + PROP_SHADOW, + PROP_OUTLINE_COLOR, PROP_LAST }; @@ -518,6 +521,18 @@ gst_base_text_overlay_class_init (GstBaseTextOverlayClass * klass) "Color to use for text (big-endian ARGB).", 0, G_MAXUINT32, DEFAULT_PROP_COLOR, G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE | G_PARAM_STATIC_STRINGS)); + /** + * GstTextOverlay:outline-color + * + * Color of the outline of the rendered text. + * + * Since: 0.10.35 + **/ + g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_OUTLINE_COLOR, + g_param_spec_uint ("outline-color", "Text Outline Color", + "Color to use for outline the text (big-endian ARGB).", 0, + G_MAXUINT32, DEFAULT_PROP_OUTLINE_COLOR, + G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE | G_PARAM_STATIC_STRINGS)); /** * GstBaseTextOverlay:line-alignment @@ -666,6 +681,7 @@ gst_base_text_overlay_init (GstBaseTextOverlay * overlay, gst_base_text_overlay_adjust_values_with_fontdesc (overlay, desc); overlay->color = DEFAULT_PROP_COLOR; + overlay->outline_color = DEFAULT_PROP_OUTLINE_COLOR; overlay->halign = DEFAULT_PROP_HALIGNMENT; overlay->valign = DEFAULT_PROP_VALIGNMENT; overlay->xpad = DEFAULT_PROP_XPAD; @@ -902,6 +918,9 @@ gst_base_text_overlay_set_property (GObject * object, guint prop_id, case PROP_COLOR: overlay->color = g_value_get_uint (value); break; + case PROP_OUTLINE_COLOR: + overlay->outline_color = g_value_get_uint (value); + break; case PROP_SILENT: overlay->silent = g_value_get_boolean (value); break; @@ -994,6 +1013,9 @@ gst_base_text_overlay_get_property (GObject * object, guint prop_id, case PROP_COLOR: g_value_set_uint (value, overlay->color); break; + case PROP_OUTLINE_COLOR: + g_value_set_uint (value, overlay->outline_color); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -1411,9 +1433,14 @@ gst_base_text_overlay_render_pangocairo (GstBaseTextOverlay * overlay, pango_cairo_show_layout (cr, overlay->layout); cairo_restore (cr); + a = (overlay->outline_color >> 24) & 0xff; + r = (overlay->outline_color >> 16) & 0xff; + g = (overlay->outline_color >> 8) & 0xff; + b = (overlay->outline_color >> 0) & 0xff; + /* draw outline text */ cairo_save (cr); - cairo_set_source_rgb (cr, 0.0, 0.0, 0.0); + cairo_set_source_rgba (cr, r / 255.0, g / 255.0, b / 255.0, a / 255.0); cairo_set_line_width (cr, overlay->outline_offset); pango_cairo_layout_path (cr, overlay->layout); cairo_stroke (cr); diff --git a/ext/pango/gstbasetextoverlay.h b/ext/pango/gstbasetextoverlay.h index 43192292ae..e25af5f177 100644 --- a/ext/pango/gstbasetextoverlay.h +++ b/ext/pango/gstbasetextoverlay.h @@ -136,7 +136,7 @@ struct _GstBaseTextOverlay { gboolean want_shading; gboolean silent; gboolean wait_text; - guint color; + guint color, outline_color; PangoLayout *layout; gdouble shadow_offset; diff --git a/ext/pango/gsttextrender.c b/ext/pango/gsttextrender.c index 31f671c288..cc174f7457 100644 --- a/ext/pango/gsttextrender.c +++ b/ext/pango/gsttextrender.c @@ -377,8 +377,10 @@ gst_text_render_fixate_caps (GstPad * pad, GstCaps * caps) GstStructure *s = gst_caps_get_structure (caps, 0); GST_DEBUG ("Fixating caps %" GST_PTR_FORMAT, caps); - gst_structure_fixate_field_nearest_int (s, "width", render->image_width); - gst_structure_fixate_field_nearest_int (s, "height", render->image_height); + gst_structure_fixate_field_nearest_int (s, "width", MAX (render->image_width, + DEFAULT_RENDER_WIDTH)); + gst_structure_fixate_field_nearest_int (s, "height", + MAX (render->image_height + render->ypad, DEFAULT_RENDER_HEIGHT)); GST_DEBUG ("Fixated to %" GST_PTR_FORMAT, caps); gst_object_unref (render); @@ -401,12 +403,12 @@ gst_text_renderer_image_to_ayuv (GstTextRender * render, guchar * pixbuf, width = render->image_width; height = render->image_height; - bitp = render->text_image; - for (y = 0; y < height; y++) { + for (y = 0; y < height && ypos + y < render->height; y++) { int n; p = pixbuf + (ypos + y) * stride + xpos * 4; - for (n = 0; n < width; n++) { + bitp = render->text_image + y * width * 4; + for (n = 0; n < width && n < render->width; n++) { b = bitp[CAIRO_ARGB_B]; g = bitp[CAIRO_ARGB_G]; r = bitp[CAIRO_ARGB_R]; @@ -437,11 +439,11 @@ gst_text_renderer_image_to_argb (GstTextRender * render, guchar * pixbuf, width = render->image_width; height = render->image_height; - bitp = render->text_image; - for (i = 0; i < height; i++) { + for (i = 0; i < height && ypos + i < render->height; i++) { p = pixbuf + (ypos + i) * stride + xpos * 4; - for (j = 0; j < width; j++) { + bitp = render->text_image + i * width * 4; + for (j = 0; j < width && j < render->width; j++) { p[0] = bitp[CAIRO_ARGB_A]; p[1] = bitp[CAIRO_ARGB_R]; p[2] = bitp[CAIRO_ARGB_G]; @@ -462,7 +464,7 @@ gst_text_render_chain (GstPad * pad, GstBuffer * inbuf) GstTextRender *render; GstFlowReturn ret; GstBuffer *outbuf; - GstCaps *caps = NULL; + GstCaps *caps = NULL, *padcaps; guint8 *data; gsize size; gint n; @@ -487,18 +489,20 @@ gst_text_render_chain (GstPad * pad, GstBuffer * inbuf) gst_text_render_check_argb (render); - if (!render->use_ARGB) { - caps = - gst_video_format_new_caps (GST_VIDEO_FORMAT_AYUV, render->width, - render->height, 1, 1, 1, 1); - } else { - caps = - gst_video_format_new_caps (GST_VIDEO_FORMAT_ARGB, render->width, - render->height, 1, 1, 1, 1); + padcaps = gst_pad_get_caps (render->srcpad, NULL); + caps = gst_pad_peer_get_caps (render->srcpad, padcaps); + gst_caps_unref (padcaps); + + if (!caps || gst_caps_is_empty (caps)) { + GST_ELEMENT_ERROR (render, CORE, NEGOTIATION, (NULL), (NULL)); + ret = GST_FLOW_ERROR; + goto done; } + gst_caps_truncate (caps); + gst_pad_fixate_caps (render->srcpad, caps); + if (!gst_pad_set_caps (render->srcpad, caps)) { - gst_caps_unref (caps); GST_ELEMENT_ERROR (render, CORE, NEGOTIATION, (NULL), (NULL)); ret = GST_FLOW_ERROR; goto done; diff --git a/ext/theora/gsttheoraenc.c b/ext/theora/gsttheoraenc.c index 57d76b4590..9c8d6a4b53 100644 --- a/ext/theora/gsttheoraenc.c +++ b/ext/theora/gsttheoraenc.c @@ -989,7 +989,8 @@ theora_enc_read_multipass_cache (GstTheoraEnc * enc) { GstBuffer *cache_buf; const guint8 *cache_data; - gsize bytes_read = 0, bytes_consumed = 0; + gsize bytes_read = 0; + gint bytes_consumed = 0; GIOStatus stat = G_IO_STATUS_NORMAL; gboolean done = FALSE; @@ -1064,7 +1065,7 @@ theora_enc_write_multipass_cache (GstTheoraEnc * enc, gboolean begin, } - if (stat == G_IO_STATUS_ERROR || bytes_read < 0 || bytes_written < 0) { + if (stat == G_IO_STATUS_ERROR || bytes_read < 0) { if (begin) { if (eos) GST_ELEMENT_WARNING (enc, RESOURCE, WRITE, (NULL), diff --git a/gst-libs/gst/riff/riff-read.c b/gst-libs/gst/riff/riff-read.c index c422f043c0..5fc6df5425 100644 --- a/gst-libs/gst/riff/riff-read.c +++ b/gst-libs/gst/riff/riff-read.c @@ -555,7 +555,7 @@ too_small: * codec initialization data). * * Parses a interleaved (also known as "complex") streamĀ“s strf - * structure plus optionally some extradata from input data. This + * structure plus optionally some extradata from input data. This * function takes ownership of @buf. * * Returns: TRUE if parsing succeeded, otherwise FALSE. @@ -643,7 +643,6 @@ gst_riff_parse_info (GstElement * element, GstTagList *taglist; g_return_if_fail (_taglist != NULL); - g_return_if_fail (buf != NULL); if (!buf) { *_taglist = NULL; diff --git a/gst-libs/gst/tag/gstexiftag.c b/gst-libs/gst/tag/gstexiftag.c index 7dc9ac6225..0635240f1b 100644 --- a/gst-libs/gst/tag/gstexiftag.c +++ b/gst-libs/gst/tag/gstexiftag.c @@ -2627,14 +2627,6 @@ deserialize_resolution (GstExifReader * exif_reader, unit = GST_READ_UINT16_BE (tagdata->offset_as_data); } - if (unit != 2 && unit != 3) { - GST_WARNING ("Invalid resolution unit, ignoring PPI tags"); - return 0; - } - - xres = gst_exif_reader_get_pending_tag (exif_reader, EXIF_TAG_XRESOLUTION); - yres = gst_exif_reader_get_pending_tag (exif_reader, EXIF_TAG_YRESOLUTION); - switch (unit) { case 2: /* inch */ multiplier = 1; @@ -2643,15 +2635,16 @@ deserialize_resolution (GstExifReader * exif_reader, multiplier = 1 / 2.54; break; default: - multiplier = 1; - g_assert_not_reached (); - break; + GST_WARNING ("Invalid resolution unit, ignoring PPI tags"); + return 0; } + xres = gst_exif_reader_get_pending_tag (exif_reader, EXIF_TAG_XRESOLUTION); if (xres) { parse_exif_rational_tag (exif_reader, GST_TAG_IMAGE_HORIZONTAL_PPI, xres->count, xres->offset, multiplier, FALSE); } + yres = gst_exif_reader_get_pending_tag (exif_reader, EXIF_TAG_YRESOLUTION); if (yres) { parse_exif_rational_tag (exif_reader, GST_TAG_IMAGE_VERTICAL_PPI, yres->count, yres->offset, multiplier, FALSE); @@ -2670,7 +2663,7 @@ serialize_scene_type (GstExifWriter * writer, const GstTagList * taglist, if (gst_tag_list_peek_string_index (taglist, GST_TAG_CAPTURING_SOURCE, 0, &str)) { if (strcmp (str, "dsc") == 0) { - value = 0; + value = 1; } } diff --git a/gst/audiotestsrc/gstaudiotestsrc.c b/gst/audiotestsrc/gstaudiotestsrc.c index a40b0dae26..1ad73729ca 100644 --- a/gst/audiotestsrc/gstaudiotestsrc.c +++ b/gst/audiotestsrc/gstaudiotestsrc.c @@ -129,6 +129,9 @@ gst_audiostestsrc_wave_get_type (void) {GST_AUDIO_TEST_SRC_WAVE_TICKS, "Periodic Ticks", "ticks"}, {GST_AUDIO_TEST_SRC_WAVE_GAUSSIAN_WHITE_NOISE, "White Gaussian noise", "gaussian-noise"}, + {GST_AUDIO_TEST_SRC_WAVE_RED_NOISE, "Red (brownian) noise", "red-noise"}, + {GST_AUDIO_TEST_SRC_WAVE_BLUE_NOISE, "Blue noise", "blue-noise"}, + {GST_AUDIO_TEST_SRC_WAVE_VIOLET_NOISE, "Violet noise", "violet-noise"}, {0, NULL, NULL}, }; @@ -836,6 +839,109 @@ static const ProcessFunc gaussian_white_noise_funcs[] = { (ProcessFunc) gst_audio_test_src_create_gaussian_white_noise_double }; +/* Brownian (Red) Noise: noise where the power density decreases by 6 dB per + * octave with increasing frequency + * + * taken from http://vellocet.com/dsp/noise/VRand.html + * by Andrew Simper of Vellocet (andy@vellocet.com) + */ + +#define DEFINE_RED_NOISE(type,scale) \ +static void \ +gst_audio_test_src_create_red_noise_##type (GstAudioTestSrc * src, g##type * samples) \ +{ \ + gint i, c; \ + gdouble amp = (src->volume * scale); \ + gdouble state = src->red.state; \ + \ + for (i = 0; i < src->generate_samples_per_buffer * src->channels; ) { \ + for (c = 0; c < src->channels; ++c) { \ + while (TRUE) { \ + gdouble r = g_rand_double_range (src->gen, -1.0, 1.0); \ + state += r; \ + if (state<-8.0f || state>8.0f) state -= r; \ + else break; \ + } \ + samples[i++] = (g##type) (amp * state * 0.0625f); /* /16.0 */ \ + } \ + } \ + src->red.state = state; \ +} + +DEFINE_RED_NOISE (int16, 32767.0); +DEFINE_RED_NOISE (int32, 2147483647.0); +DEFINE_RED_NOISE (float, 1.0); +DEFINE_RED_NOISE (double, 1.0); + +static const ProcessFunc red_noise_funcs[] = { + (ProcessFunc) gst_audio_test_src_create_red_noise_int16, + (ProcessFunc) gst_audio_test_src_create_red_noise_int32, + (ProcessFunc) gst_audio_test_src_create_red_noise_float, + (ProcessFunc) gst_audio_test_src_create_red_noise_double +}; + +/* Blue Noise: apply spectral inversion to pink noise */ + +#define DEFINE_BLUE_NOISE(type) \ +static void \ +gst_audio_test_src_create_blue_noise_##type (GstAudioTestSrc * src, g##type * samples) \ +{ \ + gint i, c; \ + static gdouble flip=1.0; \ + \ + gst_audio_test_src_create_pink_noise_##type (src, samples); \ + for (i = 0; i < src->generate_samples_per_buffer * src->channels; ) { \ + for (c = 0; c < src->channels; ++c) { \ + samples[i++] *= flip; \ + } \ + flip *= -1.0; \ + } \ +} + +DEFINE_BLUE_NOISE (int16); +DEFINE_BLUE_NOISE (int32); +DEFINE_BLUE_NOISE (float); +DEFINE_BLUE_NOISE (double); + +static const ProcessFunc blue_noise_funcs[] = { + (ProcessFunc) gst_audio_test_src_create_blue_noise_int16, + (ProcessFunc) gst_audio_test_src_create_blue_noise_int32, + (ProcessFunc) gst_audio_test_src_create_blue_noise_float, + (ProcessFunc) gst_audio_test_src_create_blue_noise_double +}; + + +/* Violet Noise: apply spectral inversion to red noise */ + +#define DEFINE_VIOLET_NOISE(type) \ +static void \ +gst_audio_test_src_create_violet_noise_##type (GstAudioTestSrc * src, g##type * samples) \ +{ \ + gint i, c; \ + static gdouble flip=1.0; \ + \ + gst_audio_test_src_create_red_noise_##type (src, samples); \ + for (i = 0; i < src->generate_samples_per_buffer * src->channels; ) { \ + for (c = 0; c < src->channels; ++c) { \ + samples[i++] *= flip; \ + } \ + flip *= -1.0; \ + } \ +} + +DEFINE_VIOLET_NOISE (int16); +DEFINE_VIOLET_NOISE (int32); +DEFINE_VIOLET_NOISE (float); +DEFINE_VIOLET_NOISE (double); + +static const ProcessFunc violet_noise_funcs[] = { + (ProcessFunc) gst_audio_test_src_create_violet_noise_int16, + (ProcessFunc) gst_audio_test_src_create_violet_noise_int32, + (ProcessFunc) gst_audio_test_src_create_violet_noise_float, + (ProcessFunc) gst_audio_test_src_create_violet_noise_double +}; + + /* * gst_audio_test_src_change_wave: * Assign function pointer of wave genrator. @@ -888,6 +994,23 @@ gst_audio_test_src_change_wave (GstAudioTestSrc * src) src->gen = g_rand_new (); src->process = gaussian_white_noise_funcs[src->format]; break; + case GST_AUDIO_TEST_SRC_WAVE_RED_NOISE: + if (!(src->gen)) + src->gen = g_rand_new (); + src->red.state = 0.0; + src->process = red_noise_funcs[src->format]; + break; + case GST_AUDIO_TEST_SRC_WAVE_BLUE_NOISE: + if (!(src->gen)) + src->gen = g_rand_new (); + gst_audio_test_src_init_pink_noise (src); + src->process = blue_noise_funcs[src->format]; + break; + case GST_AUDIO_TEST_SRC_WAVE_VIOLET_NOISE: + if (!(src->gen)) + src->gen = g_rand_new (); + src->red.state = 0.0; + src->process = violet_noise_funcs[src->format]; default: GST_ERROR ("invalid wave-form"); break; diff --git a/gst/audiotestsrc/gstaudiotestsrc.h b/gst/audiotestsrc/gstaudiotestsrc.h index 8c76594822..529ad63c3e 100644 --- a/gst/audiotestsrc/gstaudiotestsrc.h +++ b/gst/audiotestsrc/gstaudiotestsrc.h @@ -50,6 +50,7 @@ G_BEGIN_DECLS * @GST_AUDIO_TEST_SRC_WAVE_SINE_TAB: sine wave using a table * @GST_AUDIO_TEST_SRC_WAVE_TICKS: periodic ticks * @GST_AUDIO_TEST_SRC_WAVE_GAUSSIAN_WHITE_NOISE: white (zero mean) Gaussian noise; volume sets the standard deviation of the noise in units of the range of values of the sample type, e.g. volume=0.1 produces noise with a standard deviation of 0.1*32767=3277 with 16-bit integer samples, or 0.1*1.0=0.1 with floating-point samples. + * @GST_AUDIO_TEST_SRC_WAVE_RED_NOISE: red (brownian) noise * * Different types of supported sound waves. */ @@ -63,8 +64,11 @@ typedef enum { GST_AUDIO_TEST_SRC_WAVE_PINK_NOISE, GST_AUDIO_TEST_SRC_WAVE_SINE_TAB, GST_AUDIO_TEST_SRC_WAVE_TICKS, - GST_AUDIO_TEST_SRC_WAVE_GAUSSIAN_WHITE_NOISE -} GstAudioTestSrcWave; + GST_AUDIO_TEST_SRC_WAVE_GAUSSIAN_WHITE_NOISE, + GST_AUDIO_TEST_SRC_WAVE_RED_NOISE, + GST_AUDIO_TEST_SRC_WAVE_BLUE_NOISE, + GST_AUDIO_TEST_SRC_WAVE_VIOLET_NOISE +} GstAudioTestSrcWave; #define PINK_MAX_RANDOM_ROWS (30) #define PINK_RANDOM_BITS (16) @@ -78,6 +82,10 @@ typedef struct { gdouble scalar; /* Used to scale within range of -1.0 to +1.0 */ } GstPinkNoise; +typedef struct { + gdouble state; /* noise state */ +} GstRedNoise; + typedef enum { GST_AUDIO_TEST_SRC_FORMAT_NONE = -1, GST_AUDIO_TEST_SRC_FORMAT_S16 = 0, @@ -105,14 +113,14 @@ struct _GstAudioTestSrc { GstAudioTestSrcWave wave; gdouble volume; gdouble freq; - + /* audio parameters */ gint channels; gint samplerate; gint samples_per_buffer; gint sample_size; GstAudioTestSrcFormat format; - + /*< private >*/ gboolean tags_pushed; /* send tags just once ? */ GstClockTimeDiff timestamp_offset; /* base offset */ @@ -125,11 +133,12 @@ struct _GstAudioTestSrc { gint generate_samples_per_buffer; /* used to generate a partial buffer */ gboolean can_activate_pull; gboolean reverse; /* play backwards */ - + /* waveform specific context data */ GRand *gen; /* random number generator */ gdouble accumulator; /* phase angle */ GstPinkNoise pink; + GstRedNoise red; gdouble wave_table[1024]; }; diff --git a/gst/playback/gstplaybin2.c b/gst/playback/gstplaybin2.c index bb4e627685..89f27d1aa2 100644 --- a/gst/playback/gstplaybin2.c +++ b/gst/playback/gstplaybin2.c @@ -2522,6 +2522,8 @@ pad_added_cb (GstElement * decodebin, GstPad * pad, GstSourceGroup * group) (_("Missing element '%s' - check your GStreamer installation."), "input-selector"), (NULL)); } else { + g_object_set (select->selector, "sync-streams", TRUE, NULL); + g_signal_connect (select->selector, "notify::active-pad", G_CALLBACK (selector_active_pad_changed), playbin); diff --git a/gst/volume/gstvolume.c b/gst/volume/gstvolume.c index d2b7c5cb06..04935d37db 100644 --- a/gst/volume/gstvolume.c +++ b/gst/volume/gstvolume.c @@ -871,6 +871,7 @@ volume_transform_ip (GstBaseTransform * base, GstBuffer * outbuf) guint nsamples = size / (width * channels); GstClockTime interval = gst_util_uint64_scale_int (1, GST_SECOND, rate); GstClockTime ts = GST_BUFFER_TIMESTAMP (outbuf); + gboolean use_mutes = FALSE; ts = gst_segment_to_stream_time (&base->segment, GST_FORMAT_TIME, ts); @@ -892,6 +893,7 @@ volume_transform_ip (GstBaseTransform * base, GstBuffer * outbuf) gst_object_unref (mute_csource); mute_csource = NULL; + use_mutes = TRUE; } else { g_free (self->mutes); self->mutes = NULL; @@ -911,7 +913,7 @@ volume_transform_ip (GstBaseTransform * base, GstBuffer * outbuf) orc_memset_f64 (self->volumes, self->current_volume, nsamples); } - if (mute_csource) { + if (use_mutes) { orc_prepare_volumes (self->volumes, self->mutes, nsamples); } diff --git a/sys/ximage/ximagepool.c b/sys/ximage/ximagepool.c index b6edc3b710..5a7d5334aa 100644 --- a/sys/ximage/ximagepool.c +++ b/sys/ximage/ximagepool.c @@ -99,8 +99,27 @@ gst_buffer_add_meta_ximage (GstBuffer * buffer, GstXImageSink * ximagesink, xcontext->visual, xcontext->depth, ZPixmap, NULL, &meta->SHMInfo, meta->width, meta->height); - if (!meta->ximage || error_caught) - goto create_failed; + if (!meta->ximage || error_caught) { + g_mutex_unlock (ximagesink->x_lock); + + /* Reset error flag */ + error_caught = FALSE; + + /* Push a warning */ + GST_ELEMENT_WARNING (ximagesink, RESOURCE, WRITE, + ("Failed to create output image buffer of %dx%d pixels", + meta->width, meta->height), + ("could not XShmCreateImage a %dx%d image", + meta->width, meta->height)); + + /* Retry without XShm */ + ximagesink->xcontext->use_xshm = FALSE; + + /* Hold X mutex again to try without XShm */ + g_mutex_lock (ximagesink->x_lock); + + goto no_xshm; + } /* we have to use the returned bytes_per_line for our shm size */ meta->size = meta->ximage->bytes_per_line * meta->ximage->height; @@ -135,6 +154,7 @@ gst_buffer_add_meta_ximage (GstBuffer * buffer, GstXImageSink * ximagesink, GST_DEBUG_OBJECT (ximagesink, "XServer ShmAttached to 0x%x, id 0x%lx", meta->SHMInfo.shmid, meta->SHMInfo.shmseg); } else + no_xshm: #endif /* HAVE_XSHM */ { guint allocsize; diff --git a/sys/ximage/ximagesink.c b/sys/ximage/ximagesink.c index 1ef50ee73d..46903fbdd4 100644 --- a/sys/ximage/ximagesink.c +++ b/sys/ximage/ximagesink.c @@ -1500,8 +1500,10 @@ config_failed: static gboolean gst_ximagesink_interface_supported (GstImplementsInterface * iface, GType type) { - g_assert (type == GST_TYPE_NAVIGATION || type == GST_TYPE_X_OVERLAY); - return TRUE; + if (type == GST_TYPE_NAVIGATION || type == GST_TYPE_X_OVERLAY) + return TRUE; + else + return FALSE; } static void diff --git a/sys/xvimage/xvimagepool.c b/sys/xvimage/xvimagepool.c index e5fafd34e6..36ba4162ba 100644 --- a/sys/xvimage/xvimagepool.c +++ b/sys/xvimage/xvimagepool.c @@ -101,8 +101,26 @@ gst_buffer_add_meta_xvimage (GstBuffer * buffer, GstXvImageSink * xvimagesink, meta->xvimage = XvShmCreateImage (xcontext->disp, xcontext->xv_port_id, meta->im_format, NULL, meta->width, meta->height, &meta->SHMInfo); - if (!meta->xvimage || error_caught) - goto create_failed; + if (!meta->xvimage || error_caught) { + g_mutex_unlock (xvimagesink->x_lock); + + /* Reset error flag */ + error_caught = FALSE; + + /* Push a warning */ + GST_ELEMENT_WARNING (xvimagesink, RESOURCE, WRITE, + ("Failed to create output image buffer of %dx%d pixels", + meta->width, meta->height), + ("could not XShmCreateImage a %dx%d image", + meta->width, meta->height)); + + /* Retry without XShm */ + xvimagesink->xcontext->use_xshm = FALSE; + + /* Hold X mutex again to try without XShm */ + g_mutex_lock (xvimagesink->x_lock); + goto no_xshm; + } /* we have to use the returned data_size for our shm size */ meta->size = meta->xvimage->data_size; @@ -189,6 +207,7 @@ gst_buffer_add_meta_xvimage (GstBuffer * buffer, GstXvImageSink * xvimagesink, GST_DEBUG_OBJECT (xvimagesink, "XServer ShmAttached to 0x%x, id 0x%lx", meta->SHMInfo.shmid, meta->SHMInfo.shmseg); } else + no_xshm: #endif /* HAVE_XSHM */ { meta->xvimage = XvCreateImage (xcontext->disp, diff --git a/sys/xvimage/xvimagesink.c b/sys/xvimage/xvimagesink.c index 33f54ea3e6..87cacf137f 100644 --- a/sys/xvimage/xvimagesink.c +++ b/sys/xvimage/xvimagesink.c @@ -2060,9 +2060,11 @@ config_failed: static gboolean gst_xvimagesink_interface_supported (GstImplementsInterface * iface, GType type) { - g_assert (type == GST_TYPE_NAVIGATION || type == GST_TYPE_X_OVERLAY || - type == GST_TYPE_COLOR_BALANCE || type == GST_TYPE_PROPERTY_PROBE); - return TRUE; + if (type == GST_TYPE_NAVIGATION || type == GST_TYPE_X_OVERLAY || + type == GST_TYPE_COLOR_BALANCE || type == GST_TYPE_PROPERTY_PROBE) + return TRUE; + else + return FALSE; } static void diff --git a/tests/examples/seek/seek.c b/tests/examples/seek/seek.c index 0780cd6989..7df277d017 100644 --- a/tests/examples/seek/seek.c +++ b/tests/examples/seek/seek.c @@ -32,9 +32,13 @@ #include #include -#ifdef HAVE_X +#include +#if defined (GDK_WINDOWING_X11) #include +#elif defined (GDK_WINDOWING_WIN32) +#include #endif + #include #if (!GTK_CHECK_VERSION(2, 23, 0) || GTK_CHECK_VERSION(2, 90, 0)) && !GTK_CHECK_VERSION(2, 91, 1) @@ -57,17 +61,10 @@ gtk_widget_get_allocation (GtkWidget * w, GtkAllocation * a) /* configuration */ -//#define SOURCE "filesrc" -#define SOURCE "gnomevfssrc" +#define SOURCE "filesrc" -#define ASINK "alsasink" -//#define ASINK "osssink" - -#define VSINK "xvimagesink" -//#define VSINK "sdlvideosink" -//#define VSINK "ximagesink" -//#define VSINK "aasink" -//#define VSINK "cacasink" +static gchar *opt_audiosink_str; /* NULL */ +static gchar *opt_videosink_str; /* NULL */ #define FILL_INTERVAL 100 //#define UPDATE_INTERVAL 500 @@ -219,7 +216,7 @@ make_mod_pipeline (const gchar * location) src = gst_element_factory_make_or_warn (SOURCE, "src"); decoder = gst_element_factory_make_or_warn ("modplug", "decoder"); - audiosink = gst_element_factory_make_or_warn (ASINK, "sink"); + audiosink = gst_element_factory_make_or_warn (opt_audiosink_str, "sink"); //g_object_set (G_OBJECT (audiosink), "sync", FALSE, NULL); g_object_set (G_OBJECT (src), "location", location, NULL); @@ -254,7 +251,7 @@ make_dv_pipeline (const gchar * location) demux = gst_element_factory_make_or_warn ("dvdemux", "demuxer"); v_queue = gst_element_factory_make_or_warn ("queue", "v_queue"); decoder = gst_element_factory_make_or_warn ("ffdec_dvvideo", "decoder"); - videosink = gst_element_factory_make_or_warn (VSINK, "v_sink"); + videosink = gst_element_factory_make_or_warn (opt_videosink_str, "v_sink"); a_queue = gst_element_factory_make_or_warn ("queue", "a_queue"); audiosink = gst_element_factory_make_or_warn ("alsasink", "a_sink"); @@ -295,7 +292,7 @@ make_wav_pipeline (const gchar * location) src = gst_element_factory_make_or_warn (SOURCE, "src"); decoder = gst_element_factory_make_or_warn ("wavparse", "decoder"); - audiosink = gst_element_factory_make_or_warn (ASINK, "sink"); + audiosink = gst_element_factory_make_or_warn (opt_audiosink_str, "sink"); g_object_set (G_OBJECT (src), "location", location, NULL); @@ -327,7 +324,7 @@ make_flac_pipeline (const gchar * location) src = gst_element_factory_make_or_warn (SOURCE, "src"); decoder = gst_element_factory_make_or_warn ("flacdec", "decoder"); - audiosink = gst_element_factory_make_or_warn (ASINK, "sink"); + audiosink = gst_element_factory_make_or_warn (opt_audiosink_str, "sink"); g_object_set (G_OBJECT (audiosink), "sync", FALSE, NULL); g_object_set (G_OBJECT (src), "location", location, NULL); @@ -359,7 +356,7 @@ make_sid_pipeline (const gchar * location) src = gst_element_factory_make_or_warn (SOURCE, "src"); decoder = gst_element_factory_make_or_warn ("siddec", "decoder"); - audiosink = gst_element_factory_make_or_warn (ASINK, "sink"); + audiosink = gst_element_factory_make_or_warn (opt_audiosink_str, "sink"); //g_object_set (G_OBJECT (audiosink), "sync", FALSE, NULL); g_object_set (G_OBJECT (src), "location", location, NULL); @@ -426,7 +423,7 @@ make_vorbis_pipeline (const gchar * location) demux = gst_element_factory_make_or_warn ("oggdemux", "demux"); decoder = gst_element_factory_make_or_warn ("vorbisdec", "decoder"); convert = gst_element_factory_make_or_warn ("audioconvert", "convert"); - audiosink = gst_element_factory_make_or_warn (ASINK, "sink"); + audiosink = gst_element_factory_make_or_warn (opt_audiosink_str, "sink"); g_object_set (G_OBJECT (audiosink), "sync", TRUE, NULL); g_object_set (G_OBJECT (src), "location", location, NULL); @@ -473,7 +470,7 @@ make_theora_pipeline (const gchar * location) demux = gst_element_factory_make_or_warn ("oggdemux", "demux"); decoder = gst_element_factory_make_or_warn ("theoradec", "decoder"); convert = gst_element_factory_make_or_warn ("ffmpegcolorspace", "convert"); - videosink = gst_element_factory_make_or_warn (VSINK, "sink"); + videosink = gst_element_factory_make_or_warn (opt_videosink_str, "sink"); g_object_set (G_OBJECT (src), "location", location, NULL); @@ -531,7 +528,7 @@ make_vorbis_theora_pipeline (const gchar * location) a_queue = gst_element_factory_make_or_warn ("queue", "a_queue"); a_decoder = gst_element_factory_make_or_warn ("vorbisdec", "a_dec"); a_convert = gst_element_factory_make_or_warn ("audioconvert", "a_convert"); - audiosink = gst_element_factory_make_or_warn (ASINK, "a_sink"); + audiosink = gst_element_factory_make_or_warn (opt_audiosink_str, "a_sink"); gst_bin_add (GST_BIN (pipeline), audio_bin); @@ -557,7 +554,7 @@ make_vorbis_theora_pipeline (const gchar * location) v_convert = gst_element_factory_make_or_warn ("ffmpegcolorspace", "v_convert"); v_scale = gst_element_factory_make_or_warn ("videoscale", "v_scale"); - videosink = gst_element_factory_make_or_warn (VSINK, "v_sink"); + videosink = gst_element_factory_make_or_warn (opt_videosink_str, "v_sink"); gst_bin_add (GST_BIN (pipeline), video_bin); @@ -611,7 +608,7 @@ make_avi_msmpeg4v3_mp3_pipeline (const gchar * location) a_queue = gst_element_factory_make_or_warn ("queue", "a_queue"); a_decoder = gst_element_factory_make_or_warn ("mad", "a_dec"); a_convert = gst_element_factory_make_or_warn ("audioconvert", "a_convert"); - audiosink = gst_element_factory_make_or_warn (ASINK, "a_sink"); + audiosink = gst_element_factory_make_or_warn (opt_audiosink_str, "a_sink"); gst_bin_add (GST_BIN (audio_bin), a_queue); gst_bin_add (GST_BIN (audio_bin), a_decoder); @@ -636,7 +633,7 @@ make_avi_msmpeg4v3_mp3_pipeline (const gchar * location) v_decoder = gst_element_factory_make_or_warn ("ffdec_msmpeg4", "v_dec"); v_convert = gst_element_factory_make_or_warn ("ffmpegcolorspace", "v_convert"); - videosink = gst_element_factory_make_or_warn (VSINK, "v_sink"); + videosink = gst_element_factory_make_or_warn (opt_videosink_str, "v_sink"); gst_bin_add (GST_BIN (video_bin), v_queue); gst_bin_add (GST_BIN (video_bin), v_decoder); @@ -677,7 +674,7 @@ make_mp3_pipeline (const gchar * location) parser = gst_element_factory_make_or_warn ("mp3parse", "parse"); decoder = gst_element_factory_make_or_warn ("mad", "dec"); queue = gst_element_factory_make_or_warn ("queue", "queue"); - audiosink = gst_element_factory_make_or_warn (ASINK, "sink"); + audiosink = gst_element_factory_make_or_warn (opt_audiosink_str, "sink"); seekable_elements = g_list_prepend (seekable_elements, audiosink); @@ -726,7 +723,7 @@ make_avi_pipeline (const gchar * location) audio_bin = gst_bin_new ("a_decoder_bin"); a_decoder = gst_element_factory_make_or_warn ("mad", "a_dec"); - audiosink = gst_element_factory_make_or_warn (ASINK, "a_sink"); + audiosink = gst_element_factory_make_or_warn (opt_audiosink_str, "a_sink"); a_queue = gst_element_factory_make_or_warn ("queue", "a_queue"); gst_element_link (a_decoder, a_queue); gst_element_link (a_queue, audiosink); @@ -747,7 +744,7 @@ make_avi_pipeline (const gchar * location) video_bin = gst_bin_new ("v_decoder_bin"); v_decoder = gst_element_factory_make_or_warn ("ffmpegdecall", "v_dec"); - videosink = gst_element_factory_make_or_warn (VSINK, "v_sink"); + videosink = gst_element_factory_make_or_warn (opt_videosink_str, "v_sink"); v_queue = gst_element_factory_make_or_warn ("queue", "v_queue"); gst_element_link (v_decoder, v_queue); gst_element_link (v_queue, videosink); @@ -795,7 +792,7 @@ make_mpeg_pipeline (const gchar * location) audio_bin = gst_bin_new ("a_decoder_bin"); a_decoder = gst_element_factory_make_or_warn ("mad", "a_dec"); a_queue = gst_element_factory_make_or_warn ("queue", "a_queue"); - audiosink = gst_element_factory_make_or_warn (ASINK, "a_sink"); + audiosink = gst_element_factory_make_or_warn (opt_audiosink_str, "a_sink"); gst_bin_add (GST_BIN (audio_bin), a_decoder); gst_bin_add (GST_BIN (audio_bin), a_queue); gst_bin_add (GST_BIN (audio_bin), audiosink); @@ -816,7 +813,7 @@ make_mpeg_pipeline (const gchar * location) v_decoder = gst_element_factory_make_or_warn ("mpeg2dec", "v_dec"); v_queue = gst_element_factory_make_or_warn ("queue", "v_queue"); v_filter = gst_element_factory_make_or_warn ("ffmpegcolorspace", "v_filter"); - videosink = gst_element_factory_make_or_warn (VSINK, "v_sink"); + videosink = gst_element_factory_make_or_warn (opt_videosink_str, "v_sink"); gst_bin_add (GST_BIN (video_bin), v_decoder); gst_bin_add (GST_BIN (video_bin), v_queue); @@ -872,7 +869,7 @@ make_mpegnt_pipeline (const gchar * location) audio_bin = gst_bin_new ("a_decoder_bin"); a_decoder = gst_element_factory_make_or_warn ("mad", "a_dec"); a_queue = gst_element_factory_make_or_warn ("queue", "a_queue"); - audiosink = gst_element_factory_make_or_warn (ASINK, "a_sink"); + audiosink = gst_element_factory_make_or_warn (opt_audiosink_str, "a_sink"); //g_object_set (G_OBJECT (audiosink), "fragment", 0x00180008, NULL); g_object_set (G_OBJECT (audiosink), "sync", FALSE, NULL); gst_element_link (a_decoder, a_queue); @@ -894,7 +891,7 @@ make_mpegnt_pipeline (const gchar * location) video_bin = gst_bin_new ("v_decoder_bin"); v_decoder = gst_element_factory_make_or_warn ("mpeg2dec", "v_dec"); v_filter = gst_element_factory_make_or_warn ("ffmpegcolorspace", "v_filter"); - videosink = gst_element_factory_make_or_warn (VSINK, "v_sink"); + videosink = gst_element_factory_make_or_warn (opt_videosink_str, "v_sink"); gst_element_link_many (v_decoder, v_filter, videosink, NULL); gst_bin_add_many (GST_BIN (video_bin), v_decoder, v_filter, videosink, NULL); @@ -918,11 +915,13 @@ playerbin_set_uri (GstElement * player, const gchar * location) gchar *uri; /* Add "file://" prefix for convenience */ - if (g_str_has_prefix (location, "/")) { - uri = g_strconcat ("file://", location, NULL); + if (g_str_has_prefix (location, "/") || !gst_uri_is_valid (location)) { + uri = gst_filename_to_uri (location, NULL); + g_print ("Setting URI: %s\n", uri); g_object_set (G_OBJECT (player), "uri", uri, NULL); g_free (uri); } else { + g_print ("Setting URI: %s\n", location); g_object_set (G_OBJECT (player), "uri", location, NULL); } } @@ -931,6 +930,7 @@ static GstElement * construct_playerbin (const gchar * name, const gchar * location) { GstElement *player; + GstElement *avsink; player = gst_element_factory_make (name, "player"); g_assert (player); @@ -942,6 +942,14 @@ construct_playerbin (const gchar * name, const gchar * location) /* force element seeking on this pipeline */ elem_seek = TRUE; + avsink = gst_element_factory_make_or_warn (opt_audiosink_str, "a_sink"); + if (avsink) + g_object_set (player, "audio-sink", avsink, NULL); + + avsink = gst_element_factory_make_or_warn (opt_videosink_str, "v_sink"); + if (avsink) + g_object_set (player, "video-sink", avsink, NULL); + return player; } @@ -2432,7 +2440,7 @@ msg_clock_lost (GstBus * bus, GstMessage * message, GstPipeline * data) } } -#ifdef HAVE_X +#if defined (GDK_WINDOWING_X11) || defined (GDK_WINDOWING_WIN32) static gulong embed_xid = 0; @@ -2500,11 +2508,15 @@ realize_cb (GtkWidget * widget, gpointer data) } #endif -#ifdef HAVE_X +#if defined (GDK_WINDOWING_X11) || defined (GDK_WINDOWING_WIN32) { GdkWindow *window = gtk_widget_get_window (video_window); +#if defined (GDK_WINDOWING_WIN32) + embed_xid = GDK_WINDOW_HWND (window); +#else embed_xid = GDK_WINDOW_XID (window); +#endif g_print ("Window realize: video window XID = %lu\n", embed_xid); } #endif @@ -2538,7 +2550,7 @@ connect_bus_signals (GstElement * pipeline) { GstBus *bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline)); -#ifdef HAVE_X +#if defined (GDK_WINDOWING_X11) || defined (GDK_WINDOWING_WIN32) /* handle prepare-xwindow-id element message synchronously */ gst_bus_set_sync_handler (bus, (GstBusSyncHandler) bus_sync_handler, pipeline); @@ -2645,12 +2657,16 @@ main (int argc, char **argv) GtkWidget *scrub_checkbox, *play_scrub_checkbox; GtkWidget *rate_label, *volume_label; GOptionEntry options[] = { + {"audiosink", '\0', 0, G_OPTION_ARG_STRING, &opt_audiosink_str, + "audio sink to use (default: " DEFAULT_AUDIOSINK ")", NULL}, {"stats", 's', 0, G_OPTION_ARG_NONE, &stats, "Show pad stats", NULL}, {"elem", 'e', 0, G_OPTION_ARG_NONE, &elem_seek, "Seek on elements instead of pads", NULL}, {"verbose", 'v', 0, G_OPTION_ARG_NONE, &verbose, "Verbose properties", NULL}, + {"videosink", '\0', 0, G_OPTION_ARG_STRING, &opt_videosink_str, + "video sink to use (default: " DEFAULT_VIDEOSINK ")", NULL}, {NULL} }; GOptionContext *ctx; @@ -2669,6 +2685,12 @@ main (int argc, char **argv) exit (1); } + if (opt_audiosink_str == NULL) + opt_audiosink_str = g_strdup (DEFAULT_AUDIOSINK); + + if (opt_videosink_str == NULL) + opt_videosink_str = g_strdup (DEFAULT_VIDEOSINK); + GST_DEBUG_CATEGORY_INIT (seek_debug, "seek", 0, "seek example"); if (argc != 3) { @@ -2978,7 +3000,7 @@ main (int argc, char **argv) * asks for the XID of the window to render onto */ gtk_widget_realize (window); -#ifdef HAVE_X +#if defined (GDK_WINDOWING_X11) || defined (GDK_WINDOWING_WIN32) /* we should have the XID now */ g_assert (embed_xid != 0); #endif