Java Code Examples for android.media.MediaCodec#getOutputBuffers()

The following examples show how to use android.media.MediaCodec#getOutputBuffers() . You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example 1
Source File: MediaMoviePlayer.java    From libcommon with Apache License 2.0 5 votes vote down vote up
/**
 * @param media_extractor
 * @param trackIndex
 * @return
 */
protected MediaCodec internal_start_audio(final MediaExtractor media_extractor, final int trackIndex) {
	if (DEBUG) Log.v(TAG, "internal_start_audio:");
	MediaCodec codec = null;
	if (trackIndex >= 0) {
        final MediaFormat format = media_extractor.getTrackFormat(trackIndex);
        final String mime = format.getString(MediaFormat.KEY_MIME);
		try {
			codec = MediaCodec.createDecoderByType(mime);
			codec.configure(format, null, null, 0);
	        codec.start();
	    	if (DEBUG) Log.v(TAG, "internal_start_audio:codec started");
	    	//
	        final ByteBuffer[] buffers = codec.getOutputBuffers();
	        int sz = buffers[0].capacity();
	        if (sz <= 0)
	        	sz = mAudioInputBufSize;
	        if (DEBUG) Log.v(TAG, "AudioOutputBufSize:" + sz);
	        mAudioOutTempBuf = new byte[sz];
		} catch (final IOException e) {
			Log.w(TAG, e);
		}
	}
	return codec;
}
 
Example 2
Source File: MediaCodecBufferCompatWrapper.java    From GPUVideo-android with MIT License 5 votes vote down vote up
MediaCodecBufferCompatWrapper(MediaCodec mediaCodec) {
    this.mediaCodec = mediaCodec;

    if (Build.VERSION.SDK_INT < 21) {
        inputBuffers = mediaCodec.getInputBuffers();
        putputBuffers = mediaCodec.getOutputBuffers();
    } else {
        inputBuffers = putputBuffers = null;
    }
}
 
Example 3
Source File: MediaCodecBufferCompatWrapper.java    From phoenix with Apache License 2.0 5 votes vote down vote up
public MediaCodecBufferCompatWrapper(MediaCodec mediaCodec) {
    mMediaCodec = mediaCodec;

    if (Build.VERSION.SDK_INT < 21) {
        mInputBuffers = mediaCodec.getInputBuffers();
        mOutputBuffers = mediaCodec.getOutputBuffers();
    } else {
        mInputBuffers = mOutputBuffers = null;
    }
}
 
Example 4
Source File: AudioCodec.java    From bcm-android with GNU General Public License v3.0 5 votes vote down vote up
private void handleCodecOutput(MediaCodec mediaCodec,
                               ByteBuffer[] codecOutputBuffers,
                               MediaCodec.BufferInfo bufferInfo,
                               OutputStream outputStream)
        throws IOException {
    int codecOutputBufferIndex = mediaCodec.dequeueOutputBuffer(bufferInfo, 0);

    while (codecOutputBufferIndex != MediaCodec.INFO_TRY_AGAIN_LATER) {
        if (codecOutputBufferIndex >= 0) {
            ByteBuffer encoderOutputBuffer = codecOutputBuffers[codecOutputBufferIndex];

            encoderOutputBuffer.position(bufferInfo.offset);
            encoderOutputBuffer.limit(bufferInfo.offset + bufferInfo.size);

            if ((bufferInfo.flags & MediaCodec.BUFFER_FLAG_CODEC_CONFIG) != MediaCodec.BUFFER_FLAG_CODEC_CONFIG) {
                byte[] header = createAdtsHeader(bufferInfo.size - bufferInfo.offset);


                outputStream.write(header);

                byte[] data = new byte[encoderOutputBuffer.remaining()];
                encoderOutputBuffer.get(data);
                outputStream.write(data);
            }

            encoderOutputBuffer.clear();

            mediaCodec.releaseOutputBuffer(codecOutputBufferIndex, false);
        } else if (codecOutputBufferIndex == MediaCodec.INFO_OUTPUT_BUFFERS_CHANGED) {
            codecOutputBuffers = mediaCodec.getOutputBuffers();
        }

        codecOutputBufferIndex = mediaCodec.dequeueOutputBuffer(bufferInfo, 0);
    }

}
 
