Make MP2.prepare|play handled with task queue

Test: plays video
Bug: 63934228
Change-Id: Iecf8b2079e87241365ab6b7b7b0a5a669c948427
This commit is contained in:
Dongwon Kang
2018-03-02 18:10:49 -08:00
parent 47cab8322a
commit adf77a01e8
2 changed files with 99 additions and 4 deletions

View File

@@ -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();
}
}
}
};
}

View File

@@ -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},