Revision 87335b80

b/src/libsharedvideo/reader-example.cpp
4 4
#include "shared-video.h"
5 5

  
6 6
GstElement *pipeline;
7
GstElement *wdisplay;
7
GstElement *shmDisplay;
8 8
GstElement *videomixer;
9 9

  
10 10
std::string socketName;
......
31 31
	gst_message_parse_error (msg, &error, &debug);
32 32
	g_free (debug);
33 33

  
34
	g_printerr ("Error nico: %s\n", error->message);
34
	//g_printerr ("Error nico: %s\n", error->message);
35 35
	g_error_free (error);
36 36

  
37 37
	//g_print ("Now nulling: \n");
......
91 91
    gst_bus_add_watch (bus, bus_call, loop);
92 92
    gst_object_unref (bus);
93 93

  
94
    wdisplay   = gst_element_factory_make ("xvimagesink", NULL);
94
    GstElement *localVideoSource = gst_element_factory_make ("videotestsrc", NULL);
95
    GstElement *localDisplay = gst_element_factory_make ("xvimagesink", NULL);
96

  
97
    shmDisplay   = gst_element_factory_make ("xvimagesink", NULL);
98
    g_object_set (G_OBJECT (shmDisplay), "sync", FALSE, NULL);
99
    g_object_set (G_OBJECT (localDisplay), "sync", FALSE, NULL);
95 100
    videomixer = gst_element_factory_make ("videomixer", NULL);
96
    if (!pipeline || !wdisplay) {
101
    if (!pipeline || !shmDisplay || !localVideoSource || !localDisplay) {
97 102
	g_printerr ("One element could not be created. Exiting.\n");
98 103
	return -1;
99 104
    }
100 105

  
101
    gst_bin_add_many (GST_BIN (pipeline), videomixer, wdisplay, NULL);
102
    gst_element_link (videomixer,wdisplay);
106
    gst_bin_add_many (GST_BIN (pipeline), videomixer, shmDisplay, localVideoSource, localDisplay, NULL);
107
    gst_element_link (videomixer,shmDisplay);
108
    
109
    gst_element_link (localVideoSource, localDisplay);
110

  
103 111
    //the shared video source is created and attached to the pipeline
104 112
    //the source with control the pipeline state
105 113
    socketName.append (argv[1]);
106
    // new ScenicSharedVideo::Reader (pipeline,wdisplay,socketName);
114
    // new ScenicSharedVideo::Reader (pipeline,shmDisplay,socketName);
107 115
    g_timeout_add (1000, (GSourceFunc) add_shared_video_reader, NULL);
108 116

  
109 117
    gst_element_set_state (pipeline, GST_STATE_PLAYING);
b/src/libsharedvideo/shared-video-reader.cpp
2 2

  
3 3
namespace ScenicSharedVideo 
4 4
{ 
5

  
6 5
    Reader::Reader ()
7 6
    {}
8 7

  
......
10 9
    {
11 10
	pipeline_     = pipeline;
12 11
	sink_         = sink;
12
	
13 13
	socketName_.append(socketName);
14 14

  
15
	GstStaticPadTemplate video_template =
16
	   GST_STATIC_PAD_TEMPLATE (
17
	       "sink",          
18
	       GST_PAD_SINK,    // the direction of the pad
19
	       GST_PAD_REQUEST,  // when this pad will be present
20
	       GST_STATIC_CAPS ("video")
21
	       );
22

  
23
	tmpl_ = gst_static_pad_template_get (&video_template);
24

  
25
	if(tmpl_ == NULL ) g_print ("fucking template\n");
26
	else g_print ("joie\n");
27

  
28
	//monitoring the shared memory file
15
        //monitoring the shared memory file
29 16
	shmfile_ = g_file_new_for_commandline_arg (socketName_.c_str());
30 17
	if (shmfile_ == NULL) {
31 18
	    g_printerr ("argument not valid. \n");
32 19
	}
33 20
	
34 21
	if (g_file_query_exists (shmfile_,NULL)){
35
	    g_print ("Now reading constructor: \n");
36
	    //gst_element_set_state (pipeline_, GST_STATE_PLAYING);
37 22
	    Reader::attach ();
38 23
	}
24

  
25
	GstBus *bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline));
26
	gst_bus_set_sync_handler (bus, message_handler, static_cast<void *>(this));
27
	gst_object_unref (bus);
39 28
	
40 29
	GFile *dir = g_file_get_parent (shmfile_);
41 30
	dirMonitor_ = g_file_monitor_directory (dir, G_FILE_MONITOR_NONE, NULL, NULL); 
......
43 32
	g_signal_connect (dirMonitor_, "changed", G_CALLBACK (Reader::file_system_monitor_change), static_cast<void *>(this)); 
44 33
    }
