@Override protected void onDisabled() throws ExoPlaybackException { inputBuffer = null; outputBuffer = null; format = null; audioSessionId = AudioTrack.SESSION_ID_NOT_SET; try { if (decoder != null) { decoder.release(); decoder = null; codecCounters.codecReleaseCount++; } audioTrack.release(); } finally { super.onDisabled(); } }
private boolean processOutput() throws ExoPlaybackException { if (mOutputStreamEnded) { return false; } if (!mOutputReady) { if (mInputStreamEnded) { mOutputStreamEnded = true; mEndOfStreamMs = SystemClock.elapsedRealtime(); return false; } return true; } ensureAudioTrackInitialized(); int handleBufferResult; try { // To reduce discontinuity, interpolate presentation time. mInterpolatedTimeUs = mPresentationTimeUs + mPresentationCount * AC3_SAMPLE_DURATION_US; handleBufferResult = AUDIO_TRACK.handleBuffer(mOutputBuffer, 0, mOutputBuffer.limit(), mInterpolatedTimeUs); } catch (AudioTrack.WriteException e) { notifyAudioTrackWriteError(e); throw new ExoPlaybackException(e); } if ((handleBufferResult & AudioTrack.RESULT_POSITION_DISCONTINUITY) != 0) { Log.i(TAG, "Play discontinuity happened"); mCurrentPositionUs = Long.MIN_VALUE; } if ((handleBufferResult & AudioTrack.RESULT_BUFFER_CONSUMED) != 0) { mCodecCounters.renderedOutputBufferCount++; mOutputReady = false; return true; } return false; }
@Override public long getPositionUs() { if (!AUDIO_TRACK.isInitialized()) { return mAudioClock.getPositionUs(); } else if (!AUDIO_TRACK.isEnabled()) { if (mInterpolatedTimeUs > 0) { return mInterpolatedTimeUs - ESTIMATED_TRACK_RENDERING_DELAY_US; } return mPresentationTimeUs; } long audioTrackCurrentPositionUs = AUDIO_TRACK.getCurrentPositionUs(isEnded()); if (audioTrackCurrentPositionUs == AudioTrack.CURRENT_POSITION_NOT_SET) { mPreviousPositionUs = 0L; if (DEBUG) { long oldPositionUs = Math.max(mCurrentPositionUs, 0); long currentPositionUs = Math.max(mPresentationTimeUs, mCurrentPositionUs); Log.d(TAG, "Audio position is not set, diff in us: " + String.valueOf(currentPositionUs - oldPositionUs)); } mCurrentPositionUs = Math.max(mPresentationTimeUs, mCurrentPositionUs); } else { if (mPreviousPositionUs > audioTrackCurrentPositionUs + BACKWARD_AUDIO_TRACK_MOVE_THRESHOLD_US) { Log.e(TAG, "audio_position BACK JUMP: " + (mPreviousPositionUs - audioTrackCurrentPositionUs)); mCurrentPositionUs = audioTrackCurrentPositionUs; } else { mCurrentPositionUs = Math.max(mCurrentPositionUs, audioTrackCurrentPositionUs); } mPreviousPositionUs = audioTrackCurrentPositionUs; } long upperBound = mPresentationTimeUs + CURRENT_POSITION_FROM_PTS_LIMIT_US; if (mCurrentPositionUs > upperBound) { mCurrentPositionUs = upperBound; } return mCurrentPositionUs; }
private void notifyAudioTrackInitializationError(final AudioTrack.InitializationException e) { if (mEventHandler == null || mEventListener == null) { return; } mEventHandler.post(new Runnable() { @Override public void run() { mEventListener.onAudioTrackInitializationError(e); } }); }
public void initialize() throws AudioTrack.InitializationException { if (!mIsEnabled) { return; } if (mAudioSessionID != AudioTrack.SESSION_ID_NOT_SET) { mAudioTrack.initialize(mAudioSessionID); } else { mAudioSessionID = mAudioTrack.initialize(); } }
public int handleBuffer(ByteBuffer buffer, int offset, int size, long presentationTimeUs) throws AudioTrack.WriteException { if (!mIsEnabled) { return AudioTrack.RESULT_BUFFER_CONSUMED; } return mAudioTrack.handleBuffer(buffer, offset, size, presentationTimeUs); }
@Override public long getPositionUs() { long newCurrentPositionUs = audioTrack.getCurrentPositionUs(isEnded()); if (newCurrentPositionUs != AudioTrack.CURRENT_POSITION_NOT_SET) { currentPositionUs = allowPositionDiscontinuity ? newCurrentPositionUs : Math.max(currentPositionUs, newCurrentPositionUs); allowPositionDiscontinuity = false; } return (long) (currentPositionUs * audioTrack.getPlaybackSpeed()); }
@Override protected void onDisabled() { audioSessionId = AudioTrack.SESSION_ID_NOT_SET; try { audioTrack.release(); } finally { super.onDisabled(); } }
private void notifyAudioTrackInitializationError(final AudioTrack.InitializationException e) { if (eventHandler != null && eventListener != null) { eventHandler.post(new Runnable() { @Override public void run() { eventListener.onAudioTrackInitializationError(e); } }); } }
private void notifyAudioTrackWriteError(final AudioTrack.WriteException e) { if (eventHandler != null && eventListener != null) { eventHandler.post(new Runnable() { @Override public void run() { eventListener.onAudioTrackWriteError(e); } }); } }
/** * @param source The upstream source from which the renderer obtains samples. * @param eventHandler A handler to use when delivering events to {@code eventListener}. May be * null if delivery of events is not required. * @param eventListener A listener of events. May be null if delivery of events is not required. */ public LibopusAudioTrackRenderer(SampleSource source, Handler eventHandler, EventListener eventListener) { super(source); this.eventHandler = eventHandler; this.eventListener = eventListener; this.audioSessionId = AudioTrack.SESSION_ID_NOT_SET; audioTrack = new AudioTrack(); formatHolder = new MediaFormatHolder(); }
@Override public long getPositionUs() { long newCurrentPositionUs = audioTrack.getCurrentPositionUs(isEnded()); if (newCurrentPositionUs != AudioTrack.CURRENT_POSITION_NOT_SET) { currentPositionUs = allowPositionDiscontinuity ? newCurrentPositionUs : Math.max(currentPositionUs, newCurrentPositionUs); allowPositionDiscontinuity = false; } return currentPositionUs; }
/** * @param source The upstream source from which the renderer obtains samples. * @param eventHandler A handler to use when delivering events to {@code eventListener}. May be * null if delivery of events is not required. * @param eventListener A listener of events. May be null if delivery of events is not required. */ public LibflacAudioTrackRenderer(SampleSource source, Handler eventHandler, EventListener eventListener) { super(source); this.eventHandler = eventHandler; this.eventListener = eventListener; this.audioSessionId = AudioTrack.SESSION_ID_NOT_SET; this.audioTrack = new AudioTrack(); formatHolder = new MediaFormatHolder(); }
@Override protected void onDisabled() throws ExoPlaybackException { audioSessionId = AudioTrack.SESSION_ID_NOT_SET; try { audioTrack.release(); } finally { super.onDisabled(); } }
@Override public void onAudioTrackInitializationError(AudioTrack.InitializationException e) { if (internalErrorListener != null) { internalErrorListener.onAudioTrackInitializationError(e); } }
@Override public void onAudioTrackWriteError(AudioTrack.WriteException e) { if (internalErrorListener != null) { internalErrorListener.onAudioTrackWriteError(e); } }
@Override public void onAudioTrackInitializationError(AudioTrack.InitializationException e) { printInternalError("audioTrackInitializationError", e); }
@Override public void onAudioTrackWriteError(AudioTrack.WriteException e) { printInternalError("audioTrackWriteError", e); }