Example 5
Source File: MediaCodecBufferCompatWrapper.java    From phoenix with Apache License 2.0 5 votes vote down vote up
public MediaCodecBufferCompatWrapper(MediaCodec mediaCodec) {
    mMediaCodec = mediaCodec;

    if (Build.VERSION.SDK_INT < 21) {
        mInputBuffers = mediaCodec.getInputBuffers();
        mOutputBuffers = mediaCodec.getOutputBuffers();
    } else {
        mInputBuffers = mOutputBuffers = null;
    }
}
 
Example 6
Source File: AudioCodec.java    From deltachat-android with GNU General Public License v3.0 5 votes vote down vote up
private void handleCodecOutput(MediaCodec mediaCodec,
                               ByteBuffer[] codecOutputBuffers,
                               MediaCodec.BufferInfo bufferInfo,
                               OutputStream outputStream)
    throws IOException
{
  int codecOutputBufferIndex = mediaCodec.dequeueOutputBuffer(bufferInfo, 0);

  while (codecOutputBufferIndex != MediaCodec.INFO_TRY_AGAIN_LATER) {
    if (codecOutputBufferIndex >= 0) {
      ByteBuffer encoderOutputBuffer = codecOutputBuffers[codecOutputBufferIndex];

      encoderOutputBuffer.position(bufferInfo.offset);
      encoderOutputBuffer.limit(bufferInfo.offset + bufferInfo.size);

      if ((bufferInfo.flags & MediaCodec.BUFFER_FLAG_CODEC_CONFIG) != MediaCodec.BUFFER_FLAG_CODEC_CONFIG) {
        byte[] header = createAdtsHeader(bufferInfo.size - bufferInfo.offset);


        outputStream.write(header);

        byte[] data = new byte[encoderOutputBuffer.remaining()];
        encoderOutputBuffer.get(data);
        outputStream.write(data);
      }

      encoderOutputBuffer.clear();

      mediaCodec.releaseOutputBuffer(codecOutputBufferIndex, false);
    }  else if (codecOutputBufferIndex== MediaCodec.INFO_OUTPUT_BUFFERS_CHANGED) {
      codecOutputBuffers = mediaCodec.getOutputBuffers();
    }

    codecOutputBufferIndex = mediaCodec.dequeueOutputBuffer(bufferInfo, 0);
  }

}
 
Example 7
Source File: MediaCodecWrapper.java    From ScreenCapture with MIT License 5 votes vote down vote up
private MediaCodecWrapper(MediaCodec codec) {
    mDecoder = codec;
    codec.start();
    mInputBuffers = codec.getInputBuffers();
    mOutputBuffers = codec.getOutputBuffers();
    mOutputBufferInfo = new MediaCodec.BufferInfo[mOutputBuffers.length];
    mAvailableInputBuffers = new ArrayDeque<>(mOutputBuffers.length);
    mAvailableOutputBuffers = new ArrayDeque<>(mInputBuffers.length);
}
 
Example 8
Source File: CodecUtil.java    From AAVT with Apache License 2.0 5 votes vote down vote up
public static ByteBuffer getOutputBuffer(MediaCodec codec, int index){
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
        return codec.getOutputBuffer(index);
    }else{
        return codec.getOutputBuffers()[index];
    }
}
 
Example 9
Source File: CameraRecorder.java    From AAVT with Apache License 2.0 5 votes vote down vote up
private ByteBuffer getOutputBuffer(MediaCodec codec, int index){
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
        return codec.getOutputBuffer(index);
    }else{
        return codec.getOutputBuffers()[index];
    }
}
 
Example 10
Source File: MediaCodecRenderer.java    From TelePlus-Android with GNU General Public License v2.0 4 votes vote down vote up
private void getCodecBuffers(MediaCodec codec) {
  if (Util.SDK_INT < 21) {
    inputBuffers = codec.getInputBuffers();
    outputBuffers = codec.getOutputBuffers();
  }
}
 
Example 11
Source File: AudioDecoder.java    From ssj with GNU General Public License v3.0 4 votes vote down vote up
/**
 * Decodes audio file into a raw file. This method accepts audio file formats with valid
 * headers (like .mp3, .mp4, and .wav).
 * @param filepath Path of the file to decode.
 * @return Decoded raw audio file.
 * @throws IOException when file cannot be read.
 */
