[Libav-user] Using ffmpeg with SDL2 - Bad src image pointers / New decoding flow - questions
bsenftner at earthlink.net
Sun Feb 5 22:15:37 EET 2017
I’m in a somewhat similar situation as you, working on a video player, using a more C approach versus C++ classes for all the data and logic. I write a hybrid, with classes, but minimally. I prefer C. And I’m using wxWidgets with OpenGL, so there is very little hiding/encapsulation of my data handling.
In your “Init AV backend” I have additional calls to:
avdevice_register_all(); seems to be necessary for USB streams
avfilter_register_all(); you will want an avfilter graph to filter the stream of failed frames and similar error recovery
avformat_network_init(); if you’re playing IP streams, you’ll want this
When you call sws_getContext(), for your 3rd parameter pass in the videoCodecContext->pix_fmt. It’s value means “unset” and essentially tells sws to insure to return pixels in your desired format.
When using avcodec_send_packet() one needs to use avcodec_receive_frame(), as that is the API design. Consider those two routines the in and out of a single algorithm.
Also, due to buffering, you will want avcodec_receive_frame() called in a while loop, to drain the buffered frames after av_read_Frame() has indicated the stream EOF’ed or terminated.
It also looks like you’re not using AVFilter yet, which I have found is critical to stable playback - and it replaces your use of sws_context… (with it’s own use of sws, but with a lot more logic around it)
Regardless of your using AVFilter or directly using sws, your pixel data is not guaranteed to always be a single continuous pixel buffer with all codecs. Your logic needs to look at each frame’s linesize (in the case of RGB pixels) and compare that to your calculated correct number of expected bytes. If they match, then you have a continuous buffer for each pixel line. If they do not match, your logic needs to loop over the pixel buffer copying the pixels from each row start, because each row can have additional bytes that are not image pixels at the end of the pixel row.
I don’t know when you started working on your player, but it looks from reading your comments, you are just a few beats behind my figuring all this out. I can’t share my code directly with you, but keep posting. The advice from others looks correct, but as you point out, you’re working in C, and C++ encapsulation is just hiding details you want to see.
> On Feb 5, 2017, at 9:09 AM, Jan <jan at dwrox.net> wrote:
> On 05.02.2017 17:34, Gonzalo Garramuño wrote:
>> El 05/02/17 a las 12:07, Jan escribió:
>>> Im currently working on a video player software, which should be based
>>> on ffmpeg tools and at the moment of writing, using SDL2 for display
>>> of the video content.
>>> The documentation for ffmpeg is a bit difficult to get through, as
>>> most example code seems to be outdated or using deprecated features.
>>> The SDL tutorial is also not valid anymore, as well as the updated
>>> version on Github or other information which can be found using a
>>> search engine of choice.
>>> What am I missing out here, the alignment?
>> You are missing several things. First you need to call
>> avcodec_receive_frame to get the returned frame after
>> avcodec_send_packet. See the docs for the function and this blog.
>> Also, you don't need to set anything to writable or check for it.
>> Finally, I would look at the code in ffplay.c as it is now compatible
>> with sdl2, I believe.
> The blog does give litte information from what I have looked over. There is no example on how to initialize anything.
> FFPlay works on my Linux machine, but is so cluttered, that I dont want to use it, and yes, it does the job. Unfortunately its as whole not simple and intuitive as what to use the features.
> My code is error prone for some formats, but its much clearer to understand on what has to memory allocated and done in order to get working frames.
> The code you provide in your seconds post, c++, is no option.
> I am working with C - so I dont use BoostLib or similar. Its also not an explanation (for me) to use Boost lib as dependency to get things going.
> I appreciate your help, but its simply not the solution, yet.
> Perhaps there is a more like C approach on how to get the setup ready?
> Libav-user mailing list
> Libav-user at ffmpeg.org <mailto:Libav-user at ffmpeg.org>
> http://ffmpeg.org/mailman/listinfo/libav-user <http://ffmpeg.org/mailman/listinfo/libav-user>
-------------- next part --------------
An HTML attachment was scrubbed...
More information about the Libav-user