<div dir="ltr">Hello Nicolas,<br><div><br></div><div>thanks for replying. The documentation is not very clear. I already looked at</div><div>encode_video.c and it wasn't useful as it creates a dummy image, I have to read</div><div>data from a cairo surface instead. There should be more documentation on <b>HOW</b></div><div>to put the single puzzle pieces <b>TOGETHER, </b>not just describing the <b>SINGLE</b> pieces</div><div>to my humble opinion.</div><div><br></div><div>Also I'm not sure what you mean with: "Calling av_frame_make_writable() on a frame you just allocated makes</div> no sense." as in encode_video.c at line 140 I see the call to av_frame_allloc() and then at line<div>160, so after line 140 I read the call to av_frame_make_writable()...</div><div><br></div><div>I know where the flaw is as I used return codes not visible in the code above. I</div><div>clearly stated it in my message:</div><div><br></div><div>"But <b>avcodec_send_frame</b>() called from img_export_encode_av_frame() always return:"</div><div><br></div><div>Did you reply from the beach...?</div><div><br></div><div>Anyway thanks for the tip on the stride. I will made new researches based on this information.</div><div><br></div><div>Kind regards</div><div>Giuseppe<br><div><br></div></div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Mon, 16 Aug 2021 at 10:20, Nicolas George <<a href="mailto:george@nsup.org" target="_blank">george@nsup.org</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">Colossus (12021-08-16):<br>
> I have this piece of code:<br>
> static gboolean img_export_frame_to_avframe(img_window_struct *img,<br>
> cairo_surface_t *surface)<br>
> {<br>
> gint width, height, stride, row, col, offset;<br>
> uint8_t  *pix;<br>
> <br>
> /* Image info and pixel data */<br>
> width  = cairo_image_surface_get_width( surface );<br>
> height = cairo_image_surface_get_height( surface );<br>
> stride = cairo_image_surface_get_stride( surface );<br>
> pix    = cairo_image_surface_get_data( surface );<br>
> <br>
> g_print("Stride: %d\n",stride);<br>
> <br>
> /* Avlibrary stuff */<br>
> img->video_frame = av_frame_alloc();<br>
> av_frame_make_writable(img->video_frame);<br>
> img->video_frame->format = AV_PIX_FMT_RGBA;<br>
> img->video_frame->width  = width;<br>
> img->video_frame->height = height;<br>
> img->video_frame->linesize[0] = stride;<br>
> <br>
> av_frame_get_buffer(img->video_frame, 1);<br>
> img->video_packet = av_packet_alloc();<br>
> <br>
> for( row = 0; row < img->video_frame->height; row++ )<br>
> {<br>
> for( col = 0; col < img->video_frame->width; col++ )<br>
> {<br>
> offset = 3 * col + row * img->video_frame->linesize[0];<br>
> img->video_frame->data[0][offset + 0] = pix[0];<br>
> img->video_frame->data[0][offset + 1] = pix[1];<br>
> img->video_frame->data[0][offset + 2] = pix[2];<br>
> }<br>
> }<br>
> img_export_encode_av_frame(img->video_frame, img->video_format_context,<br>
> img->codec_context, img->video_packet);<br>
> return TRUE;<br>
> }<br>
> <br>
> But avcodec_send_frame() called from img_export_encode_av_frame() always<br>
> return:<br>
> <br>
> libx264 @ 0x5582519787c0] Input picture width (640) is greater than stride<br>
> (0)<br>
> <br>
> The stride is 5120 not 0! Where am I wrong? Also I grepped with the<br>
> recursive option the whole ffmpeg4 source and I couldn't find the error<br>
> message above of course without the 640 and 0...<br>
<br>
You are calling frame-related functions haphazardly and seem to have<br>
misunderstood how stride works. And you do not check your return values.<br>
And you seem to be misusing the encoding API too.<br>
<br>
Stride is not a property of the image, it is a property of the allocated<br>
memory. That means stride is chosen by whoever allocates the image. If<br>
you ask FFmpeg to allocate the image for you, then FFmpeg gets to decide<br>
the stride.<br>
<br>
You would set the stride yourself if you were trying to use an already<br>
allocated memory buffer. For example if you want to use memory mapped<br>
from a video device. Or if you want to use the frame data from<br>
cairo_surface_t directly (which I am not sure is possible, and very<br>
tricky anyway).<br>
<br>
As for the frame-related functions:<br>
<br>
- Calling av_frame_make_writable() on a frame you just allocated makes<br>
  no sense.<br>
<br>
- Calling av_frame_make_writable() before av_frame_get_buffer(). The<br>
  point of av_frame_make_writable() is to reuse buffers that are already<br>
  allocated if possible.<br>
<br>
As for the encoding API, your single call to<br>
img_export_encode_av_frame() shows you probably assume one input frame<br>
will give you one output packet. This is not true.<br>
<br>
Start with checking the return value of all your function calls, and you<br>
will see where the flaw is.<br>
<br>
Look at doc/examples/encode_video.c to see how it does it and work from<br>
there.<br>
<br>
Regards,<br>
<br>
-- <br>
  Nicolas George<br>
_______________________________________________<br>
Libav-user mailing list<br>
<a href="mailto:Libav-user@ffmpeg.org" target="_blank">Libav-user@ffmpeg.org</a><br>
<a href="https://ffmpeg.org/mailman/listinfo/libav-user" rel="noreferrer" target="_blank">https://ffmpeg.org/mailman/listinfo/libav-user</a><br>
<br>
To unsubscribe, visit link above, or email<br>
<a href="mailto:libav-user-request@ffmpeg.org" target="_blank">libav-user-request@ffmpeg.org</a> with subject "unsubscribe".<br>
</blockquote></div>