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

Commit cbcd6e86 authored by James Dong's avatar James Dong Committed by Android (Google) Code Review
Browse files

Merge "Defines MediaPlayer APIs to support multiple audio/video/timedtext tracks."

parents 213744c5 f9d660a5
Loading
Loading
Loading
Loading
+20 −3
Original line number Diff line number Diff line
@@ -120,6 +120,9 @@ enum media_info_type {
    MEDIA_INFO_NOT_SEEKABLE = 801,
    // New media metadata is available.
    MEDIA_INFO_METADATA_UPDATE = 802,

    //9xx
    MEDIA_INFO_TIMED_TEXT_ERROR = 900,
};


@@ -140,9 +143,6 @@ enum media_player_states {
// The same enum space is used for both set and get, in case there are future keys that
// can be both set and get.  But as of now, all parameters are either set only or get only.
enum media_parameter_keys {
    KEY_PARAMETER_TIMED_TEXT_TRACK_INDEX = 1000,                // set only
    KEY_PARAMETER_TIMED_TEXT_ADD_OUT_OF_BAND_SOURCE = 1001,     // set only

    // Streaming/buffering parameters
    KEY_PARAMETER_CACHE_STAT_COLLECT_FREQ_MS = 1100,            // set only

@@ -155,6 +155,23 @@ enum media_parameter_keys {
    KEY_PARAMETER_PLAYBACK_RATE_PERMILLE = 1300,                // set only
};

// Keep INVOKE_ID_* in sync with MediaPlayer.java.
enum media_player_invoke_ids {
    INVOKE_ID_GET_TRACK_INFO = 1,
    INVOKE_ID_ADD_EXTERNAL_SOURCE = 2,
    INVOKE_ID_ADD_EXTERNAL_SOURCE_FD = 3,
    INVOKE_ID_SELECT_TRACK = 4,
    INVOKE_ID_UNSELECT_TRACK = 5,
};

// Keep MEDIA_TRACK_TYPE_* in sync with MediaPlayer.java.
enum media_track_type {
    MEDIA_TRACK_TYPE_UNKNOWN = 0,
    MEDIA_TRACK_TYPE_VIDEO = 1,
    MEDIA_TRACK_TYPE_AUDIO = 2,
    MEDIA_TRACK_TYPE_TIMEDTEXT = 3,
};

// ----------------------------------------------------------------------------
// ref-counted object for callbacks
class MediaPlayerListener: virtual public RefBase
+1 −0
Original line number Diff line number Diff line
@@ -54,6 +54,7 @@ extern const char *MEDIA_MIMETYPE_CONTAINER_MPEG2PS;
extern const char *MEDIA_MIMETYPE_CONTAINER_WVM;

extern const char *MEDIA_MIMETYPE_TEXT_3GPP;
extern const char *MEDIA_MIMETYPE_TEXT_SUBRIP;

}  // namespace android

+10 −10
Original line number Diff line number Diff line
@@ -37,26 +37,26 @@ public:

    ~TimedTextDriver();

    // TODO: pause-resume pair seems equivalent to stop-start pair.
    // Check if it is replaceable with stop-start.
    status_t start();
    status_t stop();
    status_t pause();
    status_t resume();
    status_t selectTrack(int32_t index);
    status_t unselectTrack(int32_t index);

    status_t seekToAsync(int64_t timeUs);

    status_t addInBandTextSource(const sp<MediaSource>& source);
    status_t addOutOfBandTextSource(const Parcel &request);
    status_t addOutOfBandTextSource(const char *uri, const char *mimeType);
    // Caller owns the file desriptor and caller is responsible for closing it.
    status_t addOutOfBandTextSource(
            int fd, off64_t offset, size_t length, const char *mimeType);

    status_t setTimedTextTrackIndex(int32_t index);
    void getTrackInfo(Parcel *parcel);

private:
    Mutex mLock;

    enum State {
        UNINITIALIZED,
        STOPPED,
        PLAYING,
        PAUSED,
    };
@@ -67,11 +67,11 @@ private:

    // Variables to be guarded by mLock.
    State mState;
    Vector<sp<TimedTextSource> > mTextInBandVector;
    Vector<sp<TimedTextSource> > mTextOutOfBandVector;
    int32_t mCurrentTrackIndex;
    Vector<sp<TimedTextSource> > mTextSourceVector;
    // -- End of variables to be guarded by mLock

    status_t setTimedTextTrackIndex_l(int32_t index);
    status_t selectTrack_l(int32_t index);

    DISALLOW_EVIL_CONSTRUCTORS(TimedTextDriver);
};
+2 −1
Original line number Diff line number Diff line
@@ -166,7 +166,8 @@ player_type StagefrightPlayer::playerType() {
}

