Skip to content

Commit

Permalink
[android] Handle mediacodec callback with a handler thread
Browse files Browse the repository at this point in the history
Now the MediaCodec callbacks and the activity lifecycle callbacks
are called on the main thread. When pausing YouTube, the MediaCodec
callbacks may be blocked until the lifecycle callbacks are done.
This may cause frame drops on a resource-limited device when the
MediaCodec callback to notify a newly decoded frame is blocked and
we run out of decoded frames. Running the MediaCodec callbacks on a
handler thread could avoid this problem.

Change-Id: I5ffdb1f5a582c3d01964b3f98c99d7aed211674a
  • Loading branch information
mingchou committed Dec 5, 2023
1 parent 0cc8357 commit fb9e04c
Showing 1 changed file with 10 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@
import android.media.MediaFormat;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.HandlerThread;
import android.view.Surface;
import androidx.annotation.Nullable;
import dev.cobalt.util.Log;
Expand Down Expand Up @@ -93,6 +95,9 @@ class MediaCodecBridge {
// which would cause GC cycles long enough to impact playback.
private final MediaCodec.BufferInfo info = new MediaCodec.BufferInfo();

private final Handler mHandler;
private final HandlerThread mHandlerThread;

// Type of bitrate adjustment for video encoder.
public enum BitrateAdjustmentTypes {
// No adjustment - video encoder has no known bitrate problem.
Expand Down Expand Up @@ -461,6 +466,9 @@ private MediaCodecBridge(
mLastPresentationTimeUs = 0;
mFlushed = true;
mBitrateAdjustmentType = bitrateAdjustmentType;
mHandlerThread = new HandlerThread("DecodeHandler");
mHandlerThread.start();
mHandler = new Handler(mHandlerThread.getLooper());
mCallback =
new MediaCodec.Callback() {
@Override
Expand Down Expand Up @@ -525,7 +533,7 @@ public void onOutputFormatChanged(MediaCodec codec, MediaFormat format) {
}
}
};
mMediaCodec.setCallback(mCallback);
mMediaCodec.setCallback(mCallback, mHandler);

// TODO: support OnFrameRenderedListener for non tunnel mode
if (tunnelModeAudioSessionId != -1) {
Expand Down Expand Up @@ -806,6 +814,7 @@ public void release() {
Log.e(TAG, "Cannot release media codec", e);
}
mMediaCodec = null;
mHandlerThread.quitSafely();
}

@SuppressWarnings("unused")
Expand Down

0 comments on commit fb9e04c

Please sign in to comment.