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

The following examples show how to use android.media.MediaCodec#releaseOutputBuffer() . 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: ConvertAudioStreamProvider.java    From vinyl-cast with MIT License 6 votes vote down vote up
/**
 * Handle reading encoded audio from MediaCodec OutputBuffer
 * @param codec
 * @param outputBufferId
 * @param info
 * @return number bytes read
 * @throws IOException
 */
private int dequeueCodecOutputBuffer(MediaCodec codec, int outputBufferId, MediaCodec.BufferInfo info) throws IOException {
    int outBitsSize = info.size;
    int outPacketSize = outBitsSize + 7;    // 7 is ADTS header size
    ByteBuffer outBuf = codec.getOutputBuffer(outputBufferId);

    outBuf.position(info.offset);
    outBuf.limit(info.offset + outBitsSize);

    byte[] packet = new byte[outPacketSize];
    addADTStoPacket(packet, outPacketSize);
    outBuf.get(packet, 7, outBitsSize);

    convertedAudioWriteStream.write(packet, 0, outPacketSize);
    convertedAudioWriteStream.flush();

    outBuf.clear();
    codec.releaseOutputBuffer(outputBufferId, false);

    return outBitsSize;
}
 
Example 2
Source File: MediaCodecVideoTrackRenderer.java    From Exoplayer_VLC with Apache License 2.0 6 votes vote down vote up
@TargetApi(21)
private void renderOutputBufferTimedV21(MediaCodec codec, int bufferIndex, long releaseTimeNs) {
  maybeNotifyVideoSizeChanged();
  TraceUtil.beginSection("releaseOutputBufferTimed");
  codec.releaseOutputBuffer(bufferIndex,false);// releaseTimeNs);
  TraceUtil.endSection();
  codecCounters.renderedOutputBufferCount++;
  maybeNotifyDrawnToSurface();
}
 
Example 3
Source File: EncodedAudioRecorder.java    From AlexaAndroid with GNU General Public License v2.0 6 votes vote down vote up
/**
 * Save the encoded (output) buffer into the complete encoded recording.
 * TODO: copy directly (without the intermediate byte array)
 */
@TargetApi(Build.VERSION_CODES.JELLY_BEAN)
private void dequeueOutputBuffer(MediaCodec codec, ByteBuffer[] outputBuffers, int index, MediaCodec.BufferInfo info) {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
        ByteBuffer buffer = outputBuffers[index];
        Log.i("size/remaining: " + info.size + "/" + buffer.remaining());
        if (info.size <= buffer.remaining()) {
            final byte[] bufferCopied = new byte[info.size];
            buffer.get(bufferCopied); // TODO: catch BufferUnderflow
            // TODO: do we need to clear?
            // on N5: always size == remaining(), clearing is not needed
            // on SGS2: remaining decreases until it becomes less than size, which results in BufferUnderflow
            // (but SGS2 records only zeros anyway)
            //buffer.clear();
            codec.releaseOutputBuffer(index, false);
            addEncoded(bufferCopied);
            if (Log.DEBUG) {
                AudioUtils.showSomeBytes("out", bufferCopied);
            }
        } else {
            Log.e("size > remaining");
            codec.releaseOutputBuffer(index, false);
        }
    }
}
 
Example 4
Source File: EncodedAudioRecorder.java    From speechutils with Apache License 2.0 6 votes vote down vote up
/**
 * Save the encoded (output) buffer into the complete encoded recording.
 * TODO: copy directly (without the intermediate byte array)
 */
@TargetApi(Build.VERSION_CODES.JELLY_BEAN)
private void dequeueOutputBuffer(MediaCodec codec, ByteBuffer[] outputBuffers, int index, MediaCodec.BufferInfo info) {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
        ByteBuffer buffer = outputBuffers[index];
        Log.i("size/remaining: " + info.size + "/" + buffer.remaining());
        if (info.size <= buffer.remaining()) {
            final byte[] bufferCopied = new byte[info.size];
            buffer.get(bufferCopied); // TODO: catch BufferUnderflow
            // TODO: do we need to clear?
            // on N5: always size == remaining(), clearing is not needed
            // on SGS2: remaining decreases until it becomes less than size, which results in BufferUnderflow
            // (but SGS2 records only zeros anyway)
            //buffer.clear();
            codec.releaseOutputBuffer(index, false);
            addEncoded(bufferCopied);
            if (Log.DEBUG) {
                AudioUtils.showSomeBytes("out", bufferCopied);
            }
        } else {
            Log.e("size > remaining");
            codec.releaseOutputBuffer(index, false);
        }
    }
}
 
