[Libav-user] transcoder class instance memory leak.

강구철 kckang at skycom.ne.kr
Fri Nov 23 08:38:54 EET 2018


hear is transcoder class src. use it as a instance and  memory leak after delete instance.
every resource release and close. what's problem? 
main transact func is "tcode(opus pkt in, aac pkt out)"

class trans{
    public:

    ///DECLARE 
    AVCodecContext    *oc;
    AVCodecContext    *opus_context;
    AVCodecContext    *aac_context;
    AVCodecContext    *aac_context2;
    AVCodecContext    *input_codec_context;
    AVFormatContext   *output_format_context;
    const   AVCodec   *opus_codec;
    const   AVCodec   *aac_codec;
    const   AVCodec   *aac_codec2;
    const   AVCodec   *h264_codec;
    float AAC_ENCTIME;
    int   AAC_SAMPRATE;
    int   OPUS_SAMPRATE;
    int                OPUSsize;
    int                OPUScnt ;
    int                AACsize ;
    int                AACcnt  ;
    AVFrame           *decoded_frame;///opus decode by ffmpeg
    AVFrame           *decoded_frame2;///opus decode by ffmpeg
    AVFrame           *framebuf;
    AVPacket          *pkt1;
    AVPacket          *pkt2;
    int                data_present;
    CUnitInspection   *gen1;
    CUnitInspection   *gen2;

    AVAudioFifo *fifo;
    AVAudioFifo *fifo2;
    SwrContext *resample_context;
    RTPPaserUtilityLibrary::ConvertStreamAVGranules* _instance;

    int len;
    string outfile;
	int pcmsize;
    uint8_t inbuf[AUDIO_INBUF_SIZE + AV_INPUT_BUFFER_PADDING_SIZE];
    char out_buf [2000]; //from file
    int  out_size;
    uint8_t *data;
    size_t data_size;
    int ix1;
	int channel;
    int ret;
    int cnt[100];
    int init(int a, int b, int c);
    trans();
    ~trans();

    int push_q(AVAudioFifo *fifo,
                               uint8_t **converted_input_samples,
                               const int frame_size);

    int pop_q(AVAudioFifo *_queue, AVFrame* mframe);


    int tcode(string *src, string* dst);
    int tcode(AVPacket* src, AVPacket* dst);

};

int   RTP_REASSEMBLE::trans::init(int a, int b, int c)
{
        opus_context->channels = 1;
        opus_context->channel_layout = AV_CH_LAYOUT_MONO;
        opus_context->sample_rate    = OPUS_SAMPRATE;
        opus_context->sample_fmt     = AV_SAMPLE_FMT_FLTP;
        opus_context->bit_rate       = OPUS_SAMPRATE;

        aac_context->channels = 1;
        aac_context->channel_layout = AV_CH_LAYOUT_MONO;
        aac_context->sample_rate    = AAC_SAMPRATE;
        aac_context->sample_fmt     = AV_SAMPLE_FMT_FLTP;
        aac_context->bit_rate       = AAC_SAMPRATE;
        fifo = av_audio_fifo_alloc(aac_context->sample_fmt, aac_context->channels, 2048);
        aac_context2->channels = 1;
        aac_context2->channel_layout = AV_CH_LAYOUT_MONO;
        aac_context2->sample_rate    = AAC_SAMPRATE;
        aac_context2->sample_fmt     = AV_SAMPLE_FMT_FLTP;
        aac_context2->bit_rate       = AAC_SAMPRATE;


		return 0;
};

