Hi all,
Let's hope there are still people reading this mailing list :-)
I am in the process of writing a small AVI player using OpenDivX and MAD (I need MAD because the ultimate goal is for it to run on my Linux-powered iPAQ and I need fixed point math :-) ).
If I put aside the licensing issues ( :-) ), my biggest problem is to really understand how the low-level MAD interface is working. After looking at the WinAMP plug-in source, I somewhat understood how it works (except for the timers, where I am completely lost). My understanding for now is :
- read some data from the stream - call mad_stream_buffer - call mad_frame_decode - call mad_synth_frame - send the data to the sound device - copy the data remaining in the buffer (ie the 'next_frame' pointer) to the start of my input buffer
For a stand-alone player, this works wonderfully. The problem comes when I try to incorporate this in my AVI player. Indeed, when I added some printfs to my small player, I saw that MAD always :
- output the same amount of data (0.006 seconds of sound) - always 'progressed' of the same amount of data in my stream
On the other hand, in my AVI stream, for each video frame, the amount of MP3 data is not AT ALL constant.... Moreover, it is sometimes smaller than the amount of data read by MAD => I get (as soon as the first video frame) a decode error from MAD (I did not check exactly what error it was).
I could do 'buffering' (ie concatenate some sound AVI chunks) but then I would completely lose my synchro (and I do not want to rely on timers or to retrieve the synchro, it would start to get bad with long films).
So anyone could light my lantern as to how MAD can be used to do what I need ?
Thanks,
Lionel
PS: I hope this is the right mailing list, I did not know if I should send this to the devel list or the user list :-)
Hi Lionel,
If I put aside the licensing issues ( :-) ), my biggest problem is to really understand how the low-level MAD interface is working. After looking at the WinAMP plug-in source, I somewhat understood how it works (except for the timers, where I am completely lost). My understanding for now is :
- read some data from the stream
- call mad_stream_buffer
These steps:
- call mad_frame_decode
- call mad_synth_frame
- send the data to the sound device
should be repeated until MAD returns the error MAD_ERROR_BUFLEN.
- copy the data remaining in the buffer (ie the 'next_frame' pointer) to the start of my input buffer
For a stand-alone player, this works wonderfully. The problem comes when I try to incorporate this in my AVI player. Indeed, when I added some printfs to my small player, I saw that MAD always :
- output the same amount of data (0.006 seconds of sound)
- always 'progressed' of the same amount of data in my stream
Each MPEG audio frame generally contains the same number of PCM samples, and (in the case of constant bitrate streams) will usually consume the same amount of data from the stream. Each call to mad_frame_decode() and mad_synth_frame() will decode only a single frame.
On the other hand, in my AVI stream, for each video frame, the amount of MP3 data is not AT ALL constant.... Moreover, it is sometimes smaller than the amount of data read by MAD => I get (as soon as the first video frame) a decode error from MAD (I did not check exactly what error it was).
You will have to demultiplex the MPEG audio data from the video data and stream this independently to MAD.
I could do 'buffering' (ie concatenate some sound AVI chunks) but then I would completely lose my synchro (and I do not want to rely on timers or to retrieve the synchro, it would start to get bad with long films).
You will probably have to deal with the synchronization somehow. MAD's timers can help you keep track of how much audio data has been decoded. They might seem intimidating but they're really quite simple to use. I'll post some details in a follow-up message.
PS: I hope this is the right mailing list, I did not know if I should send this to the devel list or the user list :-)
I think mad-dev is probably more appropriate; I've adjusted the Reply-To header but you might need to subscribe before you can reply.
Cheers, -rob