nuplayer2: remove NuCachedSource2 reference from GenericSource

Bug: 63934228
Change-Id: I6862ca94327df88dddd7afaa125622c64d61516b
gugelfrei
Robert Shih 7 years ago
parent cab10da0da
commit 49fb89d3a0

@ -1244,37 +1244,15 @@ sp<AMediaCodecCryptoInfoWrapper> AMediaExtractorWrapper::getSampleCryptoInfo() {
return new AMediaCodecCryptoInfoWrapper(AMediaExtractor_getSampleCryptoInfo(mAMediaExtractor));
}
ssize_t AMediaDataSourceWrapper::AMediaDataSourceWrapper_getSize(void *userdata) {
DataSource *source = static_cast<DataSource *>(userdata);
off64_t size = -1;
source->getSize(&size);
return size;
}
ssize_t AMediaDataSourceWrapper::AMediaDataSourceWrapper_readAt(void *userdata, off64_t offset, void * buf, size_t size) {
DataSource *source = static_cast<DataSource *>(userdata);
return source->readAt(offset, buf, size);
}
void AMediaDataSourceWrapper::AMediaDataSourceWrapper_close(void *userdata) {
DataSource *source = static_cast<DataSource *>(userdata);
source->close();
}
AMediaDataSourceWrapper::AMediaDataSourceWrapper(const sp<DataSource> &dataSource)
: mDataSource(dataSource),
mAMediaDataSource(AMediaDataSource_new()) {
ALOGV("setDataSource (source: %p)", dataSource.get());
AMediaDataSource_setUserdata(mAMediaDataSource, dataSource.get());
AMediaDataSource_setReadAt(mAMediaDataSource, AMediaDataSourceWrapper_readAt);
AMediaDataSource_setGetSize(mAMediaDataSource, AMediaDataSourceWrapper_getSize);
AMediaDataSource_setClose(mAMediaDataSource, AMediaDataSourceWrapper_close);
AMediaDataSourceWrapper::AMediaDataSourceWrapper(AMediaDataSource *aDataSource)
: mAMediaDataSource(aDataSource) {
}
AMediaDataSourceWrapper::~AMediaDataSourceWrapper() {
if (mAMediaDataSource == NULL) {
return;
}
AMediaDataSource_close(mAMediaDataSource);
AMediaDataSource_delete(mAMediaDataSource);
mAMediaDataSource = NULL;
}
@ -1283,4 +1261,8 @@ AMediaDataSource* AMediaDataSourceWrapper::getAMediaDataSource() {
return mAMediaDataSource;
}
void AMediaDataSourceWrapper::close() {
AMediaDataSource_close(mAMediaDataSource);
}
} // namespace android

@ -278,6 +278,30 @@ private:
DISALLOW_EVIL_CONSTRUCTORS(AMediaCodecWrapper);
};
struct AMediaDataSourceWrapper : public RefBase {
AMediaDataSourceWrapper(AMediaDataSource*);
AMediaDataSourceWrapper(int fd, int64_t offset, int64_t length);
AMediaDataSource *getAMediaDataSource();
int getFd() { return mFd; }
int64_t getOffset() { return mOffset; }
int64_t getLength() { return mLength; }
void close();
protected:
virtual ~AMediaDataSourceWrapper();
private:
AMediaDataSource *mAMediaDataSource;
int mFd;
int64_t mOffset;
int64_t mLength;
DISALLOW_EVIL_CONSTRUCTORS(AMediaDataSourceWrapper);
};
struct AMediaExtractorWrapper : public RefBase {
AMediaExtractorWrapper(AMediaExtractor *aMediaExtractor);
@ -337,31 +361,6 @@ private:
DISALLOW_EVIL_CONSTRUCTORS(AMediaExtractorWrapper);
};
struct AMediaDataSourceWrapper : public RefBase {
static status_t translate_error(media_status_t err);
static ssize_t AMediaDataSourceWrapper_getSize(void *userdata);
static ssize_t AMediaDataSourceWrapper_readAt(void *userdata, off64_t offset, void * buf, size_t size);
static void AMediaDataSourceWrapper_close(void *userdata);
AMediaDataSourceWrapper(const sp<DataSource> &dataSource);
AMediaDataSource *getAMediaDataSource();
protected:
virtual ~AMediaDataSourceWrapper();
private:
sp<DataSource> mDataSource;
AMediaDataSource *mAMediaDataSource;
DISALLOW_EVIL_CONSTRUCTORS(AMediaDataSourceWrapper);
};
} // namespace android
#endif // NDK_WRAPPER_H_

