MediaCodec将文件从WAV转换为AMR无法播放

时间:2014-02-12 09:45:55

标签: android mediacodec

我正在使用MediaCodec.wav文件转换为.amr。我使用以下代码进行输入并获取编码缓冲区。我得到编码的文件,但它没有播放,我的输入是正确的,因为我能够在Audacity中播放该文件。我在android API测试中使用EncodeDecodeTest.java。任何指向潜在问题的指标都表示赞赏。

 MediaCodec codec = MediaCodec.createByCodecName(componentName);

    try {
        codec.configure(
                format,
                null /* surface */,
                null /* crypto */,
                MediaCodec.CONFIGURE_FLAG_ENCODE);
    } catch (IllegalStateException e) {
        AppLog.logString("codec '" + componentName + "' failed configuration.");

       // assertTrue("codec '" + componentName + "' failed configuration.", false);
    }

    codec.start();
    ByteBuffer[] codecInputBuffers = codec.getInputBuffers();
    ByteBuffer[] codecOutputBuffers = codec.getOutputBuffers();

    int numBytesSubmitted = 0;
    boolean doneSubmittingInput = false;
    int numBytesDequeued = 0;

    while (true) {
        int index =0 ;

        if (!doneSubmittingInput) {
            index = codec.dequeueInputBuffer(kTimeoutUs /* timeoutUs */);

            if (index != MediaCodec.INFO_TRY_AGAIN_LATER) {
                if (numBytesSubmitted >= filesize ){
                    codec.queueInputBuffer(
                            index,
                            0 /* offset */,
                            0 /* size */,
                            0 /* timeUs */,
                            MediaCodec.BUFFER_FLAG_END_OF_STREAM);

                    if (VERBOSE) {
                        AppLog.logString("queued input EOS.");
                    }

                    doneSubmittingInput = true;
                } else {
                    int inputsize = 0;
                    int size = 0;
                    if ((filesize - numBytesSubmitted) > codecInputBuffers[index]
                                .limit()) {
                            inputsize = codecInputBuffers[index].limit();
                        } else
                            inputsize = (int) (filesize - numBytesSubmitted);
                            size = queueInputBuffer(codec,
                                codecInputBuffers, index, in, inputsize);
                    numBytesSubmitted += size;
                    /*if (VERBOSE) {
                        AppLog.logString("queued " + size + " bytes of input data.");
                    }*/
                }
            }else
                 AppLog.logString("MediaCodec.INFO_TRY_AGAIN_LATER.");
        }

        MediaCodec.BufferInfo info = new MediaCodec.BufferInfo();
        index = codec.dequeueOutputBuffer(info, kTimeoutUs /* timeoutUs */);

        if (index == MediaCodec.INFO_TRY_AGAIN_LATER) {
        } else if (index == MediaCodec.INFO_OUTPUT_FORMAT_CHANGED) {
            AppLog.logString("INFO_OUTPUT_FORMAT_CHANGED");
            MediaFormat fmt = codec.getOutputFormat();
            AppLog.logString(fmt.getString(MediaFormat.KEY_MIME));
        } else if (index == MediaCodec.INFO_OUTPUT_BUFFERS_CHANGED) {
            codecOutputBuffers = codec.getOutputBuffers();
        } else {
            dequeueOutputBuffer(codec, codecOutputBuffers, index, info, fos);

            numBytesDequeued += info.size;

            if ((info.flags & MediaCodec.BUFFER_FLAG_END_OF_STREAM) != 0) {
                if (VERBOSE) {
                    AppLog.logString("dequeued output EOS.");
                }
                break;
            }

            if (VERBOSE) {
                AppLog.logString("dequeued " + info.size + " bytes of output data.");
            }
        }
    }

    if (VERBOSE) {
        AppLog.logString("queued a total of " + numBytesSubmitted + "bytes, "
                + "dequeued " + numBytesDequeued + " bytes.");
    }

    codec.release();
    codec = null;

queueInputBufferdequeueOutputBuffer的实施方式如下:

private int queueInputBuffer(
        MediaCodec codec, ByteBuffer[] inputBuffers, int index, FileInputStream in, int size) {
        ByteBuffer buffer = inputBuffers[index];
        buffer.clear();

       // int size = buffer.limit();
        AppLog.logString("Size is :" + size);
        byte[] data = new byte[size];
        try {
            in.read(data,0,size);
        } catch (IOException e) {
            e.printStackTrace();
        }
        buffer.put(data);
        buffer.flip();
        codec.queueInputBuffer(index, 0 /* offset */, size, 0 /* timeUs */, MediaCodec.BUFFER_FLAG_SYNC_FRAME);

        return size;
}

private void dequeueOutputBuffer(
        MediaCodec codec, ByteBuffer[] outputBuffers,
        int index, MediaCodec.BufferInfo info, FileOutputStream fos) {
    byte[] data= new byte[info.size];
    ByteBuffer out = outputBuffers[index];
    out.get(data);
    try {
        fos.write(data);
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    codec.releaseOutputBuffer(index, false /* render */);
}

0 个答案:

没有答案