Too many files open issue

classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|

Too many files open issue

sameer_evon
Hello all,

I am new to Gstreamer and c++ programming in linux. I am using Gstreamer to
record audio from RTP stream from a voip call session. For some reason
gst_bus_add_watch() is not working and EOS is not being received in the
callback, so I have made the GMainLoop object global and used
g_main_loop_quit(loop) to end the recording. But after every recording
completes, one file is being left open. After there are several calls we
receive an error "Too many files open" and the app stops working.
Please let me know if making the GMainLoop object as a global object is a
wrong practice, or if there is any incorrect thing in the program.

On using the command after every call termination : ls -l /proc/<pid>/fd, it
shows that there are 4 files that are not being closed after recording ends.
FYI for every call session, there are 4 different streams so 4 recordings
take place on different threads.(there are 4 different GMainLoop objects for
the 4 threads)

Below are some parts of the program :

int startRecording() {

            GstElement *asource, *acapsfilter, *gdepay, *queue2, *gdppay;
            GstElement *sink;
            GstBus *bus;
            guint bus_watch_id;
            GstCaps *caps;
           
            loop = g_main_loop_new (g_main_context_new(), FALSE);

            /* Create gstreamer elements */
            GstElement * pipeline     = gst_pipeline_new ("av-recorder");
            asource      = gst_element_factory_make ("udpsrc",     "aud-source");
            acapsfilter  = gst_element_factory_make ("capsfilter",  "audio-caps");
            gdepay  = gst_element_factory_make ("rtppcmadepay", "artpdepay");
            queue2   = gst_element_factory_make ("queue",   "queue2");
            sink        = gst_element_factory_make ("filesink",    "file-output");

            if (!pipeline || !asource || !acapsfilter || !gdepay || /*!gdppay ||*/
!queue2 ||!sink)
            {
              g_printerr ("One element could not be created. Exiting.\n");
              return -1;
            }

            g_object_set (G_OBJECT (asource), "port", port, NULL);

            string capstring =
"application/x-rtp,channels=(int)1,media=(string)audio,payload=(int)"+
                             boost::lexical_cast<string>(payloadInt)+
                           
",clock-rate=(int)8000,encoding-name=(string)"+encodingname;
            caps = gst_caps_from_string(capstring.c_str());
            g_object_set (G_OBJECT (acapsfilter), "caps", caps, NULL);
            gst_caps_unref (caps);
            bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline));
            bus_watch_id = gst_bus_add_watch (bus, bus_call, loop);
            gst_object_unref (bus);
            gst_bin_add_many (GST_BIN (pipeline),asource, acapsfilter, gdepay,
/*gdppay, queue2,*/ sink, NULL);
            gst_element_link_many (asource, acapsfilter, gdepay, /*gdppay,
queue2,*/ sink, NULL);
            gst_element_set_state (pipeline, GST_STATE_PLAYING);
            g_print ("***Recording (or not!)...\n");
            g_main_loop_run (loop);
            g_print ("Returned, stopping recording\n");
            gst_element_set_state (pipeline, GST_STATE_NULL);
            g_print ("Deleting pipeline\n");
            gst_object_unref (GST_OBJECT (pipeline));
            g_source_remove (bus_watch_id);
            g_main_loop_unref (loop);
}

void stopRecording() {
            g_main_loop_quit (loop);
}

// this method is not being invoked in any case
gboolean RTPRecorder::bus_call (GstBus *bus, GstMessage *msg, gpointer  
data)
        {
    GMainLoop *loop = (GMainLoop *) data;
    switch (GST_MESSAGE_TYPE (msg)) {
      case GST_MESSAGE_EOS:
        g_print ("End of stream\n");
        g_main_loop_quit (loop);
        break;
      case GST_MESSAGE_ERROR:{
        gchar  *debug;
        GError *error;
        gst_message_parse_error (msg, &error, &debug);
        g_free (debug);
        g_printerr ("Error: %s\n", error->message);
        g_error_free (error);
        g_main_loop_quit (loop);
        break;
    }
      default:
        break;
    }
    return TRUE;
 }


Any help will be highly appreciated.

Thanks!




--
Sent from: http://gstreamer-devel.966125.n4.nabble.com/
_______________________________________________
gstreamer-devel mailing list
[hidden email]
https://lists.freedesktop.org/mailman/listinfo/gstreamer-devel
Reply | Threaded
Open this post in threaded view
|

Re: Too many files open issue

James Cameron
On Thu, May 31, 2018 at 11:20:01PM -0700, [hidden email] wrote:
> Hello all,
>
> I am new to Gstreamer and c++ programming in linux. I am using
> Gstreamer to record audio from RTP stream from a voip call
> session. For some reason gst_bus_add_watch() is not working and EOS
> is not being received in the callback,

To stop recording, send an EOS event into your source element, then
wait for the EOS message from the bus, then set state to NULL.
I couldn't see in your code any sending of EOS event, and forcing
state to NULL will not send EOS.

(I haven't used gst_bus_add_watch; my preference has been
gst_bus_add_signal_watch and then connect to signal "message".)

--
James Cameron
http://quozl.netrek.org/
_______________________________________________
gstreamer-devel mailing list
[hidden email]
https://lists.freedesktop.org/mailman/listinfo/gstreamer-devel
Reply | Threaded
Open this post in threaded view
|

Re: Too many files open issue

sameer_evon
Thank you so much James for your reply. I tried to send the EOS event using
this code:
gst_element_send_event(pipeline, gst_event_new_eos())

This didn't work until I tried something like below:

void worker(GstElement *pipeline) {
    gst_element_send_event(pipeline, gst_event_new_eos());
}

void stopListening() {
    boost::thread *th = new boost::thread(worker,pipeline);
}

i.e. when EOS was sent from another thread and not from the same thread,
then only the bus watched method was being invoked. And after that all files
were being closed properly.
I don't know why it didn't work from the same thread. It would be really
helpful if you could explain this behavior and also tell if this way of
doing it is okay or not.
FYI the recording is not being done on the main thread as there are multiple
calls. So each recording task is being done on a different new thread.


Thanks again.



--
Sent from: http://gstreamer-devel.966125.n4.nabble.com/
_______________________________________________
gstreamer-devel mailing list
[hidden email]
https://lists.freedesktop.org/mailman/listinfo/gstreamer-devel