[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