00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033 #ifdef __HAVE_GSTREAMER__
00034
00035 #include <string.h>
00036 #include <signal.h>
00037 #ifdef HAVE_UNISTD_H
00038 #include <unistd.h>
00039 #endif
00040 #ifndef DISABLE_FAULT_HANDLER
00041 #include <sys/wait.h>
00042 #endif
00043 #include <locale.h>
00044 #include "mmsmedia/mmsgst.h"
00045
00046
00047
00048
00049
00050 #ifdef SA_SIGINFO
00051 #define USE_SIGINFO
00052 #endif
00053
00054 extern volatile gboolean glib_on_error_halt;
00055
00056 #ifndef DISABLE_FAULT_HANDLER
00057 static void fault_restore (void);
00058 static void fault_spin (void);
00059 static void sigint_restore (void);
00060 static gboolean caught_intr = FALSE;
00061 #endif
00062
00063 static GstElement *pipeline;
00064 static gboolean caught_error = FALSE;
00065 static gboolean tags = FALSE;
00066 static gboolean is_live = FALSE;
00067
00068 #ifndef DISABLE_FAULT_HANDLER
00069 #ifndef USE_SIGINFO
00070 static void
00071 fault_handler_sighandler (int signum)
00072 {
00073 fault_restore ();
00074
00075
00076
00077 switch (signum) {
00078 case SIGSEGV:
00079 printf ("Caught SIGSEGV\n");
00080 break;
00081 case SIGQUIT:
00082 printf ("Caught SIGQUIT\n");
00083 break;
00084 default:
00085 printf ("signo: %d\n", signum);
00086 break;
00087 }
00088
00089 fault_spin ();
00090 }
00091
00092 #else
00093
00094 static void
00095 fault_handler_sigaction (int signum, siginfo_t * si, void *misc)
00096 {
00097 fault_restore ();
00098
00099
00100
00101 switch (si->si_signo) {
00102 case SIGSEGV:
00103 printf ("Caught SIGSEGV accessing address %p\n", si->si_addr);
00104 break;
00105 case SIGQUIT:
00106 printf ("Caught SIGQUIT\n");
00107 break;
00108 default:
00109 printf ("signo: %d\n", si->si_signo);
00110 printf ("errno: %d\n", si->si_errno);
00111 printf ("code: %d\n", si->si_code);
00112 break;
00113 }
00114
00115 fault_spin ();
00116 }
00117 #endif
00118
00119 static void
00120 fault_spin (void)
00121 {
00122 int spinning = TRUE;
00123
00124 glib_on_error_halt = FALSE;
00125 g_on_error_stack_trace ("gst-launch");
00126
00127 wait (NULL);
00128
00129
00130 printf ("Spinning. Please run 'gdb gst-launch %d' to continue debugging, "
00131 "Ctrl-C to quit, or Ctrl-\\ to dump core.\n", (gint) getpid ());
00132 while (spinning)
00133 g_usleep (1000000);
00134 }
00135
00136 static void
00137 fault_restore (void)
00138 {
00139 struct sigaction action;
00140
00141 memset (&action, 0, sizeof (action));
00142 action.sa_handler = SIG_DFL;
00143
00144 sigaction (SIGSEGV, &action, NULL);
00145 sigaction (SIGQUIT, &action, NULL);
00146 }
00147
00148 static void
00149 fault_setup (void)
00150 {
00151 struct sigaction action;
00152
00153 memset (&action, 0, sizeof (action));
00154 #ifdef USE_SIGINFO
00155 action.sa_sigaction = fault_handler_sigaction;
00156 action.sa_flags = SA_SIGINFO;
00157 #else
00158 action.sa_handler = fault_handler_sighandler;
00159 #endif
00160
00161 sigaction (SIGSEGV, &action, NULL);
00162 sigaction (SIGQUIT, &action, NULL);
00163 }
00164 #endif
00165
00166 static void
00167 print_tag (const GstTagList * list, const gchar * tag, gpointer unused)
00168 {
00169 gint i, count;
00170
00171 count = gst_tag_list_get_tag_size (list, tag);
00172
00173 for (i = 0; i < count; i++) {
00174 gchar *str;
00175
00176 if (gst_tag_get_type (tag) == G_TYPE_STRING) {
00177 if (!gst_tag_list_get_string_index (list, tag, i, &str))
00178 g_assert_not_reached ();
00179 } else if (gst_tag_get_type (tag) == GST_TYPE_BUFFER) {
00180 GstBuffer *img;
00181
00182 img = gst_value_get_buffer (gst_tag_list_get_value_index (list, tag, i));
00183 if (img) {
00184 gchar *caps_str;
00185
00186 caps_str = GST_BUFFER_CAPS (img) ?
00187 gst_caps_to_string (GST_BUFFER_CAPS (img)) : g_strdup ("unknown");
00188 str = g_strdup_printf ("buffer of %u bytes, type: %s",
00189 GST_BUFFER_SIZE (img), caps_str);
00190 g_free (caps_str);
00191 } else {
00192 str = g_strdup ("NULL buffer");
00193 }
00194 } else {
00195 str =
00196 g_strdup_value_contents (gst_tag_list_get_value_index (list, tag, i));
00197 }
00198
00199 if (i == 0) {
00200 g_print ("%16s: %s\n", gst_tag_get_nick (tag), str);
00201 } else {
00202 g_print ("%16s: %s\n", "", str);
00203 }
00204
00205 g_free (str);
00206 }
00207 }
00208
00209 #ifndef DISABLE_FAULT_HANDLER
00210
00211 static void
00212 sigint_handler_sighandler (int signum)
00213 {
00214 g_print ("Caught interrupt -- ");
00215
00216 sigint_restore ();
00217
00218
00219
00220 caught_intr = TRUE;
00221 }
00222
00223
00224
00225 static gboolean
00226 check_intr (GstElement * pipeline)
00227 {
00228 if (!caught_intr) {
00229 return TRUE;
00230 } else {
00231 caught_intr = FALSE;
00232 g_print ("handling interrupt.\n");
00233
00234
00235 gst_element_post_message (GST_ELEMENT (pipeline),
00236 gst_message_new_application (GST_OBJECT (pipeline),
00237 gst_structure_new ("GstLaunchInterrupt",
00238 "message", G_TYPE_STRING, "Pipeline interrupted", NULL)));
00239
00240
00241 return FALSE;
00242 }
00243 }
00244
00245 static void
00246 sigint_setup (void)
00247 {
00248 struct sigaction action;
00249
00250 memset (&action, 0, sizeof (action));
00251 action.sa_handler = sigint_handler_sighandler;
00252
00253 sigaction (SIGINT, &action, NULL);
00254 }
00255
00256 static void
00257 sigint_restore (void)
00258 {
00259 struct sigaction action;
00260
00261 memset (&action, 0, sizeof (action));
00262 action.sa_handler = SIG_DFL;
00263
00264 sigaction (SIGINT, &action, NULL);
00265 }
00266
00267 static void
00268 play_handler (int signum)
00269 {
00270 switch (signum) {
00271 case SIGUSR1:
00272 g_print ("Caught SIGUSR1 - Play request.\n");
00273 gst_element_set_state (pipeline, GST_STATE_PLAYING);
00274 break;
00275 case SIGUSR2:
00276 g_print ("Caught SIGUSR2 - Stop request.\n");
00277 gst_element_set_state (pipeline, GST_STATE_NULL);
00278 break;
00279 }
00280 }
00281
00282 static void
00283 play_signal_setup (void)
00284 {
00285 struct sigaction action;
00286
00287 memset (&action, 0, sizeof (action));
00288 action.sa_handler = play_handler;
00289 sigaction (SIGUSR1, &action, NULL);
00290 sigaction (SIGUSR2, &action, NULL);
00291 }
00292 #endif
00293
00294
00295 static gboolean
00296 event_loop (GstElement * pipeline, gboolean blocking, GstState target_state)
00297 {
00298 GstBus *bus;
00299 GstMessage *message = NULL;
00300 gboolean res = FALSE;
00301 gboolean buffering = FALSE;
00302
00303 bus = gst_element_get_bus (GST_ELEMENT (pipeline));
00304
00305 #ifndef DISABLE_FAULT_HANDLER
00306 g_timeout_add (50, (GSourceFunc) check_intr, pipeline);
00307 #endif
00308
00309 while (TRUE) {
00310 message = gst_bus_poll (bus, GST_MESSAGE_ANY, blocking ? -1 : 0);
00311
00312
00313 if (message == NULL)
00314 goto exit;
00315
00316 switch (GST_MESSAGE_TYPE (message)) {
00317 case GST_MESSAGE_NEW_CLOCK:
00318 {
00319 GstClock *clock;
00320
00321 gst_message_parse_new_clock (message, &clock);
00322
00323 g_print ("New clock: %s\n", (clock ? GST_OBJECT_NAME (clock) : "NULL"));
00324 break;
00325 }
00326 case GST_MESSAGE_EOS:
00327 g_print ("Got EOS from element \"%s\".\n",
00328 GST_STR_NULL (GST_ELEMENT_NAME (GST_MESSAGE_SRC (message))));
00329 goto exit;
00330 case GST_MESSAGE_TAG:
00331 if (tags) {
00332 GstTagList *tags;
00333
00334 gst_message_parse_tag (message, &tags);
00335 g_print ("FOUND TAG : found by element \"%s\".\n",
00336 GST_STR_NULL (GST_ELEMENT_NAME (GST_MESSAGE_SRC (message))));
00337 gst_tag_list_foreach (tags, print_tag, NULL);
00338 gst_tag_list_free (tags);
00339 }
00340 break;
00341 case GST_MESSAGE_INFO:{
00342 GError *gerror;
00343 gchar *debug;
00344 gchar *name = gst_object_get_path_string (GST_MESSAGE_SRC (message));
00345
00346 gst_message_parse_info (message, &gerror, &debug);
00347 if (debug) {
00348 g_print ("INFO:\n%s\n", debug);
00349 }
00350 g_error_free (gerror);
00351 g_free (debug);
00352 g_free (name);
00353 break;
00354 }
00355 case GST_MESSAGE_WARNING:{
00356 GError *gerror;
00357 gchar *debug;
00358 gchar *name = gst_object_get_path_string (GST_MESSAGE_SRC (message));
00359
00360
00361 GST_DEBUG_BIN_TO_DOT_FILE_WITH_TS (GST_BIN (pipeline),
00362 GST_DEBUG_GRAPH_SHOW_ALL, "gst-launch.warning");
00363
00364 gst_message_parse_warning (message, &gerror, &debug);
00365 g_print ("WARNING: from element %s: %s\n", name, gerror->message);
00366 if (debug) {
00367 g_print ("Additional debug info:\n%s\n", debug);
00368 }
00369 g_error_free (gerror);
00370 g_free (debug);
00371 g_free (name);
00372 break;
00373 }
00374 case GST_MESSAGE_ERROR:{
00375 GError *gerror;
00376 gchar *debug;
00377
00378
00379 GST_DEBUG_BIN_TO_DOT_FILE_WITH_TS (GST_BIN (pipeline),
00380 GST_DEBUG_GRAPH_SHOW_ALL, "gst-launch.error");
00381
00382 gst_message_parse_error (message, &gerror, &debug);
00383 gst_object_default_error (GST_MESSAGE_SRC (message), gerror, debug);
00384 g_error_free (gerror);
00385 g_free (debug);
00386
00387 res = TRUE;
00388 goto exit;
00389 }
00390 case GST_MESSAGE_STATE_CHANGED:{
00391 GstState old, newX, pending;
00392
00393 gst_message_parse_state_changed (message, &old, &newX, &pending);
00394
00395
00396 if (GST_MESSAGE_SRC (message) != GST_OBJECT_CAST (pipeline))
00397 break;
00398
00399
00400 {
00401 gchar *dump_name = g_strdup_printf ("gst-launch.%s_%s",
00402 gst_element_state_get_name (old),
00403 gst_element_state_get_name (newX));
00404 GST_DEBUG_BIN_TO_DOT_FILE_WITH_TS (GST_BIN (pipeline),
00405 GST_DEBUG_GRAPH_SHOW_ALL, dump_name);
00406 g_free (dump_name);
00407 }
00408
00409
00410
00411 if (buffering) {
00412 fprintf (stderr,
00413 "Prerolled, waiting for buffering to finish...\n");
00414 break;
00415 }
00416
00417
00418 if (target_state == GST_STATE_PAUSED && newX == target_state)
00419 goto exit;
00420
00421
00422 break;
00423 }
00424 case GST_MESSAGE_BUFFERING:{
00425 gint percent;
00426
00427 gst_message_parse_buffering (message, &percent);
00428 fprintf (stderr, "%s %d%% \r", "buffering...", percent);
00429
00430
00431 if (is_live)
00432 break;
00433
00434 if (percent == 100) {
00435
00436 buffering = FALSE;
00437
00438 if (target_state == GST_STATE_PLAYING) {
00439 fprintf (stderr,
00440 "Done buffering, setting pipeline to PLAYING ...\n");
00441 gst_element_set_state (pipeline, GST_STATE_PLAYING);
00442 } else
00443 goto exit;
00444 } else {
00445
00446 if (buffering == FALSE && target_state == GST_STATE_PLAYING) {
00447
00448 fprintf (stderr, "Buffering, setting pipeline to PAUSED ...\n");
00449 gst_element_set_state (pipeline, GST_STATE_PAUSED);
00450 }
00451 buffering = TRUE;
00452 }
00453 break;
00454 }
00455 case GST_MESSAGE_LATENCY:
00456 {
00457 fprintf (stderr, "Redistribute latency...\n");
00458 gst_bin_recalculate_latency (GST_BIN (pipeline));
00459 break;
00460 }
00461 case GST_MESSAGE_APPLICATION:{
00462 const GstStructure *s;
00463
00464 s = gst_message_get_structure (message);
00465
00466 if (gst_structure_has_name (s, "GstLaunchInterrupt")) {
00467
00468
00469 fprintf (stderr, "Interrupt: Stopping pipeline ...\n");
00470
00471 res = TRUE;
00472 goto exit;
00473 }
00474 }
00475 default:
00476
00477 break;
00478 }
00479 if (message)
00480 gst_message_unref (message);
00481 }
00482 g_assert_not_reached ();
00483
00484 exit:
00485 {
00486 if (message)
00487 gst_message_unref (message);
00488 gst_object_unref (bus);
00489 return res;
00490 }
00491 }
00492
00493
00494 void mmsGstFree() {
00495
00496 if (pipeline) {
00497 GstState state, pending;
00498
00499 fprintf (stderr, "Setting pipeline to NULL ...\n");
00500 gst_element_set_state (pipeline, GST_STATE_NULL);
00501 gst_element_get_state (pipeline, &state, &pending, GST_CLOCK_TIME_NONE);
00502
00503 fprintf (stderr, "FREEING pipeline ...\n");
00504 gst_object_unref (pipeline);
00505 }
00506
00507 gst_deinit ();
00508 }
00509
00510
00511 GstElement *mmsGstLaunch(const char *pipeline_description) {
00512 GError *error = NULL;
00513 gint res = 0;
00514
00515 #ifdef ENABLE_NLS
00516 bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR);
00517 bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
00518 textdomain (GETTEXT_PACKAGE);
00519 #endif
00520
00521 if (!g_thread_supported ())
00522 g_thread_init (NULL);
00523
00524 gst_alloc_trace_set_flags_all (GST_ALLOC_TRACE_LIVE);
00525
00526 #ifndef DISABLE_FAULT_HANDLER
00527 fault_setup ();
00528
00529 sigint_setup ();
00530 play_signal_setup ();
00531 #endif
00532
00533
00534 pipeline = gst_parse_launch(pipeline_description, &error);
00535
00536 if (!pipeline) {
00537 if (error) {
00538 fprintf (stderr, "ERROR: pipeline could not be constructed: %s.\n",
00539 GST_STR_NULL (error->message));
00540 g_error_free (error);
00541 } else {
00542 fprintf (stderr, "ERROR: pipeline could not be constructed.\n");
00543 }
00544 return NULL;
00545 } else if (error) {
00546 fprintf (stderr, "WARNING: erroneous pipeline: %s\n",
00547 GST_STR_NULL (error->message));
00548 g_error_free (error);
00549 return NULL;
00550 }
00551
00552
00553 GstState state;
00554 GstStateChangeReturn ret;
00555
00556
00557 if (!GST_IS_PIPELINE (pipeline)) {
00558 GstElement *real_pipeline = gst_element_factory_make ("pipeline", NULL);
00559
00560 if (real_pipeline == NULL) {
00561 fprintf (stderr, "ERROR: the 'pipeline' element wasn't found.\n");
00562 return NULL;
00563 }
00564 gst_bin_add (GST_BIN (real_pipeline), pipeline);
00565 pipeline = real_pipeline;
00566 }
00567 fprintf (stderr, "Setting pipeline to PAUSED ...\n");
00568 ret = gst_element_set_state (pipeline, GST_STATE_PAUSED);
00569
00570 switch (ret) {
00571 case GST_STATE_CHANGE_FAILURE:
00572 fprintf (stderr, "ERROR: Pipeline doesn't want to pause.\n");
00573 res = -1;
00574 event_loop (pipeline, FALSE, GST_STATE_VOID_PENDING);
00575 goto end;
00576 case GST_STATE_CHANGE_NO_PREROLL:
00577 fprintf (stderr, "Pipeline is live and does not need PREROLL ...\n");
00578 is_live = TRUE;
00579 break;
00580 case GST_STATE_CHANGE_ASYNC:
00581 fprintf (stderr, "Pipeline is PREROLLING ...\n");
00582 caught_error = event_loop (pipeline, TRUE, GST_STATE_PAUSED);
00583 if (caught_error) {
00584 fprintf (stderr, "ERROR: pipeline doesn't want to preroll.\n");
00585 goto end;
00586 }
00587 state = GST_STATE_PAUSED;
00588
00589 case GST_STATE_CHANGE_SUCCESS:
00590 fprintf (stderr, "Pipeline is PREROLLED ...\n");
00591 break;
00592 }
00593
00594
00595 return pipeline;
00596
00597 end:
00598 mmsGstFree();
00599
00600 return NULL;
00601 }
00602
00603
00604
00605
00606 GstElement *mmsGstInit(const string uri, MMSFBSurface *surface) {
00607
00608
00609 gst_init(NULL, NULL);
00610 if (uri == "")
00611 return NULL;
00612
00613 if (strToUpr(uri.substr(0,6)) == "GST://") {
00614
00615
00616 return mmsGstLaunch(uri.substr(6).c_str());
00617 }
00618 else {
00619
00620 pipeline = gst_element_factory_make("playbin", "player");
00621
00622
00623 GstElement *videosink = gst_element_factory_make("diskovideosink", "diskovideosink");
00624
00625
00626 g_object_set(videosink, "surface", surface, NULL);
00627
00628
00629 g_object_set(G_OBJECT(pipeline), "video-sink", videosink, NULL);
00630
00631
00632 g_object_set(G_OBJECT(pipeline), "uri", uri.c_str(), NULL);
00633
00634 return pipeline;
00635 }
00636 }
00637
00638 GstElement *mmsGstInit(const string uri, MMSWindow *window) {
00639
00640
00641 gst_init(NULL, NULL);
00642 if (uri == "")
00643 return NULL;
00644
00645 if (strToUpr(uri.substr(0,6)) == "GST://") {
00646
00647
00648 return mmsGstLaunch(uri.substr(6).c_str());
00649 }
00650 else {
00651
00652 pipeline = gst_element_factory_make("playbin", "player");
00653
00654
00655 GstElement *videosink = gst_element_factory_make("diskovideosink", "diskovideosink");
00656
00657
00658
00659
00660 g_object_set(videosink, "window", window, NULL);
00661
00662
00663 g_object_set(G_OBJECT(pipeline), "video-sink", videosink, NULL);
00664
00665
00666 g_object_set(G_OBJECT(pipeline), "uri", uri.c_str(), NULL);
00667
00668 return pipeline;
00669 }
00670 }
00671
00672
00673 bool mmsGstPlay(GstElement *pipelineX) {
00674
00675 pipeline = pipelineX;
00676
00677
00678 GstState state, pending;
00679
00680
00681 caught_error = event_loop (pipeline, FALSE, GST_STATE_PLAYING);
00682
00683 if (caught_error) {
00684 fprintf (stderr, "ERROR: pipeline doesn't want to preroll.\n");
00685 } else {
00686 GstClockTime tfthen, tfnow;
00687 GstClockTimeDiff diff;
00688
00689 fprintf (stderr, "Setting pipeline to PLAYING ...\n");
00690 if (gst_element_set_state (pipeline,
00691 GST_STATE_PLAYING) == GST_STATE_CHANGE_FAILURE) {
00692 GstMessage *err_msg;
00693 GstBus *bus;
00694
00695 fprintf (stderr, "ERROR: pipeline doesn't want to play.\n");
00696 bus = gst_element_get_bus (pipeline);
00697 if ((err_msg = gst_bus_poll (bus, GST_MESSAGE_ERROR, 0))) {
00698 GError *gerror;
00699 gchar *debug;
00700
00701 gst_message_parse_error (err_msg, &gerror, &debug);
00702 gst_object_default_error (GST_MESSAGE_SRC (err_msg), gerror, debug);
00703 gst_message_unref (err_msg);
00704 g_error_free (gerror);
00705 g_free (debug);
00706 }
00707 gst_object_unref (bus);
00708
00709 mmsGstFree();
00710
00711 return false;
00712 }
00713
00714 tfthen = gst_util_get_timestamp ();
00715 caught_error = event_loop (pipeline, TRUE, GST_STATE_PLAYING);
00716 tfnow = gst_util_get_timestamp ();
00717
00718 diff = GST_CLOCK_DIFF (tfthen, tfnow);
00719
00720 g_print ("Execution ended after %" G_GUINT64_FORMAT " ns.\n", diff);
00721 }
00722
00723
00724 while (g_main_context_iteration (NULL, FALSE));
00725
00726 fprintf (stderr, "Setting pipeline to PAUSED ...\n");
00727 gst_element_set_state (pipeline, GST_STATE_PAUSED);
00728 if (!caught_error)
00729 gst_element_get_state (pipeline, &state, &pending, GST_CLOCK_TIME_NONE);
00730 fprintf (stderr, "Setting pipeline to READY ...\n");
00731 gst_element_set_state (pipeline, GST_STATE_READY);
00732 gst_element_get_state (pipeline, &state, &pending, GST_CLOCK_TIME_NONE);
00733
00734
00735 return true;
00736 }
00737
00738
00739 bool mmsGstSendKeyPress(GstElement *pipeline, MMSKeySymbol key) {
00740 if (!pipeline)
00741 return false;
00742
00743
00744 const char *ks = convertMMSKeySymbolToXKeysymString(key);
00745 if (!*ks)
00746 return true;
00747
00748
00749 GstStructure *structure =
00750 gst_structure_new( "application/x-gst-navigation",
00751 "event", G_TYPE_STRING, "key-press",
00752 "key", G_TYPE_STRING, ks,
00753 NULL);
00754 if (!structure)
00755 return false;
00756 GstEvent *event = gst_event_new_navigation(structure);
00757 if (!event)
00758 return false;
00759
00760
00761 return gst_element_send_event(pipeline, event);
00762 }
00763
00764 bool mmsGstSendKeyRelease(GstElement *pipeline, MMSKeySymbol key) {
00765 if (!pipeline)
00766 return false;
00767
00768
00769 const char *ks = convertMMSKeySymbolToXKeysymString(key);
00770 if (!*ks)
00771 return true;
00772
00773
00774 GstStructure *structure =
00775 gst_structure_new( "application/x-gst-navigation",
00776 "event", G_TYPE_STRING, "key-release",
00777 "key", G_TYPE_STRING, ks,
00778 NULL);
00779 if (!structure)
00780 return false;
00781 GstEvent *event = gst_event_new_navigation(structure);
00782 if (!event)
00783 return false;
00784
00785
00786 return gst_element_send_event(pipeline, event);
00787 }
00788
00789 bool mmsGstSendButtonPress(GstElement *pipeline, int posx, int posy) {
00790 if (!pipeline)
00791 return false;
00792
00793
00794 GstStructure *structure =
00795 gst_structure_new( "application/x-gst-navigation",
00796 "event", G_TYPE_STRING, "mouse-button-press",
00797 "button", G_TYPE_INT, 0,
00798 "pointer_x",G_TYPE_DOUBLE, (double)posx,
00799 "pointer_y",G_TYPE_DOUBLE, (double)posy,
00800 NULL);
00801 if (!structure)
00802 return false;
00803 GstEvent *event = gst_event_new_navigation(structure);
00804 if (!event)
00805 return false;
00806
00807
00808 return gst_element_send_event(pipeline, event);
00809 }
00810
00811 bool mmsGstSendButtonRelease(GstElement *pipeline, int posx, int posy) {
00812 if (!pipeline)
00813 return false;
00814
00815
00816 GstStructure *structure =
00817 gst_structure_new( "application/x-gst-navigation",
00818 "event", G_TYPE_STRING, "mouse-button-release",
00819 "button", G_TYPE_INT, 0,
00820 "pointer_x",G_TYPE_DOUBLE, (double)posx,
00821 "pointer_y",G_TYPE_DOUBLE, (double)posy,
00822 NULL);
00823 if (!structure)
00824 return false;
00825 GstEvent *event = gst_event_new_navigation(structure);
00826 if (!event)
00827 return false;
00828
00829
00830 return gst_element_send_event(pipeline, event);
00831 }
00832
00833 bool mmsGstSendAxisMotion(GstElement *pipeline, int posx, int posy) {
00834 if (!pipeline)
00835 return false;
00836
00837
00838 GstStructure *structure =
00839 gst_structure_new( "application/x-gst-navigation",
00840 "event", G_TYPE_STRING, "mouse-move",
00841 "button", G_TYPE_INT, 0,
00842 "pointer_x",G_TYPE_DOUBLE, (double)posx,
00843 "pointer_y",G_TYPE_DOUBLE, (double)posy,
00844 NULL);
00845 if (!structure)
00846 return false;
00847 GstEvent *event = gst_event_new_navigation(structure);
00848 if (!event)
00849 return false;
00850
00851
00852 return gst_element_send_event(pipeline, event);
00853 }
00854
00855
00856 #endif
00857