Merge "media: hook up OnFrameRenderedListener events to framework events" into mnc-dev

This commit is contained in:
Lajos Molnar
2015-06-10 01:04:45 +00:00
committed by Android (Google) Code Review
3 changed files with 76 additions and 36 deletions

View File

@@ -1455,15 +1455,6 @@ final public class MediaCodec {
@Retention(RetentionPolicy.SOURCE)
public @interface BufferFlag {}
private static class FrameRenderedInfo {
public long mPresentationTimeUs;
public long mNanoTime;
public FrameRenderedInfo(long presentationTimeUs, long nanoTime) {
mPresentationTimeUs = presentationTimeUs;
mNanoTime = nanoTime;
}
}
private EventHandler mEventHandler;
private EventHandler mOnFrameRenderedHandler;
private EventHandler mCallbackHandler;
@@ -1503,10 +1494,16 @@ final public class MediaCodec {
}
case EVENT_FRAME_RENDERED:
synchronized (mListenerLock) {
FrameRenderedInfo info = (FrameRenderedInfo)msg.obj;
if (mOnFrameRenderedListener != null) {
Map<String, Object> map = (Map<String, Object>)msg.obj;
for (int i = 0; ; ++i) {
Object mediaTimeUs = map.get(i + "-media-time-us");
Object systemNano = map.get(i + "-system-nano");
if (mediaTimeUs == null || systemNano == null
|| mOnFrameRenderedListener == null) {
break;
}
mOnFrameRenderedListener.onFrameRendered(
mCodec, info.mPresentationTimeUs, info.mNanoTime);
mCodec, (long)mediaTimeUs, (long)systemNano);
}
break;
}
@@ -2362,26 +2359,9 @@ final public class MediaCodec {
info = mDequeuedOutputInfos.remove(index);
}
}
// TODO
// until codec and libgui supports callback, assume frame is rendered within 50 ms
postRenderedCallback(render, info, 50 /* delayMs */);
releaseOutputBuffer(index, render, false /* updatePTS */, 0 /* dummy */);
}
private void postRenderedCallback(boolean render, @Nullable BufferInfo info, long delayMs) {
if (render && info != null) {
synchronized (mListenerLock) {
if (mOnFrameRenderedListener != null) {
FrameRenderedInfo obj = new FrameRenderedInfo(
info.presentationTimeUs, System.nanoTime() + delayMs * 1000000);
Message msg = mOnFrameRenderedHandler.obtainMessage(
EVENT_FRAME_RENDERED, obj);
mOnFrameRenderedHandler.sendMessageDelayed(msg, delayMs);
}
}
}
}
/**
* If you are done with a buffer, use this call to update its surface timestamp
* and return it to the codec to render it on the output surface. If you
@@ -2440,12 +2420,6 @@ final public class MediaCodec {
info = mDequeuedOutputInfos.remove(index);
}
}
// TODO
// until codec and libgui supports callback, assume frame is rendered at the
// render time or 16 ms from now, whichever is later.
postRenderedCallback(
true /* render */, info,
Math.max(renderTimestampNs - System.nanoTime(), 16666666) / 1000000);
releaseOutputBuffer(
index, true /* render */, true /* updatePTS */, renderTimestampNs);
}
@@ -3049,9 +3023,12 @@ final public class MediaCodec {
} else if (mOnFrameRenderedHandler != null) {
mOnFrameRenderedHandler.removeMessages(EVENT_FRAME_RENDERED);
}
native_enableOnFrameRenderedListener(listener != null);
}
}
private native void native_enableOnFrameRenderedListener(boolean enable);
private EventHandler getEventHandlerOn(
@Nullable Handler handler, @NonNull EventHandler lastHandler) {
if (handler == null) {

View File

@@ -56,6 +56,7 @@ enum {
enum {
EVENT_CALLBACK = 1,
EVENT_SET_CALLBACK = 2,
EVENT_FRAME_RENDERED = 3,
};
static struct CryptoErrorCodes {
@@ -226,6 +227,18 @@ void JMediaCodec::deleteJavaObjects(JNIEnv *env) {
mByteBufferLimitMethodID = NULL;
}
status_t JMediaCodec::enableOnFrameRenderedListener(jboolean enable) {
if (enable) {
if (mOnFrameRenderedNotification == NULL) {
mOnFrameRenderedNotification = new AMessage(kWhatFrameRendered, this);
}
} else {
mOnFrameRenderedNotification.clear();
}
return mCodec->setOnFrameRenderedNotification(mOnFrameRenderedNotification);
}
status_t JMediaCodec::setCallback(jobject cb) {
if (cb != NULL) {
if (mCallbackNotification == NULL) {
@@ -728,6 +741,27 @@ void JMediaCodec::handleCallback(const sp<AMessage> &msg) {
env->DeleteLocalRef(obj);
}
void JMediaCodec::handleFrameRenderedNotification(const sp<AMessage> &msg) {
int32_t arg1 = 0, arg2 = 0;
jobject obj = NULL;
JNIEnv *env = AndroidRuntime::getJNIEnv();
sp<AMessage> data;
CHECK(msg->findMessage("data", &data));
status_t err = ConvertMessageToMap(env, data, &obj);
if (err != OK) {
jniThrowException(env, "java/lang/IllegalStateException", NULL);
return;
}
env->CallVoidMethod(
mObject, gFields.postEventFromNativeID,
EVENT_FRAME_RENDERED, arg1, arg2, obj);
env->DeleteLocalRef(obj);
}
void JMediaCodec::onMessageReceived(const sp<AMessage> &msg) {
switch (msg->what()) {
case kWhatCallbackNotify:
@@ -735,6 +769,11 @@ void JMediaCodec::onMessageReceived(const sp<AMessage> &msg) {
handleCallback(msg);
break;
}
case kWhatFrameRendered:
{
handleFrameRenderedNotification(msg);
break;
}
default:
TRESPASS();
}
@@ -848,6 +887,22 @@ static jint throwExceptionAsNecessary(
}
}
static void android_media_MediaCodec_native_enableOnFrameRenderedListener(
JNIEnv *env,
jobject thiz,
jboolean enabled) {
sp<JMediaCodec> codec = getMediaCodec(env, thiz);
if (codec == NULL) {
throwExceptionAsNecessary(env, INVALID_OPERATION);
return;
}
status_t err = codec->enableOnFrameRenderedListener(enabled);
throwExceptionAsNecessary(env, err);
}
static void android_media_MediaCodec_native_setCallback(
JNIEnv *env,
jobject thiz,
@@ -1744,6 +1799,9 @@ static JNINativeMethod gMethods[] = {
{ "native_setInputSurface", "(Landroid/view/Surface;)V",
(void *)android_media_MediaCodec_setInputSurface },
{ "native_enableOnFrameRenderedListener", "(Z)V",
(void *)android_media_MediaCodec_native_enableOnFrameRenderedListener },
{ "native_setCallback",
"(Landroid/media/MediaCodec$Callback;)V",
(void *)android_media_MediaCodec_native_setCallback },

View File

@@ -46,6 +46,8 @@ struct JMediaCodec : public AHandler {
void registerSelf();
void release();
status_t enableOnFrameRenderedListener(jboolean enable);
status_t setCallback(jobject cb);
status_t configure(
@@ -116,11 +118,11 @@ protected:
virtual ~JMediaCodec();
virtual void onMessageReceived(const sp<AMessage> &msg);
void handleCallback(const sp<AMessage> &msg);
private:
enum {
kWhatCallbackNotify,
kWhatFrameRendered,
};
jclass mClass;
@@ -139,6 +141,7 @@ private:
sp<MediaCodec> mCodec;
sp<AMessage> mCallbackNotification;
sp<AMessage> mOnFrameRenderedNotification;
status_t mInitStatus;
@@ -148,6 +151,8 @@ private:
void cacheJavaObjects(JNIEnv *env);
void deleteJavaObjects(JNIEnv *env);
void handleCallback(const sp<AMessage> &msg);
void handleFrameRenderedNotification(const sp<AMessage> &msg);
DISALLOW_EVIL_CONSTRUCTORS(JMediaCodec);
};