diff --git a/media/java/android/media/MediaPlayer2Impl.java b/media/java/android/media/MediaPlayer2Impl.java index 42d3d2212b073..ed4501466278b 100644 --- a/media/java/android/media/MediaPlayer2Impl.java +++ b/media/java/android/media/MediaPlayer2Impl.java @@ -2769,8 +2769,8 @@ public final class MediaPlayer2Impl extends MediaPlayer2 { { if (msg.obj == null) { Log.w(TAG, "MEDIA_DRM_INFO msg.obj=NULL"); - } else if (msg.obj instanceof Parcel) { - // The parcel was parsed already in postEventFromNative + } else if (msg.obj instanceof byte[]) { + // The PlayerMessage was parsed already in postEventFromNative final DrmInfoImpl drmInfo; synchronized (mDrmLock) { @@ -2975,10 +2975,15 @@ public final class MediaPlayer2Impl extends MediaPlayer2 { case MEDIA_TIMED_TEXT: { final TimedText text; - if (msg.obj instanceof Parcel) { - Parcel parcel = (Parcel)msg.obj; - text = new TimedText(parcel); - parcel.recycle(); + if (msg.obj instanceof byte[]) { + PlayerMessage playerMsg; + try { + playerMsg = PlayerMessage.parseFrom((byte[]) msg.obj); + } catch (InvalidProtocolBufferException e) { + Log.w(TAG, "Failed to parse timed text.", e); + return; + } + text = null; // TODO: convert PlayerMessage to new TimedText(playerMsg); } else { text = null; } @@ -2994,10 +2999,20 @@ public final class MediaPlayer2Impl extends MediaPlayer2 { case MEDIA_SUBTITLE_DATA: { - if (msg.obj instanceof Parcel) { - Parcel parcel = (Parcel) msg.obj; - SubtitleData data = new SubtitleData(parcel); - parcel.recycle(); + if (msg.obj instanceof byte[]) { + PlayerMessage playerMsg; + try { + playerMsg = PlayerMessage.parseFrom((byte[]) msg.obj); + } catch (InvalidProtocolBufferException e) { + Log.w(TAG, "Failed to parse subtitle data.", e); + return; + } + Iterator in = playerMsg.getValuesList().iterator(); + SubtitleData data = new SubtitleData( + in.next().getInt32Value(), // trackIndex + in.next().getInt64Value(), // startTimeUs + in.next().getInt64Value(), // durationUs + in.next().getBytesValue().toByteArray()); // data synchronized (mEventCbLock) { for (Pair cb : mEventCallbackRecords) { cb.first.execute(() -> cb.second.onSubtitleData( @@ -3011,10 +3026,18 @@ public final class MediaPlayer2Impl extends MediaPlayer2 { case MEDIA_META_DATA: { final TimedMetaData data; - if (msg.obj instanceof Parcel) { - Parcel parcel = (Parcel) msg.obj; - data = TimedMetaData.createTimedMetaDataFromParcel(parcel); - parcel.recycle(); + if (msg.obj instanceof byte[]) { + PlayerMessage playerMsg; + try { + playerMsg = PlayerMessage.parseFrom((byte[]) msg.obj); + } catch (InvalidProtocolBufferException e) { + Log.w(TAG, "Failed to parse timed meta data.", e); + return; + } + Iterator in = playerMsg.getValuesList().iterator(); + data = new TimedMetaData( + in.next().getInt64Value(), // timestampUs + in.next().getBytesValue().toByteArray()); // metaData } else { data = null; } @@ -3062,7 +3085,7 @@ public final class MediaPlayer2Impl extends MediaPlayer2 { * the cookie passed to native_setup().) */ private static void postEventFromNative(Object mediaplayer2_ref, long srcId, - int what, int arg1, int arg2, Object obj) + int what, int arg1, int arg2, byte[] obj) { final MediaPlayer2Impl mp = (MediaPlayer2Impl)((WeakReference)mediaplayer2_ref).get(); if (mp == null) { @@ -3076,9 +3099,15 @@ public final class MediaPlayer2Impl extends MediaPlayer2 { // notification looper so its handleMessage might process the event after prepare() // has returned. Log.v(TAG, "postEventFromNative MEDIA_DRM_INFO"); - if (obj instanceof Parcel) { - Parcel parcel = (Parcel)obj; - DrmInfoImpl drmInfo = new DrmInfoImpl(parcel); + if (obj != null) { + PlayerMessage playerMsg; + try { + playerMsg = PlayerMessage.parseFrom(obj); + } catch (InvalidProtocolBufferException e) { + Log.w(TAG, "MEDIA_DRM_INFO failed to parse msg.obj " + obj); + break; + } + DrmInfoImpl drmInfo = new DrmInfoImpl(playerMsg); synchronized (mp.mDrmLock) { mp.mDrmInfoImpl = drmInfo; } @@ -3745,22 +3774,21 @@ public final class MediaPlayer2Impl extends MediaPlayer2 { supportedSchemes = SupportedSchemes; } - private DrmInfoImpl(Parcel parcel) { - Log.v(TAG, "DrmInfoImpl(" + parcel + ") size " + parcel.dataSize()); + private DrmInfoImpl(PlayerMessage msg) { + Log.v(TAG, "DrmInfoImpl(" + msg + ")"); - int psshsize = parcel.readInt(); - byte[] pssh = new byte[psshsize]; - parcel.readByteArray(pssh); + Iterator in = msg.getValuesList().iterator(); + byte[] pssh = in.next().getBytesValue().toByteArray(); Log.v(TAG, "DrmInfoImpl() PSSH: " + arrToHex(pssh)); - mapPssh = parsePSSH(pssh, psshsize); + mapPssh = parsePSSH(pssh, pssh.length); Log.v(TAG, "DrmInfoImpl() PSSH: " + mapPssh); - int supportedDRMsCount = parcel.readInt(); + int supportedDRMsCount = in.next().getInt32Value(); supportedSchemes = new UUID[supportedDRMsCount]; for (int i = 0; i < supportedDRMsCount; i++) { byte[] uuid = new byte[16]; - parcel.readByteArray(uuid); + in.next().getBytesValue().copyTo(uuid, uuid.length); supportedSchemes[i] = bytesToUUID(uuid); @@ -3768,7 +3796,7 @@ public final class MediaPlayer2Impl extends MediaPlayer2 { supportedSchemes[i]); } - Log.v(TAG, "DrmInfoImpl() Parcel psshsize: " + psshsize + + Log.v(TAG, "DrmInfoImpl() Parcel psshsize: " + pssh.length + " supportedDRMsCount: " + supportedDRMsCount); } diff --git a/media/java/android/media/SubtitleData.java b/media/java/android/media/SubtitleData.java index 9797828db891b..ba37b9b663601 100644 --- a/media/java/android/media/SubtitleData.java +++ b/media/java/android/media/SubtitleData.java @@ -79,6 +79,14 @@ public final class SubtitleData } } + /** @hide */ + public SubtitleData(int trackIndex, long startTimeUs, long durationUs, byte[] data) { + mTrackIndex = trackIndex; + mStartTimeUs = startTimeUs; + mDurationUs = durationUs; + mData = data; + } + /** * Returns the index of the MediaPlayer track which contains this subtitle data. * @return an index in the array returned by {@link MediaPlayer#getTrackInfo()}. diff --git a/media/java/android/media/TimedMetaData.java b/media/java/android/media/TimedMetaData.java index 03c877013eadc..97e6bfa170d8c 100644 --- a/media/java/android/media/TimedMetaData.java +++ b/media/java/android/media/TimedMetaData.java @@ -47,6 +47,14 @@ public final class TimedMetaData { } } + /** + * @hide + */ + public TimedMetaData(long timestampUs, byte[] metaData) { + mTimestampUs = timestampUs; + mMetaData = metaData; + } + /** * @return the timestamp associated with this metadata access unit in microseconds; * 0 denotes playback start. diff --git a/media/jni/android_media_MediaPlayer2.cpp b/media/jni/android_media_MediaPlayer2.cpp index d924b38de9811..d13262aab3ac9 100644 --- a/media/jni/android_media_MediaPlayer2.cpp +++ b/media/jni/android_media_MediaPlayer2.cpp @@ -161,7 +161,7 @@ public: JNIMediaPlayer2Listener(JNIEnv* env, jobject thiz, jobject weak_thiz); ~JNIMediaPlayer2Listener(); virtual void notify(int64_t srcId, int msg, int ext1, int ext2, - const Parcel *obj = NULL) override; + const PlayerMessage *obj = NULL) override; private: JNIMediaPlayer2Listener(); jclass mClass; // Reference to MediaPlayer2 class @@ -194,23 +194,26 @@ JNIMediaPlayer2Listener::~JNIMediaPlayer2Listener() env->DeleteGlobalRef(mClass); } -void JNIMediaPlayer2Listener::notify(int64_t srcId, int msg, int ext1, int ext2, const Parcel *obj) +void JNIMediaPlayer2Listener::notify(int64_t srcId, int msg, int ext1, int ext2, + const PlayerMessage* obj) { JNIEnv *env = JavaVMHelper::getJNIEnv(); - if (obj && obj->dataSize() > 0) { - jobject jParcel = createJavaParcelObject(env); - if (jParcel != NULL) { - // TODO: replace the following Parcel usages with proto. - // 1. MEDIA_DRM_INFO : DrmInfo - // 2. MEDIA_TIMED_TEXT : TimedText - // 2. MEDIA_SUBTITLE_DATA : SubtitleData - // 4. MEDIA_META_DATA : TimedMetaData - Parcel* nativeParcel = parcelForJavaObject(env, jParcel); - nativeParcel->setData(obj->data(), obj->dataSize()); - env->CallStaticVoidMethod(mClass, fields.post_event, mObject, - srcId, msg, ext1, ext2, jParcel); - env->DeleteLocalRef(jParcel); - } + if (obj != NULL) { + // TODO: replace the following Parcel usages with proto. + // 1. MEDIA_DRM_INFO : DrmInfo + // 2. MEDIA_TIMED_TEXT : TimedText + // 2. MEDIA_SUBTITLE_DATA : SubtitleData + // 4. MEDIA_META_DATA : TimedMetaData + int size = obj->ByteSize(); + jbyte* temp = new jbyte[size]; + obj->SerializeToArray(temp, size); + + // return the response as a byte array. + jbyteArray out = env->NewByteArray(size); + env->SetByteArrayRegion(out, 0, size, temp); + env->CallStaticVoidMethod(mClass, fields.post_event, mObject, + srcId, msg, ext1, ext2, out); + delete[] temp; } else { env->CallStaticVoidMethod(mClass, fields.post_event, mObject, srcId, msg, ext1, ext2, NULL); @@ -1089,7 +1092,7 @@ android_media_MediaPlayer2_native_init(JNIEnv *env) } fields.post_event = env->GetStaticMethodID(clazz, "postEventFromNative", - "(Ljava/lang/Object;JIIILjava/lang/Object;)V"); + "(Ljava/lang/Object;JIII[B)V"); if (fields.post_event == NULL) { return; }