[Libav-user] bad src image pointer error when converting MP4 frame to PNG

William Seemann wseemann at gmail.com
Mon Aug 19 06:19:30 CEST 2013


Hello,
     I'm using the following code to convert a frame from a mp4 video to 
a PNG image. Whenever I execute the my function (posted below) I receive 
the following error message:

     [swscaler @ 0x7fe4fb818600] bad src image pointers

This error occurs at the following line in my code:

sws_scale(scalerCtx,
               (const uint8_t * const *) pFrame->data,
               pFrame->linesize,
               0,
               src_height,
               pFrameRGB->data,
               pFrameRGB->linesize);

I've tracked down the error message in the FFmpeg source code but I'm 
unsure how to solve this problem. Can anyone help? Thanks in advance!

void convert_image(AVCodecContext *pCodecCtx, AVFrame *pFrame, AVPacket 
*avpkt, int *got_packet_ptr) {
     AVCodecContext *codecCtx;
     AVCodec *codec;

     *got_packet_ptr = 0;

     codec = avcodec_find_encoder(TARGET_IMAGE_CODEC);
     if (!codec) {
         printf("avcodec_find_decoder() failed to find decoder\n");
         goto fail;
     }

     codecCtx = avcodec_alloc_context3(codec);
     if (!codecCtx) {
         printf("avcodec_alloc_context3 failed\n");
         goto fail;
     }

     codecCtx->bit_rate = pCodecCtx->bit_rate;
     codecCtx->width = pCodecCtx->width;
     codecCtx->height = pCodecCtx->height;
     codecCtx->pix_fmt = TARGET_IMAGE_FORMAT;
     codecCtx->codec_type = AVMEDIA_TYPE_VIDEO;
     codecCtx->time_base.num = pCodecCtx->time_base.num;
     codecCtx->time_base.den = pCodecCtx->time_base.den;

     if (!codec || avcodec_open2(codecCtx, codec, NULL) < 0) {
           printf("avcodec_open2() failed\n");
         goto fail;
     }

     int src_width = pCodecCtx->width;
     int src_height = pCodecCtx->height;
     enum PixelFormat src_pixfmt = pCodecCtx->pix_fmt;
     int dst_width = pCodecCtx->width;
     int dst_height = pCodecCtx->height;

     struct SwsContext *scalerCtx;

     scalerCtx = sws_getContext(src_width,
             src_height,
             src_pixfmt,
             dst_width,
             dst_height,
             TARGET_IMAGE_FORMAT,
             SWS_BILINEAR,
             NULL, NULL, NULL);

     if (!scalerCtx) {
         printf("sws_getContext() failed\n");
         goto fail;
     }

     AVFrame *pFrameRGB = avcodec_alloc_frame();

     if (!pFrameRGB) {
         goto fail;
     }

     int numBytes = avpicture_get_size(TARGET_IMAGE_FORMAT, src_width, 
src_height);
     uint8_t *buffer = (uint8_t *) av_malloc(numBytes * sizeof(uint8_t));

     if (avpicture_fill((AVPicture *) pFrameRGB,
             buffer,
             TARGET_IMAGE_FORMAT,
             src_width,
             src_height) < 0) {
         printf("avpicture_fill() failed\n");
         goto fail;
     }

     sws_scale(scalerCtx,
               (const uint8_t * const *) pFrame->data,
               pFrame->linesize,
               0,
               src_height,
               pFrameRGB->data,
               pFrameRGB->linesize);

     int ret = avcodec_encode_video2(codecCtx, avpkt, pFrameRGB, 
got_packet_ptr);

     if (ret < 0) {
         *got_packet_ptr = 0;
     }

     // TODO is this right?
     fail:
     if (codecCtx) {
         avcodec_close(codecCtx);
     }

     if (scalerCtx) {
         sws_freeContext(scalerCtx);
     }

     if (ret < 0 || !*got_packet_ptr) {
         av_free_packet(avpkt);
     }
}


More information about the Libav-user mailing list