Make MP2.prepare|play handled with task queue
Test: plays video Bug: 63934228 Change-Id: Iecf8b2079e87241365ab6b7b7b0a5a669c948427
This commit is contained in:
@@ -72,6 +72,7 @@ import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.BitSet;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Scanner;
|
||||
@@ -131,6 +132,14 @@ public final class MediaPlayer2Impl extends MediaPlayer2 {
|
||||
private ProvisioningThread mDrmProvisioningThread;
|
||||
//--- guarded by |mDrmLock| end
|
||||
|
||||
private HandlerThread mHandlerThread;
|
||||
private final Handler mTaskHandler;
|
||||
private final Object mTaskLock = new Object();
|
||||
@GuardedBy("mTaskLock")
|
||||
private final List<Task> mPendingTasks = new LinkedList<>();
|
||||
@GuardedBy("mTaskLock")
|
||||
private Task mCurrentTask;
|
||||
|
||||
/**
|
||||
* Default constructor.
|
||||
* <p>When done with the MediaPlayer2Impl, you should call {@link #close()},
|
||||
@@ -147,6 +156,11 @@ public final class MediaPlayer2Impl extends MediaPlayer2 {
|
||||
mEventHandler = null;
|
||||
}
|
||||
|
||||
mHandlerThread = new HandlerThread("MediaPlayer2TaskThread");
|
||||
mHandlerThread.start();
|
||||
looper = mHandlerThread.getLooper();
|
||||
mTaskHandler = new Handler(looper);
|
||||
|
||||
mTimeProvider = new TimeProvider(this);
|
||||
mOpenSubtitleSources = new Vector<InputStream>();
|
||||
mGuard.open("close");
|
||||
@@ -197,8 +211,18 @@ public final class MediaPlayer2Impl extends MediaPlayer2 {
|
||||
*/
|
||||
@Override
|
||||
public void play() {
|
||||
stayAwake(true);
|
||||
_start();
|
||||
synchronized (mTaskLock) {
|
||||
mPendingTasks.add(new Task(MEDIA_CALL_PLAY, false) {
|
||||
@Override
|
||||
int process() {
|
||||
stayAwake(true);
|
||||
_start();
|
||||
// TODO: define public constants for return value (status).
|
||||
return 0;
|
||||
}
|
||||
});
|
||||
processPendingTask_l();
|
||||
}
|
||||
}
|
||||
|
||||
private native void _start() throws IllegalStateException;
|
||||
@@ -214,7 +238,21 @@ public final class MediaPlayer2Impl extends MediaPlayer2 {
|
||||
* @throws IllegalStateException if it is called in an invalid state
|
||||
*/
|
||||
@Override
|
||||
public native void prepare();
|
||||
public void prepare() {
|
||||
synchronized (mTaskLock) {
|
||||
mPendingTasks.add(new Task(MEDIA_CALL_PREPARE, true) {
|
||||
@Override
|
||||
int process() {
|
||||
_prepare();
|
||||
// TODO: define public constants for return value (status).
|
||||
return 0;
|
||||
}
|
||||
});
|
||||
processPendingTask_l();
|
||||
}
|
||||
}
|
||||
|
||||
public native void _prepare();
|
||||
|
||||
/**
|
||||
* Pauses playback. Call play() to resume.
|
||||
@@ -691,6 +729,18 @@ public final class MediaPlayer2Impl extends MediaPlayer2 {
|
||||
public void clearPendingCommands() {
|
||||
}
|
||||
|
||||
@GuardedBy("mTaskLock")
|
||||
private void processPendingTask_l() {
|
||||
if (mCurrentTask != null) {
|
||||
return;
|
||||
}
|
||||
if (!mPendingTasks.isEmpty()) {
|
||||
Task task = mPendingTasks.remove(0);
|
||||
mCurrentTask = task;
|
||||
mTaskHandler.post(task);
|
||||
}
|
||||
}
|
||||
|
||||
private void handleDataSource(boolean isCurrent, @NonNull DataSourceDesc dsd, long srcId)
|
||||
throws IOException {
|
||||
Preconditions.checkNotNull(dsd, "the DataSourceDesc cannot be null");
|
||||
@@ -2521,6 +2571,10 @@ public final class MediaPlayer2Impl extends MediaPlayer2 {
|
||||
synchronized (mEventCbLock) {
|
||||
mEventCallbackRecords.clear();
|
||||
}
|
||||
if (mHandlerThread != null) {
|
||||
mHandlerThread.quitSafely();
|
||||
mHandlerThread = null;
|
||||
}
|
||||
if (mTimeProvider != null) {
|
||||
mTimeProvider.close();
|
||||
mTimeProvider = null;
|
||||
@@ -2634,6 +2688,13 @@ public final class MediaPlayer2Impl extends MediaPlayer2 {
|
||||
}
|
||||
}
|
||||
}
|
||||
synchronized (mTaskLock) {
|
||||
if (mCurrentTask.mMediaCallType == MEDIA_CALL_PREPARE
|
||||
&& mCurrentTask.mNeedToWaitForEventToComplete) {
|
||||
mCurrentTask = null;
|
||||
processPendingTask_l();
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -4502,4 +4563,38 @@ public final class MediaPlayer2Impl extends MediaPlayer2 {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private abstract class Task implements Runnable {
|
||||
private final int mMediaCallType;
|
||||
private final boolean mNeedToWaitForEventToComplete;
|
||||
|
||||
public Task (int mediaCallType, boolean needToWaitForEventToComplete) {
|
||||
mMediaCallType = mediaCallType;
|
||||
mNeedToWaitForEventToComplete = needToWaitForEventToComplete;
|
||||
}
|
||||
|
||||
abstract int process();
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
int status = process();
|
||||
|
||||
if (!mNeedToWaitForEventToComplete) {
|
||||
final DataSourceDesc dsd;
|
||||
synchronized (mSrcLock) {
|
||||
dsd = mCurrentDSD;
|
||||
}
|
||||
synchronized (mEventCbLock) {
|
||||
for (Pair<Executor, MediaPlayer2EventCallback> cb : mEventCallbackRecords) {
|
||||
cb.first.execute(() -> cb.second.onCallComplete(
|
||||
MediaPlayer2Impl.this, dsd, mMediaCallType, status));
|
||||
}
|
||||
}
|
||||
synchronized (mTaskLock) {
|
||||
mCurrentTask = null;
|
||||
processPendingTask_l();
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1490,7 +1490,7 @@ static const JNINativeMethod gMethods[] = {
|
||||
{"_setVideoSurface", "(Landroid/view/Surface;)V", (void *)android_media_MediaPlayer2_setVideoSurface},
|
||||
{"getBufferingParams", "()Landroid/media/BufferingParams;", (void *)android_media_MediaPlayer2_getBufferingParams},
|
||||
{"setBufferingParams", "(Landroid/media/BufferingParams;)V", (void *)android_media_MediaPlayer2_setBufferingParams},
|
||||
{"prepare", "()V", (void *)android_media_MediaPlayer2_prepare},
|
||||
{"_prepare", "()V", (void *)android_media_MediaPlayer2_prepare},
|
||||
{"_start", "()V", (void *)android_media_MediaPlayer2_start},
|
||||
{"_stop", "()V", (void *)android_media_MediaPlayer2_stop},
|
||||
{"native_getMediaPlayer2State", "()I", (void *)android_media_MediaPlayer2_getMediaPlayer2State},
|
||||
|
||||
Reference in New Issue
Block a user