ffmpeg内存释放问题

shijiehehai 2014-03-04 01:49:17
最近改了个视频解码编码的小程序,能得到最后的结果,但是内存老是释放不了,希望高手指点!附代码如下:

const char *input_file_name="/users/sj/desktop/HH_videoTransform2/input.mov";
av_register_all();//注册库中所有可用的文件格式和编码器
AVFormatContext *ic;
//输入文件处理部分
ic=avformat_alloc_context();
if(av_open_input_file(&ic,input_file_name,NULL,0,NULL)!=0)
{
printf("can't open the file %s\n",input_file_name);
exit(1);
}//打开输入文件
if(av_find_stream_info(ic)<0)
{
printf("can't find suitable codec parameters\n");
exit(1);
}//取出流信息

dump_format(ic,0,input_file_name,0);//列出输入文件的相关流信息
int i;
int videoindex=-1;
int audioindex=-1;
for(i=0;i<ic->nb_streams;i++)
{
if(ic->streams->codec->codec_type==CODEC_TYPE_VIDEO)
{
videoindex=i;
//printf("video\n");
}
else if(ic->streams->codec->codec_type==CODEC_TYPE_AUDIO)
{
//printf("audio\n");
audioindex=i;
}
}
if(videoindex==-1)
{
printf("can't find video stream\n");
exit(1);
}//没有找到视频流
AVCodecContext *vCodecCtx;
vCodecCtx=ic->streams[videoindex]->codec;//取得视频流编码上下文指针
AVCodec *vCodec;
vCodec=avcodec_find_decoder(vCodecCtx->codec_id);
if(vCodec==NULL)
{
printf("can't find suitable video decoder\n");
exit(1);
}//找到合适的视频解码器
if(avcodec_open(vCodecCtx,vCodec)<0)
{
printf("can't open the video decoder\n");
exit(1);
}//打开该视频解码器
if(audioindex==-1)
{
printf("can't find audio stream\n");
// exit(1);
}//没有找到音频流

//下面为输出文件处理部分
const char *output_file_name="/users/sj/desktop/HH_videoTransform2/output.mov";
AVOutputFormat *fmt;
AVFormatContext *oc;
AVCodecContext *oVcc/*,*oAcc*/;
AVCodec *oVc/*,*oAc*/;
AVStream *video_st/*,*audio_st*/;
AVFrame *oVFrame/*,*oAFrame*/;
// double video_pts;
oVFrame=avcodec_alloc_frame();
fmt=av_guess_format(NULL,output_file_name,NULL);
if(!fmt)
{
printf("could not deduce output format from outfile extension\n");
exit(0);
}//判断是否可以判断输出文件的编码格式
oc=avformat_alloc_context();
if(!oc)
{
printf("Memory error\n");
exit(0);
}
oc->oformat=fmt;

strcpy(oc->filename, output_file_name);
video_st=av_new_stream(oc,0);
if(!video_st)
{
printf("could not alloc video stream\n");
exit(0);
}
video_st->duration=ic->streams[videoindex]->duration;
if (fmt->video_codec != CODEC_ID_NONE)
{

oVcc=avcodec_alloc_context();
oVcc=video_st->codec;
oVcc->codec_id=fmt->video_codec;
oVcc->codec_type=CODEC_TYPE_VIDEO;
oVcc->bit_rate=vCodecCtx->bit_rate;
oVcc->width=vCodecCtx->width;
oVcc->height=vCodecCtx->height;
oVcc->time_base=vCodecCtx->time_base;
oVcc->gop_size=vCodecCtx->gop_size;
//oVcc->pix_fmt=vCodecCtx->pix_fmt;
oVcc->pix_fmt=vCodecCtx->pix_fmt;
oVcc->max_b_frames=vCodecCtx->max_b_frames;
video_st->r_frame_rate=ic->streams[videoindex]->r_frame_rate;


if (oVcc->codec_id == CODEC_ID_MPEG2VIDEO)
{
oVcc->max_b_frames = 2;
}
if (oVcc->codec_id == CODEC_ID_MPEG1VIDEO)
{
oVcc->mb_decision = 2;
}
if (!strcmp(oc->oformat->name, "mp4") || !strcmp(oc->oformat->name, "mov") || !strcmp(oc->oformat->name, "3gp"))
{
oVcc->flags |= CODEC_FLAG_GLOBAL_HEADER;
}


}
if (av_set_parameters(oc, NULL) < 0)
{
printf( "Invalid output format parameters\n");
exit(0);
}//设置必要的输出参数

strcpy(oc->title,ic->title);
strcpy(oc->author,ic->author);
strcpy(oc->copyright,ic->copyright);
strcpy(oc->comment,ic->comment);
strcpy(oc->album,ic->album);
oc->year=ic->year;
oc->track=ic->track;
strcpy(oc->genre,ic->genre);
dump_format(oc,0,output_file_name,1);//列出输出文件的相关流信息
// oVc=avcodec_find_encoder(CODEC_ID_MPEG4);
oVc=avcodec_find_encoder(oVcc->codec_id);
if(!oVc)
{
printf("can't find suitable video encoder\n");
exit(0);
}//找到合适的视频编码器
if(avcodec_open(oVcc,oVc)<0)
{
printf("can't open the output video codec\n");
exit(0);
}//打开视频编码器

