Click here to Skip to main content
15,886,860 members
Please Sign up or sign in to vote.
2.00/5 (2 votes)
See more:
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:

C++
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
Updated 28-Feb-14 14:55pm
v2
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.....:)

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:

C#
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>
 
Share this answer
 
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 .
C++
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);
 
Share this answer
 
v2

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900