45 34

  
46

  
47 35
    Reader::~Reader (){
48 36
	g_object_unref(shmfile_);
49 37
	g_object_unref(dirMonitor_);
......
62 50
	gst_bin_add_many (GST_BIN (pipeline_),
63 51
			  source_, deserializer_, NULL);
64 52

  
65
	sinkPad_ = gst_element_request_pad (sink_,tmpl_,NULL,NULL);
66 53
	deserialPad_ = gst_element_get_static_pad (deserializer_,"src");
54
	sinkPad_ = gst_element_get_compatible_pad (sink_,deserialPad_,GST_PAD_CAPS(deserialPad_));
67 55

  
68 56
	gst_element_link (source_, deserializer_);
69 57
	gst_pad_link (deserialPad_,sinkPad_);
......
75 63
    void
76 64
    Reader::detach ()
77 65
    {
78
	gst_element_set_state (deserializer_, GST_STATE_NULL);
79
	gst_element_set_state (source_, GST_STATE_NULL);
80 66
	gst_element_unlink (source_, deserializer_);
81 67
	gst_pad_unlink (deserialPad_,sinkPad_);
82 68
	gst_object_unref (deserialPad_);
83 69
	gst_element_release_request_pad(sink_,sinkPad_);
84
	gst_object_unref(sinkPad_);
85
	gst_bin_remove (GST_BIN (pipeline_),source_); 
86
	gst_bin_remove (GST_BIN (pipeline_),deserializer_);
87
	
70
	//ask for element cleaning in the main thread
71
	g_idle_add ((GSourceFunc) clean_source,static_cast<void *>(this));
88 72
    }
89 73

  
74
    gboolean 
75
    Reader::clean_source (gpointer user_data)
76
    {
77
	Reader *context = static_cast<Reader*>(user_data);
78
	gst_object_unref(context->sinkPad_);
79
	gst_element_set_state (context->deserializer_, GST_STATE_NULL);
80
	gst_element_set_state (context->source_, GST_STATE_NULL);
81
	gst_bin_remove (GST_BIN (context->pipeline_),context->source_); 
82
	gst_bin_remove (GST_BIN (context->pipeline_),context->deserializer_);
83
	return FALSE;
84
    }
85

  
86
    GstBusSyncReply Reader::message_handler (GstBus *bus, GstMessage *msg, gpointer user_data)
87
    {
88
	switch (GST_MESSAGE_TYPE (msg)) {
89
	case GST_MESSAGE_EOS:
90
	    g_print ("End of stream\n");
91
	    break;
92
	case GST_MESSAGE_ERROR: {
93
	    gchar  *debug;
94
	    GError *error;
95
	    Reader *context = static_cast<Reader*>(user_data);
96
	    gst_message_parse_error (msg, &error, &debug);
97
	    g_free (debug);
98
	    if (error->code == GST_RESOURCE_ERROR_READ && g_strcmp0 (GST_ELEMENT_NAME(context->source_),GST_OBJECT_NAME(msg->src)) == 0 ){
99
		context->detach ();
100
		g_error_free (error);
101
		return GST_BUS_DROP;
102
	    }
103
	    g_error_free (error);
104
	    break;
105
	}
106
	default:
107
	    break;
108
	}
109
	return GST_BUS_PASS;
110
    }
90 111

  
91 112
    void
92 113
    Reader::file_system_monitor_change (GFileMonitor *      monitor,
......
95 116
					GFileMonitorEvent   type,
96 117
					gpointer user_data)
97 118
    {
98
	
99 119
	char *filename = g_file_get_path (file);
100

  
101 120
	Reader *context = static_cast<Reader*>(user_data);
102 121

  
103 122
	switch (type)
104 123
	{
105 124
	case G_FILE_MONITOR_EVENT_CREATED:
106 125
	    if (g_file_equal (file,context->shmfile_)) {
107
		g_print ("Now reading: \n");
108 126
		context->attach();
109
		//gst_element_set_state (context->pipeline_, GST_STATE_PLAYING);
110 127
	    }	  
111
	    g_print ("G_FILE_MONITOR_EVENT_CREATED: %s\n",filename);
112
	    break;
113
	case G_FILE_MONITOR_EVENT_DELETED:
114
	    if (g_file_equal (file,context->shmfile_)) {
115
		g_print ("Now nulling: \n");
116
//		gst_element_set_state (context->pipeline_, GST_STATE_NULL);
117
		context->detach ();
118
	    }	  
119
	    g_print ("G_FILE_MONITOR_EVENT_DELETED: %s\n",filename);
120 128
	    break;
129
	    /* case G_FILE_MONITOR_EVENT_DELETED:*/
130
	    /* break; */
121 131
	    /* case G_FILE_MONITOR_EVENT_CHANGED: */
122 132
	    /* 	  g_print ("G_FILE_MONITOR_EVENT_CHANGED\n"); */
123 133
	    /* 	  break; */
......
137 147
	    break;
138 148
	}
139 149
	g_free (filename);
140
	
141 150
    }
142
    
143 151

  
144 152
} //end namespace  ScenicSharedVideo
b/src/libsharedvideo/shared-video-writer.cpp
7 7
    
