<div dir="ltr"><p style="margin:0px 0px 1em;padding:0px;border:0px;font-size:15px;clear:both;color:rgb(36,39,41);font-family:arial,"helvetica neue",helvetica,sans-serif;line-height:19.5px">I have an object to generate videos with GStreamer. Each time I want to generate a new video y create one new object and add frames. After video is finished, I delete the object but GStreamer internal memory looks like is not released.</p><p style="margin:0px 0px 1em;padding:0px;border:0px;font-size:15px;clear:both;color:rgb(36,39,41);font-family:arial,"helvetica neue",helvetica,sans-serif;line-height:19.5px">After several videos generated all RAM is allocated and linux kills the process.</p><p style="margin:0px 0px 1em;padding:0px;border:0px;font-size:15px;clear:both;color:rgb(36,39,41);font-family:arial,"helvetica neue",helvetica,sans-serif;line-height:19.5px">Why is this happening? How can I solve this issue? Is there any other way to do it?</p><p style="margin:0px 0px 1em;padding:0px;border:0px;font-size:15px;clear:both;color:rgb(36,39,41);font-family:arial,"helvetica neue",helvetica,sans-serif;line-height:19.5px"><span style="font-family:arial,"helvetica neue",helvetica,sans-serif">GVideo.h:</span><br></p><div><div class="gmail_signature"><div><div>#ifndef GVIDEO_H</div><div>#define GVIDEO_H</div><div><br></div><div>#include <gst/gst.h></div><div><br></div><div>#include <string></div><div><br></div><div>class GVideo</div><div>{</div><div>public:</div><div>    GVideo();</div><div>    ~GVideo();</div><div><br></div><div>    void startVideo(std::string filename);</div><div>    void endVideo();</div><div><br></div><div>    void addFrame(GstSample* element);</div><div><br></div><div>    bool isRecording(){return _isRecording;}</div><div>    bool isDataNeed(){return _dataNeed;}</div><div>private:</div><div>    void setDataNeed(bool dataNeed){_dataNeed = dataNeed;}</div><div><br></div><div>protected:</div><div>    bool _isRecording;</div><div>    bool _dataNeed;</div><div>    int _frameRate;</div><div>    int _duration;</div><div>    GstClockTime _timestamp;</div><div><br></div><div>    GstElement *_pipeline;</div><div>    GstElement *_source;</div><div>};</div><div><br></div><div>#endif //GVIDEO_H</div></div><div><br></div><div><br></div><div><span style="color:rgb(36,39,41);font-family:arial,"helvetica neue",helvetica,sans-serif;font-size:15px;line-height:19.5px">GVideo.cpp:</span><br></div><div><span style="color:rgb(36,39,41);font-family:arial,"helvetica neue",helvetica,sans-serif;font-size:15px;line-height:19.5px"><br></span></div>#include "GVideo.h"<br><br>#include <gst/app/gstappsrc.h><br><br>#include <iostream><br><br>static gboolean bus_video_call(GstBus* bus, GstMessage* msg, void* user_data)<br>{<br>    //std::cout << "BUS_CALL" << std::endl;<br><br>    GVideo* video = (GVideo*)user_data;<br><br>    switch (GST_MESSAGE_TYPE(msg))<br>    {<br>        case GST_MESSAGE_EOS:<br>            {<br>                std::cout << "VIDEO GST_MESSAGE_EOS" << std::endl;<br><br>                video->endVideo();<br><br>                break;<br>            }<br>        case GST_MESSAGE_ERROR:<br>            {<br>                std::cout << "GST_MESSAGE_ERROR" << std::endl;<br><br>                GError *err;<br>                gst_message_parse_error(msg, &err, NULL);<br>                g_error("%s", err->message);<br>                g_error_free(err);<br><br>                video->endVideo();<br><br>                break;<br>            }<br>        default:<br>            break;<br>    }<br><br>    return true;<br>}<br><br>GVideo::GVideo()<br>    : _dataNeed(false), _isRecording(false)<br>{<br>    _pipeline     = NULL;<br>    _source       = NULL;<br>}<br><br>GVideo::~GVideo()<br>{<br>    std::cout << "Deleting GstVideo." << std::endl;<br><br>    if(_pipeline != NULL)<br>        endVideo();<br>}<br><br>void GVideo::startVideo(std::string filename)<br>{<br>    _isRecording = true;<br><br>    _frameRate = 2;<br>    _duration = 5;<br>    _timestamp = 0;<br>    _dataNeed = true;<br>    _pipeline     = gst_pipeline_new ("video_pipeline");<br>    _source       = gst_element_factory_make ("appsrc"      , "video_source");<br>    GstElement* _videorate    = gst_element_factory_make ("videorate"   , "video_vidrate");<br>    GstElement* _capsfilter   = gst_element_factory_make ("capsfilter"  , "video_capsfilter");<br>    GstElement* _videoconvert = gst_element_factory_make ("videoconvert", "video_conv");<br>    GstElement* _encoder      = gst_element_factory_make ("x264enc"     , "video_enc");<br>    GstElement* _muxer        = gst_element_factory_make ("mp4mux"      , "video_mux");<br>    GstElement* _filesink     = gst_element_factory_make ("filesink"    , "video_filesink");<br><br>//  g_object_set (G_OBJECT (_source), "num-buffers", _duration*_frameRate, NULL);<br>    g_object_set (G_OBJECT (_source), "caps",<br>                  gst_caps_new_simple ( "video/x-raw",<br>                                        "format", G_TYPE_STRING, "I420",<br>                                        "width", G_TYPE_INT, 352,<br>                                        "height", G_TYPE_INT, 288,<br>                                        "framerate", GST_TYPE_FRACTION, _frameRate, 1,<br>                                        NULL), NULL);<br><br>    /* setup appsrc */<br>    g_object_set (G_OBJECT (_source),<br>    //              "do-timestamp", TRUE,<br>                    "stream-type", GST_APP_STREAM_TYPE_STREAM,<br>                    "format", GST_FORMAT_TIME, NULL);<br><br>    g_object_set (G_OBJECT (_capsfilter), "caps",<br>                    gst_caps_new_simple ("video/x-raw",<br>//                                       "format", G_TYPE_STRING, "I420",<br>                                         "framerate", GST_TYPE_FRACTION, 30, 1,<br>                                         NULL), NULL);<br><br>    gst_bin_add_many (GST_BIN (_pipeline), _source, _videorate, _capsfilter, _videoconvert, _encoder, _muxer, _filesink, NULL);<br>    gst_element_link_many (_source, _videorate, _capsfilter, _videoconvert, _encoder, _muxer, _filesink, NULL);<br><br>    g_object_set (G_OBJECT (_filesink), "location", filename.c_str(), NULL);<br><br>    GstBus* bus = gst_pipeline_get_bus(GST_PIPELINE(_pipeline));<br>    gst_bus_add_watch(bus, bus_video_call, this);<br>    gst_object_unref(bus);<br><br>    gst_element_set_state (_pipeline, GST_STATE_PLAYING);<br>}<br><br>void GVideo::addFrame(GstSample* element)<br>{<br>    GstBuffer* buf = gst_sample_get_buffer((GstSample*)element);<br><br>    GST_BUFFER_PTS (buf) = _timestamp;<br>    GST_BUFFER_DURATION (buf) = gst_util_uint64_scale_int (1, GST_SECOND, _frameRate);<br>    _timestamp += GST_BUFFER_DURATION (buf);<br><br>    gst_app_src_push_sample(GST_APP_SRC(_source), element);<br><br>    if(_timestamp >= _duration*GST_SECOND)<br>    {<br>        _dataNeed = false;<br>        gst_app_src_end_of_stream(GST_APP_SRC(_source));<br>    }<br>}<br><br>void GVideo::endVideo()<br>{<br>    std::cout << "gst_element_set_state." << std::endl;<br>    gst_element_set_state (_pipeline, GST_STATE_NULL);<br>    std::cout << "gst_object_unref." << std::endl;<br>    gst_object_unref(_pipeline);<br>    std::cout << "_pipeline= NULL." << std::endl;<br>    _pipeline = NULL;<br>    std::cout << "setDataNeed." << std::endl;<br>    _isRecording = false;<br>}<div><span style="color:rgb(36,39,41);font-family:arial,"helvetica neue",helvetica,sans-serif;font-size:15px;line-height:19.5px"><br></span></div><div>thanks in advance.</div><div><br></div><div>Andoni Galdos.<br></div></div></div>
</div>