Last active
December 26, 2015 05:59
-
-
Save underdoeg/7104319 to your computer and use it in GitHub Desktop.
gstreamer network sync server
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <gst/gst.h> | |
#include <glib.h> | |
#include <sstream> | |
#include <iostream> | |
#include <gst/net/gstnet.h> | |
#include <stdio.h> | |
#include "inetserverstream.hpp" | |
#include "exception.hpp" | |
#include "socket.hpp" | |
#include "select.hpp" | |
using namespace std; | |
string toString(guint64 i) { | |
ostringstream convert; // stream used for the conversion | |
convert << i; // insert the textual representation of 'Number' in the characters in the stream | |
return convert.str(); // set 'Result' to the contents of the stream | |
}; | |
using namespace std; | |
GstElement* playbin; | |
GstClock* serverClock; | |
bool playing = false; | |
GstClockTime baseTime; | |
static gboolean handleMessage (GstBus *bus, GstMessage *msg, void* d) { | |
GError *err; | |
gchar *debug_info; | |
switch (GST_MESSAGE_TYPE (msg)) { | |
case GST_MESSAGE_DURATION: | |
cout << "DURATION" << endl; | |
break; | |
case GST_MESSAGE_ERROR: | |
gst_message_parse_error (msg, &err, &debug_info); | |
g_printerr ("Error received from element %s: %s\n", GST_OBJECT_NAME (msg->src), err->message); | |
g_printerr ("Debugging information: %s\n", debug_info ? debug_info : "none"); | |
g_clear_error (&err); | |
g_free (debug_info); | |
break; | |
case GST_MESSAGE_EOS: | |
g_print ("End-Of-Stream reached.\n"); | |
playing = false; | |
gst_element_set_state (playbin, GST_STATE_READY); | |
//baseTime = gst_clock_get_time(serverClock); | |
gst_element_set_state (playbin, GST_STATE_PLAYING); | |
//GstClockTimeDziff diff = 60000; | |
//gst_clock_id_wait(serverClock, diff); | |
break; | |
case GST_MESSAGE_STATE_CHANGED: | |
GstState old, newState, pending; | |
gst_message_parse_state_changed (msg, &old, &newState, &pending); | |
if (newState == GST_STATE_PLAYING) { | |
if(!playing) { | |
gst_pipeline_use_clock(GST_PIPELINE(playbin), serverClock); | |
baseTime = gst_clock_get_internal_time(gst_pipeline_get_clock(GST_PIPELINE(playbin))); | |
cout << "new basetime " << baseTime << endl; | |
gst_element_set_base_time(playbin, baseTime); | |
playing = true; | |
} | |
} | |
break; | |
} | |
/* We want to keep receiving messages */ | |
return true; | |
} | |
static void* startSyncServer(void* data) { | |
using std::string; | |
using libsocket::inet_stream_server; | |
using libsocket::inet_stream; | |
using libsocket::selectset; | |
string host = "0.0.0.0"; | |
string port = "1235"; | |
string answ; | |
try { | |
inet_stream_server srv(host,port,LIBSOCKET_IPv4); | |
inet_stream* cl1; | |
selectset set1; | |
set1.add_fd(srv,LIBSOCKET_READ); | |
while(true) { | |
/********* SELECT PART **********/ | |
std::cout << "Called select()\n"; | |
libsocket::ready_socks readypair; // Create pair (libsocket::fd_struct is the return type of selectset::wait() | |
readypair = set1.wait(); // Wait for a connection and place the pair to the var | |
inet_stream_server* ready_srv = dynamic_cast<inet_stream_server*>(readypair.first.back()); // Get the last fd of the LIBSOCKET_READ vector (.first) of the pair and cast the socket* to inet_stream_server* | |
readypair.first.pop_back(); // delete the fd | |
std::cout << "Ready for accepting\n"; | |
/*******************************/ | |
cl1 = ready_srv->accept(); | |
*cl1 << toString(baseTime).c_str(); | |
answ.resize(100); | |
*cl1 >> answ; | |
std::cout << answ; | |
cl1->destroy(); | |
} | |
srv.destroy(); | |
} catch (libsocket::socket_exception exc) { | |
std::cerr << exc.mesg << std::endl; | |
} | |
return NULL; | |
} | |
int main (int argc, char *argv[]) { | |
gst_init (&argc, &argv); | |
playbin = gst_element_factory_make ("playbin", "playbin"); | |
gst_element_set_state (playbin, GST_STATE_READY); | |
g_object_set (playbin, "uri", "file:///home/phwhitfield/videonodesMedia/syncTest/SD1V06H0.MOV.mp4", NULL); | |
GstElement* videosink = gst_element_factory_make("cluttersink", "videosink"); | |
if(videosink) | |
g_object_set(playbin,"video-sink", videosink); | |
else | |
cout << "could not set video sink" << endl; | |
GstBus *bus = gst_element_get_bus (playbin); | |
gst_bus_add_watch (bus, handleMessage, NULL); | |
GThread* thread; | |
if((thread = g_thread_new("printTime", &startSyncServer, NULL))==NULL) { | |
cout << "CRITICAL ERROR! COULD NOT CREATE PLAYLIST UPDATE THREAD" << endl; | |
return 0; | |
} | |
serverClock = gst_pipeline_get_clock(GST_PIPELINE (playbin)); | |
baseTime = gst_clock_get_time(serverClock); | |
cout << baseTime << endl; | |
gst_pipeline_use_clock(GST_PIPELINE(playbin), serverClock); | |
gst_net_time_provider_new(serverClock, NULL, 1234); | |
gst_element_set_base_time(playbin, baseTime); | |
gst_element_set_state (playbin, GST_STATE_PLAYING); | |
GMainLoop* loop = g_main_loop_new(NULL,FALSE); | |
g_main_loop_run(loop); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment