Recent

Author Topic: Lazarus Mediaplayer with SDL2 and FFMPEG  (Read 25403 times)

somby

  • New Member
  • *
  • Posts: 15
    • Sombys Softwareküche
Lazarus Mediaplayer with SDL2 and FFMPEG
« on: March 12, 2018, 05:47:09 pm »
My Name is Reiner Sombrowsky (info@somby.de).
I am a german software developer and I developed many years with Delphi7
specially great database applications. Since 2 years ago I take
Lazarus for new development and I found it is the best what I could be found.
That's why I would like to say thank you to the developers.
You have done a very good job.

But I am interested to realize an video-/audio- or streamplayer
similar ffplay with the basic components of FFMPEG and SDL2 in Lazarus.
But I have tried my own considerations.
Perhaps we can talk in this forum about better solutions or to optimize it.

First I am looking for the basic components. Because my developing environment
is Windows 32bit I have dowloaded the FFMPEG-Windows-Builds

"ffmpeg-3.4.2-win32-shared.zip" from "https://ffmpeg.zeranoe.com/builds/win32/shared/"
and
"ffmpeg-3.4.2-win32-dev.zip" from "https://ffmpeg.zeranoe.com/builds/win32/dev/"

The developer-build I need it to compare the Header-Files.

I found in "http://www.delphiffmpeg.com/headers/" the pascal-header-files
"ffmpeg-delphi-pascal-headers-3.3.5.zip", and now I make my own pascal-files,
with updates to the current ffmpeg-header-files.
I compared the current header files of ffmpeg version 3.4.2 with the pascal-headers
of "ffmpeg-delphi-pascal-headers-3.3.5.zip". I uses only that functions, that I need
for the player. Because the units are not complete I named the .inc Files to the
units "min_....inc".

Now I was looking for SDL2. I downloaded the Runtime-Binaries
"SDL2-2.0.8-win32-x86.zip" from "https://www.libsdl.org/download-2.0.php"
and
"SDL2_ttf-2.0.14-win32-x86.zip" from "https://www.libsdl.org/projects/SDL_ttf/"
and I downloaded SDL2-pascal-headers from "https://github.com/ev1313/Pascal-SDL-2-Headers".
I found a little Error in the file sdlrenderer.inc marked with "// rso 03.02.2018".

No to the Considerations:
The basicly souces for documentation were:
"http://dranger.com/ffmpeg/"
"http://lazyfoo.net/tutorials/SDL/"
"https://gist.github.com/Lovesan/e29d815586ea20642d85875d47cefe03"

I wanted to develop a control for Lazarus to play video, audiofiles and livestreams.
The base for the control was the TCustomControl-component.
Some comments to the current realized control.
After the "Play"-function was started correctly, a thread in the background
"ReadThread" reads the frames from the mediasource and stores these in
an audio-queue and a video-queue. If there is no place in the Queues the
thread is waiting (q.Put) so long if another thread or the mainthread set
Wakeup space.

If there is an AudioStream in the media  we start a SDL-callback AudioThread.

To synchronize Video and Audio I take the following selection:
- If we have an AudioStream we synchonize with the Audio-Timestamp
  (av_frame_get_best_effort_timestamp)
- If we have only a VideoStream or disable the Audio we syschronize with the
  current time.
We take a fixed sample rate to check for synchonizing (20ms you can change it).
A Timer invalidates every sample rate time a paint-procedure where we can show the
current Image from Videoframes. We dont calculate any delays etc., we take following
algorithm:

A): Synchronizing with Audio within the paint-procedure.
If the current VideoTimestamp is greater as the current AudioTimestamp we wait for the
next Videoframe. We dont need to present the renderer, because the last previos shown
Videoframe was copied to the renderer.
If the current Videotimestamp ist lower or equal as the current AudioTimestamp we
update a SDL-Texture with the decoded VideoFrame, copy the Texture to the Renderer
and do marking, that we have to present the renderer. We do it within a loop so long
if we don't have a VideoFrame whose Timestamp is lower or equal as the Audiotimestamp.
Because we have marked that we have to present the renderer, we present the renderer
if we leave the loop.
This is very efficient because we only present the Renderer after last frame.

