[Libav-user] Fill AVFrame from a Cairo surface

Colossus colossus73 at gmail.com
Wed Aug 18 14:17:23 EEST 2021


Ok, I reordered the code. I don't get anymore the annoying message
'input picture width greater than stride' but I get a crash in memalloc()
called
by av_send_frame().

*This is the gdb output:*
Thread 1 "imagination" received signal SIGABRT, Aborted.
__GI_raise (sig=sig at entry=6) at ../sysdeps/unix/sysv/linux/raise.c:50
50 ../sysdeps/unix/sysv/linux/raise.c: No such file or directory.
(gdb) bt
#0  __GI_raise (sig=sig at entry=6) at ../sysdeps/unix/sysv/linux/raise.c:50
#1  0x00007ffff5518537 in __GI_abort () at abort.c:79
#2  0x00007ffff5571768 in __libc_message (action=action at entry=do_abort,
fmt=fmt at entry=0x7ffff567fe2d "%s\n")
    at ../sysdeps/posix/libc_fatal.c:155
#3  0x00007ffff5578a5a in malloc_printerr (str=str at entry=0x7ffff5682110
"malloc_consolidate(): invalid chunk size")
    at malloc.c:5347
#4  0x00007ffff5579918 in malloc_consolidate (av=av at entry=0x7ffff56b1b80
<main_arena>) at malloc.c:4477
#5  0x00007ffff557b755 in _int_malloc (av=av at entry=0x7ffff56b1b80
<main_arena>, bytes=bytes at entry=16288) at malloc.c:3699
#6  0x00007ffff557c4af in _int_memalign
    (av=av at entry=0x7ffff56b1b80 <main_arena>, alignment=alignment at entry=64,
bytes=bytes at entry=16176) at malloc.c:4684
#7  0x00007ffff557d55c in _mid_memalign (alignment=64, bytes=16176,
address=<optimized out>) at malloc.c:3312
#8  0x00007ffff1e9fb2a in x264_malloc () at
/lib/x86_64-linux-gnu/libx264.so.160
#9  0x00007ffff1eba75c in  () at /lib/x86_64-linux-gnu/libx264.so.160
#10 0x00007ffff1ebe6b0 in  () at /lib/x86_64-linux-gnu/libx264.so.160
#11 0x00007ffff1f27957 in  () at /lib/x86_64-linux-gnu/libx264.so.160
#12 0x00007ffff1ea4aa1 in x264_encoder_encode () at
/lib/x86_64-linux-gnu/libx264.so.160
#13 0x00007ffff62df6d8 in  () at /lib/x86_64-linux-gnu/libavcodec.so.58
#14 0x00007ffff6094c37 in avcodec_encode_video2 () at
/lib/x86_64-linux-gnu/libavcodec.so.58
#15 0x00007ffff6095012 in  () at /lib/x86_64-linux-gnu/libavcodec.so.58
#16 0x00007ffff609519f in *avcodec_send_frame* () at
/lib/x86_64-linux-gnu/libavcodec.so.58
#17 0x000055555557aaae in img_export_encode_av_frame
    (pkt=0x5555556e6d60, ctx=0x55555643cb40, fmt=0x5555564859c0,
frame=<optimized out>) at export.c:968

And this is the code:
static gboolean img_export_frame_to_avframe(img_window_struct *img,
cairo_surface_t *surface)
{
static gint i = 0;

gint width, height, stride, row, col, offset, ret;
uint8_t  *pix, *data;
AVFrame *frame;

/* Image info and pixel data */
width  = cairo_image_surface_get_width( surface );
height = cairo_image_surface_get_height( surface );
stride = cairo_image_surface_get_stride( surface );
pix    = cairo_image_surface_get_data( surface );

/* Initialize AVFrame to be sent to the encoder */
frame = av_frame_alloc();
frame->format = img->codec_context->pix_fmt;
frame->width  = img->video_size[0];
frame->height = img->video_size[1];
av_frame_get_buffer(frame, 32);

     /* Fill the frame data with pixels from the Cairo surface */
for( row = 0; row < height; row++ )
{
data = pix + row * stride;
for( col = 0; col < width; col++ )
{
frame->data[0][row * frame->linesize[0] + col] = data[2];
frame->data[1][row * frame->linesize[1] + col] = data[1];
frame->data[2][row * frame->linesize[2] + col] = data[0];
data += 4;
}
frame->pts = i;
i++;
}
//sws_scale(img->sws_ctx, pix, img->video_frame->linesize, 0,
img->video_frame->height, img->video_frame->data, sws_frame->linesize);

ret = img_export_encode_av_frame(frame, img->video_format_context,
img->codec_context, &img->video_packet);

if (frame)
{
av_frame_free(&frame);
frame = NULL;
}
return ret;
}

gboolean img_export_encode_av_frame(AVFrame *frame, AVFormatContext *fmt,
AVCodecContext *ctx, AVPacket *pkt)
{
gint ret;

    /* send the frame to the encoder */
    ret = *avcodec_send_frame*(ctx, frame);
    if (ret < 0)
{
g_print("Av error: %s\n",av_err2str(ret));
g_print("Error sending a frame for encoding\n");
return FALSE;
}
    while (ret >= 0)
    {
        ret = avcodec_receive_packet(ctx, pkt);
        if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF)
return TRUE;
        else if (ret < 0)
g_print("Error during encoding\n");

av_interleaved_write_frame(fmt, pkt);
av_packet_unref(pkt);
return FALSE;
    }
    return TRUE;
}

What can be the cause of the crash now?

Thanks

On Mon, 16 Aug 2021 at 16:35, Nicolas George <george at nsup.org> wrote:

> Colossus (12021-08-16):
> > I told you I did and avcodec_send_frame() is the one that throws that
> error.
>
> I will trust the code I see. Re-post your code once you have fixed the
> order of the function calls and checked all the return values properly,
> if it still does not work.
>
> --
>   Nicolas George
> _______________________________________________
> Libav-user mailing list
> Libav-user at ffmpeg.org
> https://ffmpeg.org/mailman/listinfo/libav-user
>
> To unsubscribe, visit link above, or email
> libav-user-request at ffmpeg.org with subject "unsubscribe".
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://ffmpeg.org/pipermail/libav-user/attachments/20210818/dd29d172/attachment.htm>


More information about the Libav-user mailing list