Android Open Source - StreamingService Buffer Reader






From Project

Back to project page StreamingService.

License

The source code is released under:

Apache License

If you think the Android project StreamingService listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.

Java Source Code

/*
** AACDecoder - Freeware Advanced Audio (AAC) Decoder for Android
** Copyright (C) 2011 Spolecne s.r.o., http://www.spoledge.com
**  //  ww  w . j a v a2 s . co m
** This file is a part of AACDecoder.
**
** AACDecoder is free software; you can redistribute it and/or modify
** it under the terms of the GNU Lesser General Public License as published
** by the Free Software Foundation; either version 3 of the License,
** or (at your option) any later version.
** 
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
** GNU Lesser General Public License for more details.
** 
** You should have received a copy of the GNU Lesser General Public License
** along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.spoledge.aacdecoder;

import android.util.Log;

import java.io.InputStream;
import java.io.IOException;


/**
 * This is a separate thread for reading data from a stream.
 * The buffer creates 3 buffer instances - one is being filled by the execution thread,
 * one is prepared with data, one can be processed by a consumer.
 * <pre>
 *  InputStream is = ...;
 *
 *  // create a new reader with capacity of 4096 bytes per buffer:
 *  BufferReader reader = new BufferReader( 4096, is );
 *
 *  // start the execution thread which reads the stream and fills the buffers:
 *  new Thread(reader).start();
 *
 *  // get the data
 *  while (...) {
 *      BufferReader.Buffer buf = reader.next();
 *
 *      if (!buf.getSize() == 0) break;
 *
 *      // process data
 *      ...
 *  }
 * </pre>
 */
public class BufferReader implements Runnable {

    public static class Buffer {
        private byte[] data;
        private int size;

        Buffer( int capacity ) {
            data = new byte[ capacity ];
        }

        public final byte[] getData() {
            return data;
        }

        public final int getSize() {
            return size;
        }
    }

    private static String LOG = "BufferReader";

    int capacity;

    private Buffer[] buffers;

    /**
     * The buffer to be write into.
     */
    private int indexMine;

    /**
     * The index of the buffer last returned in the next() method.
     */
    private int indexBlocked;

    private boolean stopped;

    private InputStream is;


    ////////////////////////////////////////////////////////////////////////////
    // Constructors
    ////////////////////////////////////////////////////////////////////////////

    /**
     * Creates a new buffer.
     *
     * @param capacity the capacity of one buffer in bytes
     *          = total allocated memory
     *
     * @param is the input stream
     */
    public BufferReader( int capacity, InputStream is ) {
        this.capacity = capacity;
        this.is = is;

        Log.d( LOG, "init(): capacity=" + capacity );

        buffers = new Buffer[3];

        for (int i=0; i < buffers.length; i++) {
            buffers[i] = new Buffer( capacity );
        }

        indexMine = 0;
        indexBlocked = buffers.length-1;
    }


    ////////////////////////////////////////////////////////////////////////////
    // Public
    ////////////////////////////////////////////////////////////////////////////

    /**
     * Changes the capacity of the buffer.
     */
    public synchronized void setCapacity( int capacity ) {
        Log.d( LOG, "setCapacity(): " + capacity );
        this.capacity = capacity;
    }


    /**
     * The main loop.
     */
    public void run() {
        Log.d( LOG, "run() started...." );

        int cap = capacity;
        int total = 0;

        while (!stopped) {
            Buffer buffer = buffers[ indexMine ];
            total = 0;

            if (cap != buffer.data.length) {
                Log.d( LOG, "run() capacity changed: " + buffer.data.length + " -> " + cap);
                buffers[ indexMine ] = buffer = null;
                buffers[ indexMine ] = buffer = new Buffer( cap );
            }

            while (!stopped && total < cap) {
                try {
                    int n = is.read( buffer.data, total, cap - total );

                    if (n == -1) stopped = true;
                    else total += n;
                }
                catch (IOException e) {
                    Log.e( LOG, "Exception when reading: " + e );
                    stopped = true;
                }
            }

            buffer.size = total;

            synchronized (this) {
                notify();
                int indexNew = (indexMine + 1) % buffers.length;

                Log.d( LOG, "run() indexNew:"+indexNew+",indexBlocked:"+indexBlocked );
                while (!stopped && indexNew == indexBlocked) {
                    Log.d( LOG, "run() blocked...." );
                    try { wait(); } catch (InterruptedException e) {}
                    //Log.d( LOG, "run() awaken" );
                }

                indexMine = indexNew;
                cap = capacity;
            }
        }

        Log.d( LOG, "run() stopped." );
    }


    /**
     * Stops the thread - the object cannot be longer used.
     */
    public synchronized void stop() {
        stopped = true;
        notify();
    }


    /**
     * Returns true if this thread was stopped.
     */
    public boolean isStopped() {
        return stopped;
    }


    /**
     * Returns next available buffer instance.
     * The returned instance can be freely used by another thread.
     * Blocks the caller until a buffer is ready.
     */
    public synchronized Buffer next() {
        int indexNew = (indexBlocked + 1) % buffers.length;

        while (!stopped && indexNew == indexMine) {
            Log.d( LOG, "next() waiting...." );
            try { wait(); } catch (InterruptedException e) {}
            Log.d( LOG, "next() awaken" );
        }

        if (indexNew == indexMine) return null;

        indexBlocked = indexNew;

        notify();

        return buffers[ indexBlocked ]; 
    }

}




Java Source Code List

com.commandocoder.streaming.StreamingException.java
com.commandocoder.streaming.StreamingListener.java
com.commandocoder.streaming.StreamingService.java
com.spoledge.aacdecoder.AACPlayer.java
com.spoledge.aacdecoder.BufferReader.java
com.spoledge.aacdecoder.Decoder.java
com.spoledge.aacdecoder.FlashAACInputStream.java
com.spoledge.aacdecoder.FlashAACPlayer.java
com.spoledge.aacdecoder.IcyInputStream.java
com.spoledge.aacdecoder.IcyURLConnection.java
com.spoledge.aacdecoder.IcyURLStreamHandler.java
com.spoledge.aacdecoder.MP3Player.java
com.spoledge.aacdecoder.MultiPlayer.java
com.spoledge.aacdecoder.PCMFeed.java
com.spoledge.aacdecoder.PlayerCallback.java