B): Synchronizing with current Time.
We store at the beginning or after every "Resume" or "Seek" the current
VideoTimestamp in FVideoSyncPts and the current time in FVideSyncTime and then
we take the same algorithm as sychronizing with audio only we compare not
VideoTimestamp with AudioTimestamp, we compare the difference beetween the
current VideoTimeDifference (VideoTimestamp-FVideoSyncPts) and the
currenttimedifference (currenttime-FVideoSyncTime).

So you can tell me if you have good ideas.

Best regards
Reiner Sombrowsky
(somby)

Download:
https://c.1und1.de/@519844823566385489/Jae-lddLSjquAVnczAPqHg

Today (13.03.2018) I take some updates.
The last update is sdl2_ffmpeg_player_001 from the same download
« Last Edit: March 13, 2018, 04:15:46 pm by somby »
Sombys Softwareküche
https://www.somby.de

metis

  • Sr. Member
  • ****
  • Posts: 300
Re: Lazarus Mediaplayer with SDL2 and FFMPEG
« Reply #1 on: March 14, 2018, 01:52:44 pm »
@somby

nothing new for me, see:

FFPlay4Laz: http://forum.lazarus.freepascal.org/index.php/topic,26666.msg215455.html#msg215455

FFInfo4Laz: http://forum.lazarus.freepascal.org/index.php/topic,22038.msg208700.html#msg208700

Meanwhile I worked out a much more advanced Version of 'FFPlay4Laz', that
I use every Day for rendering VideoClips (-> very accurate AV-Sync and high Audioquality required !).
I'll publish it in this Forum within the next Weeks.

Refering to 'SDL2':
I know, that there are already FPC-Wrapper for it, but for the Moment I'm happy with SDL1, and
I wanted to wait, until SDL2 is implemented in Lazarus - Finally my Project is called FFPlay4Laz.

Quote
We take a fixed sample rate to check for synchonizing + We dont calculate any delays etc.
ffplay.c (and FFPlay4Laz) does it much more precise, see:
http://forum.lazarus.freepascal.org/index.php/topic,33105.msg214464.html#msg214464
-> GoTo:
"To demonstrate the PictureQueue-Sync at Work, You'll find in the Attachment a ScreenShot of
  a typical Series of real Values for 'Current VideoPictures per Sec.', generated by my 'FFPlay4Laz'."

BTW:
Pleased to have found someone, who got the same interests - after more than 3 Years.  :)
« Last Edit: March 14, 2018, 03:06:10 pm by metis »
Life could be so easy, if there weren't those f*** Details.
My FFmpeg4Lazarus = FFPlay4Laz + FFGrab4Laz + FFInfo4Laz

somby

  • New Member
  • *
  • Posts: 15
    • Sombys Softwareküche
Re: Lazarus Mediaplayer with SDL2 and FFMPEG
« Reply #2 on: March 15, 2018, 06:47:31 pm »
Hi metis,
thank you for your first replay.
I only would like to show my idea to realize such a Video-/Audio-/Livestreamplayer.
I don't want to invent the world new.
It was very important to use the latest versions of FFMPEG and SDL2.
The comment:
"We take a fixed sample rate to check for synchonizing + We dont calculate any delays etc."
does not say that this method don't give very accurate AV-Sync and high Audioquality.
You see it if you consider my method  "Paint".
I can't find any sources of your "FFPlay4Laz" to compare.
But you wrote that you will publish in the next weeks.
My download has all sources of my component.

Best regards
somby

                   
Sombys Softwareküche
https://www.somby.de

metis

  • Sr. Member
  • ****
  • Posts: 300
Re: Lazarus Mediaplayer with SDL2 and FFMPEG
« Reply #3 on: March 16, 2018, 02:07:36 pm »
@somby

Quote
I don't want to invent the world new.
I know - Anything else would be stupid. There are already plenty of Players written in C.

Quote
does not say...and high Audioquality.
For "high Audioquality", I use Portaudio -> faster, more responsive, better Sound.
This was not meant to be in the Context with Your AV-Sync-Method.

