1 /*
2 * This file is part of Wireless Display Software for Linux OS
3 *
4 * Copyright (C) 2014 Intel Corporation.
5 *
6 * Contact: Alexander Kanavin <alex.kanavin@gmail.com>
7 *
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
21 * 02110-1301 USA
22 */
23
24 #include <iostream>
25 #include <gio/gio.h>
26
27 #include "mirac-gst-test-source.hpp"
28 #include "mirac-gst-bus-handler.hpp"
29 #include "libwds/public/logging.h"
30
MiracGstTestSource(wfd_test_stream_t wfd_stream_type,std::string hostname,int port)31 MiracGstTestSource::MiracGstTestSource (wfd_test_stream_t wfd_stream_type, std::string hostname, int port)
32 {
33 std::string gst_pipeline;
34
35 std::string hostname_port = (!hostname.empty() ? "host=" + hostname + " ": " ") + (port > 0 ? "port=" + std::to_string(port) : "");
36
37 if (wfd_stream_type == WFD_TEST_BOTH) {
38 gst_pipeline = "videotestsrc ! videoconvert ! video/x-raw,format=I420 ! x264enc ! muxer. audiotestsrc ! avenc_ac3 ! muxer. mpegtsmux name=muxer ! rtpmp2tpay ! udpsink name=sink " +
39 hostname_port;
40 } else if (wfd_stream_type == WFD_TEST_AUDIO) {
41 gst_pipeline = "audiotestsrc ! avenc_ac3 ! mpegtsmux ! rtpmp2tpay ! udpsink name=sink " + hostname_port;
42 } else if (wfd_stream_type == WFD_TEST_VIDEO) {
43 gst_pipeline = "videotestsrc ! videoconvert ! video/x-raw,format=I420 ! x264enc ! mpegtsmux ! rtpmp2tpay ! udpsink name=sink " + hostname_port;
44 } else if (wfd_stream_type == WFD_DESKTOP) {
45 gst_pipeline = "ximagesrc ! videoconvert ! video/x-raw,format=I420 ! x264enc tune=zerolatency ! mpegtsmux ! rtpmp2tpay ! udpsink name=sink " + hostname_port;
46 }
47
48 GError *err = NULL;
49 gst_elem = gst_parse_launch(gst_pipeline.c_str(), &err);
50 if (err != NULL) {
51 WDS_ERROR("Cannot initialize gstreamer pipeline: [%s] %s", g_quark_to_string(err->domain), err->message);
52 }
53
54 if (gst_elem) {
55 GstBus* bus = gst_pipeline_get_bus (GST_PIPELINE (gst_elem));
56 bus_watch_id = gst_bus_add_watch (bus, mirac_gstbus_callback, this);
57 gst_object_unref (bus);
58 }
59 }
60
SetState(GstState state)61 void MiracGstTestSource::SetState(GstState state)
62 {
63 if (gst_elem) {
64 gst_element_set_state (gst_elem, state);
65 }
66 }
67
GetState() const68 GstState MiracGstTestSource::GetState() const
69 {
70 if (!gst_elem)
71 return GST_STATE_NULL;
72 GstState result;
73 gst_element_get_state (gst_elem, &result, NULL, GST_CLOCK_TIME_NONE);
74 return result;
75 }
76
UdpSourcePort()77 int MiracGstTestSource::UdpSourcePort()
78 {
79 if (gst_elem == NULL)
80 return 0;
81
82 GstElement* sink = NULL;
83 sink = gst_bin_get_by_name(GST_BIN(gst_elem), "sink");
84
85 if (sink == NULL)
86 return 0;
87
88 GSocket* socket = NULL;
89 g_object_get(sink, "used-socket", &socket, NULL);
90 if (socket == NULL)
91 return 0;
92
93 guint16 port = g_inet_socket_address_get_port(G_INET_SOCKET_ADDRESS(g_socket_get_local_address(socket, NULL)));
94
95 return port;
96 }
97
~MiracGstTestSource()98 MiracGstTestSource::~MiracGstTestSource ()
99 {
100 if (gst_elem) {
101 gst_element_set_state (gst_elem, GST_STATE_NULL);
102 g_source_remove (bus_watch_id);
103 gst_object_unref (GST_OBJECT (gst_elem));
104 }
105 }
106