8 8
    Writer::Writer (GstElement *pipeline,GstElement *videoElement,const std::string socketPath) : timereset_ (FALSE), timeshift_ (0)
9 9
    {
10
	
11 10
	qserial_     = gst_element_factory_make ("queue", NULL);
12 11
	serializer_  = gst_element_factory_make ("gdppay",  NULL);
13 12
	shmsink_     = gst_element_factory_make ("shmsink", NULL);
......
44 43
	    gst_element_set_state (serializer_, current);
45 44
	    gst_element_set_state (shmsink_, current);
46 45
	}
47

  
48

  
49 46
    }
50 47

  
51

  
52 48
    Writer::~Writer (){
53 49
    }
54 50

  
......
71 67
	}
72 68
    
73 69
	return TRUE;
74
    
75 70
    }
76 71

  
77 72
    void
......
82 77
	if(blocked)
83 78
	    g_printerr ("Error: pad not unblocked\n");
84 79
	else
85
	{
86 80
	    context->timereset_=TRUE;
87
	}
88 81
    }
89 82

  
90 83
    void 
......
107 100
	gst_object_unref (sinkPad);
108 101
    
109 102
	GstBin *bin=GST_BIN (GST_ELEMENT_PARENT(context->serializer_));
110
	
111 103

  
112 104
	//supposed to be PLAYING, possible issue because of not taking care of pending state 
113 105
	GstState current;
114 106
	gst_element_get_state (context->serializer_,&current,NULL,GST_CLOCK_TIME_NONE);
115
	//g_print("serializer state: %d \n",current);
116 107

  
117 108
	//get rid of the old serializer TODO ensure object has been cleaned up
118 109
	gst_element_set_state (context->serializer_,GST_STATE_NULL);
119

  
120 110
	//waiting for possible async state change
121 111
	gst_element_get_state (context->serializer_,NULL,NULL,GST_CLOCK_TIME_NONE);
122 112

  
......
125 115
	if(gst_element_set_state (context->serializer_, current) != GST_STATE_CHANGE_SUCCESS) 
126 116
	    g_printerr ("Error: issue changing newSerializer state\n"); 
