[Libav-user] avcodec_close() crash

Andrey Utkin andrey.krieger.utkin at gmail.com
Wed Jun 5 12:39:27 CEST 2013


2013/6/5 Андрей <ashvyrkin at gosniias.ru>:
> I use to compile the 32-bit version of ffmpeg visual studio 2012. I used the
> latter for now build from 5/29/13.
> This is my test code that reproduces the problem:
>
> avcodec_register_all();
>
>     int width = 764, height = 480;
>     int got_output;
>     AVFrame *frame;
>     AVPacket pkt;
>     AVCodec *codec;
>     AVCodecContext *c = NULL;
>
>     while(1)
>     {
>         frame = avcodec_alloc_frame();
>         if (!frame) {
>             fprintf(stderr, "Could not allocate video frame\n");
>             return -1;
>         }
>         frame->format = AV_PIX_FMT_YUV420P;
>         frame->width  = width;
>         frame->height = height;
>
>         /* the image can be allocated by any means and av_image_alloc() is
>          * just the most convenient way if av_malloc() is to be used */
>         int ret = av_image_alloc(frame->data, frame->linesize, width,
> height,
>                              AV_PIX_FMT_YUV420P, 1);
>         if (ret < 0) {
>             fprintf(stderr, "Could not allocate raw picture buffer\n");
>             av_freep(&frame->data[0]);
>             avcodec_free_frame(&frame);
>             return -1;
>         }
>
>         /* find the mpeg4 video encoder */
>         codec = avcodec_find_encoder(AV_CODEC_ID_MPEG4);
>         if (!codec) {
>             fprintf(stderr, "Codec not found\n");
>             return -1;
>         }
>
>         c = avcodec_alloc_context3(codec);
>         if (!c) {
>             fprintf(stderr, "Could not allocate video codec context\n");
>             return -1;
>         }
>
>         /* put sample parameters */
>         c->profile = FF_PROFILE_MPEG4_SIMPLE;
>         /* resolution must be a multiple of two */
>         c->width = width;
>         c->height = height;
>         /* frames per second */
>         c->time_base.den = 25;
>         c->time_base.num = 1;
>         c->gop_size = 25; /* emit one intra frame every 25 frames */
>         c->pix_fmt = AV_PIX_FMT_YUV420P;
>         c->qmax = 4;
>         c->qmin = 4;
>
>         /* open it */
>         if (avcodec_open2(c, codec, NULL) < 0) {
>             fprintf(stderr, "Could not open codec\n");
>             avcodec_close(c);

You shouldn't avcodec_close() here. I think this can cause a problem.

>             av_free(c);
>             return -1;
>         }
>
>         for(int k = 0; k < 30; k++)
>         {
>             av_init_packet(&pkt);
>             pkt.data = NULL;    // packet data will be allocated by the
> encoder
>             pkt.size = 0;
>
>             frame->pts = c->frame_number;
>
>             /* encode the image */
>             if (avcodec_encode_video2(c, &pkt, frame, &got_output) < 0) {
>                 fprintf(stderr, "Error encoding frame\n");
>                 return -1;
>             }
>
>             if (got_output) {
>                 av_free_packet(&pkt);
>             }
>         }
>
>         if(c)
>         {
>             avcodec_close(c);
>             av_free(c);

Can't say for sure, but av_free() seems redundant.

>         }
>         if(frame)
>         {
>             av_freep(&frame->data[0]);
>             avcodec_free_frame(&frame);

Maybe there also something is redundant.

>         }
>     }
>
> When you call function avcodec_close () throws an exception. Such an error
> is detected on the MPEG4 codec with a frame width in the range 754-767 at an
> altitude of 480. Perhaps at other resolutions, too. Help solve the problem.
> ...sorry for bad english

You have more than one call to avcodec_close(), do you know, which one
is executed?

Your code snippet should be easily compiled on linux, there you can
use valgrind memcheck tool, which makes debugging easy.
Also i suggest you to re-read avcodec.h and avformat.h for
explanations on how to release context objects correclty, some places
in your code are suspicious for me.

--
Andrey Utkin


More information about the Libav-user mailing list