Realtime video player

Hi,

I work on quicktime player now and what I need is perfectly synchronized video &
audio. Timers don’t seem to be good solution because of limited resolution (I
need 15 FPS - that is a timer with 66.6 ms while timer resolution is 10ms). One
year ago I worked on another player and I determined current time from audio
player’s position in wave file being replayed. That was ok under DirectX - I
just called some DirectSound function that returned current position in sample.
But now I moved to SDL (the best decision I ever did :slight_smile: and I wasn’t able to
find similar function in SDL.

So the question is : is there any way how to get current sample position (with
reasonably precise resolution)?
(or any other way how to get exact synchro with audio)

Vasek

But now I moved to SDL (the best decision I ever did :slight_smile: and I wasn’t able to
find similar function in SDL.

There isn’t currently a similar function under SDL. You can get resolution
up to a fragment by timing the calls to your audio callback function, and
then interpolate the actual playback by time elapsed using SDL_GetTicks().
The relationship between time and calls to your callback function is:
(double)samples_per_fragment/audio_frequency (in seconds)

Does this make sense?

The demo MPEG player in the SDL examples ignores synchronization entirely,
trusting the audio to play at the proper rate, and calculates the framerate
separately. This isn’t the ideal solution, but it works fairly well for
short video clips on reasonably fast systems.

-Sam Lantinga				(slouken at devolution.com)

Lead Programmer, Loki Entertainment Software–
“Any sufficiently advanced bug is indistinguishable from a feature”
– Rich Kulawiec

Sam Lantinga wrote:

But now I moved to SDL (the best decision I ever did :slight_smile: and I wasn’t able to
find similar function in SDL.

There isn’t currently a similar function under SDL. You can get resolution
up to a fragment by timing the calls to your audio callback function, and
then interpolate the actual playback by time elapsed using SDL_GetTicks().
The relationship between time and calls to your callback function is:
(double)samples_per_fragment/audio_frequency (in seconds)

Does this make sense?

I hope so…
Am I right that if I use audio buffer of 1024 B then callback function is called
for 512 fragments?
Isn’t calling callback func so often way too cruel to underlaying OS ?

The demo MPEG player in the SDL examples ignores synchronization entirely,
trusting the audio to play at the proper rate, and calculates the framerate
separately. This isn’t the ideal solution, but it works fairly well for
short video clips on reasonably fast systems.
Unfortunately this won’t work for 3 minutes long intro :frowning:

Thanks for your help
V.S.

BTW, one more question : I’m going to implement interlaced mode (render only odd
lines of odd frames and even lines of even frames). Do you think it is "legal"
to temporary change (multiply by 2) pitch value of screen surface? Just
change_pitch, blit, change_pitch.

I hope so…
Am I right that if I use audio buffer of 1024 B then callback function is called
for 512 fragments?

Not necessarily. You should set the buffer in terms of samples when you
open the audio device, and SDL will calculate the number of bytes, based
on the supported audio formats for the hardware used.

Isn’t calling callback func so often way too cruel to underlaying OS ?

Nope. A 486 or higher can handle a 1024 sample buffer at 22KHz.

BTW, one more question : I’m going to implement interlaced mode (render only odd
lines of odd frames and even lines of even frames). Do you think it is "legal"
to temporary change (multiply by 2) pitch value of screen surface? Just
change_pitch, blit, change_pitch.

It won’t work exactly the way you expect, and won’t work at all with
hardware acceleration. I suggest you build the interlacing into the
decoder, if you can, and render directly to the screen surface.

BTW, I experimented with interlacing on the MPEG decoder, and rendering
every other line every other frame made for really wierd motion blur when
there was lots of movement. I don’t recommend it. Just rendering every
other line might be useful though, and doesn’t look as bad.

In the MPEG decoder, interlacing didn’t improve the framerate much.

-Sam Lantinga				(slouken at devolution.com)

Lead Programmer, Loki Entertainment Software–
“Any sufficiently advanced bug is indistinguishable from a feature”
– Rich Kulawiec

Sam Lantinga wrote:

Nope. A 486 or higher can handle a 1024 sample buffer at 22KHz.
thanks.

BTW, one more question : I’m going to implement interlaced mode (render only odd
lines of odd frames and even lines of even frames). Do you think it is "legal"
to temporary change (multiply by 2) pitch value of screen surface? Just
change_pitch, blit, change_pitch.

It won’t work exactly the way you expect, and won’t work at all with
hardware acceleration. I suggest you build the interlacing into the
decoder, if you can, and render directly to the screen surface.
The problem is that JPEG decoder outputs 24bit RGB while the program is likely
to run in 16bit mode. So I’ll need some format conversion and I though SDL blit
would be ideal (especially when it supports MMX).

BTW, I experimented with interlacing on the MPEG decoder, and rendering
every other line every other frame made for really wierd motion blur when
there was lots of movement. I don’t recommend it. Just rendering every
other line might be useful though, and doesn’t look as bad.

In the MPEG decoder, interlacing didn’t improve the framerate much.
Oops. That’s quite strange - I would expect it to improve it significantly - at
least JPEG decompression phase should be twice faster? Anyway it would reduce
file size by factor of two…

Vasek Slavik

The problem is that JPEG decoder outputs 24bit RGB while the program is likely
to run in 16bit mode. So I’ll need some format conversion and I though SDL blit
would be ideal (especially when it supports MMX).

Can you modify the decoder to output 32-bit RGB? That will be much faster
to convert than 24-bit RGB (word accesses v.s. byte accesses)

In the MPEG decoder, interlacing didn’t improve the framerate much.
Oops. That’s quite strange - I would expect it to improve it significantly - at
least JPEG decompression phase should be twice faster? Anyway it would reduce
file size by factor of two…

The MPEG decoder was a special case because the interlacing happened at
the final display stage, and that portion had already been highly optimized.
The MPEG decoder really needs the optimization at the decode level, not
the display level.

-Sam Lantinga				(slouken at devolution.com)

Lead Programmer, Loki Entertainment Software–
“Any sufficiently advanced bug is indistinguishable from a feature”
– Rich Kulawiec

Sam Lantinga wrote:

The problem is that JPEG decoder outputs 24bit RGB while the program is likely
to run in 16bit mode. So I’ll need some format conversion and I though SDL blit
would be ideal (especially when it supports MMX).

Can you modify the decoder to output 32-bit RGB? That will be much faster
to convert than 24-bit RGB (word accesses v.s. byte accesses)
What does much actually mean?
I’m going to use standard IJG libjpeg with several MMX optimizations by Intel
folks. Although I may be able to modify libjpeg to produce 32bit RGB data I
doubt I’m able to modify Intel’s assembly stuff - my understanding of MMX coding
is pretty low :frowning:
Anyway, I think this won’t speed up the player significantly - the most CPU
intensive part will be JPEG decoding (& reading from CD-ROM…)

VS