private File decode(String filepath) throws IOException
{
	// Set selected audio file as a source.
	MediaExtractor extractor = new MediaExtractor();
	extractor.setDataSource(filepath);

	// Get audio format.
	MediaFormat format = extractor.getTrackFormat(0);
	String mime = format.getString(MediaFormat.KEY_MIME);

	// Cache necessary audio attributes.
	sampleRate = format.getInteger(MediaFormat.KEY_SAMPLE_RATE);
	channelCount = format.getInteger(MediaFormat.KEY_CHANNEL_COUNT);

	// Create and configure decoder based on audio format.
	MediaCodec decoder = MediaCodec.createDecoderByType(mime);
	decoder.configure(format, null, null, 0);
	decoder.start();

	// Create input/output buffers.
	ByteBuffer[] inputBuffers = decoder.getInputBuffers();
	ByteBuffer[] outputBuffers = decoder.getOutputBuffers();
	MediaCodec.BufferInfo bufferInfo = new MediaCodec.BufferInfo();
	extractor.selectTrack(0);

	File dst = new File(FileCons.SSJ_EXTERNAL_STORAGE + File.separator + "output.raw");
	FileOutputStream f = new FileOutputStream(dst);

	boolean endOfStreamReached = false;

	while (true)
	{
		if (!endOfStreamReached)
		{
			int inputBufferIndex = decoder.dequeueInputBuffer(10 * 1000);
			if (inputBufferIndex >= 0)
			{
				ByteBuffer inputBuffer = inputBuffers[inputBufferIndex];
				int sampleSize = extractor.readSampleData(inputBuffer, 0);
				if (sampleSize < 0)
				{
					// Pass empty buffer and the end of stream flag to the codec.
					decoder.queueInputBuffer(inputBufferIndex, 0, 0,
											 0, MediaCodec.BUFFER_FLAG_END_OF_STREAM);
					endOfStreamReached = true;
				}
				else
				{
					// Pass data-filled buffer to the decoder.
					decoder.queueInputBuffer(inputBufferIndex, 0, sampleSize,
											 extractor.getSampleTime(), 0);
					extractor.advance();
				}
			}
		}

		int outputBufferIndex = decoder.dequeueOutputBuffer(bufferInfo, 10 * 1000);
		if (outputBufferIndex >= 0)
		{
			ByteBuffer outputBuffer = outputBuffers[outputBufferIndex];
			byte[] data = new byte[bufferInfo.size];
			outputBuffer.get(data);
			outputBuffer.clear();

			if (data.length > 0)
			{
				f.write(data, 0, data.length);
			}
			decoder.releaseOutputBuffer(outputBufferIndex, false);

			if ((bufferInfo.flags & MediaCodec.BUFFER_FLAG_END_OF_STREAM) != 0)
			{
				endOfStreamReached = true;
			}
		}
		else if (outputBufferIndex == MediaCodec.INFO_OUTPUT_BUFFERS_CHANGED)
		{
			outputBuffers = decoder.getOutputBuffers();
		}

		if ((bufferInfo.flags & MediaCodec.BUFFER_FLAG_END_OF_STREAM) != 0)
		{
			return dst;
		}
	}
}
 
Example 12
Source File: ScreenRecoder.java    From ScreenRecoder with MIT License 4 votes vote down vote up
private void stream(MediaCodec codec) {
	BufferInfo info = new BufferInfo();
	ByteBuffer[] buffers = null;

	while (!mQuitting) {
		int index = codec.dequeueOutputBuffer(info, TIMEOUT_USEC);
		if (index >= 0) {
			if (buffers == null) {
				buffers = codec.getOutputBuffers();
			}

			ByteBuffer buffer = buffers[index];
			buffer.limit(info.offset + info.size);
			buffer.position(info.offset);

			muxer.writeSampleData(videoTrackIndex, buffer, info);

			codec.releaseOutputBuffer(index, false);
		} else if (index == MediaCodec.INFO_OUTPUT_FORMAT_CHANGED) {
			if (mMuxerStarted) {
				throw new RuntimeException("format changed twice");
			}
			
			MediaFormat newFormat = codec.getOutputFormat();

			// now that we have the Magic Goodies, start the muxer
			videoTrackIndex = muxer.addTrack(newFormat);
			muxer.start();

			mMuxerStarted = true;

			buffers = null;
		} else if (index == MediaCodec.INFO_OUTPUT_BUFFERS_CHANGED) {
			buffers = null;
		} else if (index == MediaCodec.INFO_TRY_AGAIN_LATER) {
			Log.e("sam", "Codec dequeue buffer timed out.");
		}
	}

	muxer.stop();
	muxer.release();
}
 
