Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c10acef3 authored by jmeng's avatar jmeng Committed by Steve Kondik
Browse files

libstagefright: Add 2 APIs (suspend and resume) in Mediaplayer



- API:suspend() will just pause the player and release all the decoders
  instead of release the whole player
- API:resume() will just init the decoders again
- Add a check in onVideoEvent()
  to make sure the first seek operation will seek the next i-frame

Signed-off-by: default avatarjmeng <jmeng@codeaurora.org>

Change-Id: If16dc1c9dae2f28df8a969b1044ca67d23a8846b
parent 52c12390
Loading
Loading
Loading
Loading
+10 −0
Original line number Diff line number Diff line
@@ -96,6 +96,16 @@ public:
    virtual status_t        getMetadata(bool update_only,
                                        bool apply_filter,
                                        Parcel *metadata) = 0;

    // Suspend the video player
    // In other words, just release the audio decoder and the video decoder
    // @return OK if the video player was suspended successfully
    virtual status_t        suspend() = 0;

    // Resume the video player
    // Init the audio decoder and the video decoder
    // @return OK if the video player was resumed successfully
    virtual status_t        resume() = 0;
};

// ----------------------------------------------------------------------------
+3 −0
Original line number Diff line number Diff line
@@ -213,6 +213,9 @@ public:
        return INVALID_OPERATION;
    }

    virtual status_t suspend() { return INVALID_OPERATION; }
    virtual status_t resume() { return INVALID_OPERATION; }

private:
    friend class MediaPlayerService;

+4 −1
Original line number Diff line number Diff line
@@ -139,7 +139,8 @@ enum media_player_states {
    MEDIA_PLAYER_STARTED            = 1 << 4,
    MEDIA_PLAYER_PAUSED             = 1 << 5,
    MEDIA_PLAYER_STOPPED            = 1 << 6,
    MEDIA_PLAYER_PLAYBACK_COMPLETE  = 1 << 7
    MEDIA_PLAYER_PLAYBACK_COMPLETE  = 1 << 7,
    MEDIA_PLAYER_SUSPENDED          = 1 << 8
};

// Keep KEY_PARAMETER_* in sync with MediaPlayer.java.
@@ -232,6 +233,8 @@ public:
            status_t        getParameter(int key, Parcel* reply);
            status_t        setRetransmitEndpoint(const char* addrString, uint16_t port);
            status_t        setNextMediaPlayer(const sp<MediaPlayer>& player);
            status_t        suspend();
            status_t        resume();

            status_t updateProxyConfig(
                    const char *host, int32_t port, const char *exclusionList);
+30 −0
Original line number Diff line number Diff line
@@ -57,6 +57,8 @@ enum {
    SET_RETRANSMIT_ENDPOINT,
    GET_RETRANSMIT_ENDPOINT,
    SET_NEXT_PLAYER,
    SUSPEND,
    RESUME,
};

class BpMediaPlayer: public BpInterface<IMediaPlayer>
@@ -338,6 +340,22 @@ public:

        return err;
    }

    status_t suspend()
    {
        Parcel data, reply;
        data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
        remote()->transact(SUSPEND, data, &reply);
        return reply.readInt32();
    }

    status_t resume()
    {
        Parcel data, reply;
        data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
        remote()->transact(RESUME, data, &reply);
        return reply.readInt32();
    }
};

IMPLEMENT_META_INTERFACE(MediaPlayer, "android.media.IMediaPlayer");
@@ -537,6 +555,18 @@ status_t BnMediaPlayer::onTransact(

            return NO_ERROR;
        } break;
        case SUSPEND: {
            CHECK_INTERFACE(IMediaPlayer, data, reply);
            status_t ret = suspend();
            reply->writeInt32(ret);
            return NO_ERROR;
        } break;
        case RESUME: {
            CHECK_INTERFACE(IMediaPlayer, data, reply);
            status_t ret = resume();
            reply->writeInt32(ret);
            return NO_ERROR;
        } break;
        default:
            return BBinder::onTransact(code, data, reply, flags);
    }
