Finally designed and put together a 
fully working implementation, involving a custom blocking queue and 6 threads. I’ve tested it on Windows XP, OS X, and old Kubuntu Hardy. Windows and Mac both look amazing and run perfectly smooth. Unfortunately on Linux the video playback stutters a lot. At first I thought it was due to the GC. After integrating an impressive object pool design, the cause actually turned out to be the Java audio api.
I use the 
audio playback position to determine when a frame should be displayed. Running a little test exposes how reliable this timer is.
import javax.sound.sampled.*;
public class AudioPositionTest {
    public static void main(String[] args) throws LineUnavailableException {
        AudioFormat audFmt = new AudioFormat(18900, 16, 2, true, true);
        DataLine.Info info = new DataLine.Info(SourceDataLine.class, audFmt);
        SourceDataLine player = (SourceDataLine) AudioSystem.getLine(info);
        player.open(audFmt);
        player.start();
        byte[] abBuf = new byte[2 * 400];
        long lngTestLength = 20 * 1000; // 20 seconds
        long lngTestStart = System.currentTimeMillis();
        long lngTestEnd = lngTestStart + lngTestLength;
        System.out.println(System.getProperty("os.name") + "\tJava " +
                           System.getProperty("java.version"));
        StringBuilder sb = new StringBuilder(400);
        while (System.currentTimeMillis() < lngTestEnd) {
            player.write(abBuf, 0, abBuf.length);
            long lngTime = System.currentTimeMillis();
            long lngPos = player.getLongFramePosition();
            sb.append(lngTime - lngTestStart);
            sb.append('\t');
            sb.append(lngPos);
            System.out.println(sb);
            sb.setLength(0);
            Thread.yield();
        }
        player.stop();
        player.close();
    }
}
Graphing some of the output makes it pretty clear why Linux playback is choppy.
Since that isn’t going to work, my next test will involve registering a 
listener for 
start and stop events, and track playback time manually. Though I’m worried my time and the playback time are going to get out of sync.
 
No comments:
Post a Comment