Example 13
Source File: MediaCodecRenderer.java    From Telegram-FOSS with GNU General Public License v2.0 4 votes vote down vote up
private void getCodecBuffers(MediaCodec codec) {
  if (Util.SDK_INT < 21) {
    inputBuffers = codec.getInputBuffers();
    outputBuffers = codec.getOutputBuffers();
  }
}
 
Example 14
Source File: EncodedAudioRecorder.java    From AlexaAndroid with GNU General Public License v2.0 4 votes vote down vote up
/**
 * Reads bytes from the given recorder and encodes them with the given encoder.
 * Uses the (deprecated) Synchronous Processing using Buffer Arrays.
 * <p/>
 * Encoders (or codecs that generate compressed data) will create and return the codec specific
 * data before any valid output buffer in output buffers marked with the codec-config flag.
 * Buffers containing codec-specific-data have no meaningful timestamps.
 */
@TargetApi(Build.VERSION_CODES.JELLY_BEAN)
private void recorderEncoderLoop(MediaCodec codec, SpeechRecord speechRecord) {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
        codec.start();
        // Getting some buffers (e.g. 4 of each) to communicate with the codec
        ByteBuffer[] codecInputBuffers = codec.getInputBuffers();
        ByteBuffer[] codecOutputBuffers = codec.getOutputBuffers();
        Log.i("input buffers " + codecInputBuffers.length + "; output buffers: " + codecOutputBuffers.length);
        boolean doneSubmittingInput = false;
        int numRetriesDequeueOutputBuffer = 0;
        int index;
        while (true) {
            if (!doneSubmittingInput) {
                index = codec.dequeueInputBuffer(DEQUEUE_TIMEOUT);
                if (index >= 0) {
                    int size = queueInputBuffer(codec, codecInputBuffers, index, speechRecord);
                    if (size == -1) {
                        codec.queueInputBuffer(index, 0, 0, 0, MediaCodec.BUFFER_FLAG_END_OF_STREAM);
                        Log.i("enc: in: EOS");
                        doneSubmittingInput = true;
                    } else {
                        Log.i("enc: in: " + size);
                        mNumBytesSubmitted += size;
                    }
                } else {
                    Log.i("enc: in: timeout, will try again");
                }
            }
            MediaCodec.BufferInfo info = new MediaCodec.BufferInfo();
            index = codec.dequeueOutputBuffer(info, DEQUEUE_TIMEOUT);
            Log.i("enc: out: flags/index: " + info.flags + "/" + index);
            if (index == MediaCodec.INFO_TRY_AGAIN_LATER) {
                Log.i("enc: out: INFO_TRY_AGAIN_LATER: " + numRetriesDequeueOutputBuffer);
                if (++numRetriesDequeueOutputBuffer > MAX_NUM_RETRIES_DEQUEUE_OUTPUT_BUFFER) {
                    break;
                }
            } else if (index == MediaCodec.INFO_OUTPUT_FORMAT_CHANGED) {
                MediaFormat format = codec.getOutputFormat();
                Log.i("enc: out: INFO_OUTPUT_FORMAT_CHANGED: " + format.toString());
            } else if (index == MediaCodec.INFO_OUTPUT_BUFFERS_CHANGED) {
                codecOutputBuffers = codec.getOutputBuffers();
                Log.i("enc: out: INFO_OUTPUT_BUFFERS_CHANGED");
            } else {
                dequeueOutputBuffer(codec, codecOutputBuffers, index, info);
                mNumBytesDequeued += info.size;
                if ((info.flags & MediaCodec.BUFFER_FLAG_END_OF_STREAM) != 0) {
                    Log.i("enc: out: EOS");
                    break;
                }
            }
        }
        codec.stop();
        codec.release();
    }
}
 
Example 15
Source File: EncodedAudioRecorder.java    From AlexaAndroid with GNU General Public License v2.0 4 votes vote down vote up
/**
 * Reads bytes from the given recorder and encodes them with the given encoder.
 * Uses the (deprecated) Synchronous Processing using Buffer Arrays.
 * <p/>
 * Encoders (or codecs that generate compressed data) will create and return the codec specific
 * data before any valid output buffer in output buffers marked with the codec-config flag.
 * Buffers containing codec-specific-data have no meaningful timestamps.
 */
