N
N
nuclear_kote2020-06-03 22:38:30
Android
nuclear_kote, 2020-06-03 22:38:30

Why does dequeueInputBuffer throw IllegalStateException?

public class AACDecoderUtil {


    private static final String TAG = "AACDecoderUtil";
    //Channels
    private static final int KEY_CHANNEL_COUNT = 2;
    //sampling rate
    private static final int KEY_SAMPLE_RATE = 48000;
    //pcm for playback and decoding
    private MyAudioTrack mPlayer;
    //Decoder
    private MediaCodec mDecoder;
    //Number of frames used to record decoding failures
    private int count = 0;
    private String tag;

    public AACDecoderUtil(String tag) {
        tag = tag;
    }

    /**
     * Initialize all variables
     */
    public void start() {
        prepare();
    }

    /**
     * Initial decoder
     *
     * @return Initialization failure returns false and success returns true
     */
    public boolean prepare() {
        // Initialize AudioTrack
        mPlayer = new MyAudioTrack(KEY_SAMPLE_RATE, AudioFormat.CHANNEL_OUT_STEREO, AudioFormat.ENCODING_PCM_16BIT);
        mPlayer.init();
        try {
            //Types of data to be decoded
            String mine = "audio/mp4a-latm";
            //Initial decoder
            mDecoder = MediaCodec.createDecoderByType(mine);
            //MediaFormat is used to describe the relevant parameters of audio and video data
            MediaFormat mediaFormat = new MediaFormat();
            //data type
            mediaFormat.setString(MediaFormat.KEY_MIME, mine);
            //Number of vocal tracts
            mediaFormat.setInteger(MediaFormat.KEY_CHANNEL_COUNT, KEY_CHANNEL_COUNT);
            //sampling rate
            mediaFormat.setInteger(MediaFormat.KEY_SAMPLE_RATE,KEY_SAMPLE_RATE);
            //bit rate
            mediaFormat.setInteger(MediaFormat.KEY_BIT_RATE, 128000);
            //Used to mark whether AAC has an adts header, 1 - > Yes.
            mediaFormat.setInteger(MediaFormat.KEY_IS_ADTS, 1);
            //Types used to mark aac
            mediaFormat.setInteger(MediaFormat.KEY_AAC_PROFILE, MediaCodecInfo.CodecProfileLevel.AACObjectLC);
            //ByteBuffer key
            byte[] data = new byte[]{(byte) 0x11, (byte) 0x90};
            ByteBuffer csd_0 = ByteBuffer.wrap(data);
            mediaFormat.setByteBuffer("csd-0", csd_0);
            //Decoder configuration
            mDecoder.configure(mediaFormat, null, null, 0);
        } catch (IOException e) {
            e.printStackTrace();
            return false;
        }
        if (mDecoder == null) {
            return false;
        }
        mDecoder.start();
        return true;
    }

    /**
     * aac Decode + Play
     */
    public void decode(byte[] buf, int offset, int length) {
        //Enter ByteBuffer
        ByteBuffer[] codecInputBuffers = mDecoder.getInputBuffers();
        //Output ByteBuffer
        ByteBuffer[] codecOutputBuffers = mDecoder.getOutputBuffers();
        //Waiting time, 0 - > No waiting, - 1 - > Waiting all the time
        long kTimeOutUs = 0;
        try {
            //Returns an index of an input buffer containing valid data, - 1 - > does not exist
            int inputBufIndex = mDecoder.dequeueInputBuffer(kTimeOutUs);
            if (inputBufIndex >= 0) {
                //Get the current ByteBuffer
                ByteBuffer dstBuf = codecInputBuffers[inputBufIndex];
                //Empty ByteBuffer
                dstBuf.clear();
                //Fill in data
                dstBuf.put(buf, offset, length);
                //Submit the input buffer of the specified index to the decoder
                mDecoder.queueInputBuffer(inputBufIndex, 0, length, 0, 0);
            }
            //Codec Buffer
            MediaCodec.BufferInfo info = new MediaCodec.BufferInfo();
            //Returns an output buffer index, - 1 - > does not exist
            int outputBufferIndex = mDecoder.dequeueOutputBuffer(info, kTimeOutUs);

            if (outputBufferIndex < 0) {
                //Record the number of decoding failures
                count++;
            }
            ByteBuffer outputBuffer;
            while (outputBufferIndex >= 0) {
                //Get the decoded ByteBuffer
                outputBuffer = codecOutputBuffers[outputBufferIndex];
                //Used to save decoded data
                byte[] outData = new byte[info.size];
                outputBuffer.get(outData);
                //wipe cache
                outputBuffer.clear();
                //Play decoded data
                mPlayer.playAudioTrack(outData, 0, info.size);
                //Release decoded buffer
                mDecoder.releaseOutputBuffer(outputBufferIndex, false);
                //Decode incomplete data
                outputBufferIndex = mDecoder.dequeueOutputBuffer(info, kTimeOutUs);
            }
        } catch (Exception e) {
            Log.e(TAG, e.toString());
            e.printStackTrace();
        }
    }

    //Returns the number of decoding failures
    public int getCount() {
        return count;
    }

    /**
     * Releasing resources
     */
    public void stop() {
        try {
            if (mPlayer != null) {
                mPlayer.release();
                mPlayer = null;
            }
            if (mDecoder != null) {
                mDecoder.stop();
                mDecoder.release();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}


E/AACDecoderUtil: java.lang.IllegalStateException
W/System.err: java.lang.IllegalStateException
W/System.err:     at android.media.MediaCodec.native_dequeueInputBuffer(Native Method)
W/System.err:     at android.media.MediaCodec.dequeueInputBuffer(MediaCodec.java:2644)
        at ru.example.cap_voice_player_recorder.AACDecoderUtil.decode(AACDecoderUtil.java:117)

Answer the question

In order to leave comments, you need to log in

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question