Quote
You see it if you consider my method  "Paint".
I did: Updating the VideoImage in fix Intervals is not the same like Updating it, when needed.
These Differences are marginal, but sometimes, it can be seen (with reactive Eyes).
That's the Reason, why I use specially VideoClips for Testing the Code.
I want to achieve, that the Movement of the Lips is totally synchronous to the Sound.
You won't see this - indeed - little Difference, e.g. with translated Movies.

Quote
I can't find any sources of your "FFPlay4Laz" to compare.
You didn't find it, because there isn't, and it's not intended, that there will be.
The Meaning of my Thread was (and is), to inspire FPC-People to deal with FFmpeg-DLLs, and
not only with the EXEs (-> "NON(!)-EXE FFPlay4Laz").
The Meaning of this is, to encourage People to find own Solutions - like You did, now.  ;)
But I will always help anybody in his efforts, and I've already published lots of Code-Parts.

Quote
But you wrote that you will publish in the next weeks.
This refers only to the current running Version - why, see above.
The Meaning of presenting only a working Example is to show, that yes it's possible to do it in FPC, too.
There are still too much People out there, who think, that Pascal is not a Language for Programmers !  :(

Quote
My download has all sources of my component.
I checked them...

I had a Look at the FFExample-Code, that is apparently the Base of Your Code:
This is, how 'ffplay.c' did it some Years ago - only Differences:
As an ExampleCode it's reduced to the Minimum (e.g. no Seek-Code, no SDL-Events for UserEntries),
the SDL-Threads are replaced with C-Threads, and the Code is updated to FFmpeg v3.2.2 and SDL2.
( This short Description is not for You; it's for those, who are not familiar with FFmpeg (yet?). )


I had a Look at Your Code:
- Your Units are in Delphi-Mode - Why, if we're talking about a "Lazarus Mediaplayer" ?

- Sorry, still true: Updating the VideoImage with a fix Timer is less accurate than 'ffplay.c'.

- Why do You use 'TList', instead of FFmpeg's 'AVPacketList' ?
  The C-Code for the PacketQueues is simple, works, and is maybe faster than 'TList'.
  The FPC-Analogue to this Part of 'ffplay.c' is here (it did not change till this day):
  http://forum.lazarus.freepascal.org/index.php/topic,26666.msg196377.html#msg196377
  -> Download the File in the Attachment and GoTo: "AV-PacketQueues".


I tried Your Player:
- Considering Your very simplified AV-Sync-Code, AV-Syncing is surprisingly o.k., but 'ffplay.c' is more accurate.
-> Solution: Have I Look at 'ffplay.c': AV-Syncing is much more complex there.

- With quite a lot VideoFiles...
  ...Seeking is deactivated (e.g. with all my MKV-Files).
  ...Seeking results in a black Screen for quite a long Time.
  ...Seeking relative ( [Seek(10s)] ) does not work: The Stream only seeks back to the same Position or to BOF.

- In those Cases, where the Seek works, ...
  ...jumping to the new AudioStreamPosition is audible -> not nice.
  ...with some VideoFiles, I get ugly ("verpixelt" - I'm German, too) VideoImages, when Seeking.
-> Solution: Consider using 'avcodec_flush_buffers()'.

=> Still lots of Work.  ;)
« Last Edit: March 21, 2018, 05:14:04 pm by metis »
Life could be so easy, if there weren't those f*** Details.
My FFmpeg4Lazarus = FFPlay4Laz + FFGrab4Laz + FFInfo4Laz

somby

  • New Member
  • *
  • Posts: 15
    • Sombys Softwareküche
Re: Lazarus Mediaplayer with SDL2 and FFMPEG
« Reply #4 on: March 29, 2018, 08:42:03 pm »
There are a update for my mediaplayer:
the current versions are

sdl2_ffmepeg_player_002.7z or sdl2_ffmepeg_player_002.7z.

You can download it from
https://c.1und1.de/@519844823566385489/Jae-lddLSjquAVnczAPqHg

In this version I used the SDL2-Timer
because it has a better resolution and
I updated the seek-function
have fun with this version.
Sombys Softwareküche
https://www.somby.de

somby

  • New Member
  • *
  • Posts: 15
    • Sombys Softwareküche
Re: Lazarus Mediaplayer with SDL2 and FFMPEG
« Reply #5 on: April 04, 2018, 11:29:23 am »
Hi Lazarus-users,

I have made some small changings in uexplayer.pas and
I added a new Application (streamplayer) to
play livestreams (TV, WebCams, Radio and s. o.).

You can download this version "sdl2_ffmepeg_player_003"  from:
https://c.1und1.de/@519844823566385489/Jae-lddLSjquAVnczAPqHg

Some comments to the "streamplayer.exe":
The streamplayer is a new app with my playercontrol to
play tv-, radio-, webcam-livestreams and s.o.

In the same directory (bin) of the "streamplayer.exe" there is also
located an ini-file "streamplayer.ini" where are defined
the known available livestream-urls as sections. The section-names
can be shown and selected within the streamplayer-app. This ini-file
not uses an utf8-charset because it is simplier to edit this file
with windows-tools.
In the download there is a "streamplayer.ini" in the bin directory
with some german tv-, radio- and webcam-livestreams that I found.
You can edit this file and add, delete or update the items. It is possible that
some items are not available in the future.

The streamplayer is started in window-mode in the middle of the screen.
Streamplayer not uses mouse it only supports keybord-keys.

Some terms:
 default-mode     - The livestream is showing without menu-table.
 
 selecting-mode   - A menu-table is showing transparent over
                             the livestream, you can select any item.

 windows-mode     - Streamplayer is showing as a window in
                             the middle of the screen.

 fullscreen-mode  - Streamplayer is showing without border
                            with full screen. 


The following keys are available:

Esc        - If you are in the default-mode you can leave the app.
               If you are in the selecting-mode you can leave the
               selecting-mode without selecting an item.

Enter     - If you are in the default-mode you can switch
                on the selecting-mode.
               If you are in the selecting-mode you can select
               an item to play.

Ctrl+Up  - You can switch to the fullscreen-mode.

Ctrl-Down  - You can switch to the window-mode     

Up,Down,
Left,Right - You can navigate if you are in the selecting-mode

Space      - You can switch mute or not.

Ctrl-Space - You can switch pause or resume.

So have fun with the source-code and the streamplayer
Your somby
Sombys Softwareküche
https://www.somby.de

metis

  • Sr. Member
  • ****
  • Posts: 300
Re: Lazarus Mediaplayer with SDL2 and FFMPEG
« Reply #6 on: April 09, 2018, 03:21:04 pm »
@somby

So You found out, that it's better to use AV-StreamDurations instead of StreamDurations to get the Length.
(I was just intending to tell it to You, but You were faster.)
-> With 'FFInfo4Laz' (see the Attachment) You can check quickly, which 
     Durations are encoded in an AV-Stream, and if they are valid.
You'll see, that the most reliable Duration is the AV-StreamDuration, and
You'll see also, that there are still some AV-Streams w/o any valid Duration encoded.
-> Would be nice to have some Code to handle these Cases, too.

Some more Issues...

Since Version #2, You use the SDL-Timer.
-> I suppose/hope You're preparing variable Video-RefreshRates with 'GetVideoTimeCheck'.
In newer Versions of 'ffplay.c', the SDL-Timer is replaced with 'av_usleep()'.
Nevertheless, I go on using the SDL-Timer in 'FFPlay4Laz', 'cause I see no Need to abandon it.
-> What's Your Opinion about "SDL-Timer vs. av_usleep()" ?

You call 'CreateRenderer()' on each Paint-Event and 'OnPlay', then exiting this Procedure if already created.
-> Why don't You call it only once 'OnAppStart' ?

All Your PlayerCode is based on Ms - You may do that, but:
All FFmpeg-Times are in Seconds (e.g. PTSs, DTSs) or in MicroSeconds (e.g. Durations).
-> I think, it's better to keep the Code in Seconds. This Way, You don't need to convert Seconds to Ms
   all the Time, and MicroSeconds can be simply converted with FFmpeg-Constants, like 'AV_TIME_BASE'.

I tried Your Player #2 + #3:
- [Seek (10s)] is quite often inaccurate (Seeking to 4-11 Sec.).
- The Seek is still "verpixelt" and slow, e.g. with MPEGs.
  (Flushing the CodecBuffers 'OnSeek' does not only avoid this ugly VideoEffect, it also makes the Seek faster.)
- ad Version #2: When Seeking in a paused AudioStream, the Stream is resumed (it should stay paused).
  ad Version #3: When Seeking in an AudioStream, there's no more Sound; the App has to be restarted.

I like Your SyncMechanisms, though it's not that accurate as 'ffplay.c' - seems to be sufficient for common Purposes.
AV-Syncing gets more complex, if You want Your Player to be fast and accurate, and
it's getting even more complex, if You start Adding Features, like:
Start paused, Start paused at the last MRL-Position, Seek paused, Looping, etc.
("Der Teufel liegt im Detail." - Sorry, this is German; I don't know it in English.)

ad 'SDL':
With 'SDL2', the VideoImage is indeed much better than with 'SDL1', and
with Float32 (SDL1 is max. Int16), Audio is also better (but Portaudio still sounds even better).

 :)
Life could be so easy, if there weren't those f*** Details.
My FFmpeg4Lazarus = FFPlay4Laz + FFGrab4Laz + FFInfo4Laz

somby

  • New Member
  • *
  • Posts: 15
    • Sombys Softwareküche
Re: Lazarus Mediaplayer with SDL2 and FFMPEG
« Reply #7 on: April 12, 2018, 04:18:06 am »
Hi metis and all interested lazarus-users,

thank you metis for some hints as "flushing the codec buffers".
I have tried it to apply but there are some other problems I
will discuss later.

But first some comments to a SDL-window and my procedure "CreateRenderer".

I have developed a windows-control and not only a simple window.
This control can be used multiple with different contents in an application.
For example you can build a video-control-array with different camera-views
(provided your CPU has enought ressources).
I use the SDL-function "SDL_CreateWindowFrom" which needs an existing windows handle.
The windows handle in the control is valid after the CreateWnd-procedure and thats
why I call "SDL_CreateWindowFrom" after "CreateWnd". Because it could be possible that
the control must be recreated I use "SDL_DestroyWindow" before "DestroyWnd".
The renderer uses an existing SDL-windows handle. I have tried to call the
"SDL_CreateRenderer"-function after "SDL_CreateWindowFrom" within the overridden
"CreateWnd"-procedure, but an error occured. That's why I create the renderer if
it will be used but only one time. If the renderer is already created "CreateRenderer"
doesn't do nothing.

Now something about my synchronizing mechanism and using of timers.

I will explain my idea to synchronize.
I will assume that we will synchronize the video- with an audio-stream
(if we don't have an audio-stream we can also synchronize with current
time its a similar procedure see the "Paint"-procedure).

A cyclical timer invalidates my control and every time the "Paint"-procedure
of the control is called.
Whithin a loop of the "Paint"-procedure I peek the first video-frame in the
video-queue and compare the video-timestamp with the current audio-timestamp.
If the video-timestamp is lower or equal I mark this frame to render (but I do it not),
free an older marked video-frame, because its time is over, and delete the
first video-queue-entry.
The loop is leaved, if the timestamp of the first video-frame in the
video-queue is greater as the audio-timestamp, that means the video-frame will be
shown later.
If the loop is leaved and a video-frame is marked to render it will be done.
If the "Paint"-procedure is called and the timestamp of the first video-queue-frame
is greater as the current audio-timestamp nothing is done, the
last decoded video-frame as texture is furthermore shown from SDL.

The accurance of synchronizing is dependent of the timer-cycle. If the timer-cycle is
faster as the video-frame-rate no video-frame will be forget and a better resolution
is not possible. The CPU-time is also not so very high because "Paint" do nothing if
the timestamp of first video-frame of video-queue is greater as the audio-timestamp.
I compare this with an digital-control-system with equidistant rate.

In my first version I used as timer the windows default timer. Th maximum resolution
of it is approximately 25 ms. You can try a lower value but no lower value will be
reached. Only the multimedia-timer in the unit mmsystem or the SDL_Timer has a
very good resolution (I have tested with my "wLog"-procedure) in unit uexplayer.
That's why I use the SDL_Timer with a time-cyle of 15ms. With this time it is possible
a resultion of a frame-rate to 60.

So now to the using of "flushing codec buffers"

My older versions have a lot of pixelated frames after seeking of MPEG-Videos.
Thank you metis for the hint of "flushing codec buffers". I used the function
"avcodec_flush_buffers" after the seeking. I checked with my "wLog"-function the
"ReadThread". After seeking the function "avcodec_receive_frame"
for video-frames gaves back no valid video-frames (result-code 11) for a long time.
Audio-frames were present after a short time.
I think the decoder must first build complete frames after "avcodec_flush_buffers".
Already in my first version I queued the first audio-frames after I have received a
first valid video-frame. I used it because I found by some livestreams a lot of audio-frames
were decoded before you see the first video-frame. So you could see a black window
with sound for a long time. In the latest version (004) I use this method after seeking
to see the first video-frame earlier. But if I seek to a special time
(only MPEG-videos) the result-time can be higher as the seek-time (I have MPEG-videos
where the differce is greater 10s).
I have compared the seeking without flushing and not waiting for the first video-frame
with flushing and waiting for the first video-frame.
I found the delay-time of the first video-frame without "pixelated" by method without
flushing was the same to receive the first valid video-frame with flushing.
I have only seen this on MPEG-Videos the other types working correct.
Perhaps some other users have a good ideas to solve the problem.


So at last I found that some videos have another starttime as 0 and I have
changed some functions
.

The version 004 can be download also from:
https://c.1und1.de/@519844823566385489/Jae-lddLSjquAVnczAPqHg


Best regards
somby

Sombys Softwareküche
https://www.somby.de

metis

  • Sr. Member
  • ****
  • Posts: 300
Re: Lazarus Mediaplayer with SDL2 and FFMPEG
« Reply #8 on: April 12, 2018, 03:04:43 pm »
@somby

Next Hint: To reduce the Number of CodeLines,
You may use 'SwrCtx := swr_alloc_set_opts()', instead of
'SwrCtx := swr_alloc()' + 'av_opt_set_channel_layout()' + 'av_opt_set_int()' + 'av_opt_set_sample_fmt()'.

Quote
I found that some videos have another starttime as 0
No, lots of MRLs (Audio, too) have a Starttime - Check it with 'FFInfo4Laz'.
'ffplay.c' always uses the AV-Starttime 'OnAppStart'.

Next Time, I'll answer more to Your last Post.
(I got no Internet at Home, only at my workplace, where I have no possibility to answer more detailed.)

 :)
« Last Edit: April 12, 2018, 03:27:51 pm by metis »
Life could be so easy, if there weren't those f*** Details.
My FFmpeg4Lazarus = FFPlay4Laz + FFGrab4Laz + FFInfo4Laz

somby

  • New Member
  • *
  • Posts: 15
    • Sombys Softwareküche
Re: Lazarus Mediaplayer with SDL2 and FFMPEG
« Reply #9 on: April 13, 2018, 02:51:16 am »
Hi lazarus users,
please excuse me, I have forgotten to switch of the log -define in unit
uexplayer.
Please change
{$define log}
to
{.$define log}
and compile the projects "playercontrol" and "streamplayer" new
or you can download the version 004 again from
https://c.1und1.de/@519844823566385489/Jae-lddLSjquAVnczAPqHg

your somby
Sombys Softwareküche
https://www.somby.de

metis

  • Sr. Member
  • ****
  • Posts: 300
Re: Lazarus Mediaplayer with SDL2 and FFMPEG
« Reply #10 on: April 13, 2018, 01:46:11 pm »
@somby

All the Following refers to Your Post from Yesterday...

Quote
I have developed a windows-control + This control can be used multiple with different contents in an application.
Did You try 'TOpenGLControl', Descendent of 'TWinControl' (Unit 'OpenGLContext'), that comes with Lazarus ?
Control+Package, see: "LazDIR\components\opengl\lazopenglcontext.pas + lazopenglcontext.lpk"

My first Version of 'FFPlay4Laz' was a GUI, that used optionally the 'LazOpenGLControl' and/or
YUV in a SDL-Window for Testing Speed. I left the GUI, because 'FFPlay4Laz' is
more a Core-Unit, an AV-Engine, having all PlayerFeatures included, than an UserControl.

Quote
I will explain my idea to synchronize.
I understood Your AV-SyncIdea from the Beginning; my Point is...
Quote
The accurance of synchronizing is dependent of the timer-cycle
In my Opinion, using a fix TimerInterval, where the only Option is to show the current VideoImage or not,
is not the same as Displaying that VideoImage in variable, synchronized Intervals.
(How far this Difference is visible to the common User, is an other Question.) 
By mentioning 'av_usleep()' above, I actually wanted to point out another Issue:
Any Kind of "Sleep", generates a Delay in the running Code, 'SDL_AddTimer()' not.

Quote
After seeking the function "avcodec_receive_frame" for video-frames gaves back no valid video-frames...for a long time.
+ I think the decoder must first build complete frames after "avcodec_flush_buffers".
'ffplay.c' does it this Way:
After Reading, the AV-Packets are first put into PacketQueues. When Seeking, those PacketQueues are emptied, and a special Packet is put into the PacketQueues, called Flush-Packet.
This Flush-Packet invokes 'avcodec_flush_buffers()' before Decoding.
Then only the remaining AV-Packets are decoded, and only completely decoded (and synchronized) Frames
are put into the FrameQueues or sent to the Audio-Callback.

If I understood everything right, Your
Quote
...I queued the first audio-frames after I have received a first valid video-frame.
is the Analogue to those PacketQueues.

For how to implement that Flush-Packet, see my "FFPlay-Skeleton" for FPC:
http://forum.lazarus.freepascal.org/index.php/topic,26666.msg196377.html#msg196377
-> Download the File in the Attachment, and search for "flush_pkt".
'ffplay.c' uses this Mechanisms until today, see 'FFmpeg v3.4.2':
https://www.ffmpeg.org/download.html#get-sources
-> Download the FFmpeg-SourceFiles for 'FFmpeg v3.4.2', and search for "flush_pkt" in '..\fftools\ffplay.c'.

'FFPlay4Laz' has the same Mechanisms.
-> The Seeks are very fast, and I have no pixelated Frames, at all, even not with MPEGs, and
     there is no more Code needed to wait for the first valid VideoFrame.

BTW:
When I started my FFPlay4Laz-Project, I was also trying around lots of Code - quite frustrating.
I think, it's much easier to check 'ffplay.c' first. FFPlay is a Test-Player to check out the FFmpeg-Functions.
If it works for them, it should work for us, too.

Quote
I have only seen this on MPEG-Videos the other types working correct.
Me, too, but an AV-Player should render any Format correctly.

Quote
Perhaps some other users have a good ideas to solve the problem.
I'm waiting for this, since I've started my Thread "NON(!)-EXE FFPlay4Laz", the 4th of Dec. 2014:'(
In the End, I did all the Coding of 'FFPlay4Laz' and 'FFInfo4Laz' by myself.
-> Suppose, we'll stay alone.

Finally:
I cannot try out Your Player #4, because both, 'playercontrol.exe' and 'streamplayer.exe'  :(
open with an "Access violation", and do not work on my PC - My System:
WinXP 32bit SP3 on
INTEL Pentium DualCore 1,60GHz, 4 GB RAM (only 3,25 GB used, due to Win XP).

 :)
