This URL has Read-Only access.

Statistics
| Branch: | Tag: | Revision:

root / src / libsharedvideo / shared-video-writer.cpp @ 87335b80

History | View | Annotate | Download (5.1 kB)

1
#include "shared-video.h"
2

    
3
namespace ScenicSharedVideo 
4
{ 
5
    Writer::Writer ()
6
    {}
7
    
8
    Writer::Writer (GstElement *pipeline,GstElement *videoElement,const std::string socketPath) : timereset_ (FALSE), timeshift_ (0)
9
    {
10
        qserial_     = gst_element_factory_make ("queue", NULL);
11
        serializer_  = gst_element_factory_make ("gdppay",  NULL);
12
        shmsink_     = gst_element_factory_make ("shmsink", NULL);
13
    
14
        if ( !qserial_ || !serializer_ || !shmsink_) {
15
            g_printerr ("Writer: One gstreamer element could not be created.\n");
16
        }
17

    
18
        GstState current;
19
        gst_element_get_state (pipeline,&current,NULL,GST_CLOCK_TIME_NONE);
20
        
21
        g_object_set (G_OBJECT (shmsink_), "socket-path", socketPath.c_str(), NULL);
22
        g_object_set (G_OBJECT (shmsink_), "shm-size", 94967295, NULL);
23
        g_object_set (G_OBJECT (shmsink_), "sync", FALSE, NULL);
24
        g_object_set (G_OBJECT (shmsink_), "wait-for-connection", FALSE, NULL);
25
    
26
        //adding a probe for reseting timestamp when reconnecting
27
        GstPad *qserialPad = gst_element_get_pad (qserial_, "src");
28
        gst_pad_add_data_probe (qserialPad, 
29
                                G_CALLBACK (Writer::reset_time),
30
                                static_cast<void *>(this));
31
        gst_object_unref(qserialPad);
32
        
33
        g_signal_connect (shmsink_, "client-connected", 
34
                          G_CALLBACK (Writer::on_client_connected), 
35
                          static_cast<void *>(this));
36

    
37
        gst_bin_add_many (GST_BIN (pipeline), qserial_, serializer_, shmsink_, NULL);
38
        gst_element_link_many (videoElement, qserial_, serializer_, shmsink_,NULL);
39

    
40
        if(current != GST_STATE_NULL)
41
        {
42
            gst_element_set_state (qserial_, current);
43
            gst_element_set_state (serializer_, current);
44
            gst_element_set_state (shmsink_, current);
45
        }
46
    }
47

    
48
    Writer::~Writer (){
49
    }
50

    
51
    gboolean
52
    Writer::reset_time (GstPad * pad, GstMiniObject * mini_obj, gpointer user_data)
53
    {
54
        Writer *context = static_cast<Writer*>(user_data);
55
        if (GST_IS_EVENT (mini_obj)) {
56
        }
57
        else if (GST_IS_BUFFER (mini_obj)) {
58
            GstBuffer *buffer = GST_BUFFER_CAST (mini_obj);
59
            if(context->timereset_)
60
            {
61
                context->timeshift_=GST_BUFFER_TIMESTAMP(buffer);
62
                context->timereset_=FALSE;
63
            }
64
            GST_BUFFER_TIMESTAMP(buffer)=GST_BUFFER_TIMESTAMP(buffer) - context->timeshift_;
65
        } 
66
        else if (GST_IS_MESSAGE (mini_obj)) {
67
        }
68
    
69
        return TRUE;
70
    }
71

    
72
    void
73
    Writer::pad_unblocked (GstPad * pad, gboolean blocked, gpointer user_data)
74
    {
75
        Writer *context = static_cast<Writer*>(user_data);
76

    
77
        if(blocked)
78
            g_printerr ("Error: pad not unblocked\n");
79
        else
80
            context->timereset_=TRUE;
81
    }
82

    
83
    void 
84
    Writer::switch_to_new_serializer (GstPad * pad, gboolean blocked, gpointer user_data )
85
    {
86
        Writer *context = static_cast<Writer*>(user_data);
87

    
88
        //unlink the old serializer
89
        GstPad *srcPad=gst_element_get_static_pad(context->serializer_,"src");
90
        GstPad *srcPadPeer=gst_pad_get_peer(srcPad);
91
        if (!gst_pad_unlink (srcPad,srcPadPeer))
92
            g_printerr("Error: cannot unlink src\n");
93

    
94
        GstPad *sinkPad=gst_element_get_static_pad(context->serializer_,"sink");
95
        GstPad *sinkPadPeer=gst_pad_get_peer(sinkPad);
96
        if (!gst_pad_unlink (sinkPadPeer,sinkPad))
97
            g_printerr("Error: cannot unlink sink\n");
98

    
99
        gst_object_unref (srcPad);
100
        gst_object_unref (sinkPad);
101
    
102
        GstBin *bin=GST_BIN (GST_ELEMENT_PARENT(context->serializer_));
103

    
104
        //supposed to be PLAYING, possible issue because of not taking care of pending state 
105
        GstState current;
106
        gst_element_get_state (context->serializer_,&current,NULL,GST_CLOCK_TIME_NONE);
107

    
108
        //get rid of the old serializer TODO ensure object has been cleaned up
109
        gst_element_set_state (context->serializer_,GST_STATE_NULL);
110
        //waiting for possible async state change
111
        gst_element_get_state (context->serializer_,NULL,NULL,GST_CLOCK_TIME_NONE);
112

    
113
        //creating and linking the new serializer
114
        context->serializer_ = gst_element_factory_make ("gdppay",  NULL); 
115
        if(gst_element_set_state (context->serializer_, current) != GST_STATE_CHANGE_SUCCESS) 
116
            g_printerr ("Error: issue changing newSerializer state\n"); 
117
        else{ 
118
            gst_bin_add (bin,context->serializer_); 
119
            GstPad *newSinkPad=gst_element_get_static_pad (context->serializer_,"sink"); 
120
            GstPad *newSrcPad=gst_element_get_static_pad (context->serializer_,"src"); 
121
            gst_pad_link (newSrcPad,srcPadPeer); 
122
            gst_pad_link (sinkPadPeer,newSinkPad); 
123
            gst_object_unref (newSinkPad); 
124
            gst_object_unref (newSrcPad); 
125
        }         
126
        gst_object_unref (srcPadPeer); 
127
        gst_object_unref (sinkPadPeer); 
128

    
129
        //unblocking data stream 
130
        gst_pad_set_blocked_async (pad, 
131
                                   FALSE,
132
                                   (GstPadBlockCallback) (Writer::pad_unblocked),
133
                                   static_cast<void *>(context)); 
134
    }
135

    
136
    void 
137
    Writer::on_client_connected (GstElement * shmsink, gint num, gpointer user_data) 
138
    { 
139
        Writer *context = static_cast<Writer*>(user_data);
140
        GstPad *serializerSinkPad=gst_element_get_static_pad(context->serializer_,"sink");
141
        GstPad *padToBlock = gst_pad_get_peer(serializerSinkPad);
142
        
143
        if(!gst_pad_set_blocked_async (padToBlock, 
144
                                       TRUE, 
145
                                       (GstPadBlockCallback) (Writer::switch_to_new_serializer), 
146
                                       static_cast<void *>(context)))
147
            g_printerr("Error: when requesting the pad to be blocked\n");
148
        gst_object_unref (serializerSinkPad);
149
        gst_object_unref (padToBlock);
150
    } 
151

    
152
} //namespace ScenicSharedVideo