ffmpeg内存释放问题

80 篇文章 1 订阅

http://bbs.csdn.net/topics/390722822?page=1


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

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都还是在内存中呢,是不是释放内存的方法不对?

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值