« Last Edit: April 16, 2018, 01:07:08 pm by metis »
Life could be so easy, if there weren't those f*** Details.
My FFmpeg4Lazarus = FFPlay4Laz + FFGrab4Laz + FFInfo4Laz

somby

  • New Member
  • *
  • Posts: 15
    • Sombys Softwareküche
Re: Lazarus Mediaplayer with SDL2 and FFMPEG
« Reply #11 on: April 13, 2018, 05:28:53 pm »
Hi metis,
"Access violation": please change
{$define log}
to
{.$define log}
in uexplayer and compile the projects "playercontrol" and "streamplayer" new
or download the version 004 again.
I wrote it in my last reply

somby
Sombys Softwareküche
https://www.somby.de

metis

  • Sr. Member
  • ****
  • Posts: 300
Re: Lazarus Mediaplayer with SDL2 and FFMPEG
« Reply #12 on: April 13, 2018, 05:58:08 pm »
Hi somby,

Quote
I wrote it in my last reply

Yes, and I wrote, that all my Reply, means until the End, refers to Your Post before that.
(Why, I've already explained: Not having Internet at home... )

  ;)
 
« Last Edit: April 16, 2018, 12:57:44 pm by metis »
Life could be so easy, if there weren't those f*** Details.
My FFmpeg4Lazarus = FFPlay4Laz + FFGrab4Laz + FFInfo4Laz