RTP_REASSEMBLE::trans::trans(){
        oc                          = NULL;
        opus_context                = NULL;
        aac_context                 = NULL;
        input_codec_context         = NULL;
        output_format_context       = NULL;
        OPUSsize                    = 0;
        OPUScnt                     = 0;
        AACsize                     = 0;
        h264_codec                  = NULL;
        AACcnt                      = 0;
        decoded_frame               = NULL;///opus decode by ffmpeg
        decoded_frame2              = NULL;///opus decode by ffmpeg
        fifo                        = NULL;
        //fifo2                       = NULL;
        resample_context            = NULL;
        AAC_SAMPRATE=48000;
        OPUS_SAMPRATE=48000;
        ix1=0;
        ret = AVERROR_EXIT;
        avcodec_register_all();
        h264_codec = avcodec_find_decoder( AV_CODEC_ID_H264 );          
        opus_codec = avcodec_find_decoder( AV_CODEC_ID_OPUS );          
        aac_codec  = avcodec_find_encoder( AV_CODEC_ID_AAC  ); 
        aac_codec2 = avcodec_find_decoder( AV_CODEC_ID_AAC  );// ENCODER 
        //aac_codec  = avcodec_find_encoder( V_CODEC_ID_AAC_LATM  ); 

        framebuf = av_frame_alloc();
        if(framebuf==NULL) cout << "frame alloc fail."<<endl;
        _instance = new RTPPaserUtilityLibrary::ConvertStreamAVGranules();
        pkt1 = av_packet_alloc();
        pkt2 = av_packet_alloc();

        if (!h264_codec) {
            cout << "H264 Codec not found"<<endl;
            return;
		}
		else cout << "H264 codec found."<<endl;

        if(framebuf==NULL) cout << "frame alloc fail."<<endl;
/*
        gen1 = new CUnitInspection();
        gen2 = new CUnitInspection();

        gen1-> ifile = "opus.rtp";
        gen1->_begin();

        gen2-> ifile = "264.rtp";
        gen2->_begin();
*/
        if (!opus_codec) {
            cout << "opus Codec not found"<<endl;
            return;
        }

		else cout << "OPUS codec found."<<endl;

        opus_context   = avcodec_alloc_context3( opus_codec );
        //_instance->init_fifo(&fifo, opus_context);

        if (!opus_context) {
            cout << "Could not allocate audio opus_codec context OPUS"<<endl;
            return;
        }

        outfile = "raw.mp4";
        if (!aac_codec) {
            cout << "AAC Codec not found"<<endl;
            return;
        }
		else cout << "AAC codec found."<<endl;

        aac_context = avcodec_alloc_context3(aac_codec);
        //_instance->init_fifo(&fifo2, aac_context);

        if (!aac_context) {
            cout << "Could not allocate audio codec context AAC"<<endl;
            return;
        }

        aac_context2 = avcodec_alloc_context3(aac_codec2);
        init(1,2,3);

        if (avcodec_open2(opus_context, opus_codec, NULL) < 0) {
            cout << "Could not open codec opus"<<endl;
            return;
        }

        if (avcodec_open2(aac_context, aac_codec, NULL) < 0) {
            cout << "Could not open codec aac"<<endl;
            return;
        }

        if (avcodec_open2(aac_context2, aac_codec2, NULL) < 0) {
            cout << "Could not open codec aac2"<<endl;
            return;
        }

        if (!decoded_frame) 
        {
            cout << "Got a decoded_frame"<<endl;
            if (!(decoded_frame = av_frame_alloc())) {
                cout << "Could not allocate audio frame"<<endl;
                return;
            }
        }else{
		    cout << "nodata decoded_frame"<<endl;
		}

        if (!decoded_frame2) 
        {
            cout << "Got a decoded_frame2"<<endl;
            if (!(decoded_frame2 = av_frame_alloc())) {
                cout << "Could not allocate audio frame"<<endl;
                return;
            }
        }else{
		    cout << "nodata decoded_frame2"<<endl;
		}

}

RTP_REASSEMBLE::trans::~trans(){
OsSysLog::add(FAC_PROCESS, PRI_INFO, "%s:%d:FREE FIFO************************* ",__FILE__,__LINE__);  
 //     delete gen1;
 //		delete gen2;
        av_free_packet(pkt1);
        av_free_packet(pkt2);
		av_frame_free(&decoded_frame);
		av_frame_free(&decoded_frame2);
        av_audio_fifo_free(fifo);
        //av_audio_fifo_free(fifo2);
        delete _instance;
}