@TargetApi(Build.VERSION_CODES.JELLY_BEAN)
private void recorderEncoderLoop(MediaCodec codec, SpeechRecord speechRecord) {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
        codec.start();
        // Getting some buffers (e.g. 4 of each) to communicate with the codec
        ByteBuffer[] codecInputBuffers = codec.getInputBuffers();
        ByteBuffer[] codecOutputBuffers = codec.getOutputBuffers();
        Log.i("input buffers " + codecInputBuffers.length + "; output buffers: " + codecOutputBuffers.length);
        boolean doneSubmittingInput = false;
        int numRetriesDequeueOutputBuffer = 0;
        int index;
        while (true) {
            if (!doneSubmittingInput) {
                index = codec.dequeueInputBuffer(DEQUEUE_TIMEOUT);
                if (index >= 0) {
                    int size = queueInputBuffer(codec, codecInputBuffers, index, speechRecord);
                    if (size == -1) {
                        codec.queueInputBuffer(index, 0, 0, 0, MediaCodec.BUFFER_FLAG_END_OF_STREAM);
                        Log.i("enc: in: EOS");
                        doneSubmittingInput = true;
                    } else {
                        Log.i("enc: in: " + size);
                        mNumBytesSubmitted += size;
                    }
                } else {
                    Log.i("enc: in: timeout, will try again");
                }
            }
            MediaCodec.BufferInfo info = new MediaCodec.BufferInfo();
            index = codec.dequeueOutputBuffer(info, DEQUEUE_TIMEOUT);
            Log.i("enc: out: flags/index: " + info.flags + "/" + index);
            if (index == MediaCodec.INFO_TRY_AGAIN_LATER) {
                Log.i("enc: out: INFO_TRY_AGAIN_LATER: " + numRetriesDequeueOutputBuffer);
                if (++numRetriesDequeueOutputBuffer > MAX_NUM_RETRIES_DEQUEUE_OUTPUT_BUFFER) {
                    break;
                }
            } else if (index == MediaCodec.INFO_OUTPUT_FORMAT_CHANGED) {
                MediaFormat format = codec.getOutputFormat();
                Log.i("enc: out: INFO_OUTPUT_FORMAT_CHANGED: " + format.toString());
            } else if (index == MediaCodec.INFO_OUTPUT_BUFFERS_CHANGED) {
                codecOutputBuffers = codec.getOutputBuffers();
                Log.i("enc: out: INFO_OUTPUT_BUFFERS_CHANGED");
            } else {
                dequeueOutputBuffer(codec, codecOutputBuffers, index, info);
                mNumBytesDequeued += info.size;
                if ((info.flags & MediaCodec.BUFFER_FLAG_END_OF_STREAM) != 0) {
                    Log.i("enc: out: EOS");
                    break;
                }
            }
        }
        codec.stop();
        codec.release();
    }
}
 
Example 16
Source File: AudioRecordThread.java    From PhotoMovie with Apache License 2.0 4 votes vote down vote up
/**
 * 需要改变音频速率的情况下,需要先解码->改变速率->编码
 */