metis

  • Sr. Member
  • ****
  • Posts: 300
Re: Lazarus Mediaplayer with SDL2 and FFMPEG
« Reply #13 on: April 16, 2018, 01:06:37 pm »
@somby

I tried Your corrected Player #4...

> Better, compared with previous Versions (obviously due to 'avcodec_flush_buffers()'):
- No more pixelated VideoFrames, when Seeking in MPEGs.
- Seek is stable, means does not fail any more, when Seeking repetitively
  -> Shouldn't be a big Thing to implement 'Looping'.

> Same, compared with previous Versions:
- The Seek is a bit slow with some MRLs, but o.k.
- [Seek (10s)] is not very accurate: mostly Seeking to 8-11 Sec., with
  some MRLs to 2-5 Sec. or to BOF or to "nothing", though Seeking with the SeekBar works (strange).
- With a few Videos, Seeking with the SeekBar does not work, though [Seek (10s)] works and a Duration is shown (strange).
- When Seeking in Audios the SeekBar is quite often not updated, though the Seek was done.
- With a few Audios, the current StreamPositions is shown wrong, e.g.: [106751991:28:01:27]. (it was an ACC)
- When Seeking in a paused Audio, the Stream is resumed (it should stay paused).

> Worse, compared with previous Versions:
- When Video starts, there's always a green (0,255,0) VideoImage for a short Time.

