Remove IDataSource dependency from DataSource.
The logic for requesting file data source to media extractor service
moved to MediaExtractorFactory from GenericSource.
Bug: 65851881, Bug: 63934228
Test: MediaCts post commit tests
Change-Id: Iaba6d9bec560f0cd8a826f47d74bf491a34c83e9
diff --git a/media/libmedia/nuplayer2/GenericSource.cpp b/media/libmedia/nuplayer2/GenericSource.cpp
index 900c78b..6f78b6b 100644
--- a/media/libmedia/nuplayer2/GenericSource.cpp
+++ b/media/libmedia/nuplayer2/GenericSource.cpp
@@ -162,15 +162,30 @@
status_t NuPlayer2::GenericSource::initFromDataSource() {
sp<IMediaExtractor> extractor;
- CHECK(mDataSource != NULL);
+ CHECK(mDataSource != NULL || mFd != -1);
sp<DataSource> dataSource = mDataSource;
+ 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.
- extractor = MediaExtractorFactory::Create(dataSource, NULL);
+ if (dataSource != nullptr) {
+ extractor = MediaExtractorFactory::Create(dataSource, NULL /* mime */);
+ } else {
+ extractor = MediaExtractorFactory::CreateFromFd(
+ fd, offset, length, NULL /* mime */, &dataSource);
+ }
+
+ if (dataSource == nullptr) {
+ ALOGE("initFromDataSource, failed to create data source!");
+ mLock.lock();
+ return UNKNOWN_ERROR;
+ }
if (extractor == NULL) {
ALOGE("initFromDataSource, cannot create extractor!");
+ mLock.lock();
return UNKNOWN_ERROR;
}
@@ -179,10 +194,13 @@
size_t numtracks = extractor->countTracks();
if (numtracks == 0) {
ALOGE("initFromDataSource, source has no track!");
+ mLock.lock();
return UNKNOWN_ERROR;
}
mLock.lock();
+ mFd = -1;
+ mDataSource = dataSource;
mFileMeta = fileMeta;
if (mFileMeta != NULL) {
int64_t duration;
@@ -395,51 +413,16 @@
if (!mDisconnected) {
mDataSource = dataSource;
}
- } else {
- if (property_get_bool("media.stagefright.extractremote", true) &&
- !FileSource::requiresDrm(mFd, mOffset, mLength, nullptr /* mime */)) {
- sp<IBinder> binder =
- defaultServiceManager()->getService(String16("media.extractor"));
- if (binder != nullptr) {
- ALOGD("FileSource remote");
- sp<IMediaExtractorService> mediaExService(
- interface_cast<IMediaExtractorService>(binder));
- sp<IDataSource> source =
- mediaExService->makeIDataSource(mFd, mOffset, mLength);
- ALOGV("IDataSource(FileSource): %p %d %lld %lld",
- source.get(), mFd, (long long)mOffset, (long long)mLength);
- if (source.get() != nullptr) {
- mDataSource = CreateDataSourceFromIDataSource(source);
- if (mDataSource != nullptr) {
- // Close the local file descriptor as it is not needed anymore.
- close(mFd);
- mFd = -1;
- }
- } else {
- ALOGW("extractor service cannot make data source");
- }
- } else {
- ALOGW("extractor service not running");
- }
- }
- if (mDataSource == nullptr) {
- ALOGD("FileSource local");
- mDataSource = new FileSource(mFd, mOffset, mLength);
- }
- // TODO: close should always be done on mFd, see the lines following
- // CreateDataSourceFromIDataSource above,
- // and the FileSource constructor should dup the mFd argument as needed.
- mFd = -1;
}
- if (mDataSource == NULL) {
+ if (mFd == -1 && mDataSource == NULL) {
ALOGE("Failed to create data source!");
notifyPreparedAndCleanup(UNKNOWN_ERROR);
return;
}
}
- if (mDataSource->flags() & DataSource::kIsCachingDataSource) {
+ if (mDataSource != nullptr && mDataSource->flags() & DataSource::kIsCachingDataSource) {
mCachedSource = static_cast<NuCachedSource2 *>(mDataSource.get());
}
diff --git a/media/libmediaextractor/DataSource.cpp b/media/libmediaextractor/DataSource.cpp
index c22e4cb..72959c6 100644
--- a/media/libmediaextractor/DataSource.cpp
+++ b/media/libmediaextractor/DataSource.cpp
@@ -17,7 +17,6 @@
#define LOG_TAG "DataSource"
#include <media/DataSource.h>
-#include <media/IDataSource.h>
#include <media/stagefright/foundation/ByteUtils.h>
#include <media/stagefright/MediaErrors.h>
#include <utils/String8.h>
@@ -124,10 +123,6 @@
return ERROR_UNSUPPORTED;
}
-sp<IDataSource> DataSource::getIDataSource() const {
- return nullptr;
-}
-
String8 DataSource::getMIMEType() const {
return String8("application/octet-stream");
}
diff --git a/media/libmediaextractor/include/media/DataSource.h b/media/libmediaextractor/include/media/DataSource.h
index e917f4e..0b4bc27 100644
--- a/media/libmediaextractor/include/media/DataSource.h
+++ b/media/libmediaextractor/include/media/DataSource.h
@@ -112,9 +112,6 @@
virtual void close() {};
- // returns a pointer to IDataSource if it is wrapped.
- virtual sp<IDataSource> getIDataSource() const;
-
protected:
virtual ~DataSource() {}
diff --git a/media/libmediaplayerservice/nuplayer/GenericSource.cpp b/media/libmediaplayerservice/nuplayer/GenericSource.cpp
index a3f4efb..cbbf34d 100644
--- a/media/libmediaplayerservice/nuplayer/GenericSource.cpp
+++ b/media/libmediaplayerservice/nuplayer/GenericSource.cpp
@@ -26,7 +26,6 @@
#include <media/DataSource.h>
#include <media/MediaExtractor.h>
#include <media/MediaSource.h>
-#include <media/IMediaExtractorService.h>
#include <media/IMediaHTTPService.h>
#include <media/stagefright/foundation/ABuffer.h>
#include <media/stagefright/foundation/ADebug.h>
@@ -161,15 +160,30 @@
status_t NuPlayer::GenericSource::initFromDataSource() {
sp<IMediaExtractor> extractor;
- CHECK(mDataSource != NULL);
+ CHECK(mDataSource != NULL || mFd != -1);
sp<DataSource> dataSource = mDataSource;
+ 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.
- extractor = MediaExtractorFactory::Create(dataSource, NULL);
+ if (dataSource != nullptr) {
+ extractor = MediaExtractorFactory::Create(dataSource, NULL /* mime */);
+ } else {
+ extractor = MediaExtractorFactory::CreateFromFd(
+ fd, offset, length, NULL /* mime */, &dataSource);
+ }
+
+ if (dataSource == nullptr) {
+ ALOGE("initFromDataSource, failed to create data source!");
+ mLock.lock();
+ return UNKNOWN_ERROR;
+ }
if (extractor == NULL) {
ALOGE("initFromDataSource, cannot create extractor!");
+ mLock.lock();
return UNKNOWN_ERROR;
}
@@ -178,10 +192,13 @@
size_t numtracks = extractor->countTracks();
if (numtracks == 0) {
ALOGE("initFromDataSource, source has no track!");
+ mLock.lock();
return UNKNOWN_ERROR;
}
mLock.lock();
+ mFd = -1;
+ mDataSource = dataSource;
mFileMeta = fileMeta;
if (mFileMeta != NULL) {
int64_t duration;
@@ -394,51 +411,15 @@
if (!mDisconnected) {
mDataSource = dataSource;
}
- } else {
- if (property_get_bool("media.stagefright.extractremote", true) &&
- !FileSource::requiresDrm(mFd, mOffset, mLength, nullptr /* mime */)) {
- sp<IBinder> binder =
- defaultServiceManager()->getService(String16("media.extractor"));
- if (binder != nullptr) {
- ALOGD("FileSource remote");
- sp<IMediaExtractorService> mediaExService(
- interface_cast<IMediaExtractorService>(binder));
- sp<IDataSource> source =
- mediaExService->makeIDataSource(mFd, mOffset, mLength);
- ALOGV("IDataSource(FileSource): %p %d %lld %lld",
- source.get(), mFd, (long long)mOffset, (long long)mLength);
- if (source.get() != nullptr) {
- mDataSource = CreateDataSourceFromIDataSource(source);
- if (mDataSource != nullptr) {
- // Close the local file descriptor as it is not needed anymore.
- close(mFd);
- mFd = -1;
- }
- } else {
- ALOGW("extractor service cannot make data source");
- }
- } else {
- ALOGW("extractor service not running");
- }
- }
- if (mDataSource == nullptr) {
- ALOGD("FileSource local");
- mDataSource = new FileSource(mFd, mOffset, mLength);
- }
- // TODO: close should always be done on mFd, see the lines following
- // CreateDataSourceFromIDataSource above,
- // and the FileSource constructor should dup the mFd argument as needed.
- mFd = -1;
}
-
- if (mDataSource == NULL) {
+ if (mFd == -1 && mDataSource == NULL) {
ALOGE("Failed to create data source!");
notifyPreparedAndCleanup(UNKNOWN_ERROR);
return;
}
}
- if (mDataSource->flags() & DataSource::kIsCachingDataSource) {
+ if (mDataSource != nullptr && mDataSource->flags() & DataSource::kIsCachingDataSource) {
mCachedSource = static_cast<NuCachedSource2 *>(mDataSource.get());
}
diff --git a/media/libstagefright/CallbackDataSource.cpp b/media/libstagefright/CallbackDataSource.cpp
index 6dfe2de..f479644 100644
--- a/media/libstagefright/CallbackDataSource.cpp
+++ b/media/libstagefright/CallbackDataSource.cpp
@@ -113,10 +113,6 @@
return mIDataSource->DrmInitialization(mime);
}
-sp<IDataSource> CallbackDataSource::getIDataSource() const {
- return mIDataSource;
-}
-
TinyCacheSource::TinyCacheSource(const sp<DataSource>& source)
: mSource(source), mCachedOffset(0), mCachedSize(0) {
mName = String8::format("TinyCacheSource(%s)", mSource->toString().string());
@@ -194,8 +190,4 @@
return mSource->DrmInitialization(mime);
}
-sp<IDataSource> TinyCacheSource::getIDataSource() const {
- return mSource->getIDataSource();
-}
-
} // namespace android
diff --git a/media/libstagefright/MediaExtractorFactory.cpp b/media/libstagefright/MediaExtractorFactory.cpp
index 1b12510..e1e04eb 100644
--- a/media/libstagefright/MediaExtractorFactory.cpp
+++ b/media/libstagefright/MediaExtractorFactory.cpp
@@ -23,6 +23,7 @@
#include <media/MediaAnalyticsItem.h>
#include <media/MediaExtractor.h>
#include <media/stagefright/foundation/AMessage.h>
+#include <media/stagefright/FileSource.h>
#include <media/stagefright/InterfaceUtils.h>
#include <media/stagefright/MediaExtractorFactory.h>
#include <media/stagefright/MetaData.h>
@@ -44,7 +45,7 @@
// static
sp<IMediaExtractor> MediaExtractorFactory::Create(
const sp<DataSource> &source, const char *mime) {
- ALOGV("MediaExtractorFactory::Create %s", mime);
+ ALOGV("MediaExtractorFactory::%s %s", __func__, mime);
if (!property_get_bool("media.stagefright.extractremote", true)) {
// local extractor
@@ -69,10 +70,48 @@
return NULL;
}
+// static
+sp<IMediaExtractor> MediaExtractorFactory::CreateFromFd(
+ int fd, int64_t offset, int64_t length, const char *mime, sp<DataSource> *out) {
+ ALOGV("MediaExtractorFactory::%s %s", __func__, mime);
+
+ if (property_get_bool("media.stagefright.extractremote", true)) {
+ // remote extractor
+ ALOGV("get service manager");
+ sp<IBinder> binder = defaultServiceManager()->getService(String16("media.extractor"));
+
+ if (binder != 0) {
+ sp<IMediaExtractorService> mediaExService(
+ interface_cast<IMediaExtractorService>(binder));
+ if (!FileSource::requiresDrm(fd, offset, length, nullptr /* mime */)) {
+ ALOGD("FileSource remote");
+ sp<IDataSource> remoteSource =
+ mediaExService->makeIDataSource(fd, offset, length);
+ ALOGV("IDataSource(FileSource): %p %d %lld %lld",
+ remoteSource.get(), fd, (long long)offset, (long long)length);
+ if (remoteSource.get() != nullptr) {
+ // replace the caller's local source with remote source.
+ *out = CreateDataSourceFromIDataSource(remoteSource);
+ return mediaExService->makeExtractor(remoteSource, mime);
+ } else {
+ ALOGW("extractor service cannot make file source."
+ " falling back to local file source.");
+ }
+ }
+ // Falls back.
+ } else {
+ ALOGE("extractor service not running");
+ return nullptr;
+ }
+ }
+ *out = new FileSource(fd, offset, length);
+ return Create(*out, mime);
+}
+
sp<MediaExtractor> MediaExtractorFactory::CreateFromService(
const sp<DataSource> &source, const char *mime) {
- ALOGV("MediaExtractorFactory::CreateFromService %s", mime);
+ ALOGV("MediaExtractorFactory::%s %s", __func__, mime);
RegisterDefaultSniffers();
// initialize source decryption if needed
diff --git a/media/libstagefright/include/CallbackDataSource.h b/media/libstagefright/include/CallbackDataSource.h
index 9f413cd..32556d6 100644
--- a/media/libstagefright/include/CallbackDataSource.h
+++ b/media/libstagefright/include/CallbackDataSource.h
@@ -42,7 +42,6 @@
return mName;
}
virtual sp<DecryptHandle> DrmInitialization(const char *mime = NULL);
- virtual sp<IDataSource> getIDataSource() const;
private:
sp<IDataSource> mIDataSource;
@@ -71,7 +70,6 @@
return mName;
}
virtual sp<DecryptHandle> DrmInitialization(const char *mime = NULL);
- virtual sp<IDataSource> getIDataSource() const;
private:
// 2kb comes from experimenting with the time-to-first-frame from a MediaPlayer
diff --git a/media/libstagefright/include/media/stagefright/MediaExtractorFactory.h b/media/libstagefright/include/media/stagefright/MediaExtractorFactory.h
index 96298f9..f216ff8 100644
--- a/media/libstagefright/include/media/stagefright/MediaExtractorFactory.h
+++ b/media/libstagefright/include/media/stagefright/MediaExtractorFactory.h
@@ -31,6 +31,12 @@
public:
static sp<IMediaExtractor> Create(
const sp<DataSource> &source, const char *mime = NULL);
+ // Creates media extractor from the given file descriptor. To avoid binder calls for
+ // reading file data, this tries to create remote file source in extractor service.
+ // If that fails, this falls back to local file source. The data source used for extractor
+ // will be alsp returned with |out|.
+ static sp<IMediaExtractor> CreateFromFd(
+ int fd, int64_t offset, int64_t length, const char *mime, sp<DataSource> *out);
static sp<MediaExtractor> CreateFromService(
const sp<DataSource> &source, const char *mime = NULL);
diff --git a/media/libstagefright/include/media/stagefright/RemoteDataSource.h b/media/libstagefright/include/media/stagefright/RemoteDataSource.h
index e191e6a..4ddc5e3 100644
--- a/media/libstagefright/include/media/stagefright/RemoteDataSource.h
+++ b/media/libstagefright/include/media/stagefright/RemoteDataSource.h
@@ -31,9 +31,6 @@
if (source.get() == nullptr) {
return nullptr;
}
- if (source->getIDataSource().get() != nullptr) {
- return source->getIDataSource();
- }
return new RemoteDataSource(source);
}