Allow MediaExtractor to create FileSource
Remove binder call to MediaServer for reading files.
Test: Photos, Play Music, Play Movies, Youtube
Bug: 29125703
Change-Id: Id6abf592bf6d70b81158f6038b1982f0a537b9b9
diff --git a/media/libmedia/IMediaExtractorService.cpp b/media/libmedia/IMediaExtractorService.cpp
index 8b00d85..7c0d08d 100644
--- a/media/libmedia/IMediaExtractorService.cpp
+++ b/media/libmedia/IMediaExtractorService.cpp
@@ -23,11 +23,13 @@
#include <sys/types.h>
#include <binder/Parcel.h>
#include <media/IMediaExtractorService.h>
+#include <media/stagefright/MediaExtractor.h>
namespace android {
enum {
- MAKE_EXTRACTOR = IBinder::FIRST_CALL_TRANSACTION
+ MAKE_EXTRACTOR = IBinder::FIRST_CALL_TRANSACTION,
+ MAKE_IDATA_SOURCE_FD,
};
class BpMediaExtractorService : public BpInterface<IMediaExtractorService>
@@ -52,6 +54,21 @@
return NULL;
}
+ virtual sp<IDataSource> makeIDataSource(int fd, int64_t offset, int64_t length)
+ {
+ Parcel data, reply;
+ data.writeInterfaceToken(IMediaExtractorService::getInterfaceDescriptor());
+ data.writeFileDescriptor(fd);
+ data.writeInt64(offset);
+ data.writeInt64(length);
+ status_t ret = remote()->transact(MAKE_IDATA_SOURCE_FD, data, &reply);
+ ALOGV("fd:%d offset:%lld length:%lld ret:%d",
+ fd, (long long)offset, (long long)length, ret);
+ if (ret == NO_ERROR) {
+ return interface_cast<IDataSource>(reply.readStrongBinder());
+ }
+ return nullptr;
+ }
};
IMPLEMENT_META_INTERFACE(MediaExtractorService, "android.media.IMediaExtractorService");
@@ -80,6 +97,23 @@
reply->writeStrongBinder(IInterface::asBinder(ex));
return NO_ERROR;
}
+
+ case MAKE_IDATA_SOURCE_FD: {
+ CHECK_INTERFACE(IMediaExtractorService, data, reply);
+ const int fd = dup(data.readFileDescriptor()); // -1 fd checked in makeIDataSource
+ const int64_t offset = data.readInt64();
+ const int64_t length = data.readInt64();
+ ALOGV("fd %d offset%lld length:%lld", fd, (long long)offset, (long long)length);
+ sp<IDataSource> source = makeIDataSource(fd, offset, length);
+ reply->writeStrongBinder(IInterface::asBinder(source));
+ // The FileSource closes the descriptor, so if it is not created
+ // we need to close the descriptor explicitly.
+ if (source.get() == nullptr && fd != -1) {
+ close(fd);
+ }
+ return NO_ERROR;
+ }
+
default:
return BBinder::onTransact(code, data, reply, flags);
}