status_t StagefrightPlayer::invoke(const Parcel &request, Parcel *reply) {
    return INVALID_OPERATION;
    ALOGV("invoke()");
    return mPlayer->invoke(request, reply);
}

void StagefrightPlayer::setAudioSink(const sp<AudioSink> &audioSink) {
+101 −44
Original line number Diff line number Diff line
@@ -1114,7 +1114,7 @@ status_t AwesomePlayer::pause_l(bool at_eos) {
        modifyFlags(AUDIO_RUNNING, CLEAR);
    }

    if (mFlags & TEXTPLAYER_STARTED) {
    if (mFlags & TEXTPLAYER_INITIALIZED) {
        mTextDriver->pause();
        modifyFlags(TEXT_RUNNING, CLEAR);
    }
@@ -1268,32 +1268,6 @@ status_t AwesomePlayer::seekTo(int64_t timeUs) {
    return OK;
}

status_t AwesomePlayer::setTimedTextTrackIndex(int32_t index) {
    if (mTextDriver != NULL) {
        if (index >= 0) { // to turn on a text track
            status_t err = mTextDriver->setTimedTextTrackIndex(index);
            if (err != OK) {
                return err;
            }

            modifyFlags(TEXT_RUNNING, SET);
            modifyFlags(TEXTPLAYER_STARTED, SET);
            return OK;
        } else { // to turn off the text track display
            if (mFlags  & TEXT_RUNNING) {
                modifyFlags(TEXT_RUNNING, CLEAR);
            }
            if (mFlags  & TEXTPLAYER_STARTED) {
                modifyFlags(TEXTPLAYER_STARTED, CLEAR);
            }

            return mTextDriver->setTimedTextTrackIndex(index);
        }
    } else {
        return INVALID_OPERATION;
    }
}

status_t AwesomePlayer::seekTo_l(int64_t timeUs) {
    if (mFlags & CACHE_UNDERRUN) {
        modifyFlags(CACHE_UNDERRUN, CLEAR);
@@ -1315,7 +1289,7 @@ status_t AwesomePlayer::seekTo_l(int64_t timeUs) {

    seekAudioIfNecessary_l();

    if (mFlags & TEXTPLAYER_STARTED) {
    if (mFlags & TEXTPLAYER_INITIALIZED) {
        mTextDriver->seekToAsync(mSeekTimeUs);
    }

@@ -1691,8 +1665,8 @@ void AwesomePlayer::onVideoEvent() {
        }
    }

    if ((mFlags & TEXTPLAYER_STARTED) && !(mFlags & (TEXT_RUNNING | SEEK_PREVIEW))) {
        mTextDriver->resume();
    if ((mFlags & TEXTPLAYER_INITIALIZED) && !(mFlags & (TEXT_RUNNING | SEEK_PREVIEW))) {
        mTextDriver->start();
        modifyFlags(TEXT_RUNNING, SET);
    }

@@ -2232,20 +2206,6 @@ void AwesomePlayer::postAudioSeekComplete() {

status_t AwesomePlayer::setParameter(int key, const Parcel &request) {
    switch (key) {
        case KEY_PARAMETER_TIMED_TEXT_TRACK_INDEX:
        {
            Mutex::Autolock autoLock(mTimedTextLock);
            return setTimedTextTrackIndex(request.readInt32());
        }
        case KEY_PARAMETER_TIMED_TEXT_ADD_OUT_OF_BAND_SOURCE:
        {
            Mutex::Autolock autoLock(mTimedTextLock);
            if (mTextDriver == NULL) {
                mTextDriver = new TimedTextDriver(mListener);
            }

            return mTextDriver->addOutOfBandTextSource(request);
        }
        case KEY_PARAMETER_CACHE_STAT_COLLECT_FREQ_MS:
        {
            return setCacheStatCollectFreq(request);
@@ -2294,6 +2254,103 @@ status_t AwesomePlayer::getParameter(int key, Parcel *reply) {
    }
}

status_t AwesomePlayer::invoke(const Parcel &request, Parcel *reply) {
    if (NULL == reply) {
        return android::BAD_VALUE;
    }
    int32_t methodId;
    status_t ret = request.readInt32(&methodId);
    if (ret != android::OK) {
        return ret;
    }
    switch(methodId) {
        case INVOKE_ID_GET_TRACK_INFO:
        {
            Mutex::Autolock autoLock(mTimedTextLock);
            if (mTextDriver == NULL) {
                return INVALID_OPERATION;
            }
            mTextDriver->getTrackInfo(reply);
            return OK;
        }
        case INVOKE_ID_ADD_EXTERNAL_SOURCE:
        {
            Mutex::Autolock autoLock(mTimedTextLock);
            if (mTextDriver == NULL) {
                mTextDriver = new TimedTextDriver(mListener);
            }
            // String values written in Parcel are UTF-16 values.
            String16 uri16 = request.readString16();
            const char *uri = NULL;
            if (uri16 != NULL) {
                uri = String8(uri16).string();
            }
            String16 mimeType16 = request.readString16();
            const char *mimeType = NULL;
            if (mimeType16 != NULL) {
                mimeType = String8(mimeType16).string();
            }
            return mTextDriver->addOutOfBandTextSource(uri, mimeType);
        }
        case INVOKE_ID_ADD_EXTERNAL_SOURCE_FD:
        {
            Mutex::Autolock autoLock(mTimedTextLock);
            if (mTextDriver == NULL) {
                mTextDriver = new TimedTextDriver(mListener);
            }
            int fd         = request.readFileDescriptor();
            off64_t offset = request.readInt64();
            size_t length  = request.readInt64();
            String16 mimeType16 = request.readString16();
            const char *mimeType = NULL;
            if (mimeType16 != NULL) {
                mimeType = String8(mimeType16).string();
            }

            return mTextDriver->addOutOfBandTextSource(
                    fd, offset, length, mimeType);
        }
        case INVOKE_ID_SELECT_TRACK:
        {
            Mutex::Autolock autoLock(mTimedTextLock);
            if (mTextDriver == NULL) {
                return INVALID_OPERATION;
            }

            status_t err = mTextDriver->selectTrack(
                    request.readInt32());
            if (err == OK) {
                modifyFlags(TEXTPLAYER_INITIALIZED, SET);
                if (mFlags & PLAYING && !(mFlags & TEXT_RUNNING)) {
                    mTextDriver->start();
                    modifyFlags(TEXT_RUNNING, SET);
                }
            }
            return err;
        }
        case INVOKE_ID_UNSELECT_TRACK:
        {
            Mutex::Autolock autoLock(mTimedTextLock);
            if (mTextDriver == NULL) {
                return INVALID_OPERATION;
            }
            status_t err = mTextDriver->unselectTrack(
                    request.readInt32());
            if (err == OK) {
                modifyFlags(TEXTPLAYER_INITIALIZED, CLEAR);
                modifyFlags(TEXT_RUNNING, CLEAR);
            }
            return err;
        }
        default:
        {
            return ERROR_UNSUPPORTED;
        }
    }
    // It will not reach here.
    return OK;
}

bool AwesomePlayer::isStreamingHTTP() const {
    return mCachedSource != NULL || mWVMExtractor != NULL;
}
Loading