大家好,我在使用 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);
}