Example 5
Source File: MediaCodecVideoRenderer.java    From K-Sonic with MIT License 5 votes vote down vote up
@TargetApi(21)
private void renderOutputBufferV21(MediaCodec codec, int bufferIndex, long releaseTimeNs) {
  maybeNotifyVideoSizeChanged();
  TraceUtil.beginSection("releaseOutputBuffer");
  codec.releaseOutputBuffer(bufferIndex, releaseTimeNs);
  TraceUtil.endSection();
  decoderCounters.renderedOutputBufferCount++;
  consecutiveDroppedFrameCount = 0;
  maybeNotifyRenderedFirstFrame();
}
 
Example 6
Source File: MediaCodecVideoRenderer.java    From Telegram with GNU General Public License v2.0 5 votes vote down vote up
/**
 * Renders the output buffer with the specified index. This method is only called if the platform
 * API version of the device is 21 or later.
 *
 * @param codec The codec that owns the output buffer.
 * @param index The index of the output buffer to drop.
 * @param presentationTimeUs The presentation time of the output buffer, in microseconds.
 * @param releaseTimeNs The wallclock time at which the frame should be displayed, in nanoseconds.
 */
@TargetApi(21)
protected void renderOutputBufferV21(
    MediaCodec codec, int index, long presentationTimeUs, long releaseTimeNs) {
  maybeNotifyVideoSizeChanged();
  TraceUtil.beginSection("releaseOutputBuffer");
  codec.releaseOutputBuffer(index, releaseTimeNs);
  TraceUtil.endSection();
  lastRenderTimeUs = SystemClock.elapsedRealtime() * 1000;
  decoderCounters.renderedOutputBufferCount++;
  consecutiveDroppedFrameCount = 0;
  maybeNotifyRenderedFirstFrame();
}
 
Example 7
Source File: FFmpegMuxer.java    From cineio-broadcast-android with MIT License 5 votes vote down vote up
@Override
public void writeSampleData(MediaCodec encoder, int trackIndex, int bufferIndex, ByteBuffer encodedData, MediaCodec.BufferInfo bufferInfo) {
    synchronized (mReadyFence) {
        if (mReady) {
            ByteBuffer muxerInput;
            if (formatRequiresBuffering()) {
                // Copy encodedData into another ByteBuffer, recycling if possible
                Log.i("THIS IS THE ENCODED DATA", encodedData.toString());
                Log.i("THIS IS THE TRACK INDEX", String.valueOf(trackIndex));
                synchronized (mMuxerInputQueue) {
                    muxerInput = mMuxerInputQueue.get(trackIndex).isEmpty() ?
                            ByteBuffer.allocateDirect(encodedData.capacity()) : mMuxerInputQueue.get(trackIndex).remove();
                }
                muxerInput.put(encodedData);
                muxerInput.position(0);
                encoder.releaseOutputBuffer(bufferIndex, false);
                mHandler.sendMessage(mHandler.obtainMessage(MSG_WRITE_FRAME,
                        new WritePacketData(encoder, trackIndex, bufferIndex, muxerInput, bufferInfo)));
            } else {
                handleWriteSampleData(encoder, trackIndex, bufferIndex, encodedData, bufferInfo);
            }

        } else {
            Log.w(TAG, "Dropping frame because Muxer not ready!");
            releaseOutputBufer(encoder, encodedData, bufferIndex, trackIndex);
            if (formatRequiresBuffering())
                encoder.releaseOutputBuffer(bufferIndex, false);
        }
    }
}
 
Example 8
Source File: AndroidMuxer.java    From kickflip-android-sdk with Apache License 2.0 5 votes vote down vote up
@Override
public void writeSampleData(MediaCodec encoder, int trackIndex, int bufferIndex, ByteBuffer encodedData, MediaCodec.BufferInfo bufferInfo) {
    super.writeSampleData(encoder, trackIndex, bufferIndex, encodedData, bufferInfo);
    if ((bufferInfo.flags & MediaCodec.BUFFER_FLAG_CODEC_CONFIG) != 0) {
        // MediaMuxer gets the codec config info via the addTrack command
        if (VERBOSE) Log.d(TAG, "ignoring BUFFER_FLAG_CODEC_CONFIG");
        encoder.releaseOutputBuffer(bufferIndex, false);
        return;
    }

    if(bufferInfo.size == 0){
        if(VERBOSE) Log.d(TAG, "ignoring zero size buffer");
        encoder.releaseOutputBuffer(bufferIndex, false);
        return;
    }

    if (!mStarted) {
        Log.e(TAG, "writeSampleData called before muxer started. Ignoring packet. Track index: " + trackIndex + " tracks added: " + mNumTracks);
        encoder.releaseOutputBuffer(bufferIndex, false);
        return;
    }

    bufferInfo.presentationTimeUs = getNextRelativePts(bufferInfo.presentationTimeUs, trackIndex);

    mMuxer.writeSampleData(trackIndex, encodedData, bufferInfo);

    encoder.releaseOutputBuffer(bufferIndex, false);

    if(allTracksFinished()){
        stop();
    }
}
 
