Skip to content

Instantly share code, notes, and snippets.

@underdoeg
Last active December 26, 2015 05:59
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save underdoeg/7104319 to your computer and use it in GitHub Desktop.
Save underdoeg/7104319 to your computer and use it in GitHub Desktop.
gstreamer network sync server
#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