Loading include/media/IMediaPlayer.h +1 −0 Original line number Diff line number Diff line Loading @@ -64,6 +64,7 @@ public: virtual status_t setParameter(int key, const Parcel& request) = 0; virtual status_t getParameter(int key, Parcel* reply) = 0; virtual status_t setRetransmitEndpoint(const struct sockaddr_in* endpoint) = 0; virtual status_t setNextPlayer(const sp<IMediaPlayer>& next) = 0; // Invoke a generic method on the player by using opaque parcels // for the request and reply. Loading include/media/MediaPlayerInterface.h +1 −0 Original line number Diff line number Diff line Loading @@ -107,6 +107,7 @@ public: virtual void close() = 0; virtual status_t setPlaybackRatePermille(int32_t rate) { return INVALID_OPERATION; } virtual bool needsTrailingPadding() { return true; } }; MediaPlayerBase() : mCookie(0), mNotify(0) {} Loading include/media/mediaplayer.h +4 −0 Original line number Diff line number Diff line Loading @@ -96,6 +96,9 @@ enum media_error_type { enum media_info_type { // 0xx MEDIA_INFO_UNKNOWN = 1, // The player was started because it was used as the next player for another // player, which just completed playback MEDIA_INFO_STARTED_AS_NEXT = 2, // 7xx // The video is too complex for the decoder: it can't decode frames fast // enough. Possibly only the audio plays fine at this stage. Loading Loading @@ -207,6 +210,7 @@ public: status_t setParameter(int key, const Parcel& request); status_t getParameter(int key, Parcel* reply); status_t setRetransmitEndpoint(const char* addrString, uint16_t port); status_t setNextMediaPlayer(const sp<MediaPlayer>& player); private: void clear_l(); Loading media/java/android/media/MediaPlayer.java +31 −0 Original line number Diff line number Diff line Loading @@ -1154,6 +1154,26 @@ public class MediaPlayer return native_setMetadataFilter(request); } /** * Set the MediaPlayer to start when this MediaPlayer finishes playback * (i.e. reaches the end of the stream). * The media framework will attempt to transition from this player to * the next as seamlessly as possible. The next player can be set at * any time before completion. The next player must be prepared by the * app, and the application should not call start() on it. * The next MediaPlayer must be different from 'this'. An exception * will be thrown if next == this. * The application may call setNextMediaPlayer(null) to indicate no * next player should be started at the end of playback. * If the current player is looping, it will keep looping and the next * player will not be started. * * @param next the player to start after this one completes playback. * * @hide */ public native void setNextMediaPlayer(MediaPlayer next); /** * Releases resources associated with this MediaPlayer object. * It is considered good practice to call this method when you're Loading Loading @@ -1659,6 +1679,10 @@ public class MediaPlayer return; } if (what == MEDIA_INFO && arg1 == MEDIA_INFO_STARTED_AS_NEXT) { // this acquires the wakelock if needed, and sets the client side state mp.start(); } if (mp.mEventHandler != null) { Message m = mp.mEventHandler.obtainMessage(what, arg1, arg2, obj); mp.mEventHandler.sendMessage(m); Loading Loading @@ -1913,6 +1937,13 @@ public class MediaPlayer */ public static final int MEDIA_INFO_UNKNOWN = 1; /** The player was started because it was used as the next player for another * player, which just completed playback. * @see android.media.MediaPlayer.OnInfoListener * @hide */ public static final int MEDIA_INFO_STARTED_AS_NEXT = 2; /** The video is too complex for the decoder: it can't decode frames fast * enough. Possibly only the audio plays fine at this stage. * @see android.media.MediaPlayer.OnInfoListener Loading media/jni/android_media_MediaPlayer.cpp +28 −0 Original line number Diff line number Diff line Loading @@ -795,6 +795,33 @@ android_media_MediaPlayer_getParameter(JNIEnv *env, jobject thiz, jint key, jobj process_media_player_call(env, thiz, mp->getParameter(key, reply), NULL, NULL ); } static void android_media_MediaPlayer_setNextMediaPlayer(JNIEnv *env, jobject thiz, jobject java_player) { ALOGV("setNextMediaPlayer"); sp<MediaPlayer> thisplayer = getMediaPlayer(env, thiz); if (thisplayer == NULL) { jniThrowException(env, "java/lang/IllegalStateException", "This player not initialized"); return; } sp<MediaPlayer> nextplayer = (java_player == NULL) ? NULL : getMediaPlayer(env, java_player); if (nextplayer == NULL && java_player != NULL) { jniThrowException(env, "java/lang/IllegalStateException", "That player not initialized"); return; } if (nextplayer == thisplayer) { jniThrowException(env, "java/lang/IllegalArgumentException", "Next player can't be self"); return; } // tie the two players together process_media_player_call( env, thiz, thisplayer->setNextMediaPlayer(nextplayer), "java/lang/IllegalArgumentException", "setNextMediaPlayer failed." ); ; } // ---------------------------------------------------------------------------- static JNINativeMethod gMethods[] = { Loading Loading @@ -840,6 +867,7 @@ static JNINativeMethod gMethods[] = { {"setParameter", "(ILandroid/os/Parcel;)Z", (void *)android_media_MediaPlayer_setParameter}, {"getParameter", "(ILandroid/os/Parcel;)V", (void *)android_media_MediaPlayer_getParameter}, {"native_setRetransmitEndpoint", "(Ljava/lang/String;I)I", (void *)android_media_MediaPlayer_setRetransmitEndpoint}, {"setNextMediaPlayer", "(Landroid/media/MediaPlayer;)V", (void *)android_media_MediaPlayer_setNextMediaPlayer}, }; static const char* const kClassPathName = "android/media/MediaPlayer"; Loading Loading
include/media/IMediaPlayer.h +1 −0 Original line number Diff line number Diff line Loading @@ -64,6 +64,7 @@ public: virtual status_t setParameter(int key, const Parcel& request) = 0; virtual status_t getParameter(int key, Parcel* reply) = 0; virtual status_t setRetransmitEndpoint(const struct sockaddr_in* endpoint) = 0; virtual status_t setNextPlayer(const sp<IMediaPlayer>& next) = 0; // Invoke a generic method on the player by using opaque parcels // for the request and reply. Loading
include/media/MediaPlayerInterface.h +1 −0 Original line number Diff line number Diff line Loading @@ -107,6 +107,7 @@ public: virtual void close() = 0; virtual status_t setPlaybackRatePermille(int32_t rate) { return INVALID_OPERATION; } virtual bool needsTrailingPadding() { return true; } }; MediaPlayerBase() : mCookie(0), mNotify(0) {} Loading
include/media/mediaplayer.h +4 −0 Original line number Diff line number Diff line Loading @@ -96,6 +96,9 @@ enum media_error_type { enum media_info_type { // 0xx MEDIA_INFO_UNKNOWN = 1, // The player was started because it was used as the next player for another // player, which just completed playback MEDIA_INFO_STARTED_AS_NEXT = 2, // 7xx // The video is too complex for the decoder: it can't decode frames fast // enough. Possibly only the audio plays fine at this stage. Loading Loading @@ -207,6 +210,7 @@ public: status_t setParameter(int key, const Parcel& request); status_t getParameter(int key, Parcel* reply); status_t setRetransmitEndpoint(const char* addrString, uint16_t port); status_t setNextMediaPlayer(const sp<MediaPlayer>& player); private: void clear_l(); Loading
media/java/android/media/MediaPlayer.java +31 −0 Original line number Diff line number Diff line Loading @@ -1154,6 +1154,26 @@ public class MediaPlayer return native_setMetadataFilter(request); } /** * Set the MediaPlayer to start when this MediaPlayer finishes playback * (i.e. reaches the end of the stream). * The media framework will attempt to transition from this player to * the next as seamlessly as possible. The next player can be set at * any time before completion. The next player must be prepared by the * app, and the application should not call start() on it. * The next MediaPlayer must be different from 'this'. An exception * will be thrown if next == this. * The application may call setNextMediaPlayer(null) to indicate no * next player should be started at the end of playback. * If the current player is looping, it will keep looping and the next * player will not be started. * * @param next the player to start after this one completes playback. * * @hide */ public native void setNextMediaPlayer(MediaPlayer next); /** * Releases resources associated with this MediaPlayer object. * It is considered good practice to call this method when you're Loading Loading @@ -1659,6 +1679,10 @@ public class MediaPlayer return; } if (what == MEDIA_INFO && arg1 == MEDIA_INFO_STARTED_AS_NEXT) { // this acquires the wakelock if needed, and sets the client side state mp.start(); } if (mp.mEventHandler != null) { Message m = mp.mEventHandler.obtainMessage(what, arg1, arg2, obj); mp.mEventHandler.sendMessage(m); Loading Loading @@ -1913,6 +1937,13 @@ public class MediaPlayer */ public static final int MEDIA_INFO_UNKNOWN = 1; /** The player was started because it was used as the next player for another * player, which just completed playback. * @see android.media.MediaPlayer.OnInfoListener * @hide */ public static final int MEDIA_INFO_STARTED_AS_NEXT = 2; /** The video is too complex for the decoder: it can't decode frames fast * enough. Possibly only the audio plays fine at this stage. * @see android.media.MediaPlayer.OnInfoListener Loading
media/jni/android_media_MediaPlayer.cpp +28 −0 Original line number Diff line number Diff line Loading @@ -795,6 +795,33 @@ android_media_MediaPlayer_getParameter(JNIEnv *env, jobject thiz, jint key, jobj process_media_player_call(env, thiz, mp->getParameter(key, reply), NULL, NULL ); } static void android_media_MediaPlayer_setNextMediaPlayer(JNIEnv *env, jobject thiz, jobject java_player) { ALOGV("setNextMediaPlayer"); sp<MediaPlayer> thisplayer = getMediaPlayer(env, thiz); if (thisplayer == NULL) { jniThrowException(env, "java/lang/IllegalStateException", "This player not initialized"); return; } sp<MediaPlayer> nextplayer = (java_player == NULL) ? NULL : getMediaPlayer(env, java_player); if (nextplayer == NULL && java_player != NULL) { jniThrowException(env, "java/lang/IllegalStateException", "That player not initialized"); return; } if (nextplayer == thisplayer) { jniThrowException(env, "java/lang/IllegalArgumentException", "Next player can't be self"); return; } // tie the two players together process_media_player_call( env, thiz, thisplayer->setNextMediaPlayer(nextplayer), "java/lang/IllegalArgumentException", "setNextMediaPlayer failed." ); ; } // ---------------------------------------------------------------------------- static JNINativeMethod gMethods[] = { Loading Loading @@ -840,6 +867,7 @@ static JNINativeMethod gMethods[] = { {"setParameter", "(ILandroid/os/Parcel;)Z", (void *)android_media_MediaPlayer_setParameter}, {"getParameter", "(ILandroid/os/Parcel;)V", (void *)android_media_MediaPlayer_getParameter}, {"native_setRetransmitEndpoint", "(Ljava/lang/String;I)I", (void *)android_media_MediaPlayer_setRetransmitEndpoint}, {"setNextMediaPlayer", "(Landroid/media/MediaPlayer;)V", (void *)android_media_MediaPlayer_setNextMediaPlayer}, }; static const char* const kClassPathName = "android/media/MediaPlayer"; Loading