Example 9
Source File: FFmpegMuxer.java    From cineio-broadcast-android with MIT License 5 votes vote down vote up
private void releaseOutputBufer(MediaCodec encoder, ByteBuffer encodedData, int bufferIndex, int trackIndex) {
    synchronized (mEncoderReleasedSync) {
        if (!mEncoderReleased) {
            if (formatRequiresBuffering()) {
                encodedData.clear();
                synchronized (mMuxerInputQueue) {
                    mMuxerInputQueue.get(trackIndex).add(encodedData);
                }
            } else {
                encoder.releaseOutputBuffer(bufferIndex, false);
            }
        }
    }
}
 
Example 10
Source File: MediaCodecVideoRenderer.java    From MediaSDK with Apache License 2.0 5 votes vote down vote up
/**
 * Renders the output buffer with the specified index. This method is only called if the platform
 * API version of the device is less than 21.
 *
 * @param codec The codec that owns the output buffer.
 * @param index The index of the output buffer to drop.
 * @param presentationTimeUs The presentation time of the output buffer, in microseconds.
 */
protected void renderOutputBuffer(MediaCodec codec, int index, long presentationTimeUs) {
  maybeNotifyVideoSizeChanged();
  TraceUtil.beginSection("releaseOutputBuffer");
  codec.releaseOutputBuffer(index, true);
  TraceUtil.endSection();
  lastRenderTimeUs = SystemClock.elapsedRealtime() * 1000;
  decoderCounters.renderedOutputBufferCount++;
  consecutiveDroppedFrameCount = 0;
  maybeNotifyRenderedFirstFrame();
}
 
Example 11
Source File: EncoderDebugger.java    From spydroid-ipcamera with GNU General Public License v3.0 5 votes vote down vote up
private void flushMediaCodec(MediaCodec mc) {
	int index = 0;
	BufferInfo info = new BufferInfo();
	while (index != MediaCodec.INFO_TRY_AGAIN_LATER) {
		index = mc.dequeueOutputBuffer(info, 1000000/FRAMERATE);
		if (index>=0) {
			mc.releaseOutputBuffer(index, false);
		}
	}
}
 
Example 12
Source File: ExtractMpegFramesTest_egl14.java    From Android-MediaCodec-Examples with Apache License 2.0 4 votes vote down vote up
/**
 * Work loop.
 */
static void doExtract(MediaExtractor extractor, int trackIndex, MediaCodec decoder,
        CodecOutputSurface outputSurface) throws IOException {
    final int TIMEOUT_USEC = 10000;
    ByteBuffer[] decoderInputBuffers = decoder.getInputBuffers();
    MediaCodec.BufferInfo info = new MediaCodec.BufferInfo();
    int inputChunk = 0;
    int decodeCount = 0;
    long frameSaveTime = 0;

    boolean outputDone = false;
    boolean inputDone = false;
    while (!outputDone) {
        if (VERBOSE) Log.d(TAG, "loop");

        // Feed more data to the decoder.
        if (!inputDone) {
            int inputBufIndex = decoder.dequeueInputBuffer(TIMEOUT_USEC);
            if (inputBufIndex >= 0) {
                ByteBuffer inputBuf = decoderInputBuffers[inputBufIndex];
                // Read the sample data into the ByteBuffer.  This neither respects nor
                // updates inputBuf's position, limit, etc.
                int chunkSize = extractor.readSampleData(inputBuf, 0);
                if (chunkSize < 0) {
                    // 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 {
                    if (extractor.getSampleTrackIndex() != trackIndex) {
                        Log.w(TAG, "WEIRD: got sample from track " +
                                extractor.getSampleTrackIndex() + ", expected " + trackIndex);
                    }
                    long presentationTimeUs = extractor.getSampleTime();
                    decoder.queueInputBuffer(inputBufIndex, 0, chunkSize,
                            presentationTimeUs, 0 /*flags*/);
                    if (VERBOSE) {
                        Log.d(TAG, "submitted frame " + inputChunk + " to dec, size=" +
                                chunkSize);
                    }
                    inputChunk++;
                    extractor.advance();
                }
            } 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) {
                // not important for us, since we're using Surface
                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
                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 decode of frame " + decodeCount);
                    outputSurface.awaitNewImage();
                    outputSurface.drawImage(true);

                    if (decodeCount < MAX_FRAMES) {
                        File outputFile = new File(FILES_DIR,
                                String.format("frame-%02d.png", decodeCount));
                        long startWhen = System.nanoTime();
                        outputSurface.saveFrame(outputFile.toString());
                        frameSaveTime += System.nanoTime() - startWhen;
                    }
                    decodeCount++;
                }
            }
        }
    }

    int numSaved = (MAX_FRAMES < decodeCount) ? MAX_FRAMES : decodeCount;
    Log.d(TAG, "Saving " + numSaved + " frames took " +
        (frameSaveTime / numSaved / 1000) + " us per frame");
}
 