/** Add converted input audio samples to the FIFO buffer for later processing. */
int RTP_REASSEMBLE::trans::push_q(AVAudioFifo *fifo,
                               uint8_t **converted_input_samples,
                               const int frame_size)
{
    int error;
    /**
     * Make the FIFO as large as it needs to be to hold both,
     * the old and the new samples.
     */
    //OsSysLog::add(FAC_PROCESS, PRI_INFO, "%s:%d:*************************PUSH called fifo:0x%x, data:0x%x, frame_size:%d",__FILE__,__LINE__,(int64_t)fifo, (void*)**converted_input_samples, frame_size);  

    if ((error = av_audio_fifo_realloc(fifo, av_audio_fifo_size(fifo) + frame_size)) < 0) {
        return error;
    }
    /** Store the new samples in the FIFO buffer. */
    if (av_audio_fifo_write(fifo, (void **)converted_input_samples, frame_size) < frame_size) {
        return AVERROR_EXIT;
    }
        //OsSysLog::add(FAC_PROCESS, PRI_INFO, "%s:%d:*************************OK PUSH:%d tot:%d", __FILE__, __LINE__, frame_size, av_audio_fifo_size(fifo));
    return 1;
}


int RTP_REASSEMBLE::trans::pop_q(AVAudioFifo *_fifo, AVFrame* mframe)
{
    int ret;
	if(	av_audio_fifo_size (_fifo) >= 1024)
    {
		void* ptr;
		ptr = * mframe->data;
        ret = av_audio_fifo_read(_fifo, (void**)mframe->data, 1024);//@#@#
		mframe->nb_samples = ret;
        return ret;
	}
	else 
	{
        //OsSysLog::add(FAC_PROCESS, PRI_INFO, "%s:%d:*Not enough data  popup ret:%d tot:%d",__FILE__,__LINE__, ret, av_audio_fifo_size(_fifo));
        return 0;
    }
}

