1 /*
2  * This file is part of Wireless Display Software for Linux OS
3  *
4  * Copyright (C) 2014 Intel Corporation.
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
19  * 02110-1301 USA
20  */
21 
22 #include <glib.h>
23 #include <glib-unix.h>
24 #include <gst/gst.h>
25 
26 #include <iostream>
27 
28 #include "mirac-glib-logging.hpp"
29 
30 #include "sink-app.h"
31 #include "sink.h"
32 
33 
_sig_handler(gpointer data_ptr)34 static gboolean _sig_handler (gpointer data_ptr)
35 {
36     GMainLoop *main_loop = (GMainLoop *) data_ptr;
37 
38     g_main_loop_quit(main_loop);
39 
40     return G_SOURCE_CONTINUE;
41 }
42 
parse_input_and_call_sink(const std::string & command,Sink * sink)43 static void parse_input_and_call_sink(
44     const std::string& command, Sink *sink) {
45     if (command == "teardown\n") {
46         sink->Teardown();
47         return;
48     }
49     if (command == "pause\n") {
50         sink->Pause();
51         return;
52     }
53     if (command == "play\n") {
54         sink->Play();
55         return;
56     }
57     std::cout << "Received unknown command: " << command << std::endl;
58 }
59 
_user_input_handler(GIOChannel * channel,GIOCondition,gpointer data_ptr)60 static gboolean _user_input_handler (
61     GIOChannel* channel, GIOCondition /*condition*/, gpointer data_ptr)
62 {
63     GError* error = NULL;
64     char* str = NULL;
65     size_t len;
66     SinkApp* app = static_cast<SinkApp*>(data_ptr);
67 
68     switch (g_io_channel_read_line(channel, &str, &len, NULL, &error)) {
69     case G_IO_STATUS_NORMAL:
70         parse_input_and_call_sink(str, &app->sink());
71         g_free(str);
72         return true;
73     case G_IO_STATUS_ERROR:
74         std::cout << "User input error: " << error->message << std::endl;
75         g_error_free(error);
76         return false;
77     case G_IO_STATUS_EOF:
78     case G_IO_STATUS_AGAIN:
79         return true;
80     default:
81         return false;
82     }
83     return false;
84 }
85 
main(int argc,char * argv[])86 int main (int argc, char *argv[])
87 {
88     InitGlibLogging();
89     char* hostname = NULL;
90     int port = 7236;
91     std::unique_ptr<SinkApp> app;
92 
93     GOptionEntry main_entries[] = {
94         { "hostname", 0, 0, G_OPTION_ARG_STRING, &hostname, "Specify remote hostname (for debugging purposes)", "host"},
95         { "rtsp_port", 0, 0, G_OPTION_ARG_INT, &port, "Specify remote RTSP port number (for debugging purposes), 7236 by default", "rtsp_port"},
96         { NULL }
97     };
98 
99     GOptionContext* context = g_option_context_new ("- WFD sink demo application\n");
100     g_option_context_add_main_entries (context, main_entries, NULL);
101     g_option_context_add_group (context, gst_init_get_option_group ());
102 
103     GError* error = NULL;
104     if (!g_option_context_parse (context, &argc, &argv, &error)) {
105         WDS_ERROR ("option parsing failed: %s", error->message);
106         g_option_context_free(context);
107         exit (1);
108     }
109     g_option_context_free(context);
110 
111     if (hostname) {
112         app.reset(new SinkApp(std::string(hostname), port));
113         g_free (hostname);
114     } else {
115         app.reset(new SinkApp());
116     }
117 
118     GMainLoop *main_loop =  g_main_loop_new(NULL, TRUE);
119     g_unix_signal_add(SIGINT, _sig_handler, main_loop);
120     g_unix_signal_add(SIGTERM, _sig_handler, main_loop);
121 
122     GIOChannel* io_channel = g_io_channel_unix_new (STDIN_FILENO);
123     g_io_add_watch(io_channel, G_IO_IN, _user_input_handler, app.get());
124     g_io_channel_unref(io_channel);
125 
126     g_main_loop_run (main_loop);
127 
128     g_main_loop_unref (main_loop);
129 
130     return 0;
131 }
132 
133