Merge changes from topic "libdrmframework" am: 84a53822a1 am: 460618a6d1 am: c317c587d5
am: e25539a93f
Change-Id: Ib8636ca3d1a5e251de8a4ce3643f0f88dfe85234
diff --git a/cmds/stagefright/stagefright.cpp b/cmds/stagefright/stagefright.cpp
index 509d32f..9ae87d8 100644
--- a/cmds/stagefright/stagefright.cpp
+++ b/cmds/stagefright/stagefright.cpp
@@ -1085,7 +1085,7 @@
const char *filename = argv[k];
sp<DataSource> dataSource =
- DataSourceFactory::CreateFromURI(NULL /* httpService */, filename);
+ DataSourceFactory::getInstance()->CreateFromURI(NULL /* httpService */, filename);
if (strncasecmp(filename, "sine:", 5) && dataSource == NULL) {
fprintf(stderr, "Unable to create data source.\n");
diff --git a/cmds/stagefright/stream.cpp b/cmds/stagefright/stream.cpp
index 8cc0e81..fe613a8 100644
--- a/cmds/stagefright/stream.cpp
+++ b/cmds/stagefright/stream.cpp
@@ -164,7 +164,7 @@
: mCurrentBufferIndex(-1),
mCurrentBufferOffset(0) {
sp<DataSource> dataSource =
- DataSourceFactory::CreateFromURI(NULL /* httpService */, filename);
+ DataSourceFactory::getInstance()->CreateFromURI(NULL /* httpService */, filename);
CHECK(dataSource != NULL);
diff --git a/media/codec2/components/cmds/codec2.cpp b/media/codec2/components/cmds/codec2.cpp
index e572a53..38eaf88 100644
--- a/media/codec2/components/cmds/codec2.cpp
+++ b/media/codec2/components/cmds/codec2.cpp
@@ -418,7 +418,7 @@
const char *filename = argv[k];
sp<DataSource> dataSource =
- DataSourceFactory::CreateFromURI(nullptr /* httpService */, filename);
+ DataSourceFactory::getInstance()->CreateFromURI(nullptr /* httpService */, filename);
if (strncasecmp(filename, "sine:", 5) && dataSource == nullptr) {
fprintf(stderr, "Unable to create data source.\n");
diff --git a/media/libdatasource/Android.bp b/media/libdatasource/Android.bp
index dd8ef74..f191c21 100644
--- a/media/libdatasource/Android.bp
+++ b/media/libdatasource/Android.bp
@@ -2,8 +2,6 @@
name: "libdatasource",
srcs: [
- "ClearFileSource.cpp",
- "ClearMediaHTTP.cpp",
"DataSourceFactory.cpp",
"DataURISource.cpp",
"FileSource.cpp",
@@ -31,7 +29,6 @@
shared_libs: [
"liblog",
"libcutils",
- "libdrmframework",
"libutils",
"libstagefright_foundation",
"libdl",
diff --git a/media/libdatasource/ClearFileSource.cpp b/media/libdatasource/ClearFileSource.cpp
deleted file mode 100644
index afafa23..0000000
--- a/media/libdatasource/ClearFileSource.cpp
+++ /dev/null
@@ -1,143 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-//#define LOG_NDEBUG 0
-#define LOG_TAG "ClearFileSource"
-#include <utils/Log.h>
-
-#include <datasource/ClearFileSource.h>
-#include <media/stagefright/foundation/ADebug.h>
-#include <media/stagefright/FoundationUtils.h>
-#include <sys/types.h>
-#include <unistd.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-
-namespace android {
-
-ClearFileSource::ClearFileSource(const char *filename)
- : mFd(-1),
- mOffset(0),
- mLength(-1),
- mName("<null>") {
-
- if (filename) {
- mName = String8::format("FileSource(%s)", filename);
- }
- ALOGV("%s", filename);
- mFd = open(filename, O_LARGEFILE | O_RDONLY);
-
- if (mFd >= 0) {
- mLength = lseek64(mFd, 0, SEEK_END);
- } else {
- ALOGE("Failed to open file '%s'. (%s)", filename, strerror(errno));
- }
-}
-
-ClearFileSource::ClearFileSource(int fd, int64_t offset, int64_t length)
- : mFd(fd),
- mOffset(offset),
- mLength(length),
- mName("<null>") {
- ALOGV("fd=%d (%s), offset=%lld, length=%lld",
- fd, nameForFd(fd).c_str(), (long long) offset, (long long) length);
-
- if (mOffset < 0) {
- mOffset = 0;
- }
- if (mLength < 0) {
- mLength = 0;
- }
- if (mLength > INT64_MAX - mOffset) {
- mLength = INT64_MAX - mOffset;
- }
- struct stat s;
- if (fstat(fd, &s) == 0) {
- if (mOffset > s.st_size) {
- mOffset = s.st_size;
- mLength = 0;
- }
- if (mOffset + mLength > s.st_size) {
- mLength = s.st_size - mOffset;
- }
- }
- if (mOffset != offset || mLength != length) {
- ALOGW("offset/length adjusted from %lld/%lld to %lld/%lld",
- (long long) offset, (long long) length,
- (long long) mOffset, (long long) mLength);
- }
-
- mName = String8::format(
- "FileSource(fd(%s), %lld, %lld)",
- nameForFd(fd).c_str(),
- (long long) mOffset,
- (long long) mLength);
-
-}
-
-ClearFileSource::~ClearFileSource() {
- if (mFd >= 0) {
- ::close(mFd);
- mFd = -1;
- }
-}
-
-status_t ClearFileSource::initCheck() const {
- return mFd >= 0 ? OK : NO_INIT;
-}
-
-ssize_t ClearFileSource::readAt(off64_t offset, void *data, size_t size) {
- if (mFd < 0) {
- return NO_INIT;
- }
-
- Mutex::Autolock autoLock(mLock);
- if (mLength >= 0) {
- if (offset >= mLength) {
- return 0; // read beyond EOF.
- }
- uint64_t numAvailable = mLength - offset;
- if ((uint64_t)size > numAvailable) {
- size = numAvailable;
- }
- }
- return readAt_l(offset, data, size);
-}
-
-ssize_t ClearFileSource::readAt_l(off64_t offset, void *data, size_t size) {
- off64_t result = lseek64(mFd, offset + mOffset, SEEK_SET);
- if (result == -1) {
- ALOGE("seek to %lld failed", (long long)(offset + mOffset));
- return UNKNOWN_ERROR;
- }
-
- return ::read(mFd, data, size);
-}
-
-status_t ClearFileSource::getSize(off64_t *size) {
- Mutex::Autolock autoLock(mLock);
-
- if (mFd < 0) {
- return NO_INIT;
- }
-
- *size = mLength;
-
- return OK;
-}
-
-} // namespace android
diff --git a/media/libdatasource/ClearMediaHTTP.cpp b/media/libdatasource/ClearMediaHTTP.cpp
deleted file mode 100644
index 7249c84..0000000
--- a/media/libdatasource/ClearMediaHTTP.cpp
+++ /dev/null
@@ -1,184 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-//#define LOG_NDEBUG 0
-#define LOG_TAG "ClearMediaHTTP"
-#include <utils/Log.h>
-
-#include <datasource/ClearMediaHTTP.h>
-
-#include <media/stagefright/foundation/ADebug.h>
-#include <media/stagefright/foundation/ALooper.h>
-#include <media/stagefright/FoundationUtils.h>
-
-#include <media/MediaHTTPConnection.h>
-
-namespace android {
-
-ClearMediaHTTP::ClearMediaHTTP(const sp<MediaHTTPConnection> &conn)
- : mInitCheck((conn != NULL) ? OK : NO_INIT),
- mHTTPConnection(conn),
- mCachedSizeValid(false),
- mCachedSize(0ll) {
-}
-
-ClearMediaHTTP::~ClearMediaHTTP() {
-}
-
-status_t ClearMediaHTTP::connect(
- const char *uri,
- const KeyedVector<String8, String8> *headers,
- off64_t /* offset */) {
- if (mInitCheck != OK) {
- return mInitCheck;
- }
-
- KeyedVector<String8, String8> extHeaders;
- if (headers != NULL) {
- extHeaders = *headers;
- }
-
- if (extHeaders.indexOfKey(String8("User-Agent")) < 0) {
- extHeaders.add(String8("User-Agent"), String8(MakeUserAgent().c_str()));
- }
-
- mLastURI = uri;
- // reconnect() calls with uri == old mLastURI.c_str(), which gets zapped
- // as part of the above assignment. Ensure no accidental later use.
- uri = NULL;
-
- bool success = mHTTPConnection->connect(mLastURI.c_str(), &extHeaders);
-
- mLastHeaders = extHeaders;
-
- mCachedSizeValid = false;
-
- if (success) {
- AString sanitized = uriDebugString(mLastURI);
- mName = String8::format("ClearMediaHTTP(%s)", sanitized.c_str());
- }
-
- return success ? OK : UNKNOWN_ERROR;
-}
-
-void ClearMediaHTTP::close() {
- disconnect();
-}
-
-void ClearMediaHTTP::disconnect() {
- mName = String8("ClearMediaHTTP(<disconnected>)");
- if (mInitCheck != OK) {
- return;
- }
-
- mHTTPConnection->disconnect();
-}
-
-status_t ClearMediaHTTP::initCheck() const {
- return mInitCheck;
-}
-
-ssize_t ClearMediaHTTP::readAt(off64_t offset, void *data, size_t size) {
- if (mInitCheck != OK) {
- return mInitCheck;
- }
-
- int64_t startTimeUs = ALooper::GetNowUs();
-
- size_t numBytesRead = 0;
- while (numBytesRead < size) {
- size_t copy = size - numBytesRead;
-
- if (copy > 64 * 1024) {
- // limit the buffer sizes transferred across binder boundaries
- // to avoid spurious transaction failures.
- copy = 64 * 1024;
- }
-
- ssize_t n = mHTTPConnection->readAt(
- offset + numBytesRead, (uint8_t *)data + numBytesRead, copy);
-
- if (n < 0) {
- return n;
- } else if (n == 0) {
- break;
- }
-
- numBytesRead += n;
- }
-
- int64_t delayUs = ALooper::GetNowUs() - startTimeUs;
-
- addBandwidthMeasurement(numBytesRead, delayUs);
-
- return numBytesRead;
-}
-
-status_t ClearMediaHTTP::getSize(off64_t *size) {
- if (mInitCheck != OK) {
- return mInitCheck;
- }
-
- // Caching the returned size so that it stays valid even after a
- // disconnect. NuCachedSource2 relies on this.
-
- if (!mCachedSizeValid) {
- mCachedSize = mHTTPConnection->getSize();
- mCachedSizeValid = true;
- }
-
- *size = mCachedSize;
-
- return *size < 0 ? *size : static_cast<status_t>(OK);
-}
-
-uint32_t ClearMediaHTTP::flags() {
- return kWantsPrefetching | kIsHTTPBasedSource;
-}
-
-status_t ClearMediaHTTP::reconnectAtOffset(off64_t offset) {
- return connect(mLastURI.c_str(), &mLastHeaders, offset);
-}
-
-
-String8 ClearMediaHTTP::getUri() {
- if (mInitCheck != OK) {
- return String8::empty();
- }
-
- String8 uri;
- if (OK == mHTTPConnection->getUri(&uri)) {
- return uri;
- }
- return String8(mLastURI.c_str());
-}
-
-String8 ClearMediaHTTP::getMIMEType() const {
- if (mInitCheck != OK) {
- return String8("application/octet-stream");
- }
-
- String8 mimeType;
- status_t err = mHTTPConnection->getMIMEType(&mimeType);
-
- if (err != OK) {
- return String8("application/octet-stream");
- }
-
- return mimeType;
-}
-
-} // namespace android
diff --git a/media/libdatasource/DataSourceFactory.cpp b/media/libdatasource/DataSourceFactory.cpp
index 8c772dd..bb6a08c 100644
--- a/media/libdatasource/DataSourceFactory.cpp
+++ b/media/libdatasource/DataSourceFactory.cpp
@@ -30,6 +30,19 @@
namespace android {
// static
+sp<DataSourceFactory> DataSourceFactory::sInstance;
+// static
+Mutex DataSourceFactory::sInstanceLock;
+
+// static
+sp<DataSourceFactory> DataSourceFactory::getInstance() {
+ Mutex::Autolock l(sInstanceLock);
+ if (!sInstance) {
+ sInstance = new DataSourceFactory();
+ }
+ return sInstance;
+}
+
sp<DataSource> DataSourceFactory::CreateFromURI(
const sp<MediaHTTPService> &httpService,
const char *uri,
@@ -42,20 +55,16 @@
sp<DataSource> source;
if (!strncasecmp("file://", uri, 7)) {
- source = new FileSource(uri + 7);
+ source = CreateFileSource(uri + 7);
} else if (!strncasecmp("http://", uri, 7) || !strncasecmp("https://", uri, 8)) {
if (httpService == NULL) {
ALOGE("Invalid http service!");
return NULL;
}
- if (httpSource == NULL) {
- sp<MediaHTTPConnection> conn = httpService->makeHTTPConnection();
- if (conn == NULL) {
- ALOGE("Failed to make http connection from http service!");
- return NULL;
- }
- httpSource = new MediaHTTP(conn);
+ sp<HTTPBase> mediaHTTP = httpSource;
+ if (mediaHTTP == NULL) {
+ mediaHTTP = static_cast<HTTPBase *>(CreateMediaHTTP(httpService).get());
}
String8 cacheConfig;
@@ -69,24 +78,24 @@
&disconnectAtHighwatermark);
}
- if (httpSource->connect(uri, &nonCacheSpecificHeaders) != OK) {
+ if (mediaHTTP->connect(uri, &nonCacheSpecificHeaders) != OK) {
ALOGE("Failed to connect http source!");
return NULL;
}
if (contentType != NULL) {
- *contentType = httpSource->getMIMEType();
+ *contentType = mediaHTTP->getMIMEType();
}
source = NuCachedSource2::Create(
- httpSource,
+ mediaHTTP,
cacheConfig.isEmpty() ? NULL : cacheConfig.string(),
disconnectAtHighwatermark);
} else if (!strncasecmp("data:", uri, 5)) {
source = DataURISource::Create(uri);
} else {
// Assume it's a filename.
- source = new FileSource(uri);
+ source = CreateFileSource(uri);
}
if (source == NULL || source->initCheck() != OK) {
@@ -108,10 +117,15 @@
sp<MediaHTTPConnection> conn = httpService->makeHTTPConnection();
if (conn == NULL) {
+ ALOGE("Failed to make http connection from http service!");
return NULL;
} else {
return new MediaHTTP(conn);
}
}
+sp<DataSource> DataSourceFactory::CreateFileSource(const char *uri) {
+ return new FileSource(uri);
+}
+
} // namespace android
diff --git a/media/libdatasource/FileSource.cpp b/media/libdatasource/FileSource.cpp
index 65780e3..bbf7dda 100644
--- a/media/libdatasource/FileSource.cpp
+++ b/media/libdatasource/FileSource.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009 The Android Open Source Project
+ * Copyright (C) 2018 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -20,45 +20,84 @@
#include <datasource/FileSource.h>
#include <media/stagefright/foundation/ADebug.h>
-#include <private/android_filesystem_config.h>
+#include <media/stagefright/FoundationUtils.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
namespace android {
FileSource::FileSource(const char *filename)
- : ClearFileSource(filename),
- mDecryptHandle(NULL),
- mDrmManagerClient(NULL),
- mDrmBufOffset(0),
- mDrmBufSize(0),
- mDrmBuf(NULL){
+ : mFd(-1),
+ mOffset(0),
+ mLength(-1),
+ mName("<null>") {
+
+ if (filename) {
+ mName = String8::format("FileSource(%s)", filename);
+ }
+ ALOGV("%s", filename);
+ mFd = open(filename, O_LARGEFILE | O_RDONLY);
+
+ if (mFd >= 0) {
+ mLength = lseek64(mFd, 0, SEEK_END);
+ } else {
+ ALOGE("Failed to open file '%s'. (%s)", filename, strerror(errno));
+ }
}
FileSource::FileSource(int fd, int64_t offset, int64_t length)
- : ClearFileSource(fd, offset, length),
- mDecryptHandle(NULL),
- mDrmManagerClient(NULL),
- mDrmBufOffset(0),
- mDrmBufSize(0),
- mDrmBuf(NULL) {
+ : mFd(fd),
+ mOffset(offset),
+ mLength(length),
+ mName("<null>") {
+ ALOGV("fd=%d (%s), offset=%lld, length=%lld",
+ fd, nameForFd(fd).c_str(), (long long) offset, (long long) length);
+
+ if (mOffset < 0) {
+ mOffset = 0;
+ }
+ if (mLength < 0) {
+ mLength = 0;
+ }
+ if (mLength > INT64_MAX - mOffset) {
+ mLength = INT64_MAX - mOffset;
+ }
+ struct stat s;
+ if (fstat(fd, &s) == 0) {
+ if (mOffset > s.st_size) {
+ mOffset = s.st_size;
+ mLength = 0;
+ }
+ if (mOffset + mLength > s.st_size) {
+ mLength = s.st_size - mOffset;
+ }
+ }
+ if (mOffset != offset || mLength != length) {
+ ALOGW("offset/length adjusted from %lld/%lld to %lld/%lld",
+ (long long) offset, (long long) length,
+ (long long) mOffset, (long long) mLength);
+ }
+
+ mName = String8::format(
+ "FileSource(fd(%s), %lld, %lld)",
+ nameForFd(fd).c_str(),
+ (long long) mOffset,
+ (long long) mLength);
+
}
FileSource::~FileSource() {
- if (mDrmBuf != NULL) {
- delete[] mDrmBuf;
- mDrmBuf = NULL;
+ if (mFd >= 0) {
+ ::close(mFd);
+ mFd = -1;
}
+}
- if (mDecryptHandle != NULL) {
- // To release mDecryptHandle
- CHECK(mDrmManagerClient);
- mDrmManagerClient->closeDecryptSession(mDecryptHandle);
- mDecryptHandle = NULL;
- }
-
- if (mDrmManagerClient != NULL) {
- delete mDrmManagerClient;
- mDrmManagerClient = NULL;
- }
+status_t FileSource::initCheck() const {
+ return mFd >= 0 ? OK : NO_INIT;
}
ssize_t FileSource::readAt(off64_t offset, void *data, size_t size) {
@@ -67,7 +106,6 @@
}
Mutex::Autolock autoLock(mLock);
-
if (mLength >= 0) {
if (offset >= mLength) {
return 0; // read beyond EOF.
@@ -77,79 +115,29 @@
size = numAvailable;
}
}
-
- if (mDecryptHandle != NULL && DecryptApiType::CONTAINER_BASED
- == mDecryptHandle->decryptApiType) {
- return readAtDRM_l(offset, data, size);
- } else {
- return readAt_l(offset, data, size);
- }
+ return readAt_l(offset, data, size);
}
-sp<DecryptHandle> FileSource::DrmInitialization(const char *mime) {
- if (getuid() == AID_MEDIA_EX) return nullptr; // no DRM in media extractor
- if (mDrmManagerClient == NULL) {
- mDrmManagerClient = new DrmManagerClient();
+ssize_t FileSource::readAt_l(off64_t offset, void *data, size_t size) {
+ off64_t result = lseek64(mFd, offset + mOffset, SEEK_SET);
+ if (result == -1) {
+ ALOGE("seek to %lld failed", (long long)(offset + mOffset));
+ return UNKNOWN_ERROR;
}
- if (mDrmManagerClient == NULL) {
- return NULL;
- }
-
- if (mDecryptHandle == NULL) {
- mDecryptHandle = mDrmManagerClient->openDecryptSession(
- mFd, mOffset, mLength, mime);
- }
-
- if (mDecryptHandle == NULL) {
- delete mDrmManagerClient;
- mDrmManagerClient = NULL;
- }
-
- return mDecryptHandle;
+ return ::read(mFd, data, size);
}
-ssize_t FileSource::readAtDRM_l(off64_t offset, void *data, size_t size) {
- size_t DRM_CACHE_SIZE = 1024;
- if (mDrmBuf == NULL) {
- mDrmBuf = new unsigned char[DRM_CACHE_SIZE];
+status_t FileSource::getSize(off64_t *size) {
+ Mutex::Autolock autoLock(mLock);
+
+ if (mFd < 0) {
+ return NO_INIT;
}
- if (mDrmBuf != NULL && mDrmBufSize > 0 && (offset + mOffset) >= mDrmBufOffset
- && (offset + mOffset + size) <= static_cast<size_t>(mDrmBufOffset + mDrmBufSize)) {
- /* Use buffered data */
- memcpy(data, (void*)(mDrmBuf+(offset+mOffset-mDrmBufOffset)), size);
- return size;
- } else if (size <= DRM_CACHE_SIZE) {
- /* Buffer new data */
- mDrmBufOffset = offset + mOffset;
- mDrmBufSize = mDrmManagerClient->pread(mDecryptHandle, mDrmBuf,
- DRM_CACHE_SIZE, offset + mOffset);
- if (mDrmBufSize > 0) {
- int64_t dataRead = 0;
- dataRead = size > static_cast<size_t>(mDrmBufSize) ? mDrmBufSize : size;
- memcpy(data, (void*)mDrmBuf, dataRead);
- return dataRead;
- } else {
- return mDrmBufSize;
- }
- } else {
- /* Too big chunk to cache. Call DRM directly */
- return mDrmManagerClient->pread(mDecryptHandle, data, size, offset + mOffset);
- }
-}
+ *size = mLength;
-/* static */
-bool FileSource::requiresDrm(int fd, int64_t offset, int64_t length, const char *mime) {
- std::unique_ptr<DrmManagerClient> drmClient(new DrmManagerClient());
- sp<DecryptHandle> decryptHandle =
- drmClient->openDecryptSession(fd, offset, length, mime);
- bool requiresDrm = false;
- if (decryptHandle != nullptr) {
- requiresDrm = decryptHandle->decryptApiType == DecryptApiType::CONTAINER_BASED;
- drmClient->closeDecryptSession(decryptHandle);
- }
- return requiresDrm;
+ return OK;
}
} // namespace android
diff --git a/media/libdatasource/MediaHTTP.cpp b/media/libdatasource/MediaHTTP.cpp
index e57510d..58c1ce8 100644
--- a/media/libdatasource/MediaHTTP.cpp
+++ b/media/libdatasource/MediaHTTP.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2013 The Android Open Source Project
+ * Copyright (C) 2018 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -20,7 +20,6 @@
#include <datasource/MediaHTTP.h>
-#include <binder/IServiceManager.h>
#include <media/stagefright/foundation/ADebug.h>
#include <media/stagefright/foundation/ALooper.h>
#include <media/stagefright/FoundationUtils.h>
@@ -30,45 +29,156 @@
namespace android {
MediaHTTP::MediaHTTP(const sp<MediaHTTPConnection> &conn)
- : ClearMediaHTTP(conn),
- mDrmManagerClient(NULL) {
+ : mInitCheck((conn != NULL) ? OK : NO_INIT),
+ mHTTPConnection(conn),
+ mCachedSizeValid(false),
+ mCachedSize(0ll) {
}
MediaHTTP::~MediaHTTP() {
- clearDRMState_l();
}
-// DRM...
-
-sp<DecryptHandle> MediaHTTP::DrmInitialization(const char* mime) {
- if (mDrmManagerClient == NULL) {
- mDrmManagerClient = new DrmManagerClient();
+status_t MediaHTTP::connect(
+ const char *uri,
+ const KeyedVector<String8, String8> *headers,
+ off64_t /* offset */) {
+ if (mInitCheck != OK) {
+ return mInitCheck;
}
- if (mDrmManagerClient == NULL) {
- return NULL;
+ KeyedVector<String8, String8> extHeaders;
+ if (headers != NULL) {
+ extHeaders = *headers;
}
- if (mDecryptHandle == NULL) {
- mDecryptHandle = mDrmManagerClient->openDecryptSession(
- String8(mLastURI.c_str()), mime);
+ if (extHeaders.indexOfKey(String8("User-Agent")) < 0) {
+ extHeaders.add(String8("User-Agent"), String8(MakeUserAgent().c_str()));
}
- if (mDecryptHandle == NULL) {
- delete mDrmManagerClient;
- mDrmManagerClient = NULL;
+ mLastURI = uri;
+ // reconnect() calls with uri == old mLastURI.c_str(), which gets zapped
+ // as part of the above assignment. Ensure no accidental later use.
+ uri = NULL;
+
+ bool success = mHTTPConnection->connect(mLastURI.c_str(), &extHeaders);
+
+ mLastHeaders = extHeaders;
+
+ mCachedSizeValid = false;
+
+ if (success) {
+ AString sanitized = uriDebugString(mLastURI);
+ mName = String8::format("MediaHTTP(%s)", sanitized.c_str());
}
- return mDecryptHandle;
+ return success ? OK : UNKNOWN_ERROR;
}
-void MediaHTTP::clearDRMState_l() {
- if (mDecryptHandle != NULL) {
- // To release mDecryptHandle
- CHECK(mDrmManagerClient);
- mDrmManagerClient->closeDecryptSession(mDecryptHandle);
- mDecryptHandle = NULL;
+void MediaHTTP::close() {
+ disconnect();
+}
+
+void MediaHTTP::disconnect() {
+ mName = String8("MediaHTTP(<disconnected>)");
+ if (mInitCheck != OK) {
+ return;
}
+
+ mHTTPConnection->disconnect();
+}
+
+status_t MediaHTTP::initCheck() const {
+ return mInitCheck;
+}
+
+ssize_t MediaHTTP::readAt(off64_t offset, void *data, size_t size) {
+ if (mInitCheck != OK) {
+ return mInitCheck;
+ }
+
+ int64_t startTimeUs = ALooper::GetNowUs();
+
+ size_t numBytesRead = 0;
+ while (numBytesRead < size) {
+ size_t copy = size - numBytesRead;
+
+ if (copy > 64 * 1024) {
+ // limit the buffer sizes transferred across binder boundaries
+ // to avoid spurious transaction failures.
+ copy = 64 * 1024;
+ }
+
+ ssize_t n = mHTTPConnection->readAt(
+ offset + numBytesRead, (uint8_t *)data + numBytesRead, copy);
+
+ if (n < 0) {
+ return n;
+ } else if (n == 0) {
+ break;
+ }
+
+ numBytesRead += n;
+ }
+
+ int64_t delayUs = ALooper::GetNowUs() - startTimeUs;
+
+ addBandwidthMeasurement(numBytesRead, delayUs);
+
+ return numBytesRead;
+}
+
+status_t MediaHTTP::getSize(off64_t *size) {
+ if (mInitCheck != OK) {
+ return mInitCheck;
+ }
+
+ // Caching the returned size so that it stays valid even after a
+ // disconnect. NuCachedSource2 relies on this.
+
+ if (!mCachedSizeValid) {
+ mCachedSize = mHTTPConnection->getSize();
+ mCachedSizeValid = true;
+ }
+
+ *size = mCachedSize;
+
+ return *size < 0 ? *size : static_cast<status_t>(OK);
+}
+
+uint32_t MediaHTTP::flags() {
+ return kWantsPrefetching | kIsHTTPBasedSource;
+}
+
+status_t MediaHTTP::reconnectAtOffset(off64_t offset) {
+ return connect(mLastURI.c_str(), &mLastHeaders, offset);
+}
+
+
+String8 MediaHTTP::getUri() {
+ if (mInitCheck != OK) {
+ return String8::empty();
+ }
+
+ String8 uri;
+ if (OK == mHTTPConnection->getUri(&uri)) {
+ return uri;
+ }
+ return String8(mLastURI.c_str());
+}
+
+String8 MediaHTTP::getMIMEType() const {
+ if (mInitCheck != OK) {
+ return String8("application/octet-stream");
+ }
+
+ String8 mimeType;
+ status_t err = mHTTPConnection->getMIMEType(&mimeType);
+
+ if (err != OK) {
+ return String8("application/octet-stream");
+ }
+
+ return mimeType;
}
} // namespace android
diff --git a/media/libdatasource/include/datasource/ClearFileSource.h b/media/libdatasource/include/datasource/ClearFileSource.h
deleted file mode 100644
index be83748..0000000
--- a/media/libdatasource/include/datasource/ClearFileSource.h
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef CLEAR_FILE_SOURCE_H_
-
-#define CLEAR_FILE_SOURCE_H_
-
-#include <stdio.h>
-
-#include <media/DataSource.h>
-#include <media/stagefright/MediaErrors.h>
-#include <utils/threads.h>
-
-namespace android {
-
-class ClearFileSource : public DataSource {
-public:
- ClearFileSource(const char *filename);
- // ClearFileSource takes ownership and will close the fd
- ClearFileSource(int fd, int64_t offset, int64_t length);
-
- virtual status_t initCheck() const;
-
- virtual ssize_t readAt(off64_t offset, void *data, size_t size);
-
- virtual status_t getSize(off64_t *size);
-
- virtual uint32_t flags() {
- return kIsLocalFileSource;
- }
-
- virtual String8 toString() {
- return mName;
- }
-
-protected:
- virtual ~ClearFileSource();
- virtual ssize_t readAt_l(off64_t offset, void *data, size_t size);
-
- int mFd;
- int64_t mOffset;
- int64_t mLength;
- Mutex mLock;
-
-private:
- String8 mName;
-
- ClearFileSource(const ClearFileSource &);
- ClearFileSource &operator=(const ClearFileSource &);
-};
-
-} // namespace android
-
-#endif // CLEAR_FILE_SOURCE_H_
-
diff --git a/media/libdatasource/include/datasource/ClearMediaHTTP.h b/media/libdatasource/include/datasource/ClearMediaHTTP.h
deleted file mode 100644
index 5440a3a..0000000
--- a/media/libdatasource/include/datasource/ClearMediaHTTP.h
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef CLEAR_MEDIA_HTTP_H_
-
-#define CLEAR_MEDIA_HTTP_H_
-
-#include <media/stagefright/foundation/AString.h>
-
-#include "HTTPBase.h"
-
-namespace android {
-
-struct MediaHTTPConnection;
-
-struct ClearMediaHTTP : public HTTPBase {
- ClearMediaHTTP(const sp<MediaHTTPConnection> &conn);
-
- virtual status_t connect(
- const char *uri,
- const KeyedVector<String8, String8> *headers,
- off64_t offset);
-
- virtual void close();
-
- virtual void disconnect();
-
- virtual status_t initCheck() const;
-
- virtual ssize_t readAt(off64_t offset, void *data, size_t size);
-
- virtual status_t getSize(off64_t *size);
-
- virtual uint32_t flags();
-
- virtual status_t reconnectAtOffset(off64_t offset);
-
-protected:
- virtual ~ClearMediaHTTP();
-
- virtual String8 getUri();
- virtual String8 getMIMEType() const;
-
- AString mLastURI;
-
-private:
- status_t mInitCheck;
- sp<MediaHTTPConnection> mHTTPConnection;
-
- KeyedVector<String8, String8> mLastHeaders;
-
- bool mCachedSizeValid;
- off64_t mCachedSize;
-
- DISALLOW_EVIL_CONSTRUCTORS(ClearMediaHTTP);
-};
-
-} // namespace android
-
-#endif // CLEAR_MEDIA_HTTP_H_
diff --git a/media/libdatasource/include/datasource/DataSourceFactory.h b/media/libdatasource/include/datasource/DataSourceFactory.h
index 6e313d3..194abe2 100644
--- a/media/libdatasource/include/datasource/DataSourceFactory.h
+++ b/media/libdatasource/include/datasource/DataSourceFactory.h
@@ -29,17 +29,27 @@
class String8;
struct HTTPBase;
-class DataSourceFactory {
+class DataSourceFactory : public RefBase {
public:
- static sp<DataSource> CreateFromURI(
+ static sp<DataSourceFactory> getInstance();
+ sp<DataSource> CreateFromURI(
const sp<MediaHTTPService> &httpService,
const char *uri,
const KeyedVector<String8, String8> *headers = NULL,
String8 *contentType = NULL,
HTTPBase *httpSource = NULL);
- static sp<DataSource> CreateMediaHTTP(const sp<MediaHTTPService> &httpService);
- static sp<DataSource> CreateFromFd(int fd, int64_t offset, int64_t length);
+ virtual sp<DataSource> CreateMediaHTTP(const sp<MediaHTTPService> &httpService);
+ sp<DataSource> CreateFromFd(int fd, int64_t offset, int64_t length);
+
+protected:
+ virtual sp<DataSource> CreateFileSource(const char *uri);
+ DataSourceFactory() {};
+ virtual ~DataSourceFactory() {};
+
+private:
+ static sp<DataSourceFactory> sInstance;
+ static Mutex sInstanceLock;
};
} // namespace android
diff --git a/media/libdatasource/include/datasource/FileSource.h b/media/libdatasource/include/datasource/FileSource.h
index 9249842..dee0c33 100644
--- a/media/libdatasource/include/datasource/FileSource.h
+++ b/media/libdatasource/include/datasource/FileSource.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009 The Android Open Source Project
+ * Copyright (C) 2018 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -20,37 +20,43 @@
#include <stdio.h>
-#include <datasource/ClearFileSource.h>
+#include <media/DataSource.h>
#include <media/stagefright/MediaErrors.h>
#include <utils/threads.h>
-#include <drm/DrmManagerClient.h>
namespace android {
-class FileSource : public ClearFileSource {
+class FileSource : public DataSource {
public:
FileSource(const char *filename);
// FileSource takes ownership and will close the fd
FileSource(int fd, int64_t offset, int64_t length);
+ virtual status_t initCheck() const;
+
virtual ssize_t readAt(off64_t offset, void *data, size_t size);
- virtual sp<DecryptHandle> DrmInitialization(const char *mime);
+ virtual status_t getSize(off64_t *size);
- static bool requiresDrm(int fd, int64_t offset, int64_t length, const char *mime);
+ virtual uint32_t flags() {
+ return kIsLocalFileSource;
+ }
+
+ virtual String8 toString() {
+ return mName;
+ }
protected:
virtual ~FileSource();
+ virtual ssize_t readAt_l(off64_t offset, void *data, size_t size);
+
+ int mFd;
+ int64_t mOffset;
+ int64_t mLength;
+ Mutex mLock;
private:
- /*for DRM*/
- sp<DecryptHandle> mDecryptHandle;
- DrmManagerClient *mDrmManagerClient;
- int64_t mDrmBufOffset;
- ssize_t mDrmBufSize;
- unsigned char *mDrmBuf;
-
- ssize_t readAtDRM_l(off64_t offset, void *data, size_t size);
+ String8 mName;
FileSource(const FileSource &);
FileSource &operator=(const FileSource &);
diff --git a/media/libdatasource/include/datasource/MediaHTTP.h b/media/libdatasource/include/datasource/MediaHTTP.h
index 60252ce..a8d203b 100644
--- a/media/libdatasource/include/datasource/MediaHTTP.h
+++ b/media/libdatasource/include/datasource/MediaHTTP.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2013 The Android Open Source Project
+ * Copyright (C) 2018 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -18,26 +18,52 @@
#define MEDIA_HTTP_H_
-#include <datasource/ClearMediaHTTP.h>
#include <media/stagefright/foundation/AString.h>
+#include "HTTPBase.h"
+
namespace android {
struct MediaHTTPConnection;
-struct MediaHTTP : public ClearMediaHTTP {
+struct MediaHTTP : public HTTPBase {
MediaHTTP(const sp<MediaHTTPConnection> &conn);
+ virtual status_t connect(
+ const char *uri,
+ const KeyedVector<String8, String8> *headers,
+ off64_t offset);
+
+ virtual void close();
+
+ virtual void disconnect();
+
+ virtual status_t initCheck() const;
+
+ virtual ssize_t readAt(off64_t offset, void *data, size_t size);
+
+ virtual status_t getSize(off64_t *size);
+
+ virtual uint32_t flags();
+
+ virtual status_t reconnectAtOffset(off64_t offset);
+
protected:
virtual ~MediaHTTP();
- virtual sp<DecryptHandle> DrmInitialization(const char* mime);
+ virtual String8 getUri();
+ virtual String8 getMIMEType() const;
+
+ AString mLastURI;
private:
- sp<DecryptHandle> mDecryptHandle;
- DrmManagerClient *mDrmManagerClient;
+ status_t mInitCheck;
+ sp<MediaHTTPConnection> mHTTPConnection;
- void clearDRMState_l();
+ KeyedVector<String8, String8> mLastHeaders;
+
+ bool mCachedSizeValid;
+ off64_t mCachedSize;
DISALLOW_EVIL_CONSTRUCTORS(MediaHTTP);
};
diff --git a/media/libmediaplayerservice/Android.bp b/media/libmediaplayerservice/Android.bp
index 6701017..5301f5c 100644
--- a/media/libmediaplayerservice/Android.bp
+++ b/media/libmediaplayerservice/Android.bp
@@ -7,6 +7,7 @@
"MediaPlayerService.cpp",
"MediaRecorderClient.cpp",
"MetadataRetrieverClient.cpp",
+ "StagefrightMetadataRetriever.cpp",
"StagefrightRecorder.cpp",
"TestPlayerStub.cpp",
],
@@ -23,6 +24,7 @@
"libcutils",
"libdatasource",
"libdl",
+ "libdrmframework",
"libgui",
"libhidlbase",
"liblog",
@@ -46,6 +48,7 @@
],
static_libs: [
+ "libplayerservice_datasource",
"libstagefright_nuplayer",
"libstagefright_rtsp",
"libstagefright_timedtext",
diff --git a/media/libstagefright/StagefrightMetadataRetriever.cpp b/media/libmediaplayerservice/StagefrightMetadataRetriever.cpp
similarity index 98%
rename from media/libstagefright/StagefrightMetadataRetriever.cpp
rename to media/libmediaplayerservice/StagefrightMetadataRetriever.cpp
index 48aee18..41b6f72 100644
--- a/media/libstagefright/StagefrightMetadataRetriever.cpp
+++ b/media/libmediaplayerservice/StagefrightMetadataRetriever.cpp
@@ -22,11 +22,11 @@
#include <utils/Log.h>
#include <cutils/properties.h>
-#include "include/FrameDecoder.h"
-#include "include/StagefrightMetadataRetriever.h"
+#include "StagefrightMetadataRetriever.h"
+#include "FrameDecoder.h"
-#include <datasource/DataSourceFactory.h>
-#include <datasource/FileSource.h>
+#include <datasource/PlayerServiceDataSourceFactory.h>
+#include <datasource/PlayerServiceFileSource.h>
#include <media/IMediaHTTPService.h>
#include <media/stagefright/foundation/ADebug.h>
#include <media/stagefright/foundation/AMessage.h>
@@ -63,7 +63,8 @@
ALOGV("setDataSource(%s)", uri);
clearMetadata();
- mSource = DataSourceFactory::CreateFromURI(httpService, uri, headers);
+ mSource = PlayerServiceDataSourceFactory::getInstance()->CreateFromURI(
+ httpService, uri, headers);
if (mSource == NULL) {
ALOGE("Unable to create data source for '%s'.", uri);
@@ -91,7 +92,7 @@
ALOGV("setDataSource(%d, %" PRId64 ", %" PRId64 ")", fd, offset, length);
clearMetadata();
- mSource = new FileSource(fd, offset, length);
+ mSource = new PlayerServiceFileSource(fd, offset, length);
status_t err;
if ((err = mSource->initCheck()) != OK) {
diff --git a/media/libstagefright/include/StagefrightMetadataRetriever.h b/media/libmediaplayerservice/StagefrightMetadataRetriever.h
similarity index 100%
rename from media/libstagefright/include/StagefrightMetadataRetriever.h
rename to media/libmediaplayerservice/StagefrightMetadataRetriever.h
diff --git a/media/libmediaplayerservice/datasource/Android.bp b/media/libmediaplayerservice/datasource/Android.bp
new file mode 100644
index 0000000..71fa50b
--- /dev/null
+++ b/media/libmediaplayerservice/datasource/Android.bp
@@ -0,0 +1,43 @@
+cc_library_static {
+ name: "libplayerservice_datasource",
+
+ srcs: [
+ "PlayerServiceDataSourceFactory.cpp",
+ "PlayerServiceFileSource.cpp",
+ "PlayerServiceMediaHTTP.cpp",
+ ],
+
+ header_libs: [
+ "media_ndk_headers",
+ "libmedia_headers",
+ ],
+
+ shared_libs: [
+ "libdatasource",
+ "libdrmframework",
+ "liblog",
+ "libutils",
+ ],
+
+ local_include_dirs: [
+ "include",
+ ],
+
+ export_include_dirs: [
+ "include",
+ ],
+
+ cflags: [
+ "-Werror",
+ "-Wno-error=deprecated-declarations",
+ "-Wall",
+ ],
+
+ sanitize: {
+ misc_undefined: [
+ "unsigned-integer-overflow",
+ "signed-integer-overflow",
+ ],
+ cfi: true,
+ },
+}
diff --git a/media/libmediaplayerservice/datasource/PlayerServiceDataSourceFactory.cpp b/media/libmediaplayerservice/datasource/PlayerServiceDataSourceFactory.cpp
new file mode 100644
index 0000000..ef946e9
--- /dev/null
+++ b/media/libmediaplayerservice/datasource/PlayerServiceDataSourceFactory.cpp
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+//#define LOG_NDEBUG 0
+#define LOG_TAG "PlayerServuceDataSourceFactory"
+
+
+#include <datasource/PlayerServiceDataSourceFactory.h>
+#include <datasource/PlayerServiceFileSource.h>
+#include <datasource/PlayerServiceMediaHTTP.h>
+#include <media/MediaHTTPConnection.h>
+#include <media/MediaHTTPService.h>
+
+namespace android {
+
+// static
+sp<PlayerServiceDataSourceFactory> PlayerServiceDataSourceFactory::sInstance;
+// static
+Mutex PlayerServiceDataSourceFactory::sInstanceLock;
+
+// static
+sp<PlayerServiceDataSourceFactory> PlayerServiceDataSourceFactory::getInstance() {
+ Mutex::Autolock l(sInstanceLock);
+ if (!sInstance) {
+ sInstance = new PlayerServiceDataSourceFactory();
+ }
+ return sInstance;
+}
+
+sp<DataSource> PlayerServiceDataSourceFactory::CreateMediaHTTP(
+ const sp<MediaHTTPService> &httpService) {
+ if (httpService == NULL) {
+ return NULL;
+ }
+
+ sp<MediaHTTPConnection> conn = httpService->makeHTTPConnection();
+ if (conn == NULL) {
+ ALOGE("Failed to make http connection from http service!");
+ return NULL;
+ } else {
+ return new PlayerServiceMediaHTTP(conn);
+ }
+}
+
+sp<DataSource> PlayerServiceDataSourceFactory::CreateFileSource(const char *uri) {
+ return new PlayerServiceFileSource(uri);
+}
+
+} // namespace android
diff --git a/media/libmediaplayerservice/datasource/PlayerServiceFileSource.cpp b/media/libmediaplayerservice/datasource/PlayerServiceFileSource.cpp
new file mode 100644
index 0000000..1580891
--- /dev/null
+++ b/media/libmediaplayerservice/datasource/PlayerServiceFileSource.cpp
@@ -0,0 +1,155 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "PlayerServiceFileSource"
+#include <utils/Log.h>
+
+#include <datasource/PlayerServiceFileSource.h>
+#include <media/stagefright/foundation/ADebug.h>
+#include <private/android_filesystem_config.h>
+
+namespace android {
+
+PlayerServiceFileSource::PlayerServiceFileSource(const char *filename)
+ : FileSource(filename),
+ mDecryptHandle(NULL),
+ mDrmManagerClient(NULL),
+ mDrmBufOffset(0),
+ mDrmBufSize(0),
+ mDrmBuf(NULL){
+}
+
+PlayerServiceFileSource::PlayerServiceFileSource(int fd, int64_t offset, int64_t length)
+ : FileSource(fd, offset, length),
+ mDecryptHandle(NULL),
+ mDrmManagerClient(NULL),
+ mDrmBufOffset(0),
+ mDrmBufSize(0),
+ mDrmBuf(NULL) {
+}
+
+PlayerServiceFileSource::~PlayerServiceFileSource() {
+ if (mDrmBuf != NULL) {
+ delete[] mDrmBuf;
+ mDrmBuf = NULL;
+ }
+
+ if (mDecryptHandle != NULL) {
+ // To release mDecryptHandle
+ CHECK(mDrmManagerClient);
+ mDrmManagerClient->closeDecryptSession(mDecryptHandle);
+ mDecryptHandle = NULL;
+ }
+
+ if (mDrmManagerClient != NULL) {
+ delete mDrmManagerClient;
+ mDrmManagerClient = NULL;
+ }
+}
+
+ssize_t PlayerServiceFileSource::readAt(off64_t offset, void *data, size_t size) {
+ if (mFd < 0) {
+ return NO_INIT;
+ }
+
+ Mutex::Autolock autoLock(mLock);
+
+ if (mLength >= 0) {
+ if (offset >= mLength) {
+ return 0; // read beyond EOF.
+ }
+ uint64_t numAvailable = mLength - offset;
+ if ((uint64_t)size > numAvailable) {
+ size = numAvailable;
+ }
+ }
+
+ if (mDecryptHandle != NULL && DecryptApiType::CONTAINER_BASED
+ == mDecryptHandle->decryptApiType) {
+ return readAtDRM_l(offset, data, size);
+ } else {
+ return readAt_l(offset, data, size);
+ }
+}
+
+sp<DecryptHandle> PlayerServiceFileSource::DrmInitialization(const char *mime) {
+ if (getuid() == AID_MEDIA_EX) return nullptr; // no DRM in media extractor
+ if (mDrmManagerClient == NULL) {
+ mDrmManagerClient = new DrmManagerClient();
+ }
+
+ if (mDrmManagerClient == NULL) {
+ return NULL;
+ }
+
+ if (mDecryptHandle == NULL) {
+ mDecryptHandle = mDrmManagerClient->openDecryptSession(
+ mFd, mOffset, mLength, mime);
+ }
+
+ if (mDecryptHandle == NULL) {
+ delete mDrmManagerClient;
+ mDrmManagerClient = NULL;
+ }
+
+ return mDecryptHandle;
+}
+
+ssize_t PlayerServiceFileSource::readAtDRM_l(off64_t offset, void *data, size_t size) {
+ size_t DRM_CACHE_SIZE = 1024;
+ if (mDrmBuf == NULL) {
+ mDrmBuf = new unsigned char[DRM_CACHE_SIZE];
+ }
+
+ if (mDrmBuf != NULL && mDrmBufSize > 0 && (offset + mOffset) >= mDrmBufOffset
+ && (offset + mOffset + size) <= static_cast<size_t>(mDrmBufOffset + mDrmBufSize)) {
+ /* Use buffered data */
+ memcpy(data, (void*)(mDrmBuf+(offset+mOffset-mDrmBufOffset)), size);
+ return size;
+ } else if (size <= DRM_CACHE_SIZE) {
+ /* Buffer new data */
+ mDrmBufOffset = offset + mOffset;
+ mDrmBufSize = mDrmManagerClient->pread(mDecryptHandle, mDrmBuf,
+ DRM_CACHE_SIZE, offset + mOffset);
+ if (mDrmBufSize > 0) {
+ int64_t dataRead = 0;
+ dataRead = size > static_cast<size_t>(mDrmBufSize) ? mDrmBufSize : size;
+ memcpy(data, (void*)mDrmBuf, dataRead);
+ return dataRead;
+ } else {
+ return mDrmBufSize;
+ }
+ } else {
+ /* Too big chunk to cache. Call DRM directly */
+ return mDrmManagerClient->pread(mDecryptHandle, data, size, offset + mOffset);
+ }
+}
+
+/* static */
+bool PlayerServiceFileSource::requiresDrm(int fd, int64_t offset, int64_t length, const char *mime) {
+ std::unique_ptr<DrmManagerClient> drmClient(new DrmManagerClient());
+ sp<DecryptHandle> decryptHandle =
+ drmClient->openDecryptSession(fd, offset, length, mime);
+ bool requiresDrm = false;
+ if (decryptHandle != nullptr) {
+ requiresDrm = decryptHandle->decryptApiType == DecryptApiType::CONTAINER_BASED;
+ drmClient->closeDecryptSession(decryptHandle);
+ }
+ return requiresDrm;
+}
+
+} // namespace android
diff --git a/media/libmediaplayerservice/datasource/PlayerServiceMediaHTTP.cpp b/media/libmediaplayerservice/datasource/PlayerServiceMediaHTTP.cpp
new file mode 100644
index 0000000..0124720
--- /dev/null
+++ b/media/libmediaplayerservice/datasource/PlayerServiceMediaHTTP.cpp
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "PlayerServiceMediaHTTP"
+#include <utils/Log.h>
+
+#include <datasource/PlayerServiceMediaHTTP.h>
+
+#include <binder/IServiceManager.h>
+#include <media/stagefright/foundation/ADebug.h>
+#include <media/stagefright/foundation/ALooper.h>
+#include <media/stagefright/FoundationUtils.h>
+
+#include <media/MediaHTTPConnection.h>
+
+namespace android {
+
+PlayerServiceMediaHTTP::PlayerServiceMediaHTTP(const sp<MediaHTTPConnection> &conn)
+ : MediaHTTP(conn),
+ mDrmManagerClient(NULL) {
+}
+
+PlayerServiceMediaHTTP::~PlayerServiceMediaHTTP() {
+ clearDRMState_l();
+}
+
+// DRM...
+
+sp<DecryptHandle> PlayerServiceMediaHTTP::DrmInitialization(const char* mime) {
+ if (mDrmManagerClient == NULL) {
+ mDrmManagerClient = new DrmManagerClient();
+ }
+
+ if (mDrmManagerClient == NULL) {
+ return NULL;
+ }
+
+ if (mDecryptHandle == NULL) {
+ mDecryptHandle = mDrmManagerClient->openDecryptSession(
+ String8(mLastURI.c_str()), mime);
+ }
+
+ if (mDecryptHandle == NULL) {
+ delete mDrmManagerClient;
+ mDrmManagerClient = NULL;
+ }
+
+ return mDecryptHandle;
+}
+
+void PlayerServiceMediaHTTP::clearDRMState_l() {
+ if (mDecryptHandle != NULL) {
+ // To release mDecryptHandle
+ CHECK(mDrmManagerClient);
+ mDrmManagerClient->closeDecryptSession(mDecryptHandle);
+ mDecryptHandle = NULL;
+ }
+}
+
+} // namespace android
diff --git a/media/libmediaplayerservice/datasource/include/datasource/PlayerServiceDataSourceFactory.h b/media/libmediaplayerservice/datasource/include/datasource/PlayerServiceDataSourceFactory.h
new file mode 100644
index 0000000..7d58c5c
--- /dev/null
+++ b/media/libmediaplayerservice/datasource/include/datasource/PlayerServiceDataSourceFactory.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef PLAYER_SERVICE_DATA_SOURCE_FACTORY_H_
+
+#define PLAYER_SERVICE_DATA_SOURCE_FACTORY_H_
+
+#include <datasource/DataSourceFactory.h>
+#include <media/DataSource.h>
+#include <sys/types.h>
+#include <utils/RefBase.h>
+
+namespace android {
+
+struct MediaHTTPService;
+class String8;
+struct HTTPBase;
+
+class PlayerServiceDataSourceFactory : public DataSourceFactory {
+public:
+ static sp<PlayerServiceDataSourceFactory> getInstance();
+ virtual sp<DataSource> CreateMediaHTTP(const sp<MediaHTTPService> &httpService);
+
+protected:
+ virtual sp<DataSource> CreateFileSource(const char *uri);
+
+private:
+ static sp<PlayerServiceDataSourceFactory> sInstance;
+ static Mutex sInstanceLock;
+ PlayerServiceDataSourceFactory() {};
+};
+
+} // namespace android
+
+#endif // PLAYER_SERVICE_DATA_SOURCE_FACTORY_H_
diff --git a/media/libmediaplayerservice/datasource/include/datasource/PlayerServiceFileSource.h b/media/libmediaplayerservice/datasource/include/datasource/PlayerServiceFileSource.h
new file mode 100644
index 0000000..08a013e
--- /dev/null
+++ b/media/libmediaplayerservice/datasource/include/datasource/PlayerServiceFileSource.h
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef PLAYER_SERVICE_FILE_SOURCE_H_
+
+#define PLAYER_SERVICE_FILE_SOURCE_H_
+
+#include <stdio.h>
+
+#include <datasource/FileSource.h>
+#include <media/stagefright/MediaErrors.h>
+#include <utils/threads.h>
+#include <drm/DrmManagerClient.h>
+
+namespace android {
+
+// FileSource implementation which works on MediaPlayerService.
+// Supports OMA(forword-lock) files.
+class PlayerServiceFileSource : public FileSource {
+public:
+ PlayerServiceFileSource(const char *filename);
+ // PlayerServiceFileSource takes ownership and will close the fd
+ PlayerServiceFileSource(int fd, int64_t offset, int64_t length);
+
+ virtual ssize_t readAt(off64_t offset, void *data, size_t size);
+
+ virtual sp<DecryptHandle> DrmInitialization(const char *mime);
+
+ static bool requiresDrm(int fd, int64_t offset, int64_t length, const char *mime);
+
+protected:
+ virtual ~PlayerServiceFileSource();
+
+private:
+ /*for DRM*/
+ sp<DecryptHandle> mDecryptHandle;
+ DrmManagerClient *mDrmManagerClient;
+ int64_t mDrmBufOffset;
+ ssize_t mDrmBufSize;
+ unsigned char *mDrmBuf;
+
+ ssize_t readAtDRM_l(off64_t offset, void *data, size_t size);
+
+ PlayerServiceFileSource(const PlayerServiceFileSource &);
+ PlayerServiceFileSource &operator=(const PlayerServiceFileSource &);
+};
+
+} // namespace android
+
+#endif // PLAYER_SERVICE_FILE_SOURCE_H_
+
diff --git a/media/libmediaplayerservice/datasource/include/datasource/PlayerServiceMediaHTTP.h b/media/libmediaplayerservice/datasource/include/datasource/PlayerServiceMediaHTTP.h
new file mode 100644
index 0000000..0032cd7
--- /dev/null
+++ b/media/libmediaplayerservice/datasource/include/datasource/PlayerServiceMediaHTTP.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef PLAYER_SERVICE_MEDIA_HTTP_H_
+
+#define PLAYER_SERVICE_MEDIA_HTTP_H_
+
+#include <datasource/MediaHTTP.h>
+#include <media/stagefright/foundation/AString.h>
+
+namespace android {
+
+struct MediaHTTPConnection;
+
+// MediaHTTP implementation which works on MediaPlayerService.
+// Supports OMA(forword-lock) stream.
+struct PlayerServiceMediaHTTP : public MediaHTTP {
+ PlayerServiceMediaHTTP(const sp<MediaHTTPConnection> &conn);
+
+protected:
+ virtual ~PlayerServiceMediaHTTP();
+
+ virtual sp<DecryptHandle> DrmInitialization(const char* mime);
+
+private:
+ sp<DecryptHandle> mDecryptHandle;
+ DrmManagerClient *mDrmManagerClient;
+
+ void clearDRMState_l();
+
+ DISALLOW_EVIL_CONSTRUCTORS(PlayerServiceMediaHTTP);
+};
+
+} // namespace android
+
+#endif // PLAYER_SERVICE_MEDIA_HTTP_H_
diff --git a/media/libmediaplayerservice/nuplayer/Android.bp b/media/libmediaplayerservice/nuplayer/Android.bp
index 19c8e76..c8f48a2 100644
--- a/media/libmediaplayerservice/nuplayer/Android.bp
+++ b/media/libmediaplayerservice/nuplayer/Android.bp
@@ -54,6 +54,10 @@
"libpowermanager",
],
+ static_libs: [
+ "libplayerservice_datasource",
+ ],
+
name: "libstagefright_nuplayer",
sanitize: {
diff --git a/media/libmediaplayerservice/nuplayer/GenericSource.cpp b/media/libmediaplayerservice/nuplayer/GenericSource.cpp
index e26f1e6..f17520a 100644
--- a/media/libmediaplayerservice/nuplayer/GenericSource.cpp
+++ b/media/libmediaplayerservice/nuplayer/GenericSource.cpp
@@ -23,8 +23,8 @@
#include "AnotherPacketSource.h"
#include <binder/IServiceManager.h>
#include <cutils/properties.h>
-#include <datasource/DataSourceFactory.h>
-#include <datasource/FileSource.h>
+#include <datasource/PlayerServiceDataSourceFactory.h>
+#include <datasource/PlayerServiceFileSource.h>
#include <datasource/HTTPBase.h>
#include <datasource/NuCachedSource2.h>
#include <media/DataSource.h>
@@ -385,7 +385,8 @@
if (!strncasecmp("http://", uri, 7) || !strncasecmp("https://", uri, 8)) {
sp<DataSource> httpSource;
mDisconnectLock.unlock();
- httpSource = DataSourceFactory::CreateMediaHTTP(mHTTPService);
+ httpSource = PlayerServiceDataSourceFactory::getInstance()
+ ->CreateMediaHTTP(mHTTPService);
if (httpSource == NULL) {
ALOGE("Failed to create http source!");
notifyPreparedAndCleanup(UNKNOWN_ERROR);
@@ -401,9 +402,9 @@
mLock.unlock();
mDisconnectLock.unlock();
// This might take long time if connection has some issue.
- sp<DataSource> dataSource = DataSourceFactory::CreateFromURI(
- mHTTPService, uri, &mUriHeaders, &contentType,
- static_cast<HTTPBase *>(mHttpSource.get()));
+ sp<DataSource> dataSource = PlayerServiceDataSourceFactory::getInstance()
+ ->CreateFromURI(mHTTPService, uri, &mUriHeaders, &contentType,
+ static_cast<HTTPBase *>(mHttpSource.get()));
mDisconnectLock.lock();
mLock.lock();
if (!mDisconnected) {
@@ -411,7 +412,8 @@
}
} else {
if (property_get_bool("media.stagefright.extractremote", true) &&
- !FileSource::requiresDrm(mFd, mOffset, mLength, nullptr /* mime */)) {
+ !PlayerServiceFileSource::requiresDrm(
+ mFd, mOffset, mLength, nullptr /* mime */)) {
sp<IBinder> binder =
defaultServiceManager()->getService(String16("media.extractor"));
if (binder != nullptr) {
@@ -438,7 +440,7 @@
}
if (mDataSource == nullptr) {
ALOGD("FileSource local");
- mDataSource = new FileSource(mFd, mOffset, mLength);
+ mDataSource = new PlayerServiceFileSource(mFd, mOffset, mLength);
}
// TODO: close should always be done on mFd, see the lines following
// CreateDataSourceFromIDataSource above,
diff --git a/media/libstagefright/Android.bp b/media/libstagefright/Android.bp
index 806e277..bb476b5 100644
--- a/media/libstagefright/Android.bp
+++ b/media/libstagefright/Android.bp
@@ -161,7 +161,6 @@
"SimpleDecodingSource.cpp",
"SkipCutBuffer.cpp",
"StagefrightMediaScanner.cpp",
- "StagefrightMetadataRetriever.cpp",
"StagefrightPluginLoader.cpp",
"SurfaceUtils.cpp",
"ThrottledSource.cpp",
diff --git a/media/libstagefright/NuMediaExtractor.cpp b/media/libstagefright/NuMediaExtractor.cpp
index b89dcdf..66fb4b0 100644
--- a/media/libstagefright/NuMediaExtractor.cpp
+++ b/media/libstagefright/NuMediaExtractor.cpp
@@ -82,7 +82,7 @@
}
sp<DataSource> dataSource =
- DataSourceFactory::CreateFromURI(httpService, path, headers);
+ DataSourceFactory::getInstance()->CreateFromURI(httpService, path, headers);
if (dataSource == NULL) {
return -ENOENT;
diff --git a/media/libstagefright/httplive/HTTPDownloader.cpp b/media/libstagefright/httplive/HTTPDownloader.cpp
index 7183dbd..68f1de9 100644
--- a/media/libstagefright/httplive/HTTPDownloader.cpp
+++ b/media/libstagefright/httplive/HTTPDownloader.cpp
@@ -21,8 +21,8 @@
#include "HTTPDownloader.h"
#include "M3UParser.h"
-#include <datasource/ClearMediaHTTP.h>
-#include <datasource/ClearFileSource.h>
+#include <datasource/MediaHTTP.h>
+#include <datasource/FileSource.h>
#include <media/DataSource.h>
#include <media/MediaHTTPConnection.h>
#include <media/MediaHTTPService.h>
@@ -38,7 +38,7 @@
HTTPDownloader::HTTPDownloader(
const sp<MediaHTTPService> &httpService,
const KeyedVector<String8, String8> &headers) :
- mHTTPDataSource(new ClearMediaHTTP(httpService->makeHTTPConnection())),
+ mHTTPDataSource(new MediaHTTP(httpService->makeHTTPConnection())),
mExtraHeaders(headers),
mDisconnecting(false) {
}
@@ -91,7 +91,7 @@
if (reconnect) {
if (!strncasecmp(url, "file://", 7)) {
- mDataSource = new ClearFileSource(url + 7);
+ mDataSource = new FileSource(url + 7);
} else if (strncasecmp(url, "http://", 7)
&& strncasecmp(url, "https://", 8)) {
return ERROR_UNSUPPORTED;
diff --git a/media/libstagefright/omx/tests/OMXHarness.cpp b/media/libstagefright/omx/tests/OMXHarness.cpp
index ee01d6c..6848a83 100644
--- a/media/libstagefright/omx/tests/OMXHarness.cpp
+++ b/media/libstagefright/omx/tests/OMXHarness.cpp
@@ -278,7 +278,7 @@
static sp<IMediaExtractor> CreateExtractorFromURI(const char *uri) {
sp<DataSource> source =
- DataSourceFactory::CreateFromURI(NULL /* httpService */, uri);
+ DataSourceFactory::getInstance()->CreateFromURI(NULL /* httpService */, uri);
if (source == NULL) {
return NULL;
diff --git a/media/libstagefright/rtsp/SDPLoader.cpp b/media/libstagefright/rtsp/SDPLoader.cpp
index 5bd218d..e236267 100644
--- a/media/libstagefright/rtsp/SDPLoader.cpp
+++ b/media/libstagefright/rtsp/SDPLoader.cpp
@@ -22,7 +22,7 @@
#include "ASessionDescription.h"
-#include <datasource/ClearMediaHTTP.h>
+#include <datasource/MediaHTTP.h>
#include <media/MediaHTTPConnection.h>
#include <media/MediaHTTPService.h>
#include <media/stagefright/foundation/ABuffer.h>
@@ -42,7 +42,7 @@
mFlags(flags),
mNetLooper(new ALooper),
mCancelled(false),
- mHTTPDataSource(new ClearMediaHTTP(httpService->makeHTTPConnection())) {
+ mHTTPDataSource(new MediaHTTP(httpService->makeHTTPConnection())) {
mNetLooper->setName("sdp net");
mNetLooper->start(false /* runOnCallingThread */,
false /* canCallJava */,
diff --git a/media/ndk/NdkMediaDataSource.cpp b/media/ndk/NdkMediaDataSource.cpp
index f6892e6..c1d4686 100644
--- a/media/ndk/NdkMediaDataSource.cpp
+++ b/media/ndk/NdkMediaDataSource.cpp
@@ -202,7 +202,7 @@
headers.add(key8, value8);
}
- sp<DataSource> source = DataSourceFactory::CreateFromURI(service, uri, &headers);
+ sp<DataSource> source = DataSourceFactory::getInstance()->CreateFromURI(service, uri, &headers);
if (source == NULL) {
ALOGE("AMediaDataSource_newUri source is null");
return NULL;
diff --git a/services/mediaextractor/MediaExtractorService.cpp b/services/mediaextractor/MediaExtractorService.cpp
index ac6b771..6239fb2 100644
--- a/services/mediaextractor/MediaExtractorService.cpp
+++ b/services/mediaextractor/MediaExtractorService.cpp
@@ -55,7 +55,7 @@
sp<IDataSource> MediaExtractorService::makeIDataSource(int fd, int64_t offset, int64_t length)
{
- sp<DataSource> source = DataSourceFactory::CreateFromFd(fd, offset, length);
+ sp<DataSource> source = DataSourceFactory::getInstance()->CreateFromFd(fd, offset, length);
return CreateIDataSourceFromDataSource(source);
}