diff options
Diffstat (limited to 'media')
-rw-r--r-- | media/libmediaplayerservice/nuplayer/RTSPSource.cpp | 57 | ||||
-rw-r--r-- | media/libmediaplayerservice/nuplayer/RTSPSource.h | 6 | ||||
-rw-r--r-- | media/libstagefright/AwesomePlayer.cpp | 4 | ||||
-rw-r--r-- | media/libstagefright/DRMExtractor.cpp | 8 | ||||
-rw-r--r-- | media/libstagefright/DataSource.cpp | 2 | ||||
-rw-r--r-- | media/libstagefright/WVMExtractor.cpp | 56 | ||||
-rw-r--r-- | media/libstagefright/foundation/ABitReader.cpp | 8 | ||||
-rw-r--r-- | media/libstagefright/include/WVMExtractor.h | 8 | ||||
-rw-r--r-- | media/libstagefright/rtsp/MyHandler.h | 14 |
9 files changed, 131 insertions, 32 deletions
diff --git a/media/libmediaplayerservice/nuplayer/RTSPSource.cpp b/media/libmediaplayerservice/nuplayer/RTSPSource.cpp index e72adc4..6d28298 100644 --- a/media/libmediaplayerservice/nuplayer/RTSPSource.cpp +++ b/media/libmediaplayerservice/nuplayer/RTSPSource.cpp @@ -38,7 +38,8 @@ NuPlayer::RTSPSource::RTSPSource( mFlags(0), mState(DISCONNECTED), mFinalResult(OK), - mDisconnectReplyID(0) { + mDisconnectReplyID(0), + mSeekGeneration(0) { if (headers) { mExtraHeaders = *headers; @@ -146,14 +147,21 @@ status_t NuPlayer::RTSPSource::getDuration(int64_t *durationUs) { } status_t NuPlayer::RTSPSource::seekTo(int64_t seekTimeUs) { + sp<AMessage> msg = new AMessage(kWhatPerformSeek, mReflector->id()); + msg->setInt32("generation", ++mSeekGeneration); + msg->setInt64("timeUs", seekTimeUs); + msg->post(200000ll); + + return OK; +} + +void NuPlayer::RTSPSource::performSeek(int64_t seekTimeUs) { if (mState != CONNECTED) { - return UNKNOWN_ERROR; + return; } mState = SEEKING; mHandler->seek(seekTimeUs); - - return OK; } bool NuPlayer::RTSPSource::isSeekable() { @@ -168,6 +176,20 @@ void NuPlayer::RTSPSource::onMessageReceived(const sp<AMessage> &msg) { mDisconnectReplyID = replyID; finishDisconnectIfPossible(); return; + } else if (msg->what() == kWhatPerformSeek) { + int32_t generation; + CHECK(msg->findInt32("generation", &generation)); + + if (generation != mSeekGeneration) { + // obsolete. + return; + } + + int64_t seekTimeUs; + CHECK(msg->findInt64("timeUs", &seekTimeUs)); + + performSeek(seekTimeUs); + return; } CHECK_EQ(msg->what(), (int)kWhatNotify); @@ -208,21 +230,32 @@ void NuPlayer::RTSPSource::onMessageReceived(const sp<AMessage> &msg) { break; } - const TrackInfo &info = mTracks.editItemAt(trackIndex); - sp<AnotherPacketSource> source = info.mSource; + TrackInfo *info = &mTracks.editItemAt(trackIndex); + + sp<AnotherPacketSource> source = info->mSource; if (source != NULL) { -#if 1 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. Assume the first packets correspond + // to time 0. + + ALOGV("This is a live stream, assuming time = 0"); + + info->mRTPTime = rtpTime; + info->mNormalPlaytimeUs = 0ll; + info->mNPTMappingValid = true; + } + int64_t nptUs = - ((double)rtpTime - (double)info.mRTPTime) - / info.mTimeScale + ((double)rtpTime - (double)info->mRTPTime) + / info->mTimeScale * 1000000ll - + info.mNormalPlaytimeUs; + + info->mNormalPlaytimeUs; accessUnit->meta()->setInt64("timeUs", nptUs); -#endif source->queueAccessUnit(accessUnit); } @@ -278,6 +311,7 @@ void NuPlayer::RTSPSource::onMessageReceived(const sp<AMessage> &msg) { TrackInfo *info = &mTracks.editItemAt(trackIndex); info->mRTPTime = rtpTime; info->mNormalPlaytimeUs = nptUs; + info->mNPTMappingValid = true; break; } @@ -305,6 +339,7 @@ void NuPlayer::RTSPSource::onConnected() { info.mTimeScale = timeScale; info.mRTPTime = 0; info.mNormalPlaytimeUs = 0ll; + info.mNPTMappingValid = false; if ((isAudio && mAudioTrack == NULL) || (isVideo && mVideoTrack == NULL)) { diff --git a/media/libmediaplayerservice/nuplayer/RTSPSource.h b/media/libmediaplayerservice/nuplayer/RTSPSource.h index 66eab72..59d06ad 100644 --- a/media/libmediaplayerservice/nuplayer/RTSPSource.h +++ b/media/libmediaplayerservice/nuplayer/RTSPSource.h @@ -56,6 +56,7 @@ private: enum { kWhatNotify = 'noti', kWhatDisconnect = 'disc', + kWhatPerformSeek = 'seek', }; enum State { @@ -76,6 +77,7 @@ private: int32_t mTimeScale; uint32_t mRTPTime; int64_t mNormalPlaytimeUs; + bool mNPTMappingValid; }; AString mURL; @@ -95,12 +97,16 @@ private: sp<AnotherPacketSource> mAudioTrack; sp<AnotherPacketSource> mVideoTrack; + int32_t mSeekGeneration; + sp<AnotherPacketSource> getSource(bool audio); void onConnected(); void onDisconnected(const sp<AMessage> &msg); void finishDisconnectIfPossible(); + void performSeek(int64_t seekTimeUs); + DISALLOW_EVIL_CONSTRUCTORS(RTSPSource); }; diff --git a/media/libstagefright/AwesomePlayer.cpp b/media/libstagefright/AwesomePlayer.cpp index 964cb1f..8405264 100644 --- a/media/libstagefright/AwesomePlayer.cpp +++ b/media/libstagefright/AwesomePlayer.cpp @@ -2091,7 +2091,7 @@ status_t AwesomePlayer::finishSetDataSource_l() { String8 mimeType; float confidence; sp<AMessage> dummy; - bool success = SniffDRM(dataSource, &mimeType, &confidence, &dummy); + bool success = SniffWVM(dataSource, &mimeType, &confidence, &dummy); if (!success || strcasecmp( @@ -2099,6 +2099,8 @@ status_t AwesomePlayer::finishSetDataSource_l() { return ERROR_UNSUPPORTED; } + dataSource->DrmInitialization(); + mWVMExtractor = new WVMExtractor(dataSource); mWVMExtractor->setAdaptiveStreamingMode(true); extractor = mWVMExtractor; diff --git a/media/libstagefright/DRMExtractor.cpp b/media/libstagefright/DRMExtractor.cpp index 1f3d581..afc4a80 100644 --- a/media/libstagefright/DRMExtractor.cpp +++ b/media/libstagefright/DRMExtractor.cpp @@ -282,13 +282,13 @@ bool SniffDRM( if (decryptHandle != NULL) { if (decryptHandle->decryptApiType == DecryptApiType::CONTAINER_BASED) { *mimeType = String8("drm+container_based+") + decryptHandle->mimeType; + *confidence = 10.0f; } else if (decryptHandle->decryptApiType == DecryptApiType::ELEMENTARY_STREAM_BASED) { *mimeType = String8("drm+es_based+") + decryptHandle->mimeType; - } else if (decryptHandle->decryptApiType == DecryptApiType::WV_BASED) { - *mimeType = MEDIA_MIMETYPE_CONTAINER_WVM; - LOGW("SniffWVM: found match\n"); + *confidence = 10.0f; + } else { + return false; } - *confidence = 10.0f; return true; } diff --git a/media/libstagefright/DataSource.cpp b/media/libstagefright/DataSource.cpp index e471f73..d0a7880 100644 --- a/media/libstagefright/DataSource.cpp +++ b/media/libstagefright/DataSource.cpp @@ -32,6 +32,7 @@ #include "include/DRMExtractor.h" #include "include/FLACExtractor.h" #include "include/AACExtractor.h" +#include "include/WVMExtractor.h" #include "matroska/MatroskaExtractor.h" @@ -120,6 +121,7 @@ void DataSource::RegisterDefaultSniffers() { RegisterSniffer(SniffAAC); RegisterSniffer(SniffAVI); RegisterSniffer(SniffMPEG2PS); + RegisterSniffer(SniffWVM); char value[PROPERTY_VALUE_MAX]; if (property_get("drm.service.enabled", value, NULL) diff --git a/media/libstagefright/WVMExtractor.cpp b/media/libstagefright/WVMExtractor.cpp index 26eda0c..79dedca 100644 --- a/media/libstagefright/WVMExtractor.cpp +++ b/media/libstagefright/WVMExtractor.cpp @@ -45,17 +45,12 @@ namespace android { static Mutex gWVMutex; WVMExtractor::WVMExtractor(const sp<DataSource> &source) - : mDataSource(source) { - { - Mutex::Autolock autoLock(gWVMutex); - if (gVendorLibHandle == NULL) { - gVendorLibHandle = dlopen("libwvm.so", RTLD_NOW); - } + : mDataSource(source) +{ + Mutex::Autolock autoLock(gWVMutex); - if (gVendorLibHandle == NULL) { - LOGE("Failed to open libwvm.so"); - return; - } + if (!getVendorLibHandle()) { + return; } typedef WVMLoadableExtractor *(*GetInstanceFunc)(sp<DataSource>); @@ -71,6 +66,19 @@ WVMExtractor::WVMExtractor(const sp<DataSource> &source) } } +bool WVMExtractor::getVendorLibHandle() +{ + if (gVendorLibHandle == NULL) { + gVendorLibHandle = dlopen("libwvm.so", RTLD_NOW); + } + + if (gVendorLibHandle == NULL) { + LOGE("Failed to open libwvm.so"); + } + + return gVendorLibHandle != NULL; +} + WVMExtractor::~WVMExtractor() { } @@ -113,5 +121,33 @@ void WVMExtractor::setAdaptiveStreamingMode(bool adaptive) { } } +bool SniffWVM( + const sp<DataSource> &source, String8 *mimeType, float *confidence, + sp<AMessage> *) { + + Mutex::Autolock autoLock(gWVMutex); + + if (!WVMExtractor::getVendorLibHandle()) { + return false; + } + + typedef WVMLoadableExtractor *(*SnifferFunc)(sp<DataSource>); + SnifferFunc snifferFunc = + (SnifferFunc) dlsym(gVendorLibHandle, + "_ZN7android15IsWidevineMediaENS_2spINS_10DataSourceEEE"); + + if (snifferFunc) { + if ((*snifferFunc)(source)) { + *mimeType = MEDIA_MIMETYPE_CONTAINER_WVM; + *confidence = 10.0f; + return true; + } + } else { + LOGE("IsWidevineMedia not found in libwvm.so"); + } + + return false; +} + } //namespace android diff --git a/media/libstagefright/foundation/ABitReader.cpp b/media/libstagefright/foundation/ABitReader.cpp index f07dd4f..5499c32 100644 --- a/media/libstagefright/foundation/ABitReader.cpp +++ b/media/libstagefright/foundation/ABitReader.cpp @@ -79,7 +79,13 @@ void ABitReader::skipBits(size_t n) { } void ABitReader::putBits(uint32_t x, size_t n) { - CHECK_LE(mNumBitsLeft + n, 32u); + CHECK_LE(n, 32u); + + while (mNumBitsLeft + n > 32) { + mNumBitsLeft -= 8; + --mData; + ++mSize; + } mReservoir = (mReservoir >> n) | (x << (32 - n)); mNumBitsLeft += n; diff --git a/media/libstagefright/include/WVMExtractor.h b/media/libstagefright/include/WVMExtractor.h index deecd25..9f763f9 100644 --- a/media/libstagefright/include/WVMExtractor.h +++ b/media/libstagefright/include/WVMExtractor.h @@ -23,6 +23,8 @@ namespace android { +struct AMessage; +class String8; class DataSource; class WVMLoadableExtractor : public MediaExtractor { @@ -58,6 +60,8 @@ public: // is used. void setAdaptiveStreamingMode(bool adaptive); + static bool getVendorLibHandle(); + protected: virtual ~WVMExtractor(); @@ -69,6 +73,10 @@ private: WVMExtractor &operator=(const WVMExtractor &); }; +bool SniffWVM( + const sp<DataSource> &source, String8 *mimeType, float *confidence, + sp<AMessage> *); + } // namespace android #endif // DRM_EXTRACTOR_H_ diff --git a/media/libstagefright/rtsp/MyHandler.h b/media/libstagefright/rtsp/MyHandler.h index dd049c2..21ef298 100644 --- a/media/libstagefright/rtsp/MyHandler.h +++ b/media/libstagefright/rtsp/MyHandler.h @@ -1100,6 +1100,8 @@ struct MyHandler : public AHandler { float npt1, npt2; if (!ASessionDescription::parseNTPRange(val.c_str(), &npt1, &npt2)) { // This is a live stream and therefore not seekable. + + LOGI("This is a live stream"); return; } @@ -1386,12 +1388,14 @@ private: msg->setInt32("what", kWhatConnected); msg->post(); - for (size_t i = 0; i < mTracks.size(); ++i) { - TrackInfo *info = &mTracks.editItemAt(i); + if (mSeekable) { + for (size_t i = 0; i < mTracks.size(); ++i) { + TrackInfo *info = &mTracks.editItemAt(i); - postNormalPlayTimeMapping( - i, - info->mNormalPlayTimeRTP, info->mNormalPlayTimeUs); + postNormalPlayTimeMapping( + i, + info->mNormalPlayTimeRTP, info->mNormalPlayTimeUs); + } } mFirstAccessUnit = false; |