127 117
	else{ 
128
	    //g_print ("changing serializer state\n"); 
129 118
	    gst_bin_add (bin,context->serializer_); 
130 119
	    GstPad *newSinkPad=gst_element_get_static_pad (context->serializer_,"sink"); 
131 120
	    GstPad *newSrcPad=gst_element_get_static_pad (context->serializer_,"src"); 
......
138 127
	gst_object_unref (sinkPadPeer); 
139 128

  
140 129
	//unblocking data stream 
141
	//g_print ("setting pad to unblocked\n"); 
142 130
	gst_pad_set_blocked_async (pad, 
143 131
				   FALSE,
144 132
				   (GstPadBlockCallback) (Writer::pad_unblocked),
......
149 137
    Writer::on_client_connected (GstElement * shmsink, gint num, gpointer user_data) 
150 138
    { 
151 139
	Writer *context = static_cast<Writer*>(user_data);
152
	
153
	//g_print ("on client connected %d\n",num); 
154 140
	GstPad *serializerSinkPad=gst_element_get_static_pad(context->serializer_,"sink");
155 141
	GstPad *padToBlock = gst_pad_get_peer(serializerSinkPad);
156 142
	
b/src/libsharedvideo/shared-video.h
4 4
#include <gst/gst.h>
5 5
#include <gio/gio.h>
6 6

  
7

  
8 7
namespace ScenicSharedVideo
9 8
{
10 9
   class Writer {
......
30 29
       Reader ();
31 30
       ~Reader ();
32 31
   private:
32
       //pipeline elements
33
       GstElement *pipeline_;
33 34
       GstElement *source_;
34 35
       GstElement *deserializer_;
35 36
       GstElement *sink_;
36
       GFile *shmfile_; 
37
       GstElement *pipeline_;
38
       GFileMonitor* dirMonitor_;
39
       GstPadTemplate *tmpl_;
40 37
       GstPad *sinkPad_;
41 38
       GstPad *deserialPad_;
39
       //monitoring the shm file
40
       GFile *shmfile_; 
41
       GFileMonitor* dirMonitor_;
42 42
       std::string socketName_; 
43
       //dynamic linking
43 44
       void attach ();
44 45
       void detach ();
46
       //gcallbacks
47
       static gboolean clean_source (gpointer user_data);
48
       static GstBusSyncReply message_handler (GstBus *bus, GstMessage *msg, gpointer user_data);
45 49
       static void file_system_monitor_change (GFileMonitor *monitor, GFile *file, GFile *other_file, GFileMonitorEvent type, gpointer user_data);
46 50
   };
47 51

  
48
}
49

  
52
}      //end namespace  ScenicSharedVideo
50 53
#endif //_SCENIC_SHARED_VIDEO_H_
51 54

  
b/src/libsharedvideo/writer-example.cpp
5 5

  
6 6

  
7 7
GstElement *pipeline;
8

  
9 8
GstElement *source;    
10 9
GstElement *tee;       
11 10
GstElement *qlocalxv;  
......
28 27
    exit(sig);
29 28
}
30 29

  
31

  
32

  
33
static gboolean
34
bus_call (GstBus     *bus,
35
          GstMessage *msg,
36
          gpointer    data)
37
{
38
    GMainLoop *loop = (GMainLoop *) data;
39

  
40
    switch (GST_MESSAGE_TYPE (msg)) {
41

  
42
    case GST_MESSAGE_EOS:
43
	g_print ("End of stream\n");
44
	g_main_loop_quit (loop);
45
	break;
46

  
47
    case GST_MESSAGE_ERROR: {
48
	gchar  *debug;
49
	GError *error;
50

  
51
	gst_message_parse_error (msg, &error, &debug);
52
	g_free (debug);
53

  
54
	g_printerr ("Error: %s\n", error->message);
55
	g_error_free (error);
56

  
57
	g_main_loop_quit (loop);
58
	break;
59
    }
60
    default:
61
	break;
62
    }
63

  
64
    return TRUE;
65
}
66

  
67

  
30
//will create the shared video, reading from the tee element  
68 31
static gboolean  
69 32
add_shared_video_writer()
70 33
{
71 34
    writer = new ScenicSharedVideo::Writer (pipeline,tee,socketName);
35
    g_print ("Now writing to the shared memory\n");
72 36
    return FALSE;
73 37
}
74 38

  
......
78 42
{
79 43
    (void) signal(SIGINT,leave);
80 44

  
81
    /* Initialisation */
82 45
    gst_init (&argc, &argv);
83

  
84 46
    GMainLoop *loop = g_main_loop_new (NULL, FALSE);
85 47

  
86 48
    /* Check input arguments */
......
88 50
	g_printerr ("Usage: %s <socket-path>\n", argv[0]);
89 51
	return -1;
90 52
    }
53
    socketName.append (argv[1]);
54

  
91 55

  
92 56
    /* Create gstreamer elements */
93
    pipeline    = gst_pipeline_new ("shared-video-writer");
94
    source      = gst_element_factory_make ("videotestsrc",  "video-source");
57
    pipeline    = gst_pipeline_new (NULL);
58
    source      = gst_element_factory_make ("videotestsrc",  NULL);
95 59
    
96 60
    camsource   = gst_element_factory_make ("v4l2src",  NULL);
97 61

  
98 62
    timeoverlay = gst_element_factory_make ("timeoverlay", NULL);
99 63
    tee         = gst_element_factory_make ("tee", NULL);
100

  
101 64
 
102 65
    qlocalxv    = gst_element_factory_make ("queue", NULL);
103 66
    imgsink     = gst_element_factory_make ("xvimagesink", NULL);
......
108 71
	return -1;
109 72
    }
