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

Commit 6472badc authored by Insun Kang's avatar Insun Kang
Browse files

Fix: status checking in TimedTextDriver.

o fixes seeking error when there's no enabled text track.
o clean up status checking code for deselectTrack.
o fixes a potential bug : pause->backward seek can trigger unwanted
resume.

Bug: 6682160
Change-Id: I03d8788b27fb9c0a6092be83ad3578ccf3266905
(cherry picked from commit 2dafb6071d4f14e0e208912500694912211aa26b)
parent bb6bc849
Loading
Loading
Loading
Loading
+28 −8
Original line number Diff line number Diff line
@@ -145,21 +145,41 @@ status_t TimedTextDriver::selectTrack(size_t index) {
}

status_t TimedTextDriver::unselectTrack(size_t index) {
    Mutex::Autolock autoLock(mLock);
    if (mCurrentTrackIndex != index) {
        return INVALID_OPERATION;
    }
    status_t err = pause();
    if (err != OK) {
        return err;
    }
    Mutex::Autolock autoLock(mLock);
    switch (mState) {
        case UNINITIALIZED:
            return INVALID_OPERATION;
        case PLAYING:
            mPlayer->pause();
            mState = UNINITIALIZED;
            return OK;
        case PAUSED:
            mState = UNINITIALIZED;
            return OK;
        default:
            TRESPASS();
    }
    return UNKNOWN_ERROR;
}

status_t TimedTextDriver::seekToAsync(int64_t timeUs) {
    Mutex::Autolock autoLock(mLock);
    switch (mState) {
        case UNINITIALIZED:
            return INVALID_OPERATION;
        case PAUSED:
            mPlayer->seekToAsync(timeUs);
            return OK;
        case PLAYING:
            mPlayer->seekToAsync(timeUs);
            return OK;
        defaut:
            TRESPASS();
    }
    return UNKNOWN_ERROR;
}