private void decodeToPCM(MediaCodec decoder, MediaExtractor extractor, MediaFormat oriAudioFormat, String outPath, Long endTimeUs) throws IOException {
    int maxBufferSize = getAudioMaxBufferSize(oriAudioFormat);
    ByteBuffer buffer = ByteBuffer.allocateDirect(maxBufferSize);
    MediaCodec.BufferInfo info = new MediaCodec.BufferInfo();

    //调整音频速率需要重解码音频帧
    decoder.configure(oriAudioFormat, null, null, 0);
    decoder.start();

    boolean decodeDone = false;
    boolean decodeInputDone = false;
    final int TIMEOUT_US = 2500;
    File pcmFile = new File(outPath);
    FileChannel writeChannel = new FileOutputStream(pcmFile).getChannel();
    ByteBuffer[] inputBuffers = null;
    ByteBuffer[] outputBuffers = null;

    try {
        while (!decodeDone) {
            if (!decodeInputDone) {
                boolean eof = false;
                int decodeInputIndex = decoder.dequeueInputBuffer(TIMEOUT_US);
                if (Build.VERSION.SDK_INT < 21 && decodeInputIndex == MediaCodec.INFO_OUTPUT_BUFFERS_CHANGED) {
                    outputBuffers = decoder.getOutputBuffers();
                    inputBuffers = decoder.getInputBuffers();
                } else if (decodeInputIndex >= 0) {
                    long sampleTimeUs = extractor.getSampleTime();
                    if (sampleTimeUs == -1) {
                        eof = true;
                    } else if (endTimeUs != null && sampleTimeUs > endTimeUs) {
                        eof = true;
                    }

                    if (eof) {
                        decodeInputDone = true;
                        decoder.queueInputBuffer(decodeInputIndex, 0, 0, 0, MediaCodec.BUFFER_FLAG_END_OF_STREAM);
                    } else {
                        info.size = extractor.readSampleData(buffer, 0);
                        info.presentationTimeUs = sampleTimeUs;
                        info.flags = extractor.getSampleFlags();
                        ByteBuffer inputBuffer = null;
                        if (android.os.Build.VERSION.SDK_INT >= 21) {
                            inputBuffer = decoder.getInputBuffer(decodeInputIndex);
                        } else {
                            inputBuffer = inputBuffers[decodeInputIndex];
                        }
                        inputBuffer.put(buffer);
                        MLog.i(TAG, "audio decode queueInputBuffer " + info.presentationTimeUs / 1000);
                        decoder.queueInputBuffer(decodeInputIndex, 0, info.size, info.presentationTimeUs, info.flags);
                        extractor.advance();
                    }

                }
            }

            while (!decodeDone) {
                int outputBufferIndex = decoder.dequeueOutputBuffer(info, TIMEOUT_US);
                if (outputBufferIndex == MediaCodec.INFO_TRY_AGAIN_LATER) {
                    break;
                } else if (outputBufferIndex == MediaCodec.INFO_OUTPUT_FORMAT_CHANGED) {
                    MediaFormat newFormat = decoder.getOutputFormat();
                    MLog.i(TAG, "audio decode newFormat = " + newFormat);
                } else if (outputBufferIndex < 0) {
                    //ignore
                    MLog.e(TAG, "unexpected result from audio decoder.dequeueOutputBuffer: " + outputBufferIndex);
                } else {
                    if (info.flags == MediaCodec.BUFFER_FLAG_END_OF_STREAM) {
                        decodeDone = true;
                    } else {
                        ByteBuffer decodeOutputBuffer = null;
                        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) {
                            decodeOutputBuffer = decoder.getOutputBuffer(outputBufferIndex);
                        } else {
                            decodeOutputBuffer = outputBuffers[outputBufferIndex];
                        }
                        MLog.i(TAG, "audio decode saveFrame " + info.presentationTimeUs / 1000);
                        writeChannel.write(decodeOutputBuffer);
                    }
                    decoder.releaseOutputBuffer(outputBufferIndex, false);
                }
            }
        }
    } finally {
        writeChannel.close();
        extractor.release();
        decoder.stop();
        decoder.release();
    }
}
 
Example 17
Source File: MediaCodecRenderer.java    From Telegram with GNU General Public License v2.0 4 votes vote down vote up
private void getCodecBuffers(MediaCodec codec) {
  if (Util.SDK_INT < 21) {
    inputBuffers = codec.getInputBuffers();
    outputBuffers = codec.getOutputBuffers();
  }
}
 
Example 18
Source File: DecodeEditEncodeTest.java    From Android-MediaCodec-Examples with Apache License 2.0 4 votes vote down vote up
/**
 * Checks the video data.
 *
 * @return the number of bad frames
 */