@ -28,6 +28,7 @@ cc_library_static {
"libcrypto",
"libmediametrics",
"libmediandk",
"libmediandk_utils",
"libmediautils",
"libmemunreachable",
"libnativewindow",

@ -28,6 +28,7 @@ cc_library_static {
"frameworks/av/media/libstagefright/mpeg2ts",
"frameworks/av/media/libstagefright/rtsp",
"frameworks/av/media/libstagefright/timedtext",
"frameworks/av/media/ndk",
],
cflags: [
@ -49,6 +50,7 @@ cc_library_static {
"libgui",
"libmedia",
"libmediandk",
"libmediandk_utils",
"libpowermanager",
],

@ -21,29 +21,20 @@
#include "NuPlayer2Drm.h"
#include "AnotherPacketSource.h"
#include <binder/IServiceManager.h>
#include <cutils/properties.h>
#include <media/DataSource.h>
#include <media/MediaBufferHolder.h>
#include <media/IMediaExtractorService.h>
#include <media/IMediaSource.h>
#include <media/MediaHTTPService.h>
#include <media/MediaSource.h>
#include <media/NdkWrapper.h>
#include <media/stagefright/foundation/ABuffer.h>
#include <media/stagefright/foundation/ADebug.h>
#include <media/stagefright/foundation/AMessage.h>
#include <media/stagefright/ClearDataSourceFactory.h>
#include <media/stagefright/InterfaceUtils.h>
#include <media/stagefright/MediaBuffer.h>
#include <media/stagefright/MediaClock.h>
#include <media/stagefright/MediaDefs.h>
#include <media/stagefright/MediaExtractorFactory.h>
#include <media/stagefright/MetaData.h>
#include <media/stagefright/NdkUtils.h>
#include <media/stagefright/Utils.h>
#include "../../libstagefright/include/NuCachedSource2.h"
#include "../../libstagefright/include/HTTPBase.h"
#include "NdkMediaDataSourceCallbacksPriv.h"
namespace android {
@ -88,9 +79,6 @@ NuPlayer2::GenericSource2::GenericSource2(
void NuPlayer2::GenericSource2::resetDataSource() {
ALOGV("resetDataSource");
mHTTPService.clear();
mHttpSource.clear();
mDisconnected = false;
mUri.clear();
mUriHeaders.clear();
if (mFd >= 0) {
@ -109,7 +97,6 @@ void NuPlayer2::GenericSource2::resetDataSource() {
}
status_t NuPlayer2::GenericSource2::setDataSource(
const sp<MediaHTTPService> &httpService,
const char *url,
const KeyedVector<String8, String8> *headers) {
Mutex::Autolock _l(mLock);
@ -117,7 +104,6 @@ status_t NuPlayer2::GenericSource2::setDataSource(
resetDataSource();
mHTTPService = httpService;
mUri = url;
if (headers) {
@ -150,7 +136,8 @@ status_t NuPlayer2::GenericSource2::setDataSource(const sp<DataSource>& source)
ALOGV("setDataSource (source: %p)", source.get());
resetDataSource();
mDataSource = source;
AMediaDataSource *aSource = convertDataSourceToAMediaDataSource(source);
mDataSourceWrapper = new AMediaDataSourceWrapper(aSource);
return OK;
}
@ -161,24 +148,21 @@ sp<MetaData> NuPlayer2::GenericSource2::getFileFormatMeta() const {
status_t NuPlayer2::GenericSource2::initFromDataSource() {
mExtractor = new AMediaExtractorWrapper(AMediaExtractor_new());
CHECK(mDataSource != NULL || mFd != -1);
sp<DataSource> dataSource = mDataSource;
CHECK(mFd >=0 || mDataSourceWrapper != NULL);
sp<AMediaDataSourceWrapper> aSourceWrapper = mDataSourceWrapper;
const int fd = mFd;
const int64_t offset = mOffset;
const int64_t length = mLength;
mLock.unlock();
// This might take long time if data source is not reliable.
status_t err;
if (dataSource != nullptr) {
mDataSourceWrapper = new AMediaDataSourceWrapper(dataSource);
err = mExtractor->setDataSource(mDataSourceWrapper->getAMediaDataSource());
if (aSourceWrapper != NULL) {
err = mExtractor->setDataSource(aSourceWrapper->getAMediaDataSource());
} else {
err = mExtractor->setDataSource(fd, offset, length);
err = mExtractor->setDataSource(fd, mOffset, mLength);
}
if (err != OK) {
ALOGE("initFromDataSource, failed to create data source!");
ALOGE("initFromDataSource, failed to set extractor data source!");
mLock.lock();
return UNKNOWN_ERROR;
}
@ -190,10 +174,8 @@ status_t NuPlayer2::GenericSource2::initFromDataSource() {
return UNKNOWN_ERROR;
}
mLock.lock();
mFd = -1;
mDataSource = dataSource;
mFileMeta = convertMediaFormatWrapperToMetaData(mExtractor->getFormat());
mLock.lock();
if (mFileMeta != NULL) {
int64_t duration;
if (mFileMeta->findInt64(kKeyDuration, &duration)) {
@ -214,11 +196,7 @@ status_t NuPlayer2::GenericSource2::initFromDataSource() {
}
sp<AMediaExtractorWrapper> trackExtractor = new AMediaExtractorWrapper(AMediaExtractor_new());
if (mDataSourceWrapper != nullptr) {
err = trackExtractor->setDataSource(mDataSourceWrapper->getAMediaDataSource());
} else {
err = trackExtractor->setDataSource(fd, offset, length);
}
trackExtractor->setDataSource(mDataSourceWrapper->getAMediaDataSource());
const char *mime;
sp<MetaData> meta = convertMediaFormatWrapperToMetaData(trackFormat);
@ -329,8 +307,8 @@ NuPlayer2::GenericSource2::~GenericSource2() {
mLooper->unregisterHandler(id());
mLooper->stop();
}
if (mDataSource != NULL) {
mDataSource->close();
if (mDataSourceWrapper != NULL) {
mDataSourceWrapper->close();
}
resetDataSource();
}
@ -356,55 +334,39 @@ void NuPlayer2::GenericSource2::prepareAsync(int64_t startTimeUs) {
}
void NuPlayer2::GenericSource2::onPrepareAsync(int64_t startTimeUs) {
ALOGV("onPrepareAsync: mDataSource: %d", (mDataSource != NULL));
// delayed data source creation
if (mDataSource == NULL) {
// set to false first, if the extractor
// comes back as secure, set it to true then.
mIsSecure = false;
if (!mUri.empty()) {
const char* uri = mUri.c_str();
String8 contentType;
if (!strncasecmp("http://", uri, 7) || !strncasecmp("https://", uri, 8)) {
mHttpSource = ClearDataSourceFactory::CreateMediaHTTP(mHTTPService);
if (mHttpSource == NULL) {
ALOGE("Failed to create http source!");
notifyPreparedAndCleanup(UNKNOWN_ERROR);
return;
}
}
mLock.unlock();
// This might take long time if connection has some issue.
sp<DataSource> dataSource = ClearDataSourceFactory::CreateFromURI(
mHTTPService, uri, &mUriHeaders, &contentType,
static_cast<HTTPBase *>(mHttpSource.get()));
mLock.lock();
if (!mDisconnected) {
mDataSource = dataSource;
}
}
if (mFd == -1 && mDataSource == NULL) {
ALOGE("Failed to create data source!");
notifyPreparedAndCleanup(UNKNOWN_ERROR);
return;
ALOGV("onPrepareAsync: mFd %d mUri %s mDataSourceWrapper: %p",
mFd, mUri.c_str(), mDataSourceWrapper.get());
if (!mUri.empty()) {
const char* uri = mUri.c_str();
size_t numheaders = mUriHeaders.size();
const char **key_values = numheaders ? new const char *[numheaders * 2] : NULL;
for (size_t i = 0; i < numheaders; ++i) {
key_values[i * 2] = mUriHeaders.keyAt(i).c_str();
key_values[i * 2 + 1] = mUriHeaders.valueAt(i).c_str();
}
mLock.unlock();
AMediaDataSource *aSource = AMediaDataSource_newUri(uri, numheaders, key_values);
mLock.lock();
mDataSourceWrapper = aSource ? new AMediaDataSourceWrapper(aSource) : NULL;
delete[] key_values;
// For cached streaming cases, we need to wait for enough
// buffering before reporting prepared.
mIsStreaming = !strncasecmp("http://", uri, 7) || !strncasecmp("https://", uri, 8);
}
if (mDataSource != nullptr && mDataSource->flags() & DataSource::kIsCachingDataSource) {
mCachedSource = static_cast<NuCachedSource2 *>(mDataSource.get());
if (mDisconnected || (mFd < 0 && mDataSourceWrapper == NULL)) {
ALOGE("mDisconnected(%d) or Failed to create data source!", mDisconnected);
notifyPreparedAndCleanup(UNKNOWN_ERROR);
return;
}
// For cached streaming cases, we need to wait for enough
// buffering before reporting prepared.
mIsStreaming = (mCachedSource != NULL);
// init extractor from data source
status_t err = initFromDataSource();
if (mFd >= 0) {
close(mFd);
mFd = -1;
}
if (err != OK) {
ALOGE("Failed to init from data source!");
@ -441,7 +403,6 @@ void NuPlayer2::GenericSource2::finishPrepareAsync() {
ALOGV("finishPrepareAsync");
if (mIsStreaming) {
mCachedSource->resumeFetchingIfNecessary();
mPreparing = true;
++mPollBufferingGeneration;
schedulePollBuffering();
@ -460,9 +421,7 @@ void NuPlayer2::GenericSource2::finishPrepareAsync() {
void NuPlayer2::GenericSource2::notifyPreparedAndCleanup(status_t err) {
if (err != OK) {
mDataSource.clear();
mCachedSource.clear();
mHttpSource.clear();
mDataSourceWrapper.clear();
mBitrate = -1;
mPrevBufferPercentage = -1;
@ -502,47 +461,19 @@ void NuPlayer2::GenericSource2::resume() {
}
void NuPlayer2::GenericSource2::disconnect() {
sp<DataSource> dataSource, httpSource;
{
Mutex::Autolock _l(mLock);
dataSource = mDataSource;
httpSource = mHttpSource;
mDisconnected = true;
}
if (dataSource != NULL) {
// disconnect data source
if (dataSource->flags() & DataSource::kIsCachingDataSource) {
static_cast<NuCachedSource2 *>(dataSource.get())->disconnect();
}
} else if (httpSource != NULL) {
static_cast<HTTPBase *>(httpSource.get())->disconnect();
if (mDataSourceWrapper != NULL) {
mDataSourceWrapper->close();
}
mDataSourceWrapper = NULL;
}
status_t NuPlayer2::GenericSource2::feedMoreTSData() {
return OK;
}
void NuPlayer2::GenericSource2::sendCacheStats() {
int32_t kbps = 0;
status_t err = UNKNOWN_ERROR;
if (mCachedSource != NULL) {
err = mCachedSource->getEstimatedBandwidthKbps(&kbps);
}
if (err == OK) {
sp<AMessage> notify = dupNotify();
notify->setInt32("what", kWhatCacheStats);
notify->setInt32("bandwidth", kbps);
notify->post();
}
}
void NuPlayer2::GenericSource2::onMessageReceived(const sp<AMessage> &msg) {
Mutex::Autolock _l(mLock);
switch (msg->what()) {
@ -840,8 +771,6 @@ status_t NuPlayer2::GenericSource2::dequeueAccessUnit(
}
if (track->mPackets->getAvailableBufferCount(&finalResult) < 2
&& !mSentPauseOnBuffering && !mPreparing) {
mCachedSource->resumeFetchingIfNecessary();
sendCacheStats();
mSentPauseOnBuffering = true;
sp<AMessage> notify = dupNotify();
notify->setInt32("what", kWhatPauseOnBufferingStart);
@ -1397,7 +1326,6 @@ void NuPlayer2::GenericSource2::readBuffer(
notifyPrepared();
mPreparing = false;
} else {
sendCacheStats();
mSentPauseOnBuffering = false;
sp<AMessage> notify = dupNotify();
notify->setInt32("what", kWhatResumeOnBufferingEnd);
@ -1458,40 +1386,22 @@ void NuPlayer2::GenericSource2::schedulePollBuffering() {
}
void NuPlayer2::GenericSource2::onPollBuffering() {
status_t finalStatus = UNKNOWN_ERROR;
int64_t cachedDurationUs = -1ll;
ssize_t cachedDataRemaining = -1;
if (mCachedSource != NULL) {
cachedDataRemaining = mCachedSource->approxDataRemaining(&finalStatus);
if (finalStatus == OK) {
off64_t size;
int64_t bitrate = 0ll;
if (mDurationUs > 0 && mCachedSource->getSize(&size) == OK) {
// |bitrate| uses bits/second unit, while size is number of bytes.
bitrate = size * 8000000ll / mDurationUs;
} else if (mBitrate > 0) {
bitrate = mBitrate;
}
if (bitrate > 0) {
cachedDurationUs = cachedDataRemaining * 8000000ll / bitrate;
}
}
}
if (finalStatus != OK) {
ALOGV("onPollBuffering: EOS (finalStatus = %d)", finalStatus);
if (finalStatus == ERROR_END_OF_STREAM) {
notifyBufferingUpdate(100);
}
sp<AMediaExtractorWrapper> extractor;
if (mVideoTrack.mExtractor != NULL) {
extractor = mVideoTrack.mExtractor;
} else if (mAudioTrack.mExtractor != NULL) {
extractor = mAudioTrack.mExtractor;
}
return;
if (extractor != NULL) {
cachedDurationUs = extractor->getCachedDuration();
}
if (cachedDurationUs >= 0ll) {
if (mDurationUs > 0ll) {
ssize_t sampleSize = extractor->getSampleSize();
if (sampleSize >= 0ll) {
int64_t cachedPosUs = getLastReadPosition() + cachedDurationUs;
int percentage = 100.0 * cachedPosUs / mDurationUs;
if (percentage > 100) {
@ -1499,9 +1409,11 @@ void NuPlayer2::GenericSource2::onPollBuffering() {
}
notifyBufferingUpdate(percentage);
ALOGV("onPollBuffering: cachedDurationUs %.1f sec", cachedDurationUs / 1000000.0f);
} else {
notifyBufferingUpdate(100);
ALOGV("onPollBuffering: EOS");
}
ALOGV("onPollBuffering: cachedDurationUs %.1f sec", cachedDurationUs / 1000000.0f);
}
schedulePollBuffering();

@ -37,11 +37,9 @@ struct ARTSPController;
class DataSource;
class IDataSource;
class IMediaSource;
struct MediaHTTPService;
struct MediaSource;
class MediaBuffer;
struct MediaClock;
struct NuCachedSource2;
struct NuPlayer2::GenericSource2 : public NuPlayer2::Source,
public MediaBufferObserver // Modular DRM
@ -50,7 +48,6 @@ struct NuPlayer2::GenericSource2 : public NuPlayer2::Source,
const sp<MediaClock> &mediaClock);
status_t setDataSource(
const sp<MediaHTTPService> &httpService,
const char *url,
const KeyedVector<String8, String8> *headers);
@ -151,7 +148,6 @@ private:
bool mIsStreaming;
uid_t mUID;
const sp<MediaClock> mMediaClock;
sp<MediaHTTPService> mHTTPService;
AString mUri;
KeyedVector<String8, String8> mUriHeaders;
int mFd;
@ -159,9 +155,6 @@ private:
int64_t mLength;
bool mDisconnected;
sp<DataSource> mDataSource;
sp<NuCachedSource2> mCachedSource;
sp<DataSource> mHttpSource;
sp<MetaData> mFileMeta;
sp<AMediaDataSourceWrapper> mDataSourceWrapper;
sp<AMediaExtractorWrapper> mExtractor;
@ -232,8 +225,6 @@ private:
void onPollBuffering();
void notifyBufferingUpdate(int32_t percentage);
void sendCacheStats();
sp<AMessage> getFormat_l(bool audio);
sp<MetaData> getFormatMeta_l(bool audio);
int32_t getDataGeneration(media_track_type type) const;

@ -307,7 +307,7 @@ status_t NuPlayer2::createNuPlayer2Source(const sp<DataSourceDesc> &dsd,
sp<GenericSource2> genericSource =
new GenericSource2(notify, mUID, mMediaClock);
err = genericSource->setDataSource(httpService, url, headers);
err = genericSource->setDataSource(url, headers);
if (err == OK) {
*source = genericSource;

@ -224,6 +224,11 @@ AMediaDataSource* AMediaDataSource_newUri(
}
sp<DataSource> source = DataSourceFactory::CreateFromURI(service, uri, &headers);
if (source == NULL) {
ALOGE("AMediaDataSource_newUri source is null");
return NULL;
}
ALOGI("AMediaDataSource_newUri source %s flags %u", source->toString().c_str(), source->flags());
AMediaDataSource* aSource = convertDataSourceToAMediaDataSource(source);
aSource->mImpl = source;
aSource->mFlags = source->flags();

Loading…
Cancel
Save