+53 −2
Original line number Diff line number Diff line
@@ -298,6 +298,9 @@ status_t MediaPlayer::start()
            }
        }
        return ret;
    } else if ( (mPlayer != 0) && ( mCurrentState & MEDIA_PLAYER_SUSPENDED ) ) {
        ALOGV("start while suspended, so ignore this start");
        return NO_ERROR;
    }
    ALOGE("start called in state %d", mCurrentState);
    return INVALID_OPERATION;
@@ -394,7 +397,7 @@ status_t MediaPlayer::getCurrentPosition(int *msec)
status_t MediaPlayer::getDuration_l(int *msec)
{
    ALOGV("getDuration_l");
    bool isValidState = (mCurrentState & (MEDIA_PLAYER_PREPARED | MEDIA_PLAYER_STARTED | MEDIA_PLAYER_PAUSED | MEDIA_PLAYER_STOPPED | MEDIA_PLAYER_PLAYBACK_COMPLETE));
    bool isValidState = (mCurrentState & (MEDIA_PLAYER_PREPARED | MEDIA_PLAYER_STARTED | MEDIA_PLAYER_PAUSED | MEDIA_PLAYER_STOPPED | MEDIA_PLAYER_PLAYBACK_COMPLETE | MEDIA_PLAYER_SUSPENDED));
    if (mPlayer != 0 && isValidState) {
        int durationMs;
        status_t ret = mPlayer->getDuration(&durationMs);
@@ -423,7 +426,7 @@ status_t MediaPlayer::getDuration(int *msec)
status_t MediaPlayer::seekTo_l(int msec)
{
    ALOGV("seekTo %d", msec);
    if ((mPlayer != 0) && ( mCurrentState & ( MEDIA_PLAYER_STARTED | MEDIA_PLAYER_PREPARED | MEDIA_PLAYER_PAUSED |  MEDIA_PLAYER_PLAYBACK_COMPLETE) ) ) {
    if ((mPlayer != 0) && ( mCurrentState & ( MEDIA_PLAYER_STARTED | MEDIA_PLAYER_PREPARED | MEDIA_PLAYER_PAUSED |  MEDIA_PLAYER_PLAYBACK_COMPLETE | MEDIA_PLAYER_SUSPENDED) ) ) {
        if ( msec < 0 ) {
            ALOGW("Attempt to seek to invalid position: %d", msec);
            msec = 0;
@@ -835,4 +838,52 @@ extern "C" int _ZN7android11MediaPlayer18setAudioStreamTypeEi() {
}
#endif

status_t MediaPlayer::suspend() {
    ALOGV("MediaPlayer::suspend()");
    Mutex::Autolock _l(mLock);
    if (mPlayer == NULL) {
        ALOGE("mPlayer = NULL");
        return NO_INIT;
    }

    bool isValidState = (mCurrentState & (MEDIA_PLAYER_PREPARED | MEDIA_PLAYER_STARTED | MEDIA_PLAYER_PAUSED | MEDIA_PLAYER_STOPPED | MEDIA_PLAYER_PLAYBACK_COMPLETE | MEDIA_PLAYER_SUSPENDED));
    if (!isValidState) {
        ALOGE("suspend while in a invalid state = %d", mCurrentState);
        return UNKNOWN_ERROR;
    }

    status_t ret = mPlayer->suspend();

    if (OK != ret) {
        ALOGE("MediaPlayer::suspend() return with error ret = %d", ret);
        return ret;
    }
    mCurrentState = MEDIA_PLAYER_SUSPENDED;
    return OK;
}

status_t MediaPlayer::resume() {
    ALOGV("MediaPlayer::resume()");
    Mutex::Autolock _l(mLock);
    if (mPlayer == NULL) {
        ALOGE("mPlayer == NULL");
        return NO_INIT;
    }

    bool isValidState = (mCurrentState == MEDIA_PLAYER_SUSPENDED);
    if (!isValidState) {
        ALOGE("resume while in a invalid state = %d", mCurrentState);
        return UNKNOWN_ERROR;
    }

    status_t ret = mPlayer->resume();

    if (OK != ret) {
        ALOGE("MediaPlayer::resume() return with error ret = %d", ret);
        return ret;
    }
    mCurrentState = MEDIA_PLAYER_PREPARED;
    return OK;
}

}; // namespace android
Loading