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-lddLSjquAVnczAPqHgBest regards
somby