Example 13
Source File: MediaPlayerGrabber.java    From VIA-AI with MIT License 4 votes vote down vote up
private void frameDisplay(MediaCodec decoder) {
        MediaCodec.BufferInfo info = new MediaCodec.BufferInfo();

        int srcColorFormat = 0;
        int srcStride = 0;
        int outputBufferId = decoder.dequeueOutputBuffer(info, DEFAULT_TIMEOUT_US);
        if (outputBufferId >= 0) {
            if ((info.flags & MediaCodec.BUFFER_FLAG_END_OF_STREAM) != 0) {
                sawOutputEOS = false;
            }

            boolean doRender = (info.size != 0);
            if (doRender) {
                outputFrameCount++;

                ByteBuffer b = null;
                Image image = null;

                if (Helper.isUpperThanAPI21()) {
                    image = decoder.getOutputImage(outputBufferId);
                    if(image!=null) {
//                        Log.d(TAG, "image:" + image.getWidth() + "," + image.getHeight() + "," + image.getFormat());
                    } else {
                        b = decoder.getOutputBuffer(outputBufferId);
                        MediaFormat format = decoder.getOutputFormat(outputBufferId);
                        srcColorFormat = format.getInteger(KEY_COLOR_FORMAT);
                        srcStride = format.getInteger(KEY_STRIDE);
                    }
                } else {
                    b = outputByteBuffers[outputBufferId];
                }

                if(time==-1) time = System.currentTimeMillis();
                else {
                    long diff = (System.currentTimeMillis()-time);
                    if(diff<33) {
                        //waitMs((33*1000-diff)/1000);
                        waitMs((33-diff));
                    }
                    time = System.currentTimeMillis();
                }

                if(callback!=null) {
                    if(image!=null) callback.onImageReady(image);
                    else if (b!=null) callback.onFrameReady(b,info.offset, width, height, srcColorFormat , srcStride);
                }

                decoder.releaseOutputBuffer(outputBufferId, false);
            }
        }
    }
 
Example 14
Source File: HeifReader.java    From heifreader with MIT License 4 votes vote down vote up
private static void renderHevcImage(ByteBuffer bitstream, ImageInfo info, Surface surface) {
    long beginTime = SystemClock.elapsedRealtimeNanos();

    // configure HEVC decoder
    MediaCodec decoder = configureDecoder(info, bitstream.limit(), surface);
    MediaFormat outputFormat = decoder.getOutputFormat();
    Log.d(TAG, "HEVC output-format=" + outputFormat);

    decoder.start();
    try {
        // set bitstream to decoder
        int inputBufferId = decoder.dequeueInputBuffer(-1);
        if (inputBufferId < 0) {
            throw new IllegalStateException("dequeueInputBuffer return " + inputBufferId);
        }
        ByteBuffer inBuffer = decoder.getInputBuffer(inputBufferId);
        inBuffer.put(bitstream);
        decoder.queueInputBuffer(inputBufferId, 0, bitstream.limit(), 0, 0);

        // notify end of stream
        inputBufferId = decoder.dequeueInputBuffer(-1);
        if (inputBufferId < 0) {
            throw new IllegalStateException("dequeueInputBuffer return " + inputBufferId);
        }
        decoder.queueInputBuffer(inputBufferId, 0, 0, 0, MediaCodec.BUFFER_FLAG_END_OF_STREAM);

        // get decoded image
        MediaCodec.BufferInfo bufferInfo = new MediaCodec.BufferInfo();
        while (true) {
            int outputBufferId = decoder.dequeueOutputBuffer(bufferInfo, -1);
            if (outputBufferId >= 0) {
                decoder.releaseOutputBuffer(outputBufferId, true);
                break;
            } else if (outputBufferId == MediaCodec.INFO_OUTPUT_FORMAT_CHANGED) {
                outputFormat = decoder.getOutputFormat();
                Log.d(TAG, "HEVC output-format=" + outputFormat);
            } else {
                Log.d(TAG, "HEVC dequeueOutputBuffer return " + outputBufferId);
            }
        }
        decoder.flush();
    } finally {
        decoder.stop();
        decoder.release();
    }
    long endTime = SystemClock.elapsedRealtimeNanos();
    Log.i(TAG, "HEVC decoding elapsed=" + (endTime - beginTime) / 1000000.f + "[msec]");
}
 