status_t TimedTextDriver::addInBandTextSource(
+52 −23
Original line number Diff line number Diff line
@@ -41,6 +41,8 @@ static const int64_t kInvalidTimeUs = INT_MIN;
TimedTextPlayer::TimedTextPlayer(const wp<MediaPlayerBase> &listener)
    : mListener(listener),
      mSource(NULL),
      mPendingSeekTimeUs(kInvalidTimeUs),
      mPaused(false),
      mSendSubtitleGeneration(0) {
}

@@ -53,9 +55,7 @@ TimedTextPlayer::~TimedTextPlayer() {
}

void TimedTextPlayer::start() {
    sp<AMessage> msg = new AMessage(kWhatSeek, id());
    msg->setInt64("seekTimeUs", kInvalidTimeUs);
    msg->post();
    (new AMessage(kWhatStart, id()))->post();
}

void TimedTextPlayer::pause() {
@@ -81,11 +81,34 @@ void TimedTextPlayer::setDataSource(sp<TimedTextSource> source) {
void TimedTextPlayer::onMessageReceived(const sp<AMessage> &msg) {
    switch (msg->what()) {
        case kWhatPause: {
            mSendSubtitleGeneration++;
            mPaused = true;
            break;
        }
        case kWhatResume: {
            mPaused = false;
            if (mPendingSeekTimeUs != kInvalidTimeUs) {
                seekToAsync(mPendingSeekTimeUs);
                mPendingSeekTimeUs = kInvalidTimeUs;
            } else {
                doRead();
            }
            break;
        }
        case kWhatStart: {
            sp<MediaPlayerBase> listener = mListener.promote();
            if (listener == NULL) {
                ALOGE("Listener is NULL when kWhatStart is received.");
                break;
            }
            mPaused = false;
            mPendingSeekTimeUs = kInvalidTimeUs;
            int32_t positionMs = 0;
            listener->getCurrentPosition(&positionMs);
            int64_t seekTimeUs = positionMs * 1000ll;

            notifyListener();
            mSendSubtitleGeneration++;
            doSeekAndRead(seekTimeUs);
            break;
        }
        case kWhatRetryRead: {
@@ -110,7 +133,6 @@ void TimedTextPlayer::onMessageReceived(const sp<AMessage> &msg) {
            break;
        }
        case kWhatSeek: {
            mSendSubtitleGeneration++;
            int64_t seekTimeUs = kInvalidTimeUs;
            // Clear a displayed timed text before seeking.
            notifyListener();
@@ -123,6 +145,11 @@ void TimedTextPlayer::onMessageReceived(const sp<AMessage> &msg) {
                    seekTimeUs = positionMs * 1000ll;
                }
            }
            if (mPaused) {
                mPendingSeekTimeUs = seekTimeUs;
                break;
            }
            mSendSubtitleGeneration++;
            doSeekAndRead(seekTimeUs);
            break;
        }
@@ -221,8 +248,6 @@ void TimedTextPlayer::doRead(MediaSource::ReadOptions* options) {

void TimedTextPlayer::postTextEvent(const sp<ParcelEvent>& parcel, int64_t timeUs) {
    int64_t delayUs = delayUsFromCurrentTime(timeUs);
    sp<MediaPlayerBase> listener = mListener.promote();
    if (listener != NULL) {
    sp<AMessage> msg = new AMessage(kWhatSendSubtitle, id());
    msg->setInt32("generation", mSendSubtitleGeneration);
    if (parcel != NULL) {
@@ -231,12 +256,12 @@ void TimedTextPlayer::postTextEvent(const sp<ParcelEvent>& parcel, int64_t timeU
    msg->setInt64("fireTimeUs", timeUs);
    msg->post(delayUs);
}
}

int64_t TimedTextPlayer::delayUsFromCurrentTime(int64_t fireTimeUs) {
    sp<MediaPlayerBase> listener = mListener.promote();
    if (listener == NULL) {
        // TODO: it may be better to return kInvalidTimeUs
        ALOGE("%s: Listener is NULL.", __FUNCTION__, fireTimeUs);
        return 0;
    }
    int32_t positionMs = 0;
@@ -256,20 +281,24 @@ int64_t TimedTextPlayer::delayUsFromCurrentTime(int64_t fireTimeUs) {

void TimedTextPlayer::notifyError(int error) {
    sp<MediaPlayerBase> listener = mListener.promote();
    if (listener != NULL) {
        listener->sendEvent(MEDIA_INFO, MEDIA_INFO_TIMED_TEXT_ERROR, error);
    if (listener == NULL) {
        ALOGE("%s(error=%d): Listener is NULL.", __FUNCTION__, error);
        return;
    }
    listener->sendEvent(MEDIA_INFO, MEDIA_INFO_TIMED_TEXT_ERROR, error);
}

void TimedTextPlayer::notifyListener(const Parcel *parcel) {
    sp<MediaPlayerBase> listener = mListener.promote();
    if (listener != NULL) {
    if (listener == NULL) {
        ALOGE("%s: Listener is NULL.", __FUNCTION__);
        return;
    }
    if (parcel != NULL && (parcel->dataSize() > 0)) {
        listener->sendEvent(MEDIA_TIMED_TEXT, 0, 0, parcel);
    } else {  // send an empty timed text to clear the screen
        listener->sendEvent(MEDIA_TIMED_TEXT);
    }
}
}

}  // namespace android
+4 −1
Original line number Diff line number Diff line
@@ -50,8 +50,9 @@ protected:
private:
    enum {
        kWhatPause = 'paus',
        kWhatSeek = 'seek',
        kWhatResume = 'resm',
        kWhatStart = 'strt',
        kWhatSeek = 'seek',
        kWhatRetryRead = 'read',
        kWhatSendSubtitle = 'send',
        kWhatSetSource = 'ssrc',
@@ -64,6 +65,8 @@ private:

    wp<MediaPlayerBase> mListener;
    sp<TimedTextSource> mSource;
    int64_t mPendingSeekTimeUs;
    bool mPaused;
    int32_t mSendSubtitleGeneration;

    void doSeekAndRead(int64_t seekTimeUs);