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 encode

Other Parts Discussed in Thread: AM5728

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

}