private int checkVideoData(VideoChunks inputData, MediaCodec decoder, OutputSurface surface) {
    final int TIMEOUT_USEC = 1000;
    ByteBuffer[] decoderInputBuffers = decoder.getInputBuffers();
    ByteBuffer[] decoderOutputBuffers = decoder.getOutputBuffers();
    MediaCodec.BufferInfo info = new MediaCodec.BufferInfo();
    int inputChunk = 0;
    int checkIndex = 0;
    int badFrames = 0;
    boolean outputDone = false;
    boolean inputDone = false;
    while (!outputDone) {
        if (VERBOSE) Log.d(TAG, "check loop");
        // Feed more data to the decoder.
        if (!inputDone) {
            int inputBufIndex = decoder.dequeueInputBuffer(TIMEOUT_USEC);
            if (inputBufIndex >= 0) {
                if (inputChunk == inputData.getNumChunks()) {
                    // End of stream -- send empty frame with EOS flag set.
                    decoder.queueInputBuffer(inputBufIndex, 0, 0, 0L,
                            MediaCodec.BUFFER_FLAG_END_OF_STREAM);
                    inputDone = true;
                    if (VERBOSE) Log.d(TAG, "sent input EOS");
                } else {
                    // Copy a chunk of input to the decoder.  The first chunk should have
                    // the BUFFER_FLAG_CODEC_CONFIG flag set.
                    ByteBuffer inputBuf = decoderInputBuffers[inputBufIndex];
                    inputBuf.clear();
                    inputData.getChunkData(inputChunk, inputBuf);
                    int flags = inputData.getChunkFlags(inputChunk);
                    long time = inputData.getChunkTime(inputChunk);
                    decoder.queueInputBuffer(inputBufIndex, 0, inputBuf.position(),
                            time, flags);
                    if (VERBOSE) {
                        Log.d(TAG, "submitted frame " + inputChunk + " to dec, size=" +
                                inputBuf.position() + " flags=" + flags);
                    }
                    inputChunk++;
                }
            } else {
                if (VERBOSE) Log.d(TAG, "input buffer not available");
            }
        }
        if (!outputDone) {
            int decoderStatus = decoder.dequeueOutputBuffer(info, TIMEOUT_USEC);
            if (decoderStatus == MediaCodec.INFO_TRY_AGAIN_LATER) {
                // no output available yet
                if (VERBOSE) Log.d(TAG, "no output from decoder available");
            } else if (decoderStatus == MediaCodec.INFO_OUTPUT_BUFFERS_CHANGED) {
                decoderOutputBuffers = decoder.getOutputBuffers();
                if (VERBOSE) Log.d(TAG, "decoder output buffers changed");
            } else if (decoderStatus == MediaCodec.INFO_OUTPUT_FORMAT_CHANGED) {
                MediaFormat newFormat = decoder.getOutputFormat();
                if (VERBOSE) Log.d(TAG, "decoder output format changed: " + newFormat);
            } else if (decoderStatus < 0) {
                fail("unexpected result from decoder.dequeueOutputBuffer: " + decoderStatus);
            } else { // decoderStatus >= 0
                ByteBuffer decodedData = decoderOutputBuffers[decoderStatus];
                if (VERBOSE) Log.d(TAG, "surface decoder given buffer " + decoderStatus +
                        " (size=" + info.size + ")");
                if ((info.flags & MediaCodec.BUFFER_FLAG_END_OF_STREAM) != 0) {
                    if (VERBOSE) Log.d(TAG, "output EOS");
                    outputDone = true;
                }
                boolean doRender = (info.size != 0);
                // As soon as we call releaseOutputBuffer, the buffer will be forwarded
                // to SurfaceTexture to convert to a texture.  The API doesn't guarantee
                // that the texture will be available before the call returns, so we
                // need to wait for the onFrameAvailable callback to fire.
                decoder.releaseOutputBuffer(decoderStatus, doRender);
                if (doRender) {
                    if (VERBOSE) Log.d(TAG, "awaiting frame " + checkIndex);
                    assertEquals("Wrong time stamp", computePresentationTime(checkIndex),
                            info.presentationTimeUs);
                    surface.awaitNewImage();
                    surface.drawImage();
                    if (!checkSurfaceFrame(checkIndex++)) {
                        badFrames++;
                    }
                }
            }
        }
    }
    return badFrames;
}
 
Example 19
Source File: MediaPlayerGrabber.java    From VIA-AI with MIT License 4 votes vote down vote up
private void decodeFrames(final MediaCodec decoder, MediaExtractor extractor, MediaFormat mediaFormat) {
    boolean sawInputEOS = false;
    sawOutputEOS = false;
    decoder.configure(mediaFormat, null, null, 0);
    decoder.start();

    if(!Helper.isUpperThanAPI21()) {
        inputByteBuffers = decoder.getInputBuffers();
        outputByteBuffers = decoder.getOutputBuffers();
    }

    while (!sawOutputEOS && !stopDecode) {
        if (!sawInputEOS) {
            int inputBufferId = decoder.dequeueInputBuffer(DEFAULT_TIMEOUT_US);
            if (inputBufferId >= 0) {
                ByteBuffer inputBuffer = null;
                if (Helper.isUpperThanAPI21()) {
                    inputBuffer = decoder.getInputBuffer(inputBufferId);
                } else {
                    inputBuffer = inputByteBuffers[inputBufferId];
                }

                int sampleSize = extractor.readSampleData(inputBuffer, 0);
                if (sampleSize < 0) {
                    decoder.queueInputBuffer(inputBufferId, 0, 0, 0L, 0);
                    sawInputEOS = false;
                    extractor.seekTo(0, MediaExtractor.SEEK_TO_PREVIOUS_SYNC);
                } else {
                    long presentationTimeUs = extractor.getSampleTime();
                    decoder.queueInputBuffer(inputBufferId, 0, sampleSize, presentationTimeUs, 0);
                    extractor.advance();
                }
            }

        }

        if(displayThread==null) {
            displayThread = new Thread(new Runnable() {
                @Override
                public void run() {
                    while (!sawOutputEOS && !stopDisplay) {
                        frameDisplay(decoder);
                    }
                }
            });
            displayThread.start();
        }
    }

}
 
