c++ - GStreamer memory leak issue -


i have object generate videos gstreamer. each time want generate new video y create 1 new object , add frames. after video finished, delete object gstreamer internal memory looks not released.

after several videos generated ram allocated , linux kills process.

why happening? how can solve issue? there other way it?

gvideo.h:

#ifndef gvideo_h #define gvideo_h  #include <gst/gst.h>  #include <string>  class gvideo { public:     gvideo();     ~gvideo();      void startvideo(std::string filename);     void endvideo();      void addframe(gstsample* element);      bool isrecording(){return _isrecording;}     bool isdataneed(){return _dataneed;} private:     void setdataneed(bool dataneed){_dataneed = dataneed;}  protected:     bool _isrecording;     bool _dataneed;     int _framerate;     int _duration;     gstclocktime _timestamp;      gstelement *_pipeline;     gstelement *_source; };  #endif //gvideo_h 

gvideo.cpp

#include "gvideo.h"  #include <gst/app/gstappsrc.h>  #include <iostream>  static gboolean bus_video_call(gstbus* bus, gstmessage* msg, void* user_data) {     //std::cout << "bus_call" << std::endl;      gvideo* video = (gvideo*)user_data;      switch (gst_message_type(msg))     {         case gst_message_eos:             {                 std::cout << "video gst_message_eos" << std::endl;                  video->endvideo();                  break;             }         case gst_message_error:             {                 std::cout << "gst_message_error" << std::endl;                  gerror *err;                 gst_message_parse_error(msg, &err, null);                 g_error("%s", err->message);                 g_error_free(err);                  video->endvideo();                  break;             }         default:             break;     }      return true; }  gvideo::gvideo()     : _dataneed(false), _isrecording(false) {     _pipeline     = null;     _source       = null; }  gvideo::~gvideo() {     std::cout << "deleting gstvideo." << std::endl;      if(_pipeline != null)         endvideo(); }  void gvideo::startvideo(std::string filename) {     _isrecording = true;      _framerate = 2;     _duration = 5;     _timestamp = 0;     _dataneed = true;     _pipeline     = gst_pipeline_new ("video_pipeline");     _source       = gst_element_factory_make ("appsrc"      , "video_source");     gstelement* _videorate    = gst_element_factory_make ("videorate"   , "video_vidrate");     gstelement* _capsfilter   = gst_element_factory_make ("capsfilter"  , "video_capsfilter");     gstelement* _videoconvert = gst_element_factory_make ("videoconvert", "video_conv");     gstelement* _encoder      = gst_element_factory_make ("x264enc"     , "video_enc");     gstelement* _muxer        = gst_element_factory_make ("mp4mux"      , "video_mux");     gstelement* _filesink     = gst_element_factory_make ("filesink"    , "video_filesink");  //  g_object_set (g_object (_source), "num-buffers", _duration*_framerate, null);     g_object_set (g_object (_source), "caps",                   gst_caps_new_simple ( "video/x-raw",                                         "format", g_type_string, "i420",                                         "width", g_type_int, 352,                                         "height", g_type_int, 288,                                         "framerate", gst_type_fraction, _framerate, 1,                                         null), null);      /* setup appsrc */     g_object_set (g_object (_source),     //              "do-timestamp", true,                     "stream-type", gst_app_stream_type_stream,                     "format", gst_format_time, null);      g_object_set (g_object (_capsfilter), "caps",                     gst_caps_new_simple ("video/x-raw", //                                       "format", g_type_string, "i420",                                          "framerate", gst_type_fraction, 30, 1,                                          null), null);      gst_bin_add_many (gst_bin (_pipeline), _source, _videorate, _capsfilter, _videoconvert, _encoder, _muxer, _filesink, null);     gst_element_link_many (_source, _videorate, _capsfilter, _videoconvert, _encoder, _muxer, _filesink, null);      g_object_set (g_object (_filesink), "location", filename.c_str(), null);      gstbus* bus = gst_pipeline_get_bus(gst_pipeline(_pipeline));     gst_bus_add_watch(bus, bus_video_call, this);     gst_object_unref(bus);      gst_element_set_state (_pipeline, gst_state_playing); }  void gvideo::addframe(gstsample* element) {     gstbuffer* buf = gst_sample_get_buffer((gstsample*)element);      gst_buffer_pts (buf) = _timestamp;     gst_buffer_duration (buf) = gst_util_uint64_scale_int (1, gst_second, _framerate);     _timestamp += gst_buffer_duration (buf);      gst_app_src_push_sample(gst_app_src(_source), element);      if(_timestamp >= _duration*gst_second)     {         _dataneed = false;         gst_app_src_end_of_stream(gst_app_src(_source));     } }  void gvideo::endvideo() {     std::cout << "gst_element_set_state." << std::endl;     gst_element_set_state (_pipeline, gst_state_null);     std::cout << "gst_object_unref." << std::endl;     gst_object_unref(_pipeline);     std::cout << "_pipeline= null." << std::endl;     _pipeline = null;     std::cout << "setdataneed." << std::endl;     _isrecording = false; } 

i guess whatever calling addframe() might need unref sample.

https://gstreamer.freedesktop.org/data/doc/gstreamer/head/gst-plugins-base-libs/html/gst-plugins-base-libs-appsrc.html#gst-app-src-push-sample

in docs there indicates "transfer: none" on sample parameter, believe means caller needs unref. reason older method gst_app_src_push_buffer has transfer "full". dunno why.

https://gstreamer.freedesktop.org/data/doc/gstreamer/head/gst-plugins-base-libs/html/gst-plugins-base-libs-appsrc.html#gst-app-src-push-buffer


Comments

Popular posts from this blog

serialization - Convert Any type in scala to Array[Byte] and back -

matplotlib support failed in PyCharm on OSX -

python - Matplotlib: TypeError: 'AxesSubplot' object is not callable -