【问题标题】:Data structure for buffering encoded audio in android在android中缓冲编码音频的数据结构
【发布时间】:2014-06-11 22:36:15
【问题描述】:

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

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

【问题讨论】:

    标签: android audio decoding blockingqueue


    【解决方案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);
    }
    

    【讨论】:

    • 我想我无法正确表达我的问题。我需要知道一个数据结构,我可以使用它来放置接收到的块(字节 []),直到实际开始解码。一旦解码开始,我想挑选那些块(字节[])并提供给解码器。我可以使用 BlockingQueue 但如何在读/写队列时指定字节 [] 大小?
    • 抱歉,我误解了这个问题,仍然不明白什么可以满足您的需求,因为我会使用 BlockingQueue 实例并将 byte[](不同大小)作为单个对象提供给它跨度>
    • 如果我使用 BlockingQueue,如何通过 put(object) 放置不同大小的 byte[] 数组,以及在 take(object) 中返回什么大小的 byte[] ? @bardi
    • LinkedBlockingQueue&lt;byte[]&gt; lbq = new LinkedBlockingQueue&lt;byte[]&gt;(); String str1 = "blablabla"; lbq.put(str1.getBytes()); byte[] b1 = null; b1 = lbq.take(); System.out.println(b1.length);
    • 是的,我检查过 BlockingQueue。我们可以将不同大小的 byte[] 放入队列中,并且在出队时,即 take(),它以与输入的相同长度 n 顺序返回 byte[]。编辑您的答案,我会接受。感谢您的帮助。
    猜你喜欢
    • 2011-11-02
    • 2014-09-08
    • 1970-01-01
    • 2011-06-01
    • 2017-07-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-09-28
    相关资源
    最近更新 更多