int RTP_REASSEMBLE::trans::tcode(AVPacket* src, AVPacket* dst){
//return -1;//KKC 8888
	AACContext *ac = (AACContext*)aac_context->priv_data;

    /*
    static int aac_decode_er_frame(AVCodecContext *avctx, void *data, int *got_frame_ptr, GetBitContext *gb)
    {
        AACContext *ac = avctx->priv_data;
        const MPEG4AudioConfig *const m4ac = &ac->oc[1].m4ac;
        ChannelElement *che;
        int err, i;
        int samples = m4ac->frame_length_short ? 960 : 1024;
        int chan_config = m4ac->chan_config;
        int aot = m4ac->object_type;
 
        if (aot == AOT_ER_AAC_LD || aot == AOT_ER_AAC_ELD)
            samples >>= 1;
    }*/
    
    MPEG4AudioConfig *m4ac = &(ac->oc[0].m4ac);
    m4ac->frame_length_short = 1;//1:960, 0:1024
   int ret;
   FILE *f, *outfile;
   int data_size;
   data_size = av_get_bytes_per_sample(opus_context->sample_fmt);

   if (src->size){
       data_present = 0;
       //decoded_frame->linesize[0]=1024*4;
       //decoded_frame->linesize[1]=1024*4;
       //opus_context->frame_size=960;//TESTTEST
       //decoded_frame->data[0] = (uint8_t*)av_malloc(4*1024);//TESTTEST

	   if(decoded_frame2->data[0]!=NULL)
	   av_free(decoded_frame2->data[0]);

       decoded_frame2->data[0] = (uint8_t*)av_malloc(4*1024);//@#@#
	   ret = avcodec_decode_audio4(opus_context, decoded_frame,  &data_present, src);

       if(ret<0) 
	   {
           //OsSysLog::add(FAC_PROCESS,PRI_INFO,"%s:%d DECODE Error  ======%d", __FILE__, __LINE__,ret);
	       return ret;
	   }
#ifdef _NOUSE
	   else
	   {
           if(data_present){
               if(channel%2)//7777
                   outfile = fopen("/temp/abc1.wav", "a");
	           else
                   outfile = fopen("/temp/abc2.wav", "a");

           if (!outfile) {
               OsSysLog::add(FAC_PROCESS,PRI_INFO,"%s:%d abc.wav open  Error  ======", __FILE__, __LINE__);
		       //return 0;
           }

   	       //av_freep(&decoded_frame);//TESTTEST

           unsigned char cbuf[4]={0,0,0,0};//GEN WAVE------------------;
           unsigned char *pbuf;
           cbuf[0]=0xf2;
           cbuf[1]=0xdb;
           cbuf[2]=0x0;
           cbuf[3]=0x3f;

           //decoded_frame->data[0] = (uint8_t*)av_malloc(4*1024);//BLANK 1024
           //if(1) decoded_frame->nb_samples =  960;//good for mp4
	       //else  decoded_frame->nb_samples = 1024;//good for wav space
		   
           pbuf = decoded_frame->data[0];

#ifdef _NOUSE
           for(int i=960; i<1024 ; i++){
//             OsSysLog::add(FAC_PROCESS,PRI_INFO,"%s:%d i:%d ======", __FILE__, __LINE__, i*4+3);
	           pbuf[i*4+0] =  cbuf[0];  //float
	           pbuf[i*4+1] =  cbuf[1];  //float
	           pbuf[i*4+2] =  cbuf[2];  //float
	           pbuf[i*4+3] =  cbuf[3];  //float
	    	   cbuf[2]     += 2;        //mod wav   to 0~96
		       if(cbuf[2] >= 96) cbuf[2]=0; //mod reset to 0
	       }//END OF GENWAVE---------------------------------------------------------
#endif

           fwrite(decoded_frame->data[0] , decoded_frame->nb_samples*data_size, 1, outfile);//opus_context->channels*
	       fclose(outfile);	

//OsSysLog::add(FAC_PROCESS,PRI_INFO,"LN:%d Ddata_present=%d OPUS DECODE Success  === duration:%d ret(size):%d linesize:%d nbsampels:%d",  __LINE__, data_present, decoded_frame->pkt_duration, ret,decoded_frame->linesize,decoded_frame->nb_samples);

        }//data present growes up and cut off it.
    }
#endif
		   
//#ifdef _VIDEODUMP// test file write


//OsSysLog::add(FAC_PROCESS, PRI_INFO, "BAAAAAAAAAAAAAAAAAAAAA ch=%d,samp=%d, fmt=%d, data_size=%d ch=%d chLayout=%ld frame_size=%d\n", \
    opus_context->channels, decoded_frame->nb_samples, opus_context->sample_fmt, data_size, opus_context->channels, opus_context->channel_layout,opus_context->frame_size);

    OPUSsize += decoded_frame->nb_samples * opus_context->channels * data_size;
//OsSysLog::add(FAC_PROCESS,PRI_INFO,"%s:%d RAW PCMsize= %d, opusCNT= %d decodeRAW:%d", __FILE__, __LINE__, OPUSsize, OPUScnt++, decoded_frame->nb_samples);
//#endif
	
    av_init_packet(dst);
	dst->data = NULL;//IMPORTANT for dynamic reallocate surface
    dst->size = 0;ret = -1;
    ///////////////////////////////////////////////////////////////////////////////	
    //int push_q(AVAudioFifo *fifo, uint8_t **converted_input_samples, const int frame_size);
    //int pop_q(AVAudioFifo *fifo,  AVFrame* mframe);
    /////////////////////////////////////////////////////////////////////////////
    uint8_t* ptr;
    //ptr = 	
    push_q(fifo, decoded_frame->data, decoded_frame->nb_samples);//PUSH 
	decoded_frame2->nb_samples = 1024;
    ret = pop_q (fifo, decoded_frame2);            //POP
     
    //decoded_frame->nb_samples = 1024;
    //aac_context->frame_size   = 960;
    aac_context->frame_size   = 1024;

    //OsSysLog::add(FAC_PROCESS,PRI_INFO,"%s:%d AAC ENCODE try decodedframeSize:%d aacctxFramesieze:%d======frameLnShort:%d privdataSIZE:0x%x", __FILE__, __LINE__, decoded_frame2->nb_samples, aac_context->frame_size, m4ac->frame_length_short,aac_context->priv_data);
	if(ret>0){// pop ok (que hav sample over 1024)
        ret = avcodec_encode_audio2(aac_context, dst, decoded_frame2, &data_present);//@#@#AAC ENCODING

#ifdef _AAC_ENCODE_RESULT_PRINT
        if(ret != 0) 
        {
           OsSysLog::add(FAC_PROCESS,PRI_INFO,"%s:%d AAC ENCODE Error  OK  ret:%d ======", __FILE__, __LINE__, ret);
        }else{
           OsSysLog::add(FAC_PROCESS,PRI_INFO,"%s:%d AAC ENCODE OK size is %d AACcnt:%d AACsize:%d aacctxFramesize:%d======", __FILE__, __LINE__,                     dst->size, AACcnt, AACsize,aac_context->frame_size);
           AACsize += (int)(dst->size);

           if(pkt2->size != 0)
               AACcnt++;
        }
#endif
	}

}