Example 20
Source File: EncodedAudioRecorder.java    From speechutils with Apache License 2.0 4 votes vote down vote up
/**
 * Reads bytes from the given recorder and encodes them with the given encoder.
 * Uses the (deprecated) Synchronous Processing using Buffer Arrays.
 * <p/>
 * Encoders (or codecs that generate compressed data) will create and return the codec specific
 * data before any valid output buffer in output buffers marked with the codec-config flag.
 * Buffers containing codec-specific-data have no meaningful timestamps.
 */
@TargetApi(Build.VERSION_CODES.JELLY_BEAN)
private int recorderEncoderLoop(MediaCodec codec, SpeechRecord speechRecord) {
    int status = -1;
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
        codec.start();
        // Getting some buffers (e.g. 4 of each) to communicate with the codec
        ByteBuffer[] codecInputBuffers = codec.getInputBuffers();
        ByteBuffer[] codecOutputBuffers = codec.getOutputBuffers();
        Log.i("input buffers " + codecInputBuffers.length + "; output buffers: " + codecOutputBuffers.length);
        boolean doneSubmittingInput = false;
        int numDequeueOutputBufferTimeout = 0;
        int index;
        while (true) {
            if (!doneSubmittingInput) {
                index = codec.dequeueInputBuffer(DEQUEUE_INPUT_BUFFER_TIMEOUT);
                if (index >= 0) {
                    int size = queueInputBuffer(codec, codecInputBuffers, index, speechRecord);
                    if (size == -1) {
                        codec.queueInputBuffer(index, 0, 0, 0, MediaCodec.BUFFER_FLAG_END_OF_STREAM);
                        Log.i("enc: in: EOS");
                        doneSubmittingInput = true;
                    } else {
                        Log.i("enc: in: " + size);
                        mNumBytesSubmitted += size;
                    }
                } else {
                    Log.i("enc: in: timeout, will try again");
                }
            }
            MediaCodec.BufferInfo info = new MediaCodec.BufferInfo();
            index = codec.dequeueOutputBuffer(info, DEQUEUE_OUTPUT_BUFFER_TIMEOUT);
            Log.i("enc: out: flags/index: " + info.flags + "/" + index);
            if (index == MediaCodec.INFO_TRY_AGAIN_LATER) {
                numDequeueOutputBufferTimeout++;
                Log.i("enc: out: INFO_TRY_AGAIN_LATER: " + numDequeueOutputBufferTimeout);
                if (numDequeueOutputBufferTimeout > MAX_NUM_RETRIES_DEQUEUE_OUTPUT_BUFFER) {
                    break;
                }
            } else if (index == MediaCodec.INFO_OUTPUT_FORMAT_CHANGED) {
                MediaFormat format = codec.getOutputFormat();
                Log.i("enc: out: INFO_OUTPUT_FORMAT_CHANGED: " + format.toString());
            } else if (index == MediaCodec.INFO_OUTPUT_BUFFERS_CHANGED) {
                codecOutputBuffers = codec.getOutputBuffers();
                Log.i("enc: out: INFO_OUTPUT_BUFFERS_CHANGED");
            } else {
                dequeueOutputBuffer(codec, codecOutputBuffers, index, info);
                mNumBytesDequeued += info.size;
                numDequeueOutputBufferTimeout = 0;
                if ((info.flags & MediaCodec.BUFFER_FLAG_END_OF_STREAM) != 0) {
                    Log.i("enc: out: EOS");
                    status = 0;
                    break;
                }
            }
        }
        codec.stop();
        codec.release();
        Log.i("stopped and released codec");
    }
    return status;
}