comparison libpurple/mediamanager.c @ 29298:fb99a0067812

propagate from branch 'im.pidgin.pidgin' (head 70d69397ed952b26b453423c381c70d6783eb66d) to branch 'im.pidgin.cpw.attention_ui' (head 1cf0dea282a0d0e4aeac4770e0150d6d0c10830a)
author Marcus Lundblad <ml@update.uu.se>
date Thu, 13 Aug 2009 17:42:44 +0000
parents f77978e6968e
children 8c991e09efcb
comparison
equal deleted inserted replaced
29297:338d6a211055 29298:fb99a0067812
37 #endif 37 #endif
38 38
39 #ifdef USE_VV 39 #ifdef USE_VV
40 40
41 #include <gst/farsight/fs-conference-iface.h> 41 #include <gst/farsight/fs-conference-iface.h>
42 #include <gst/farsight/fs-element-added-notifier.h>
42 #include <gst/interfaces/xoverlay.h> 43 #include <gst/interfaces/xoverlay.h>
43 44
44 /** @copydoc _PurpleMediaManagerPrivate */ 45 /** @copydoc _PurpleMediaManagerPrivate */
45 typedef struct _PurpleMediaManagerPrivate PurpleMediaManagerPrivate; 46 typedef struct _PurpleMediaManagerPrivate PurpleMediaManagerPrivate;
46 /** @copydoc _PurpleMediaOutputWindow */ 47 /** @copydoc _PurpleMediaOutputWindow */
154 purple_media_manager_init (PurpleMediaManager *media) 155 purple_media_manager_init (PurpleMediaManager *media)
155 { 156 {
156 media->priv = PURPLE_MEDIA_MANAGER_GET_PRIVATE(media); 157 media->priv = PURPLE_MEDIA_MANAGER_GET_PRIVATE(media);
157 media->priv->medias = NULL; 158 media->priv->medias = NULL;
158 media->priv->next_output_window_id = 1; 159 media->priv->next_output_window_id = 1;
160
161 purple_prefs_add_none("/purple/media");
162 purple_prefs_add_none("/purple/media/audio");
163 purple_prefs_add_none("/purple/media/audio/volume");
164 purple_prefs_add_int("/purple/media/audio/volume/input", 10);
165 purple_prefs_add_int("/purple/media/audio/volume/output", 10);
159 } 166 }
160 167
161 static void 168 static void
162 purple_media_manager_finalize (GObject *media) 169 purple_media_manager_finalize (GObject *media)
163 { 170 {
227 { 234 {
228 #ifdef USE_VV 235 #ifdef USE_VV
229 g_return_val_if_fail(PURPLE_IS_MEDIA_MANAGER(manager), NULL); 236 g_return_val_if_fail(PURPLE_IS_MEDIA_MANAGER(manager), NULL);
230 237
231 if (manager->priv->pipeline == NULL) { 238 if (manager->priv->pipeline == NULL) {
239 FsElementAddedNotifier *notifier;
240 gchar *filename;
241 GError *err = NULL;
242 GKeyFile *keyfile;
232 GstBus *bus; 243 GstBus *bus;
233 manager->priv->pipeline = gst_pipeline_new(NULL); 244 manager->priv->pipeline = gst_pipeline_new(NULL);
234 245
235 bus = gst_pipeline_get_bus( 246 bus = gst_pipeline_get_bus(
236 GST_PIPELINE(manager->priv->pipeline)); 247 GST_PIPELINE(manager->priv->pipeline));
239 G_CALLBACK(pipeline_bus_call), manager); 250 G_CALLBACK(pipeline_bus_call), manager);
240 gst_bus_set_sync_handler(bus, 251 gst_bus_set_sync_handler(bus,
241 gst_bus_sync_signal_handler, NULL); 252 gst_bus_sync_signal_handler, NULL);
242 gst_object_unref(bus); 253 gst_object_unref(bus);
243 254
255 filename = g_build_filename(purple_user_dir(),
256 "fs-element.conf", NULL);
257 keyfile = g_key_file_new();
258 if (!g_key_file_load_from_file(keyfile, filename,
259 G_KEY_FILE_NONE, &err)) {
260 if (err->code == 4)
261 purple_debug_info("mediamanager",
262 "Couldn't read "
263 "fs-element.conf: %s\n",
264 err->message);
265 else
266 purple_debug_error("mediamanager",
267 "Error reading "
268 "fs-element.conf: %s\n",
269 err->message);
270 g_error_free(err);
271 }
272 g_free(filename);
273
274 /* Hack to make alsasrc stop messing up audio timestamps */
275 if (!g_key_file_has_key(keyfile,
276 "alsasrc", "slave-method", NULL)) {
277 g_key_file_set_integer(keyfile,
278 "alsasrc", "slave-method", 2);
279 }
280
281 notifier = fs_element_added_notifier_new();
282 fs_element_added_notifier_add(notifier,
283 GST_BIN(manager->priv->pipeline));
284 fs_element_added_notifier_set_properties_from_keyfile(
285 notifier, keyfile);
286
244 gst_element_set_state(manager->priv->pipeline, 287 gst_element_set_state(manager->priv->pipeline,
245 GST_STATE_PLAYING); 288 GST_STATE_PLAYING);
246 } 289 }
247 290
248 return manager->priv->pipeline; 291 return manager->priv->pipeline;
354 request_pad_unlinked_cb(GstPad *pad, GstPad *peer, gpointer user_data) 397 request_pad_unlinked_cb(GstPad *pad, GstPad *peer, gpointer user_data)
355 { 398 {
356 GstElement *parent = GST_ELEMENT_PARENT(pad); 399 GstElement *parent = GST_ELEMENT_PARENT(pad);
357 GstIterator *iter; 400 GstIterator *iter;
358 GstPad *remaining_pad; 401 GstPad *remaining_pad;
402 GstIteratorResult result;
359 403
360 gst_element_release_request_pad(GST_ELEMENT_PARENT(pad), pad); 404 gst_element_release_request_pad(GST_ELEMENT_PARENT(pad), pad);
361 iter = gst_element_iterate_pads(parent); 405 iter = gst_element_iterate_src_pads(parent);
362 406
363 if (gst_iterator_next(iter, (gpointer)&remaining_pad) 407 result = gst_iterator_next(iter, (gpointer)&remaining_pad);
364 == GST_ITERATOR_DONE) { 408
409 if (result == GST_ITERATOR_DONE) {
365 gst_element_set_locked_state(parent, TRUE); 410 gst_element_set_locked_state(parent, TRUE);
366 gst_element_set_state(parent, GST_STATE_NULL); 411 gst_element_set_state(parent, GST_STATE_NULL);
367 gst_bin_remove(GST_BIN(GST_ELEMENT_PARENT(parent)), parent); 412 gst_bin_remove(GST_BIN(GST_ELEMENT_PARENT(parent)), parent);
413 } else if (result == GST_ITERATOR_OK) {
414 gst_object_unref(remaining_pad);
368 } 415 }
369 416
370 gst_iterator_free(iter); 417 gst_iterator_free(iter);
371 } 418 }
372 #endif 419 #endif
424 g_object_set(fakesink, "sync", FALSE, NULL); 471 g_object_set(fakesink, "sync", FALSE, NULL);
425 gst_bin_add(GST_BIN(bin), fakesink); 472 gst_bin_add(GST_BIN(bin), fakesink);
426 gst_element_link(tee, fakesink); 473 gst_element_link(tee, fakesink);
427 474
428 ret = bin; 475 ret = bin;
429 gst_element_set_locked_state(ret, TRUE);
430 gst_object_ref(ret); 476 gst_object_ref(ret);
431 gst_bin_add(GST_BIN(purple_media_manager_get_pipeline( 477 gst_bin_add(GST_BIN(purple_media_manager_get_pipeline(
432 manager)), ret); 478 manager)), ret);
433 } 479 }
434 g_free(id); 480 g_free(id);
665 ow->participant != NULL && 711 ow->participant != NULL &&
666 !strcmp(participant, ow->participant)) || 712 !strcmp(participant, ow->participant)) ||
667 (participant == ow->participant)) && 713 (participant == ow->participant)) &&
668 !strcmp(session_id, ow->session_id)) { 714 !strcmp(session_id, ow->session_id)) {
669 GstBus *bus; 715 GstBus *bus;
670 GstElement *queue; 716 GstElement *queue, *colorspace;
671 GstElement *tee = purple_media_get_tee(media, 717 GstElement *tee = purple_media_get_tee(media,
672 session_id, participant); 718 session_id, participant);
673 719
674 if (tee == NULL) 720 if (tee == NULL)
675 continue; 721 continue;
676 722
677 queue = gst_element_factory_make( 723 queue = gst_element_factory_make(
678 "queue", NULL); 724 "queue", NULL);
725 colorspace = gst_element_factory_make(
726 "ffmpegcolorspace", NULL);
679 ow->sink = purple_media_manager_get_element( 727 ow->sink = purple_media_manager_get_element(
680 manager, PURPLE_MEDIA_RECV_VIDEO, 728 manager, PURPLE_MEDIA_RECV_VIDEO,
681 ow->media, ow->session_id, 729 ow->media, ow->session_id,
682 ow->participant); 730 ow->participant);
683 731
694 g_object_set(G_OBJECT(ow->sink), 742 g_object_set(G_OBJECT(ow->sink),
695 "async", FALSE, NULL); 743 "async", FALSE, NULL);
696 } 744 }
697 745
698 gst_bin_add_many(GST_BIN(GST_ELEMENT_PARENT(tee)), 746 gst_bin_add_many(GST_BIN(GST_ELEMENT_PARENT(tee)),
699 queue, ow->sink, NULL); 747 queue, colorspace, ow->sink, NULL);
700 748
701 bus = gst_pipeline_get_bus(GST_PIPELINE( 749 bus = gst_pipeline_get_bus(GST_PIPELINE(
702 manager->priv->pipeline)); 750 manager->priv->pipeline));
703 g_signal_connect(bus, "sync-message::element", 751 g_signal_connect(bus, "sync-message::element",
704 G_CALLBACK(window_id_cb), ow); 752 G_CALLBACK(window_id_cb), ow);
705 gst_object_unref(bus); 753 gst_object_unref(bus);
706 754
707 gst_element_sync_state_with_parent(ow->sink); 755 gst_element_set_state(ow->sink, GST_STATE_PLAYING);
708 gst_element_link(queue, ow->sink); 756 gst_element_set_state(colorspace, GST_STATE_PLAYING);
709 gst_element_sync_state_with_parent(queue); 757 gst_element_set_state(queue, GST_STATE_PLAYING);
758 gst_element_link(colorspace, ow->sink);
759 gst_element_link(queue, colorspace);
710 gst_element_link(tee, queue); 760 gst_element_link(tee, queue);
711 } 761 }
712 } 762 }
713 return TRUE; 763 return TRUE;
714 #else 764 #else
773 823
774 if (output_window->sink != NULL) { 824 if (output_window->sink != NULL) {
775 GstPad *pad = gst_element_get_static_pad( 825 GstPad *pad = gst_element_get_static_pad(
776 output_window->sink, "sink"); 826 output_window->sink, "sink");
777 GstPad *peer = gst_pad_get_peer(pad); 827 GstPad *peer = gst_pad_get_peer(pad);
778 GstElement *queue = GST_ELEMENT_PARENT(peer); 828 GstElement *colorspace = GST_ELEMENT_PARENT(peer), *queue;
779 gst_object_unref(pad); 829 gst_object_unref(pad);
830 gst_object_unref(peer);
831 pad = gst_element_get_static_pad(colorspace, "sink");
832 peer = gst_pad_get_peer(pad);
833 queue = GST_ELEMENT_PARENT(peer);
834 gst_object_unref(pad);
835 gst_object_unref(peer);
780 pad = gst_element_get_static_pad(queue, "sink"); 836 pad = gst_element_get_static_pad(queue, "sink");
781 peer = gst_pad_get_peer(pad); 837 peer = gst_pad_get_peer(pad);
782 gst_object_unref(pad); 838 gst_object_unref(pad);
783 if (peer != NULL) 839 if (peer != NULL)
784 gst_element_release_request_pad(GST_ELEMENT_PARENT(peer), peer); 840 gst_element_release_request_pad(GST_ELEMENT_PARENT(peer), peer);
785 gst_element_set_locked_state(queue, TRUE); 841 gst_element_set_locked_state(queue, TRUE);
786 gst_element_set_state(queue, GST_STATE_NULL); 842 gst_element_set_state(queue, GST_STATE_NULL);
787 gst_bin_remove(GST_BIN(GST_ELEMENT_PARENT(queue)), queue); 843 gst_bin_remove(GST_BIN(GST_ELEMENT_PARENT(queue)), queue);
844 gst_element_set_locked_state(colorspace, TRUE);
845 gst_element_set_state(colorspace, GST_STATE_NULL);
846 gst_bin_remove(GST_BIN(GST_ELEMENT_PARENT(colorspace)), colorspace);
788 gst_element_set_locked_state(output_window->sink, TRUE); 847 gst_element_set_locked_state(output_window->sink, TRUE);
789 gst_element_set_state(output_window->sink, GST_STATE_NULL); 848 gst_element_set_state(output_window->sink, GST_STATE_NULL);
790 gst_bin_remove(GST_BIN(GST_ELEMENT_PARENT(output_window->sink)), 849 gst_bin_remove(GST_BIN(GST_ELEMENT_PARENT(output_window->sink)),
791 output_window->sink); 850 output_window->sink);
792 } 851 }