110 73

  
74
    g_object_set (G_OBJECT (imgsink), "sync", FALSE, NULL);
75

  
111 76
    /*specifying video format*/
112
     /* GstCaps *videocaps;  */
113
     /* videocaps = gst_caps_new_simple ("video/x-raw-yuv",  */
114
     /* 				     "format", GST_TYPE_FOURCC, GST_MAKE_FOURCC ('I', '4', '2', '0'),  */
115
     /* 				     "framerate", GST_TYPE_FRACTION, 30, 1,  */
116
     /* 				     "pixel-aspect-ratio", GST_TYPE_FRACTION, 1, 1,  */
117
     /* 				     /\* "width", G_TYPE_INT, 600,  *\/ */
118
     /* 				     /\* "height", G_TYPE_INT, 400,  *\/ */
119
     /* 				      "width", G_TYPE_INT, 1920,   */
120
     /* 				      "height", G_TYPE_INT, 1080,   */
121
     /* 				     NULL);  */
122

  
123
    /* we add a message handler */
124
    GstBus *bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline));
125
    gst_bus_add_watch (bus, bus_call, loop);
126
    gst_object_unref (bus);
127

  
128
    /* we add all elements into the pipeline */
77
    // GstCaps *videocaps;  
78
    // videocaps = gst_caps_new_simple ("video/x-raw-yuv",  
79
    //   				     "format", GST_TYPE_FOURCC, GST_MAKE_FOURCC ('I', '4', '2', '0'),  
80
    //   				     "framerate", GST_TYPE_FRACTION, 30, 1,  
81
    //   				     "pixel-aspect-ratio", GST_TYPE_FRACTION, 1, 1,  
82
    // 				     /* "width", G_TYPE_INT, 600,  */ 
83
    // 				     /* "height", G_TYPE_INT, 400,  */ 
84
    // 				     "width", G_TYPE_INT, 1920,   
85
    // 				     "height", G_TYPE_INT, 1080,   
86
    //   				     NULL);  
87

  
129 88
    gst_bin_add_many (GST_BIN (pipeline),
130 89
		      //source, 
131 90
		      camsource, 
132 91
		      timeoverlay, tee, qlocalxv, imgsink, NULL);
133 92

  
134
    //init before set playing state 
135
    socketName.append (argv[1]);
136
    //writer = new ScenicSharedVideo::Writer (pipeline,tee,socketName);
137 93

  
94
    //shared video can be pluged before or after the pipeline state is set to PLAYING 
138 95
    g_timeout_add (1000, (GSourceFunc) add_shared_video_writer, NULL);
139

  
96
    //add_shared_video_writer();
140 97

  
141 98
    /* we link the elements together */
142 99
    //gst_element_link_filtered (source, timeoverlay,videocaps);
143 100
    gst_element_link (camsource,timeoverlay);
144 101
    gst_element_link (timeoverlay, tee);
145 102
    gst_element_link_many (tee, qlocalxv,imgsink,NULL);
146
        
147
    g_object_set (G_OBJECT (imgsink), "sync", FALSE, NULL);
148

  
149 103

  
150 104
    /* Set the pipeline to "playing" state*/
151
    g_print ("Now writing: %s\n", argv[1]);
152 105
    gst_element_set_state (pipeline, GST_STATE_PLAYING);
153
    
154 106

  
155
    
156

  
157
    /* Iterate */
158 107
    g_print ("Running...\n");
159 108
    g_main_loop_run (loop);
160 109

  
161 110
    /* Out of the main loop, clean up nicely */
162 111
    g_print ("Returned, stopping playback\n");
163 112
    gst_element_set_state (pipeline, GST_STATE_NULL);
164

  
165 113
    g_print ("Deleting pipeline\n");
166 114
    gst_object_unref (GST_OBJECT (pipeline));
167 115

  

Also available in: Unified diff