Example 15
Source File: AudioEncoder.java    From LiveMultimedia with Apache License 2.0 4 votes vote down vote up
private synchronized void dequeueOutputBuffer(
        MediaCodec codec, ByteBuffer[] outputBuffers,
        int index, MediaCodec.BufferInfo info) {
    codec.releaseOutputBuffer(index, false /* render */);
}
 
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: MediaCodecAudioRenderer.java    From MediaSDK with Apache License 2.0 4 votes vote down vote up
@Override
protected boolean processOutputBuffer(
    long positionUs,
    long elapsedRealtimeUs,
    MediaCodec codec,
    ByteBuffer buffer,
    int bufferIndex,
    int bufferFlags,
    long bufferPresentationTimeUs,
    boolean isDecodeOnlyBuffer,
    boolean isLastBuffer,
    Format format)
    throws ExoPlaybackException {
  if (codecNeedsEosBufferTimestampWorkaround
      && bufferPresentationTimeUs == 0
      && (bufferFlags & MediaCodec.BUFFER_FLAG_END_OF_STREAM) != 0
      && lastInputTimeUs != C.TIME_UNSET) {
    bufferPresentationTimeUs = lastInputTimeUs;
  }

  if (passthroughEnabled && (bufferFlags & MediaCodec.BUFFER_FLAG_CODEC_CONFIG) != 0) {
    // Discard output buffers from the passthrough (raw) decoder containing codec specific data.
    codec.releaseOutputBuffer(bufferIndex, false);
    return true;
  }

  if (isDecodeOnlyBuffer) {
    codec.releaseOutputBuffer(bufferIndex, false);
    decoderCounters.skippedOutputBufferCount++;
    audioSink.handleDiscontinuity();
    return true;
  }

  try {
    if (audioSink.handleBuffer(buffer, bufferPresentationTimeUs)) {
      codec.releaseOutputBuffer(bufferIndex, false);
      decoderCounters.renderedOutputBufferCount++;
      return true;
    }
  } catch (AudioSink.InitializationException | AudioSink.WriteException e) {
    // TODO(internal: b/145658993) Use outputFormat instead.
    throw createRendererException(e, inputFormat);
  }
  return false;
}
 
Example 18
Source File: BaseEncoder.java    From rtmp-rtsp-stream-client-java with Apache License 2.0 4 votes vote down vote up
private void processOutput(@NonNull ByteBuffer byteBuffer, @NonNull MediaCodec mediaCodec,
    int outBufferIndex, @NonNull MediaCodec.BufferInfo bufferInfo) throws IllegalStateException {
  checkBuffer(byteBuffer, bufferInfo);
  sendBuffer(byteBuffer, bufferInfo);
  mediaCodec.releaseOutputBuffer(outBufferIndex, false);
}
 
Example 19
Source File: MediaCodecVideoRenderer.java    From MediaSDK with Apache License 2.0 3 votes vote down vote up
/**
 * Skips the output buffer with the specified index.
 *
 * @param codec The codec that owns the output buffer.
 * @param index The index of the output buffer to skip.
 * @param presentationTimeUs The presentation time of the output buffer, in microseconds.
 */
protected void skipOutputBuffer(MediaCodec codec, int index, long presentationTimeUs) {
  TraceUtil.beginSection("skipVideoBuffer");
  codec.releaseOutputBuffer(index, false);
  TraceUtil.endSection();
  decoderCounters.skippedOutputBufferCount++;
}
 
Example 20
Source File: MediaCodecVideoRenderer.java    From TelePlus-Android with GNU General Public License v2.0 3 votes vote down vote up
/**
 * Drops the output buffer with the specified index.
 *
 * @param codec The codec that owns the output buffer.
 * @param index The index of the output buffer to drop.
 * @param presentationTimeUs The presentation time of the output buffer, in microseconds.
 */
protected void dropOutputBuffer(MediaCodec codec, int index, long presentationTimeUs) {
  TraceUtil.beginSection("dropVideoBuffer");
  codec.releaseOutputBuffer(index, false);
  TraceUtil.endSection();
  updateDroppedBufferCounters(1);
}