BTW:
Cannot test Your StreamPlayer, because - as already mentioned - I have no Internet at home.

=> Video is getting better !  :)
Life could be so easy, if there weren't those f*** Details.
My FFmpeg4Lazarus = FFPlay4Laz + FFGrab4Laz + FFInfo4Laz

somby

  • New Member
  • *
  • Posts: 15
    • Sombys Softwareküche
Re: Lazarus Mediaplayer with SDL2 and FFMPEG
« Reply #14 on: April 20, 2018, 06:06:03 pm »
Hi lazarus-users,
today I have some minutes again to employ
with my SDL2_FFMPEG-player. In another
project I use a queuing method that I have it also
realized in this mediaplayer. The queuing method
works without critical sections and is very fast.
You can see it in my new version 005 from the
current download url. I don't need critical sections
because I check a atomic variable FValid if it can makes changings.
I use also two windows events to wakeup the functions
Get and Put if these are waiting.
Thank you for some hints from metis but it is impossible to solute all
the problems. First I have created my SDL-window
at first time if I need, so you don't see a bad white
frame within the control at begin. Also I use the texture
at first time if it is filled with data from playing, thats why
you don't see a green filled control.
The biggest problem is to seek within a file.
If I don't flush all buffers after seeking the first visible frames
are with a lot of bad pixels but with a good timing.
If I flush all buffers after seeking, the first visible frame is without bad pixels but with a timing
in some samples a lot of seconds after the seek time.
Ffplay has same problems, you can find it in documentation of
ffplay (https://ffmpeg.org/ffplay.html) see "Seek with -ss pos".
I think the player is working good anough for my using and for
a lot of other users.
I use mainly the streamplayer in my own application.

So many fun to use my player
The download Version 005 you can also find at
https://c.1und1.de/@519844823566385489/Jae-lddLSjquAVnczAPqHg

For interest users, I have also posted an article
to using GoogleMap-API within a lazarus application
(see "Lazarus Application integrates GoogleMap-API")


 
Sombys Softwareküche
https://www.somby.de

 

TinyPortal © 2005-2018