void NuPlayer::RTSPSource::performSeek(int64_t seekTimeUs) { if (mState != CONNECTED) { finishSeek(INVALID_OPERATION); return; } mState = SEEKING; mHandler->seek(seekTimeUs); }
void NuPlayer::RTSPSource::onMessageReceived(const sp<AMessage> &msg) { if (msg->what() == kWhatDisconnect) { sp<AReplyToken> replyID; CHECK(msg->senderAwaitsResponse(&replyID)); mDisconnectReplyID = replyID; finishDisconnectIfPossible(); return; } else if (msg->what() == kWhatPerformSeek) { int32_t generation; CHECK(msg->findInt32("generation", &generation)); CHECK(msg->senderAwaitsResponse(&mSeekReplyID)); if (generation != mSeekGeneration) { // obsolete. finishSeek(OK); return; } int64_t seekTimeUs; CHECK(msg->findInt64("timeUs", &seekTimeUs)); performSeek(seekTimeUs); return; } else if (msg->what() == kWhatPollBuffering) { onPollBuffering(); return; } else if (msg->what() == kWhatSignalEOS) { onSignalEOS(msg); return; } CHECK_EQ(msg->what(), (int)kWhatNotify); int32_t what; CHECK(msg->findInt32("what", &what)); switch (what) { case MyHandler::kWhatConnected: { onConnected(); notifyVideoSizeChanged(); uint32_t flags = 0; if (mHandler->isSeekable()) { flags = FLAG_CAN_PAUSE | FLAG_CAN_SEEK | FLAG_CAN_SEEK_BACKWARD | FLAG_CAN_SEEK_FORWARD; } notifyFlagsChanged(flags); schedulePollBuffering(); break; } case MyHandler::kWhatDisconnected: { onDisconnected(msg); break; } case MyHandler::kWhatSeekDone: { mState = CONNECTED; // Unblock seekTo here in case we attempted to seek in a live stream finishSeek(OK); break; } case MyHandler::kWhatSeekPaused: { sp<AnotherPacketSource> source = getSource(true /* audio */); if (source != NULL) { source->queueDiscontinuity(ATSParser::DISCONTINUITY_NONE, /* extra */ NULL, /* discard */ true); } source = getSource(false /* video */); if (source != NULL) { source->queueDiscontinuity(ATSParser::DISCONTINUITY_NONE, /* extra */ NULL, /* discard */ true); }; status_t err = OK; msg->findInt32("err", &err); if (err == OK) { int64_t timeUs; CHECK(msg->findInt64("time", &timeUs)); mHandler->continueSeekAfterPause(timeUs); } else { finishSeek(err); } break; } case MyHandler::kWhatAccessUnit: { size_t trackIndex; CHECK(msg->findSize("trackIndex", &trackIndex)); if (mTSParser == NULL) { CHECK_LT(trackIndex, mTracks.size()); } else { CHECK_EQ(trackIndex, 0u); } sp<ABuffer> accessUnit; CHECK(msg->findBuffer("accessUnit", &accessUnit)); int32_t damaged; if (accessUnit->meta()->findInt32("damaged", &damaged) && damaged) { ALOGI("dropping damaged access unit."); break; } if (mTSParser != NULL) { size_t offset = 0; status_t err = OK; while (offset + 188 <= accessUnit->size()) { err = mTSParser->feedTSPacket( accessUnit->data() + offset, 188); if (err != OK) { break; } offset += 188; } if (offset < accessUnit->size()) { err = ERROR_MALFORMED; } if (err != OK) { signalSourceEOS(err); } postSourceEOSIfNecessary(); break; } TrackInfo *info = &mTracks.editItemAt(trackIndex); sp<AnotherPacketSource> source = info->mSource; if (source != NULL) { uint32_t rtpTime; CHECK(accessUnit->meta()->findInt32("rtp-time", (int32_t *)&rtpTime)); if (!info->mNPTMappingValid) { // This is a live stream, we didn't receive any normal // playtime mapping. We won't map to npt time. source->queueAccessUnit(accessUnit); break; } int64_t nptUs = ((double)rtpTime - (double)info->mRTPTime) / info->mTimeScale * 1000000ll + info->mNormalPlaytimeUs; accessUnit->meta()->setInt64("timeUs", nptUs); source->queueAccessUnit(accessUnit); } postSourceEOSIfNecessary(); break; } case MyHandler::kWhatEOS: { int32_t finalResult; CHECK(msg->findInt32("finalResult", &finalResult)); CHECK_NE(finalResult, (status_t)OK); if (mTSParser != NULL) { signalSourceEOS(finalResult); } size_t trackIndex; CHECK(msg->findSize("trackIndex", &trackIndex)); CHECK_LT(trackIndex, mTracks.size()); TrackInfo *info = &mTracks.editItemAt(trackIndex); sp<AnotherPacketSource> source = info->mSource; if (source != NULL) { source->signalEOS(finalResult); } break; } case MyHandler::kWhatSeekDiscontinuity: { size_t trackIndex; CHECK(msg->findSize("trackIndex", &trackIndex)); CHECK_LT(trackIndex, mTracks.size()); TrackInfo *info = &mTracks.editItemAt(trackIndex); sp<AnotherPacketSource> source = info->mSource; if (source != NULL) { source->queueDiscontinuity( ATSParser::DISCONTINUITY_TIME, NULL, true /* discard */); } break; } case MyHandler::kWhatNormalPlayTimeMapping: { size_t trackIndex; CHECK(msg->findSize("trackIndex", &trackIndex)); CHECK_LT(trackIndex, mTracks.size()); uint32_t rtpTime; CHECK(msg->findInt32("rtpTime", (int32_t *)&rtpTime)); int64_t nptUs; CHECK(msg->findInt64("nptUs", &nptUs)); TrackInfo *info = &mTracks.editItemAt(trackIndex); info->mRTPTime = rtpTime; info->mNormalPlaytimeUs = nptUs; info->mNPTMappingValid = true; break; } case SDPLoader::kWhatSDPLoaded: { onSDPLoaded(msg); break; } default: TRESPASS(); } }