Introduce AMediaDataSource_newUri API
Bug: 109928575
Test: android.media.cts.NativeDecoderTest#testExtractor
Change-Id: I3471ffbbd2bef4fada0ed370c58468dacbed1b35
diff --git a/media/ndk/Android.bp b/media/ndk/Android.bp
index 2f298cf..417f1df 100644
--- a/media/ndk/Android.bp
+++ b/media/ndk/Android.bp
@@ -83,6 +83,7 @@
"libgui",
"libui",
"libmedia2_jni_core",
+ "libmediandk_utils",
],
export_include_dirs: ["include"],
@@ -99,3 +100,44 @@
symbol_file: "libmediandk.map.txt",
export_include_dirs: ["include"],
}
+
+cc_library {
+ name: "libmediandk_utils",
+
+ srcs: [
+ "NdkMediaDataSourceCallbacks.cpp",
+ ],
+
+ include_dirs: [
+ "frameworks/av/media/libstagefright/include",
+ "frameworks/av/media/ndk/include",
+ ],
+
+ export_include_dirs: [
+ "include",
+ ],
+
+ cflags: [
+ "-Werror",
+ "-Wno-error=deprecated-declarations",
+ "-Wall",
+ ],
+
+ shared_libs: [
+ "libstagefright_foundation",
+ "liblog",
+ "libutils",
+ "libcutils",
+ ],
+
+ sanitize: {
+ misc_undefined: [
+ "unsigned-integer-overflow",
+ "signed-integer-overflow",
+ ],
+ cfi: true,
+ diag: {
+ cfi: true,
+ },
+ },
+}
diff --git a/media/ndk/NdkMediaDataSource.cpp b/media/ndk/NdkMediaDataSource.cpp
index ec2aed6..9ea734b 100644
--- a/media/ndk/NdkMediaDataSource.cpp
+++ b/media/ndk/NdkMediaDataSource.cpp
@@ -32,12 +32,14 @@
#include <media/IMediaHTTPService.h>
#include <media/NdkMediaError.h>
#include <media/NdkMediaDataSource.h>
+#include <media/stagefright/DataSourceFactory.h>
#include <media/stagefright/InterfaceUtils.h>
#include <mediaplayer2/JavaVMHelper.h>
#include <mediaplayer2/JMedia2HTTPService.h>
#include "../../libstagefright/include/HTTPBase.h"
#include "../../libstagefright/include/NuCachedSource2.h"
+#include "NdkMediaDataSourceCallbacksPriv.h"
using namespace android;
@@ -188,6 +190,24 @@
}
EXPORT
+AMediaDataSource* AMediaDataSource_newUri(
+ const char *uri,
+ int numheaders,
+ const char * const *key_values) {
+
+ sp<MediaHTTPService> service = createMediaHttpService(uri, /* version = */ 1);
+ KeyedVector<String8, String8> headers;
+ for (int i = 0; i < numheaders; ++i) {
+ String8 key8(key_values[i * 2]);
+ String8 value8(key_values[i * 2 + 1]);
+ headers.add(key8, value8);
+ }
+
+ sp<DataSource> source = DataSourceFactory::CreateFromURI(service, uri, &headers);
+ return convertDataSourceToAMediaDataSource(source);
+}
+
+EXPORT
void AMediaDataSource_delete(AMediaDataSource *mSource) {
ALOGV("dtor");
if (mSource != NULL) {
diff --git a/media/ndk/NdkMediaDataSourceCallbacks.cpp b/media/ndk/NdkMediaDataSourceCallbacks.cpp
new file mode 100644
index 0000000..4338048
--- /dev/null
+++ b/media/ndk/NdkMediaDataSourceCallbacks.cpp
@@ -0,0 +1,42 @@
+/*
+ * Copyright 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 "NdkMediaDataSourceCallbacks"
+
+#include "NdkMediaDataSourceCallbacksPriv.h"
+#include <media/DataSource.h>
+
+namespace android {
+
+ssize_t DataSource_getSize(void *userdata) {
+ DataSource *source = static_cast<DataSource *>(userdata);
+ off64_t size = -1;
+ source->getSize(&size);
+ return size;
+}
+
+ssize_t DataSource_readAt(void *userdata, off64_t offset, void * buf, size_t size) {
+ DataSource *source = static_cast<DataSource *>(userdata);
+ return source->readAt(offset, buf, size);
+}
+
+void DataSource_close(void *userdata) {
+ DataSource *source = static_cast<DataSource *>(userdata);
+ source->close();
+}
+
+} // namespace android
diff --git a/media/ndk/NdkMediaDataSourceCallbacksPriv.h b/media/ndk/NdkMediaDataSourceCallbacksPriv.h
new file mode 100644
index 0000000..65fb0aa
--- /dev/null
+++ b/media/ndk/NdkMediaDataSourceCallbacksPriv.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright 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 A_MEDIA_DATA_SOURCE_CALLBACKS_H
+
+#define A_MEDIA_DATA_SOURCE_CALLBACKS_H
+
+#include <media/DataSource.h>
+#include <media/NdkMediaDataSource.h>
+#include <media/NdkMediaError.h>
+#include <sys/types.h>
+
+namespace android {
+
+ssize_t DataSource_getSize(void *userdata);
+
+ssize_t DataSource_readAt(void *userdata, off64_t offset, void * buf, size_t size);
+
+void DataSource_close(void *userdata);
+
+static inline AMediaDataSource* convertDataSourceToAMediaDataSource(const sp<DataSource> &source) {
+ if (source == NULL) {
+ return NULL;
+ }
+ AMediaDataSource *mSource = AMediaDataSource_new();
+ AMediaDataSource_setUserdata(mSource, source.get());
+ AMediaDataSource_setReadAt(mSource, DataSource_readAt);
+ AMediaDataSource_setGetSize(mSource, DataSource_getSize);
+ AMediaDataSource_setClose(mSource, DataSource_close);
+ return mSource;
+}
+
+} // namespace android
+
+#endif // A_MEDIA_DATA_SOURCE_CALLBACKS_H
diff --git a/media/ndk/include/media/NdkMediaDataSource.h b/media/ndk/include/media/NdkMediaDataSource.h
index ea5ba0c..021029b 100644
--- a/media/ndk/include/media/NdkMediaDataSource.h
+++ b/media/ndk/include/media/NdkMediaDataSource.h
@@ -86,6 +86,30 @@
*/
AMediaDataSource* AMediaDataSource_new() __INTRODUCED_IN(28);
+#if __ANDROID_API__ >= 29
+
+/**
+ * Create new media data source. Returns NULL if memory allocation
+ * for the new data source object fails.
+ *
+ * Set the |uri| from which the data source will read,
+ * plus additional http headers when initiating the request.
+ *
+ * Headers will contain corresponding items from |key_values|
+ * in the following fashion:
+ *
+ * key_values[0]:key_values[1]
+ * key_values[2]:key_values[3]
+ * ...
+ * key_values[(numheaders - 1) * 2]:key_values[(numheaders - 1) * 2 + 1]
+ *
+ */
+AMediaDataSource* AMediaDataSource_newUri(const char *uri,
+ int numheaders,
+ const char * const *key_values) __INTRODUCED_IN(29);
+
+#endif /*__ANDROID_API__ >= 29 */
+
/**
* Delete a previously created media data source.
*/
diff --git a/media/ndk/libmediandk.map.txt b/media/ndk/libmediandk.map.txt
index 1fd69a2..a805e87 100644
--- a/media/ndk/libmediandk.map.txt
+++ b/media/ndk/libmediandk.map.txt
@@ -141,6 +141,7 @@
AMediaDataSource_setGetSize; # introduced=28
AMediaDataSource_setReadAt; # introduced=28
AMediaDataSource_setUserdata; # introduced=28
+ AMediaDataSource_newUri; # introduced=29
AMediaDrm_closeSession;
AMediaDrm_createByUUID;
AMediaDrm_decrypt;