[Mplayer-cvslog] CVS: main/DOCS SOUNDCARDS,1.18,1.19 tech-eng.txt,1.9,1.10
Berczi Gabor
gabucino at users.sourceforge.net
Fri May 25 19:04:13 CEST 2001
Update of /cvsroot/mplayer/main/DOCS
In directory usw-pr-cvs1:/tmp/cvs-serv22816/DOCS
Modified Files:
SOUNDCARDS tech-eng.txt
Log Message:
Index: SOUNDCARDS
===================================================================
RCS file: /cvsroot/mplayer/main/DOCS/SOUNDCARDS,v
retrieving revision 1.18
retrieving revision 1.19
diff -C2 -r1.18 -r1.19
*** SOUNDCARDS 2001/05/15 19:24:09 1.18
--- SOUNDCARDS 2001/05/25 17:04:11 1.19
***************
*** 4,14 ****
Aureal Vortex 2:
! OSS : OK
ALSA : no driver
! Max kHz : 48 (probably)
GUS PnP:
! OSS : none
! ALSA : see Aureal Vortex2
Max kHz : 48
--- 4,16 ----
Aureal Vortex 2:
! OSS : no driver
ALSA : no driver
! Max kHz : 48
! Driver : aureal.sourceforge.net
GUS PnP:
! OSS/Free: no driver
! OSS : OK
! ALSA : OK
Max kHz : 48
Index: tech-eng.txt
===================================================================
RCS file: /cvsroot/mplayer/main/DOCS/tech-eng.txt,v
retrieving revision 1.9
retrieving revision 1.10
diff -C2 -r1.9 -r1.10
*** tech-eng.txt 2001/04/20 20:48:25 1.9
--- tech-eng.txt 2001/05/25 17:04:11 1.10
***************
*** 1,13 ****
So, I'll describe how this stuff works.
- The basis of the program's structure is basically logical, however it's
- a big hack :)
-
The main modules:
! 1. streamer.c: this is the input, this reads the file or the VCD. what it has
! to know: appropriate buffering by sector, seek, skip functions,
! reading by bytes, or blocks with any size.
! The stream_t structure describes the input stream, file/device.
2. demuxer.c: this does the demultiplexing of the input to audio and video
--- 1,10 ----
So, I'll describe how this stuff works.
The main modules:
! 1. streamer.c: this is the input layer, this reads the file or the VCD or
! stdin. what it has to know: appropriate buffering by sector, seek, skip
! functions, reading by bytes, or blocks with any size. The stream_t
! structure describes the input stream, file/device.
2. demuxer.c: this does the demultiplexing of the input to audio and video
***************
*** 22,29 ****
in chained list, cause of their different size.
! 2.b. demuxer stream, that is DS. Struct: demux_stream_t
! Every channel (a/v) has one. This contains the packets for the stream (see
! 2.a). For now, there can be 2 for each demuxer, one for the audio and
! one for the video.
2.c. stream header. There are 2 types (for now): sh_audio_t and sh_video_t
--- 19,29 ----
in chained list, cause of their different size.
! 2.b. demuxer stream, that is DS.
! Struct: demux_stream_t
! Every channel (a/v) has one. This contains the packets for the stream
! (see 2.a). For now, there can be 3 for each demuxer :
! - audio (d_audio)
! - video (d_video)
! - DVD subtitle (d_dvdsub)
2.c. stream header. There are 2 types (for now): sh_audio_t and sh_video_t
***************
*** 41,49 ****
For example: we have an asf file, 6 streams inside it, 1 audio, 5
! video. During the reading of the header, 6 sh structs are created,
! 1 audio and 5 video. When it starts reading the packet, it chooses
! the first found audio & video stream, and sets the sh pointers of
! d_audio and d_video according to them. So later it reads only these
! streams. Of course the user can force choosing a specific stream with
-vid and -aid switches.
A good example for this is the DVD, where the english stream is not
--- 41,50 ----
For example: we have an asf file, 6 streams inside it, 1 audio, 5
! video. During the reading of the header, 6 sh structs are created, 1
! audio and 5 video. When it starts reading the packet, it chooses the
! stream for the first found audio & video packet, and sets the sh
! pointers of d_audio and d_video according to them. So later it reads
! only these streams. Of course the user can force choosing a specific
! stream with
-vid and -aid switches.
A good example for this is the DVD, where the english stream is not
***************
*** 75,84 ****
The timing is solved odd, since it has/recommended to be done differently
for each of the formats, and sometimes can be done in many ways.
- There are the a_frame and v_frame float variables, they store the
- just played a/v position is seconds.
A new frame is displayed if v_frame<a_frame, and sound is decoded if
a_frame<v_frame.
When playing (a/v), it increases the variables by the duration of the
! played a/v. In video, it's usually 1.0/fps, but I have to mention that
fps doesn't really matters at video, for example asf doesn't have that,
instead there is "duration" and it can change per frame.
--- 76,99 ----
The timing is solved odd, since it has/recommended to be done differently
for each of the formats, and sometimes can be done in many ways.
A new frame is displayed if v_frame<a_frame, and sound is decoded if
a_frame<v_frame.
+
+ The structure of the playing loop :
+ while(not EOF) {
+ fill audio buffer (read & decode audio) + increase a_frame
+ read & decode a single video frame + increase v_frame
+ sleep (wait until a_frame>=v_frame)
+ display the frame
+ apply A-V PTS correction to a_frame
+ check for keys -> pause,seek,...
+ }
+
When playing (a/v), it increases the variables by the duration of the
! played a/v.
! - with audio this is played bytes / sh_audio->o_bps
! Note: i_bps = number of compressed bytes for one second of audio
! o_bps = number of uncompressed bytes for one second of audio
! (this is = bps*samplerate*channels)
! - with video this is usually == 1.0/fps, but I have to note that
fps doesn't really matters at video, for example asf doesn't have that,
instead there is "duration" and it can change per frame.
***************
*** 98,110 ****
Of course this is not everything, several things suck.
For example the soundcards delay, which has to be corrected by
! MPlayer: that's why it needs the size of the audio buffer. It can
! be measured with select(), which is unfortunately not supported by
! every card... That's when it has to be given with the -abs option.
- Then there's another problem: in MPEG, the PTS is not given by
- frames, rather by sectors, which can contain 10 frames, or only 0.1 .
- In order this won't fuck up timing, we average the PTS by 5 frames,
- and use this when correcting.
-
Life didn't get simpler with AVI. There's the "official" timing
method, the BPS-based, so the header contains how many compressed
--- 113,130 ----
Of course this is not everything, several things suck.
For example the soundcards delay, which has to be corrected by
! MPlayer! The audio delay is the sum of all these:
! - bytes read since the last timestamp:
! t1 = d_audio->pts_bytes/sh_audio->i_bps
! - if Win32/ACM then the bytes stored in audio input buffer
! t2 = a_in_buffer_len/sh_audio->i_bps
! - uncompressed bytes in audio out buffer
! t3 = a_buffer_len/sh_audio->o_bps
! - not yet played bytes stored in the soundcard's (or DMA's) buffer
! t4 = get_audio_delay()/sh_audio->o_bps
!
! From this we can calculate what PTS we need for the just played
! audio, then after we compare this with the video's PTS, we have
! the difference!
Life didn't get simpler with AVI. There's the "official" timing
method, the BPS-based, so the header contains how many compressed
***************
*** 122,125 ****
--- 142,166 ----
really used :) the other isn't stored anywhere, this can only be
measured...
+
+ 3.a. audio playback:
+ Some words on audio playback:
+ Not the playing is hard, but:
+ 1. knowing when to write into the buffer, without blocking
+ 2. knowing how much was played of what we wrote into
+ The first is needed for audio decoding, and to keep the buffer
+ full (so the audio will never skip). And the second is needed for
+ correct timing, because some soundcards delay even 3-7 seconds,
+ which can't be forgotten about.
+ To solve this, the OSS gives several possibilities:
+ - ioctl(SNDCTL_DSP_GETODELAY): tells how many unplayed bytes are in
+ the soundcard's buffer -> perfect for timing, but not all drivers
+ support it :(
+ - ioctl(SNDCTL_DSP_GETOSPACE): tells how much can we write into the
+ soundcard's buffer, without blocking. If the driver doesn't
+ support GETODELAY, we can use this to know how much the delay is.
+ - select(): should tell if we can write into the buffer without
+ blocking. Unfortunately it doesn't say how much we could :((
+ Also, doesn't/badly works with some drivers.
+ Only used if none of the above works.
4. Codecs. They are separate libs.
_______________________________________________
Mplayer-cvslog mailing list
Mplayer-cvslog at lists.sourceforge.net
http://lists.sourceforge.net/lists/listinfo/mplayer-cvslog
More information about the MPlayer-cvslog
mailing list