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

Commit cdd1f539 authored by Wei Jia's avatar Wei Jia Committed by The Android Automerger
Browse files

Revert GenericSource track selection changes

This reverts commit bace25b0.
This reverts commit eb1735e3.
This reverts commit 05312bc7.

Bug: 16660839
parent 4670188e
Loading
Loading
Loading
Loading
+61 −407
Original line number Diff line number Diff line
@@ -41,8 +41,6 @@ NuPlayer::GenericSource::GenericSource(
        bool uidValid,
        uid_t uid)
    : Source(notify),
      mFetchSubtitleDataGeneration(0),
      mFetchTimedTextDataGeneration(0),
      mDurationUs(0ll),
      mAudioIsVorbis(false),
      mIsWidevine(isWidevine),
@@ -61,8 +59,6 @@ NuPlayer::GenericSource::GenericSource(
        const sp<AMessage> &notify,
        int fd, int64_t offset, int64_t length)
    : Source(notify),
      mFetchSubtitleDataGeneration(0),
      mFetchTimedTextDataGeneration(0),
      mDurationUs(0ll),
      mAudioIsVorbis(false) {
    DataSource::RegisterDefaultSniffers();
@@ -184,18 +180,20 @@ void NuPlayer::GenericSource::start() {

    if (mAudioTrack.mSource != NULL) {
        CHECK_EQ(mAudioTrack.mSource->start(), (status_t)OK);

        mAudioTrack.mPackets =
            new AnotherPacketSource(mAudioTrack.mSource->getFormat());

        readBuffer(MEDIA_TRACK_TYPE_AUDIO);
        readBuffer(true /* audio */);
    }

    if (mVideoTrack.mSource != NULL) {
        CHECK_EQ(mVideoTrack.mSource->start(), (status_t)OK);

        mVideoTrack.mPackets =
            new AnotherPacketSource(mVideoTrack.mSource->getFormat());

        readBuffer(MEDIA_TRACK_TYPE_VIDEO);
        readBuffer(false /* audio */);
    }
}

@@ -203,158 +201,6 @@ status_t NuPlayer::GenericSource::feedMoreTSData() {
    return OK;
}

void NuPlayer::GenericSource::onMessageReceived(const sp<AMessage> &msg) {
    switch (msg->what()) {
      case kWhatFetchSubtitleData:
      {
          fetchTextData(kWhatSendSubtitleData, MEDIA_TRACK_TYPE_SUBTITLE,
                  mFetchSubtitleDataGeneration, mSubtitleTrack.mPackets, msg);
          break;
      }

      case kWhatFetchTimedTextData:
      {
          fetchTextData(kWhatSendTimedTextData, MEDIA_TRACK_TYPE_TIMEDTEXT,
                  mFetchTimedTextDataGeneration, mTimedTextTrack.mPackets, msg);
          break;
      }

      case kWhatSendSubtitleData:
      {
          sendTextData(kWhatSubtitleData, MEDIA_TRACK_TYPE_SUBTITLE,
                  mFetchSubtitleDataGeneration, mSubtitleTrack.mPackets, msg);
          break;
      }

      case kWhatSendTimedTextData:
      {
          sendTextData(kWhatTimedTextData, MEDIA_TRACK_TYPE_TIMEDTEXT,
                  mFetchTimedTextDataGeneration, mTimedTextTrack.mPackets, msg);
          break;
      }

      case kWhatChangeAVSource:
      {
          int32_t trackIndex;
          CHECK(msg->findInt32("trackIndex", &trackIndex));
          const sp<MediaSource> source = mSources.itemAt(trackIndex);

          Track* track;
          const char *mime;
          media_track_type trackType, counterpartType;
          sp<MetaData> meta = source->getFormat();
          meta->findCString(kKeyMIMEType, &mime);
          if (!strncasecmp(mime, "audio/", 6)) {
              track = &mAudioTrack;
              trackType = MEDIA_TRACK_TYPE_AUDIO;
              counterpartType = MEDIA_TRACK_TYPE_VIDEO;;
          } else {
              CHECK(!strncasecmp(mime, "video/", 6));
              track = &mVideoTrack;
              trackType = MEDIA_TRACK_TYPE_VIDEO;
              counterpartType = MEDIA_TRACK_TYPE_AUDIO;;
          }


          if (track->mSource != NULL) {
              track->mSource->stop();
          }
          track->mSource = source;
          track->mSource->start();
          track->mIndex = trackIndex;

          status_t avail;
          if (!track->mPackets->hasBufferAvailable(&avail)) {
              // sync from other source
              TRESPASS();
              break;
          }

          int64_t timeUs, actualTimeUs;
          const bool formatChange = true;
          sp<AMessage> latestMeta = track->mPackets->getLatestMeta();
          CHECK(latestMeta != NULL && latestMeta->findInt64("timeUs", &timeUs));
          readBuffer(trackType, timeUs, &actualTimeUs, formatChange);
          readBuffer(counterpartType, -1, NULL, formatChange);
          ALOGV("timeUs %lld actualTimeUs %lld", timeUs, actualTimeUs);

          break;
      }

      default:
          Source::onMessageReceived(msg);
          break;
    }
}

void NuPlayer::GenericSource::fetchTextData(
        uint32_t sendWhat,
        media_track_type type,
        int32_t curGen,
        sp<AnotherPacketSource> packets,
        sp<AMessage> msg) {
    int32_t msgGeneration;
    CHECK(msg->findInt32("generation", &msgGeneration));
    if (msgGeneration != curGen) {
        // stale
        return;
    }

    int32_t avail;
    if (packets->hasBufferAvailable(&avail)) {
        return;
    }

    int64_t timeUs;
    CHECK(msg->findInt64("timeUs", &timeUs));

    int64_t subTimeUs;
    readBuffer(type, timeUs, &subTimeUs);

    int64_t delayUs = subTimeUs - timeUs;
    if (msg->what() == kWhatFetchSubtitleData) {
        const int64_t oneSecUs = 1000000ll;
        delayUs -= oneSecUs;
    }
    sp<AMessage> msg2 = new AMessage(sendWhat, id());
    msg2->setInt32("generation", msgGeneration);
    msg2->post(delayUs < 0 ? 0 : delayUs);
}

void NuPlayer::GenericSource::sendTextData(
        uint32_t what,
        media_track_type type,
        int32_t curGen,
        sp<AnotherPacketSource> packets,
        sp<AMessage> msg) {
    int32_t msgGeneration;
    CHECK(msg->findInt32("generation", &msgGeneration));
    if (msgGeneration != curGen) {
        // stale
        return;
    }

    int64_t subTimeUs;
    if (packets->nextBufferTime(&subTimeUs) != OK) {
        return;
    }

    int64_t nextSubTimeUs;
    readBuffer(type, -1, &nextSubTimeUs);

    sp<ABuffer> buffer;
    status_t dequeueStatus = packets->dequeueAccessUnit(&buffer);
    if (dequeueStatus == OK) {
        sp<AMessage> notify = dupNotify();
        notify->setInt32("what", what);
        notify->setBuffer("buffer", buffer);
        notify->post();

        const int64_t delayUs = nextSubTimeUs - subTimeUs;
        msg->post(delayUs < 0 ? 0 : delayUs);
    }
}

sp<MetaData> NuPlayer::GenericSource::getFormatMeta(bool audio) {
    sp<MediaSource> source = audio ? mAudioTrack.mSource : mVideoTrack.mSource;

@@ -375,7 +221,7 @@ status_t NuPlayer::GenericSource::dequeueAccessUnit(

    if (mIsWidevine && !audio) {
        // try to read a buffer as we may not have been able to the last time
        readBuffer(MEDIA_TRACK_TYPE_AUDIO, -1ll);
        readBuffer(audio, -1ll);
    }

    status_t finalResult;
@@ -385,52 +231,7 @@ status_t NuPlayer::GenericSource::dequeueAccessUnit(

    status_t result = track->mPackets->dequeueAccessUnit(accessUnit);

    if (!track->mPackets->hasBufferAvailable(&finalResult)) {
        readBuffer(audio? MEDIA_TRACK_TYPE_AUDIO : MEDIA_TRACK_TYPE_VIDEO, -1ll);
    }

    if (mSubtitleTrack.mSource == NULL && mTimedTextTrack.mSource == NULL) {
        return result;
    }

    if (mSubtitleTrack.mSource != NULL) {
        CHECK(mSubtitleTrack.mPackets != NULL);
    }
    if (mTimedTextTrack.mSource != NULL) {
        CHECK(mTimedTextTrack.mPackets != NULL);
    }

    if (result != OK) {
        if (mSubtitleTrack.mSource != NULL) {
            mSubtitleTrack.mPackets->clear();
            mFetchSubtitleDataGeneration++;
        }
        if (mTimedTextTrack.mSource != NULL) {
            mTimedTextTrack.mPackets->clear();
            mFetchTimedTextDataGeneration++;
        }
        return result;
    }

    int64_t timeUs;
    status_t eosResult; // ignored
    CHECK((*accessUnit)->meta()->findInt64("timeUs", &timeUs));

    if (mSubtitleTrack.mSource != NULL
            && !mSubtitleTrack.mPackets->hasBufferAvailable(&eosResult)) {
        sp<AMessage> msg = new AMessage(kWhatFetchSubtitleData, id());
        msg->setInt64("timeUs", timeUs);
        msg->setInt32("generation", mFetchSubtitleDataGeneration);
        msg->post();
    }

    if (mTimedTextTrack.mSource != NULL
            && !mTimedTextTrack.mPackets->hasBufferAvailable(&eosResult)) {
        sp<AMessage> msg = new AMessage(kWhatFetchTimedTextData, id());
        msg->setInt64("timeUs", timeUs);
        msg->setInt32("generation", mFetchTimedTextDataGeneration);
        msg->post();
    }
    readBuffer(audio, -1ll);

    return result;
}
@@ -490,247 +291,100 @@ sp<AMessage> NuPlayer::GenericSource::getTrackInfo(size_t trackIndex) const {
    return format;
}

ssize_t NuPlayer::GenericSource::getSelectedTrack(media_track_type type) const {
    const Track *track = NULL;
    switch (type) {
    case MEDIA_TRACK_TYPE_VIDEO:
        track = &mVideoTrack;
        break;
    case MEDIA_TRACK_TYPE_AUDIO:
        track = &mAudioTrack;
        break;
    case MEDIA_TRACK_TYPE_TIMEDTEXT:
        track = &mTimedTextTrack;
        break;
    case MEDIA_TRACK_TYPE_SUBTITLE:
        track = &mSubtitleTrack;
        break;
    default:
        break;
    }

    if (track != NULL && track->mSource != NULL) {
        return track->mIndex;
    }

    return -1;
}
status_t NuPlayer::GenericSource::seekTo(int64_t seekTimeUs) {
    if (mVideoTrack.mSource != NULL) {
        int64_t actualTimeUs;
        readBuffer(false /* audio */, seekTimeUs, &actualTimeUs);

status_t NuPlayer::GenericSource::selectTrack(size_t trackIndex, bool select) {
    ALOGV("%s track: %zu", select ? "select" : "deselect", trackIndex);
    if (trackIndex >= mSources.size()) {
        return BAD_INDEX;
        seekTimeUs = actualTimeUs;
    }

    if (!select) {
        Track* track = NULL;
        if (mSubtitleTrack.mSource != NULL && trackIndex == mSubtitleTrack.mIndex) {
            track = &mSubtitleTrack;
            mFetchSubtitleDataGeneration++;
        } else if (mTimedTextTrack.mSource != NULL && trackIndex == mTimedTextTrack.mIndex) {
            track = &mTimedTextTrack;
            mFetchTimedTextDataGeneration++;
        }
        if (track == NULL) {
            return INVALID_OPERATION;
        }
        track->mSource->stop();
        track->mSource = NULL;
        track->mPackets->clear();
        return OK;
    if (mAudioTrack.mSource != NULL) {
        readBuffer(true /* audio */, seekTimeUs);
    }

    const sp<MediaSource> source = mSources.itemAt(trackIndex);
    sp<MetaData> meta = source->getFormat();
    const char *mime;
    CHECK(meta->findCString(kKeyMIMEType, &mime));
    if (!strncasecmp(mime, "text/", 5)) {
        bool isSubtitle = strcasecmp(mime, MEDIA_MIMETYPE_TEXT_3GPP);
        Track *track = isSubtitle ? &mSubtitleTrack : &mTimedTextTrack;
        if (track->mSource != NULL && track->mIndex == trackIndex) {
    return OK;
}
        track->mIndex = trackIndex;
        if (track->mSource != NULL) {
            track->mSource->stop();
        }
        track->mSource = mSources.itemAt(trackIndex);
        track->mSource->start();
        if (track->mPackets == NULL) {
            track->mPackets = new AnotherPacketSource(track->mSource->getFormat());
        } else {
            track->mPackets->clear();
            track->mPackets->setFormat(track->mSource->getFormat());

        }

        if (isSubtitle) {
            mFetchSubtitleDataGeneration++;
        } else {
            mFetchTimedTextDataGeneration++;
        }

        return OK;
    } else if (!strncasecmp(mime, "audio/", 6) || !strncasecmp(mime, "video/", 6)) {
        bool audio = !strncasecmp(mime, "audio/", 6);
void NuPlayer::GenericSource::readBuffer(
        bool audio, int64_t seekTimeUs, int64_t *actualTimeUs) {
    Track *track = audio ? &mAudioTrack : &mVideoTrack;
        if (track->mSource != NULL && track->mIndex == trackIndex) {
            return OK;
        }
    CHECK(track->mSource != NULL);

        sp<AMessage> msg = new AMessage(kWhatChangeAVSource, id());
        msg->setInt32("trackIndex", trackIndex);
        msg->post();
        return OK;
    if (actualTimeUs) {
        *actualTimeUs = seekTimeUs;
    }

    return INVALID_OPERATION;
}
    MediaSource::ReadOptions options;

status_t NuPlayer::GenericSource::seekTo(int64_t seekTimeUs) {
    if (mVideoTrack.mSource != NULL) {
        int64_t actualTimeUs;
        readBuffer(MEDIA_TRACK_TYPE_VIDEO, seekTimeUs, &actualTimeUs);
    bool seeking = false;

        seekTimeUs = actualTimeUs;
    if (seekTimeUs >= 0) {
        options.setSeekTo(seekTimeUs);
        seeking = true;
    }

    if (mAudioTrack.mSource != NULL) {
        readBuffer(MEDIA_TRACK_TYPE_AUDIO, seekTimeUs);
    if (mIsWidevine && !audio) {
        options.setNonBlocking();
    }

    return OK;
}
    for (;;) {
        MediaBuffer *mbuf;
        status_t err = track->mSource->read(&mbuf, &options);

sp<ABuffer> NuPlayer::GenericSource::mediaBufferToABuffer(
        MediaBuffer* mb,
        media_track_type trackType,
        int64_t *actualTimeUs) {
    bool audio = trackType == MEDIA_TRACK_TYPE_AUDIO;
    size_t outLength = mb->range_length();
        options.clearSeekTo();

        if (err == OK) {
            size_t outLength = mbuf->range_length();

            if (audio && mAudioIsVorbis) {
                outLength += sizeof(int32_t);
            }

    sp<ABuffer> ab;
            sp<ABuffer> buffer;
            if (mIsWidevine && !audio) {
                // data is already provided in the buffer
        ab = new ABuffer(NULL, mb->range_length());
        ab->meta()->setPointer("mediaBuffer", mb);
        mb->add_ref();
                buffer = new ABuffer(NULL, mbuf->range_length());
                buffer->meta()->setPointer("mediaBuffer", mbuf);
                mbuf->add_ref();
            } else {
        ab = new ABuffer(outLength);
        memcpy(ab->data(),
               (const uint8_t *)mb->data() + mb->range_offset(),
               mb->range_length());
                buffer = new ABuffer(outLength);
                memcpy(buffer->data(),
                       (const uint8_t *)mbuf->data() + mbuf->range_offset(),
                       mbuf->range_length());
            }

            if (audio && mAudioIsVorbis) {
                int32_t numPageSamples;
        if (!mb->meta_data()->findInt32(kKeyValidSamples, &numPageSamples)) {
                if (!mbuf->meta_data()->findInt32(
                            kKeyValidSamples, &numPageSamples)) {
                    numPageSamples = -1;
                }

        uint8_t* abEnd = ab->data() + mb->range_length();
        memcpy(abEnd, &numPageSamples, sizeof(numPageSamples));
                memcpy(buffer->data() + mbuf->range_length(),
                       &numPageSamples,
                       sizeof(numPageSamples));
            }

    sp<AMessage> meta = ab->meta();

            int64_t timeUs;
    CHECK(mb->meta_data()->findInt64(kKeyTime, &timeUs));
    meta->setInt64("timeUs", timeUs);
            CHECK(mbuf->meta_data()->findInt64(kKeyTime, &timeUs));

    if (trackType == MEDIA_TRACK_TYPE_TIMEDTEXT) {
        const char *mime;
        CHECK(mTimedTextTrack.mSource != NULL
                && mTimedTextTrack.mSource->getFormat()->findCString(kKeyMIMEType, &mime));
        meta->setString("mime", mime);
    }

    int64_t durationUs;
    if (mb->meta_data()->findInt64(kKeyDuration, &durationUs)) {
        meta->setInt64("durationUs", durationUs);
    }

    if (trackType == MEDIA_TRACK_TYPE_SUBTITLE) {
        meta->setInt32("trackIndex", mSubtitleTrack.mIndex);
    }
            buffer->meta()->setInt64("timeUs", timeUs);

            if (actualTimeUs) {
                *actualTimeUs = timeUs;
            }

    mb->release();
    mb = NULL;

    return ab;
}

void NuPlayer::GenericSource::readBuffer(
        media_track_type trackType, int64_t seekTimeUs, int64_t *actualTimeUs, bool formatChange) {
    Track *track;
    switch (trackType) {
        case MEDIA_TRACK_TYPE_VIDEO:
            track = &mVideoTrack;
            break;
        case MEDIA_TRACK_TYPE_AUDIO:
            track = &mAudioTrack;
            break;
        case MEDIA_TRACK_TYPE_SUBTITLE:
            track = &mSubtitleTrack;
            break;
        case MEDIA_TRACK_TYPE_TIMEDTEXT:
            track = &mTimedTextTrack;
            break;
        default:
            TRESPASS();
    }
            mbuf->release();
            mbuf = NULL;

    if (track->mSource == NULL) {
        return;
    }

    if (actualTimeUs) {
        *actualTimeUs = seekTimeUs;
    }

    MediaSource::ReadOptions options;

    bool seeking = false;

    if (seekTimeUs >= 0) {
        options.setSeekTo(seekTimeUs, MediaSource::ReadOptions::SEEK_PREVIOUS_SYNC);
        seeking = true;
    }

    if (mIsWidevine && trackType != MEDIA_TRACK_TYPE_AUDIO) {
        options.setNonBlocking();
            if (seeking) {
                track->mPackets->queueDiscontinuity(
                        ATSParser::DISCONTINUITY_SEEK,
                        NULL,
                        true /* discard */);
            }

    for (;;) {
        MediaBuffer *mbuf;
        status_t err = track->mSource->read(&mbuf, &options);

        options.clearSeekTo();

        if (err == OK) {
            // formatChange && seeking: track whose source is changed during selection
            // formatChange && !seeking: track whose source is not changed during selection
            // !formatChange: normal seek
            if ((seeking || formatChange)
                    && (trackType == MEDIA_TRACK_TYPE_AUDIO
                    || trackType == MEDIA_TRACK_TYPE_VIDEO)) {
                ATSParser::DiscontinuityType type = formatChange
                        ? (seeking
                                ? ATSParser::DISCONTINUITY_FORMATCHANGE
                                : ATSParser::DISCONTINUITY_NONE)
                        : ATSParser::DISCONTINUITY_SEEK;
                track->mPackets->queueDiscontinuity( type, NULL, true /* discard */);
            }

            sp<ABuffer> buffer = mediaBufferToABuffer(mbuf, trackType, actualTimeUs);
            track->mPackets->queueAccessUnit(buffer);
            break;
        } else if (err == WOULD_BLOCK) {
+2 −34
Original line number Diff line number Diff line
@@ -23,15 +23,12 @@

#include "ATSParser.h"

#include <media/mediaplayer.h>

namespace android {

struct AnotherPacketSource;
struct ARTSPController;
struct DataSource;
struct MediaSource;
class MediaBuffer;

struct NuPlayer::GenericSource : public NuPlayer::Source {
    GenericSource(
@@ -58,8 +55,6 @@ struct NuPlayer::GenericSource : public NuPlayer::Source {
    virtual status_t getDuration(int64_t *durationUs);
    virtual size_t getTrackCount() const;
    virtual sp<AMessage> getTrackInfo(size_t trackIndex) const;
    virtual ssize_t getSelectedTrack(media_track_type type) const;
    virtual status_t selectTrack(size_t trackIndex, bool select);
    virtual status_t seekTo(int64_t seekTimeUs);

    virtual status_t setBuffers(bool audio, Vector<MediaBuffer *> &buffers);
@@ -67,19 +62,9 @@ struct NuPlayer::GenericSource : public NuPlayer::Source {
protected:
    virtual ~GenericSource();

    virtual void onMessageReceived(const sp<AMessage> &msg);

    virtual sp<MetaData> getFormatMeta(bool audio);

private:
    enum {
        kWhatFetchSubtitleData,
        kWhatFetchTimedTextData,
        kWhatSendSubtitleData,
        kWhatSendTimedTextData,
        kWhatChangeAVSource,
    };

    Vector<sp<MediaSource> > mSources;

    struct Track {
@@ -90,11 +75,7 @@ private:

    Track mAudioTrack;
    Track mVideoTrack;
    Track mSubtitleTrack;
    Track mTimedTextTrack;

    int32_t mFetchSubtitleDataGeneration;
    int32_t mFetchTimedTextDataGeneration;
    int64_t mDurationUs;
    bool mAudioIsVorbis;
    bool mIsWidevine;
@@ -103,22 +84,9 @@ private:

    void initFromDataSource(const sp<DataSource> &dataSource);

    void fetchTextData(
            uint32_t what, media_track_type type,
            int32_t curGen, sp<AnotherPacketSource> packets, sp<AMessage> msg);

    void sendTextData(
            uint32_t what, media_track_type type,
            int32_t curGen, sp<AnotherPacketSource> packets, sp<AMessage> msg);

    sp<ABuffer> mediaBufferToABuffer(
            MediaBuffer *mbuf,
            media_track_type trackType,
            int64_t *actualTimeUs = NULL);

    void readBuffer(
            media_track_type trackType,
            int64_t seekTimeUs = -1ll, int64_t *actualTimeUs = NULL, bool formatChange = false);
            bool audio,
            int64_t seekTimeUs = -1ll, int64_t *actualTimeUs = NULL);

    DISALLOW_EVIL_CONSTRUCTORS(GenericSource);
};
+2 −10
Original line number Diff line number Diff line
@@ -34,7 +34,6 @@ const int64_t kNearEOSMarkUs = 2000000ll; // 2 secs

AnotherPacketSource::AnotherPacketSource(const sp<MetaData> &meta)
    : mIsAudio(false),
      mIsVideo(false),
      mFormat(NULL),
      mLastQueuedTimeUs(0),
      mEOSResult(OK),
@@ -46,7 +45,6 @@ void AnotherPacketSource::setFormat(const sp<MetaData> &meta) {
    CHECK(mFormat == NULL);

    mIsAudio = false;
    mIsVideo = false;

    if (meta == NULL) {
        return;
@@ -58,10 +56,8 @@ void AnotherPacketSource::setFormat(const sp<MetaData> &meta) {

    if (!strncasecmp("audio/", mime, 6)) {
        mIsAudio = true;
    } else  if (!strncasecmp("video/", mime, 6)) {
        mIsVideo = true;
    } else {
        CHECK(!strncasecmp("text/", mime, 5));
        CHECK(!strncasecmp("video/", mime, 6));
    }
}

@@ -179,13 +175,9 @@ bool AnotherPacketSource::wasFormatChange(
        return (discontinuityType & ATSParser::DISCONTINUITY_AUDIO_FORMAT) != 0;
    }

    if (mIsVideo) {
    return (discontinuityType & ATSParser::DISCONTINUITY_VIDEO_FORMAT) != 0;
}

    return false;
}

void AnotherPacketSource::queueAccessUnit(const sp<ABuffer> &buffer) {
    int32_t damaged;
    if (buffer->meta()->findInt32("damaged", &damaged) && damaged) {
+0 −1
Original line number Diff line number Diff line
@@ -74,7 +74,6 @@ private:
    Condition mCondition;

    bool mIsAudio;
    bool mIsVideo;
    sp<MetaData> mFormat;
    int64_t mLastQueuedTimeUs;
    List<sp<ABuffer> > mBuffers;