This thread has been locked.
If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.
大家好,我在使用 am5728 的编码的时候,使用gstreamer 发生了内存泄露的问题,希望能得到大家的帮助,我的sdk 是ti-processor-sdk-linux-am57xx-evm-03.00.00.04
下面是我的代码:
#ifndef CGSTRENCODE_H #define CGSTRENCODE_H #include <gst/gst.h> #include <gst/app/gstappsrc.h> #include <gst/app/gstappsink.h> #include <stdio.h> #include <string.h> #include <stdlib.h> #include <sys/time.h> #include <unistd.h> #define LEN_ENCODE_NAME 128 class CGStrenCode { public: CGStrenCode(); ~CGStrenCode(); int Inital(const char * szname,bool bencode,int nWidth,int nHeight); int startCode(char * sourcebuf,int sourceLen,char * resultbuf, int* resultLen); protected: // int InitalDecode(const char * szname); int InitalEncode(const char * szname); void PushBufferEncode(char *nv12buf,int len); char* PullH264Encode(int* outlen); void CreateName(const char *,const char *); private: GstElement * m_pipeline; GstElement * m_appsrc; GstElement * m_appsink; int m_nWidth; int m_nHeight; char m_szName[LEN_ENCODE_NAME]; char * m_pSource; bool m_bInital; GstBuffer *m_pGstBuffer; }; #endif // CGSTRENCODE_H
#include "CGStrenCode.h" CGStrenCode::CGStrenCode() { m_pSource = NULL; m_nWidth = 0; m_nHeight = 0; m_bInital = false; } CGStrenCode::~CGStrenCode() { gst_element_set_state(m_pipeline, GST_STATE_NULL); fprintf(stderr, "Deleting pipeline\n"); gst_object_unref(GST_OBJECT(m_pipeline)); free(m_pSource); m_pSource = NULL; } int CGStrenCode::Inital(const char * szname,bool bencode,int nWidth,int nHeight) { if(NULL == szname || strlen(szname) == 0) return -1; if(nWidth <= 0 || nHeight <=0 ) return -2; if(m_bInital) return -99; m_nWidth = nWidth; m_nHeight = nHeight; CreateName(szname,"pipeline"); m_pipeline = gst_pipeline_new(m_szName);//"mypipeline"); g_assert(m_pipeline); CreateName(szname,"source"); m_appsrc = gst_element_factory_make("appsrc", m_szName);//"mysource"); g_assert(m_appsrc); m_pSource = (char *)(malloc(nWidth*nHeight*3)); if(NULL == m_pSource) return -3; return InitalEncode(szname); } int CGStrenCode::startCode(char * sourcebuf,int sourceLen,char * resultbuf, int* resultLen) { if(sourceLen > m_nWidth* m_nHeight *3 || sourcebuf <= 0) { printf("%d over the max len \n",sourceLen); return -1; } if(NULL == sourcebuf || NULL == m_pSource || NULL == resultbuf || NULL == resultLen) { printf("buffer empty \n"); return -2; } if(!m_bInital) return -3; int sourlen = sourceLen; memcpy(m_pSource,sourcebuf,sourlen); PushBufferEncode(m_pSource, sourlen); int reslen=0; char * buf = PullH264Encode(&reslen); *resultLen = reslen; if(*resultLen !=0) memcpy(resultbuf,buf,reslen); delete[] buf; return 0; } int CGStrenCode::InitalEncode(const char * szname) { gboolean bLinkOk; GstElement *encode; CreateName(szname,"encode"); encode = gst_element_factory_make("ducatih264enc", m_szName);//"myencode"); g_assert(encode); CreateName(szname,"sink"); m_appsink = gst_element_factory_make("appsink", m_szName);//"mysink"); g_assert(m_appsink); if (!m_pipeline || !m_appsrc || !encode || !m_appsink) { fprintf(stderr, "Could not gst_element_factory_make, terminating\n"); return -4; } GstCaps *capsappsrc2Jpegenc; // between appsrc and jpegenc capsappsrc2Jpegenc = gst_caps_new_full( gst_structure_new("video/x-raw", "format",G_TYPE_STRING,"NV12", "width",G_TYPE_INT,m_nWidth, "height",G_TYPE_INT,m_nHeight, "framerate",GST_TYPE_FRACTION,15,1, NULL), gst_structure_new("video/x-h264", "format",G_TYPE_STRING,"NV12", "width",G_TYPE_INT,m_nWidth, "height",G_TYPE_INT,m_nHeight, NULL), NULL); gst_bin_add_many(GST_BIN(m_pipeline), m_appsrc ,encode, m_appsink, NULL); bLinkOk = gst_element_link_filtered(m_appsrc, encode, capsappsrc2Jpegenc); if(!bLinkOk){ g_warning("Failed to link src encode \n"); return -5; } gst_element_link(encode, m_appsink); g_object_set (G_OBJECT (m_appsrc), "stream-type", GST_APP_STREAM_TYPE_STREAM, "format", GST_FORMAT_BYTES, NULL); g_object_set(G_OBJECT(m_appsink), "drop",true,NULL); g_object_set(G_OBJECT(encode), "rate-preset",1,NULL); fprintf(stderr, "Setting g_main_loop_run to GST_STATE_PLAYING\n"); gst_element_set_state(m_pipeline, GST_STATE_PLAYING); m_bInital = true; return 0; } void CGStrenCode::PushBufferEncode(char *nv12buf,int len) { GstFlowReturn ret; GstBuffer *buffer; GstMapInfo info; buffer = gst_buffer_new_allocate(NULL, len, NULL); gst_buffer_map(buffer, &info, GST_MAP_WRITE); memmove(info.data, nv12buf, len); ret = gst_app_src_push_buffer(GST_APP_SRC(m_appsrc), buffer); if(ret == GST_FLOW_OK){ // printf("push ok\n"); } gst_buffer_unmap(buffer, &info); } char* CGStrenCode::PullH264Encode(int* outlen) { GstSample* sample; sample = gst_app_sink_pull_sample(GST_APP_SINK(m_appsink)); if(sample == NULL) { printf("================NULL\n"); fprintf(stderr, "gst_app_sink_pull_sample returned null\n"); // gst_sample_unref (sample); return NULL; } GstBuffer* buffer = gst_sample_get_buffer (sample); GstMapInfo mapInfo; gst_buffer_map (buffer, &mapInfo, GST_MAP_READ); // printf("pull buffersize:%d\n",mapInfo.size); char* pRet = new char[mapInfo.size]; memmove(pRet, mapInfo.data, mapInfo.size); gst_buffer_unmap (buffer, &mapInfo); gst_sample_unref (sample); *outlen = mapInfo.size; return pRet; } void CGStrenCode::CreateName(const char * left,const char * right) { memset(m_szName,0,LEN_ENCODE_NAME); strcpy(m_szName,left); strcat(m_szName,right); }
我每次 来数据的时候就会申请一块内存 buffer = gst_buffer_new_allocate(NULL, len, NULL); ,然后push 到 appsrc 里面
可是我不知道应该怎么释放,如果不使用appsrc 的信号触发,好像是不需要释放内存的,我不知道我从 appsink 里面取出数据后应该怎么释放申请的内存