if(url_exist(output_file_name))
{
printf("the output file name %s has exist,please select other\n",output_file_name);
exit(0);
}//判断该输出文件是否已经存在
if (!(oc->flags & AVFMT_NOFILE))
{
if(url_fopen(&oc->pb,output_file_name,URL_WRONLY)<0)
{
printf("can't open the output file %s\n",output_file_name);
exit(0);
}//打开输出文件
}
if(!oc->nb_streams)
{
fprintf(stderr,"output file dose not contain any stream\n");
exit(0);
}//查看输出文件是否含有流信息
if(av_write_header(oc)<0)
{
fprintf(stderr, "Could not write header for output file\n");
exit(1);
}
AVPacket packet;
int out_size;
uint8_t *video_outbuf;
int video_outbuf_size;
video_outbuf_size=vCodecCtx->width*vCodecCtx->height*3/2+100000;
video_outbuf= (unsigned char *) malloc(video_outbuf_size);
int got_picture=0;
int len;
int frame_index=0,ret;
int packet_count=0;
int skipped_frame=0;
//int packet_audio=0;
while(av_read_frame(ic,&packet)>=0)//从输入文件中读取一个包
{
if(packet.stream_index==videoindex)//判断是否为当前视频流中的包
{ NSLog(@"%d packet decoded",packet_count);
len=avcodec_decode_video2(vCodecCtx, oVFrame, &got_picture, &packet);
if(len<0)
{
printf("Error while decoding\n");
exit(0);
}
if(got_picture)//
{
fflush(stdout);
oVFrame->pts=av_rescale_q(packet.pts, ic->streams[videoindex]->time_base, video_st->time_base);
oVFrame->pict_type=0;
out_size = avcodec_encode_video(oVcc, video_outbuf, video_outbuf_size, oVFrame);
if (out_size > 0)
{
AVPacket pkt;
av_init_packet(&pkt);
if(oVcc->coded_frame && oVcc->coded_frame->key_frame)
pkt.flags |= PKT_FLAG_KEY;
pkt.flags = packet.flags;
pkt.stream_index= video_st->index;
pkt.data= video_outbuf;
pkt.size= out_size;
ret=av_write_frame(oc, &pkt);
}
skipped_frame++;
}
else
{
ret=av_write_frame(oc, &packet);
}
frame_index++;
if(ret!=0)
{
printf("while write video frame error\n");
exit(0);
}
packet_count++;
}
else if(packet.stream_index==audioindex)
{


if (av_write_frame(oc, &packet) != 0)
{
fprintf(stderr, "Error while writing audio frame\n");
exit(1);
}

}
av_free_packet(&packet);
}


av_write_trailer(oc);
for(i = 0; i < oc->nb_streams; i++)
{
av_freep(&oc->streams->codec);
av_freep(&oc->streams);
}
url_fclose(oc->pb);

av_free(oVFrame);
avcodec_close(vCodecCtx);
av_close_input_file(ic);
av_freep(ic);
av_free(oc);
av_free(oVc);
av_free(oVcc);
av_free(oAc);
av_free(oAcc);

NSLog(@"transform end");

}


为什么我已经都av_free了,但是ic 、oc、oAcc,oAc,oVcc,oVc都还是在内存中呢,是不是释放内存的方法不对?
...全文
4124 7 打赏 收藏 转发到动态 举报
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
gokartscomeon 2015-10-19
  • 打赏
  • 举报
回复
楼主,问题解决了吗?
ncubrian 2014-12-15
  • 打赏
  • 举报
回复
请问vCodec用什么释放
GeorgeCao33 2014-09-10
  • 打赏
  • 举报
回复
oc 好像是用avformat_free_context 释放
GeorgeCao33 2014-09-10
  • 打赏
  • 举报
回复
oVc 应该是用avcdec_free_context 释放
GeorgeCao33 2014-09-10
  • 打赏
  • 举报
回复
这个ffmpeg 内存问题 最近我也在弄,
shijiehehai 2014-03-04
  • 打赏
  • 举报
回复
首先谢谢您的回复!我改了下 还是不行。我的视频20多M,我整个编解码过程 内存占用稳定在60M,貌似是一个ic的大小一个oc的大小,还有一点额外花销的内存。转码完成以后,经过一系列av_free步骤,内存占用还是在60多M。
__cc__ 2014-03-04
  • 打赏
  • 举报
回复
video_outbuf 没有free

2,543

社区成员

发帖
与我相关
我的任务
社区描述
专题开发/技术/项目 多媒体/流媒体开发
社区管理员
  • 多媒体/流媒体开发社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