#ifdef _DECODE_VERIFY_AAC
    ret = avcodec_decode_audio4(aac_context2, decoded_frame, &data_present, dst);
    //if(ret<1) OsSysLog::add(FAC_PROCESS,PRI_INFO,"%s:%d AAC REDECODE Error ======%d", __FILE__, __LINE__,ret);
#endif

#ifdef _DUMP_REDECODE
    if(ret<0) 
    {
        OsSysLog::add(FAC_PROCESS,PRI_INFO,"%s:%d AAC REDECODE Error  ======%d", __FILE__, __LINE__,ret);
        //return ret;
	}else{
        if(data_present){
            //OsSysLog::add(FAC_PROCESS,PRI_INFO,"%s:%d AAC REDECODE   ====%d frsize:%d", __FILE__, __LINE__,ret, decoded_frame->nb_samples);
            if(channel%2)//7777
                outfile = fopen("/temp/aac1.wav", "a+");
            else
                outfile = fopen("/temp/aac2.wav", "a+");
    
            if (!outfile) {
                OsSysLog::add(FAC_PROCESS,PRI_INFO,"%s:%d aac.wav open  Error  ======", __FILE__, __LINE__);
                return 0;
            }

            fwrite(decoded_frame->data[0] , /*decoded_frame->nb_samples * opus_context->channels */1024 * data_size, 1, outfile);//opus_context->channels*
	        fclose(outfile);	

OsSysLog::add(FAC_PROCESS,PRI_INFO,"LN:%d Ddata_present=%d DECODE Success  === duration:%d ret(size):%d linesize:%d nbsampels:%d",  __LINE__, data_present, decoded_frame->pkt_duration, ret,decoded_frame->linesize,decoded_frame->nb_samples);
       }
	   else{
           OsSysLog::add(FAC_PROCESS,PRI_INFO,"%s:%d DECODE no presents data!!  ======", __FILE__, __LINE__);
	       return ret;
       }
   }
#endif
        return 0;
}

int RTP_REASSEMBLE::trans::tcode(string *src, string* dst){

	if(pkt1 == NULL)
	{
        OsSysLog::add(FAC_PROCESS,PRI_INFO,"%s:%d Error  pkt1 NULL====data_size[%d]======", __FILE__, __LINE__, src->length());
		init(1,2,3);
	}

    // COPY NEED , dont use STRING	
	pkt1->data = (uint8_t*)src->c_str();
    pkt1->size = src->length();//solve source packet of opus sound encoded data
    //memcpy(pkt1->data, src->c_str(), src->length());
	tcode(pkt1,pkt2);

	if(pkt2 == NULL)
	{
        OsSysLog::add(FAC_PROCESS,PRI_INFO,"%s:%d Error pkt2 NUL======data22_size[%d]=====", __FILE__, __LINE__, dst->length());
		init(1,2,3);
	}

    dst->assign((uint8_t&)pkt2->data, pkt2->size);//build dst
	if(pkt2->size==0){
        OsSysLog::add(FAC_PROCESS,PRI_INFO,    "%s:%d Error====data2_size zero[%d:%d]=======", __FILE__, __LINE__, src->length(), dst->length());
	}
    return 1;// protection code 
}





More information about the Libav-user mailing list