用于在android中缓冲编码音频的数据结构

时间:2014-06-11 10:55:04

标签: android audio decoding blockingqueue

我有TCP客户端通过套接字接收音频(编码)数据。我必须将接收到的数据保存在某个缓冲区中,并在解码器块请求块时提供给解码器。数据以byte []为单位,数组大小可以变化。我应该使用什么作为缓冲区来保持接收到的byte []块。 我知道BlockingQueue但它没有提供添加和检索N个字节[]。

Java是否为此提供了任何数据结构,我们可以使用ByteBuffer吗?

1 个答案:

答案 0 :(得分:1)

您的客户端是否知道字节数组大小的变化? 众所周知的方法(它需要您在服务器端进行管理)是使用以下字段将数据封装在数据包中:| TYPE | SIZE | DATA | 所以,假设客户端有一个打开的套接字连接并实例化一个DataInputStream(dataInputStream = new DataInputStream(socket.getInputStream())),客户端可以读取一个run方法是这样的线程中的数据:

@Override
public void run() {
    while(running) {

        int pckType = readPacketType();

        int pckSize = readPacketSize();

        byte[] data = readPacketContent(pckSize);

        // do something with data
        // you can use Semaphore instances in order to maintains a set of permits if needed
    }
}

,其中

private int readPacketType() {
    int result = -1;
    byte[] array = new byte[1];
    try {
        dataInputStream.read(array);
        result = (int)array[0];
    } catch (IOException ex) {
        return -1;
    }
    return result;
}

private int readPacketSize() {
    int result = -1;
    byte[] array = new byte[4];
    try {
        dataInputStream.read(array);
        result = ByteBuffer.wrap(array).getInt();
    } catch (IOException ex) {
        return -1;
    }
    return result;
}

private byte[] readPacketContent(int contentSize) {
    byte[] result = new byte[contentSize];
    try {
        dataInputStream.read(result);
    } catch (IOException ex) {}
    return result;
}

注意到我为TYPE字段分配了1个字节,为SIZE字段分配了4个字节

修改 您可以使用BlockingQueue接口的实现,如LinkedBlockingQueue。您可以放置​​不同大小的byte []并连贯地检索它们(保持顺序和大小)。按照简单的检查;)

LinkedBlockingQueue<byte[]> lbq = new LinkedBlockingQueue<byte[]>();
String str1 = "blablabla";
String str2 = "blabla";
try {
    lbq.put(str1.getBytes());
    lbq.put(str2.getBytes());
    lbq.put(str1.getBytes());
} catch (InterruptedException e) {
    e.printStackTrace();
}
byte[] b = null;
int size = lbq.size();
for(int i=0; i<size; i++) {
    try {
        b = lbq.take();
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
    System.out.println(b.length);
}