zoukankan      html  css  js  c++  java
  • 【视频开发】关于FFMPEG中内存泄漏的问题之av_bitstream_filter_filter

    How may I free pkt in an ffmpeg write frame method

    Rate this:
      
     
    See more: C++ ffmpeg
    Greetings
    I'm looking at an ffmpeg source code example at :http://svn.perian.org/ffmpeg/ffmpeg.c[^]

    In the code, I'm focusing on a method that writes the video frame.

    Here is that method:

    static void write_frame(AVFormatContext *s, AVPacket *pkt, AVCodecContext *avctx, AVBitStreamFilterContext *bsfc){
        int ret;
     
        while(bsfc){
            AVPacket new_pkt= *pkt;
            int a= av_bitstream_filter_filter(bsfc, avctx, NULL,
                                              &new_pkt.data, &new_pkt.size,
                                              pkt->data, pkt->size,
                                              pkt->flags & AV_PKT_FLAG_KEY);
            if(a>0){
                av_free_packet(pkt);
                new_pkt.destruct= av_destruct_packet;
            } else if(a<0){
                fprintf(stderr, "%s failed for stream %d, codec %s",
                        bsfc->filter->name, pkt->stream_index,
                        avctx->codec ? avctx->codec->name : "copy");
                print_error("", a);
                if (exit_on_error)
                    exit_program(1);
            }
            *pkt= new_pkt;
     
            bsfc= bsfc->next;
        }
     
        ret= av_interleaved_write_frame(s, pkt);
        if(ret < 0){
            print_error("av_interleaved_write_frame()", ret);
            exit_program(1);
        }
    }

    If I test the code as is, I get a crash at the write "ret= av_interleaved_write_frame(s, pkt);"

    But if I comment our the //av_free_packet(pkt);

    It works fine, and here is the problem, until after a while, memory grows very very large.
    I suspect it's because I've commented out the av_free_packet(pkt)

    Any ideas as to why I crash with the original code (with av_free_packet(pkt))?
    Posted 28-Feb-14 12:33pm
    radnix824
    Updated 28-Feb-14 14:55pm
    CHill60157.4K
    Comments
    The_Inventor 2-Mar-14 7:51am
       
    You need to write one frame at a time. Also you are freeing a pointer to what it is that you are trying to write before you write it. Thus it crashes. If you don't free it at all you then keep allocating more and more RAM instead of writing to HDD file, and freeing memory for next frame.
    radnix 4-Mar-14 18:08pm
       
    Thanks ! yes, you've got me thinking.....:)

    2 solutions

    Rate this: bad
      
    good  

    Solution 1

    Well, I did finally get it working and will post my particular solution here with the hope it may help others. Oh, almost forgot. If you have a suggestion for change to this code, please do:

    static void write_frame(AVFormatContext *s, AVPacket *pkt, AVCodecContext *avctx, AVBitStreamFilterContext *bsfc){
        int ret;
     
        while(bsfc){
            AVPacket new_pkt= *pkt;
            int a= av_bitstream_filter_filter(bsfc, avctx, NULL,
                                              &new_pkt.data, &new_pkt.size,
                                              pkt->data, pkt->size,
                                              pkt->flags & AV_PKT_FLAG_KEY);
            if(a>0){
                //av_free_packet(pkt);//-comment this out
    
                      if (new_pkt.data != pkt->data)//-added this
                      {
                        av_free_packet(pkt);
     
                        pkt->data = new_pkt.data;
                        pkt->size = new_pkt.size;
     
                        pkt->destruct = av_destruct_packet;
                      }
    
     
    
                new_pkt.destruct= av_destruct_packet;
            } else if(a&lt;0){
                fprintf(stderr, &quot;%s failed for stream %d, codec %s&quot;,
                        bsfc-&gt;filter-&gt;name, pkt-&gt;stream_index,
                        avctx-&gt;codec ? avctx-&gt;codec-&gt;name : &quot;copy&quot;);
                print_error(&quot;&quot;, a);
                if (exit_on_error)
                    exit_program(1);
            }
           <b>// *pkt= new_pkt;//-comment this out</b>
    
            bsfc= bsfc-&gt;next;
        }
     
        ret= av_interleaved_write_frame(s, pkt);
     
        av_free_packet(pkt);//-added here
    
        av_bitstream_filter_close(bsfc);//-added here
    
     
    
        if(ret &lt; 0){
            print_error(&quot;av_interleaved_write_frame()&quot;, ret);
            exit_program(1);
        }
    }</pre>
      Permalink  
    Comments
    The_Inventor 5-Mar-14 6:51am
       
    Looks better. Just remember in a function like this, you need to use your 'dummy' variables correctly. The dummy receives the info, the function operates on the dummy, when the dummy is happy it spits it back in the format you wanted.
    radnix 5-Mar-14 18:17pm
       
    Excellent analysis and a pretty good step ahead for future application. The original code is from ffmpeg.c .
    Rate this: bad
      
    good  

    Solution 2

    AVPacket new_pkt = pkt;
    int a = av_bitstream_filter_filter(m_bsfDecoderContext, out_stream->codec,
    	NULL,
    	&new_pkt.data,
    				&new_pkt.size,
    				pkt.data,
    				pkt.size,
    				pkt.flags & AV_PKT_FLAG_KEY);
     
    			av_free_packet(&pkt);
    			pkt.data = new_pkt.data;
    			pkt.size = new_pkt.size;
     
    			if (av_interleaved_write_frame(ofmt_ctx, &pkt) < 0)break;
    			av_free(new_pkt.data);
  • 相关阅读:
    一般表的一般方法
    asp.net采集函数(采集、分析、替换、入库一体)
    在 Access 里使用查询建立 存储过程/视图, 并使用 ASP 执行
    制作Access代码生成器 研发中【资料整理】
    Asp.net中打造通用数据访问类(c#)[转]
    Ajax.Net程序教程.彭彭编写
    C# 类中 属性和方法写在一个类里 和 属性和方法 分开的区别感受!!
    自己在vs2003下写的findLabel[应用程序]
    [转]Response.Write后css失效问题的解决
    javascript结构图
  • 原文地址:https://www.cnblogs.com/huty/p/8517123.html
Copyright © 2011-2022 走看看