blob: 0295abcb35b486c06ddb6dea4eb7f2ff033f6232 [file] [log] [blame]
Marco Nelissenb2487f02015-09-01 13:23:23 -07001/*
2**
3** Copyright 2007, The Android Open Source Project
4**
5** Licensed under the Apache License, Version 2.0 (the "License");
6** you may not use this file except in compliance with the License.
7** You may obtain a copy of the License at
8**
9** http://www.apache.org/licenses/LICENSE-2.0
10**
11** Unless required by applicable law or agreed to in writing, software
12** distributed under the License is distributed on an "AS IS" BASIS,
13** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14** See the License for the specific language governing permissions and
15** limitations under the License.
16*/
17
18#define LOG_TAG "IMediaExtractorService"
19//#define LOG_NDEBUG 0
20
21#include <utils/Log.h>
22#include <stdint.h>
23#include <sys/types.h>
24#include <binder/Parcel.h>
25#include <media/IMediaExtractorService.h>
26
27namespace android {
28
29enum {
Andy Hungd49dbd62016-07-07 14:20:35 -070030 MAKE_EXTRACTOR = IBinder::FIRST_CALL_TRANSACTION,
31 MAKE_IDATA_SOURCE_FD,
Marco Nelissenb2487f02015-09-01 13:23:23 -070032};
33
34class BpMediaExtractorService : public BpInterface<IMediaExtractorService>
35{
36public:
Chih-Hung Hsieh64a28702016-05-03 09:52:51 -070037 explicit BpMediaExtractorService(const sp<IBinder>& impl)
Marco Nelissenb2487f02015-09-01 13:23:23 -070038 : BpInterface<IMediaExtractorService>(impl)
39 {
40 }
41
42 virtual sp<IMediaExtractor> makeExtractor(const sp<IDataSource> &source, const char *mime) {
43 Parcel data, reply;
44 data.writeInterfaceToken(IMediaExtractorService::getInterfaceDescriptor());
45 data.writeStrongBinder(IInterface::asBinder(source));
46 if (mime != NULL) {
47 data.writeCString(mime);
48 }
49 status_t ret = remote()->transact(MAKE_EXTRACTOR, data, &reply);
50 if (ret == NO_ERROR) {
51 return interface_cast<IMediaExtractor>(reply.readStrongBinder());
52 }
53 return NULL;
54 }
55
Andy Hungd49dbd62016-07-07 14:20:35 -070056 virtual sp<IDataSource> makeIDataSource(int fd, int64_t offset, int64_t length)
57 {
58 Parcel data, reply;
59 data.writeInterfaceToken(IMediaExtractorService::getInterfaceDescriptor());
60 data.writeFileDescriptor(fd);
61 data.writeInt64(offset);
62 data.writeInt64(length);
63 status_t ret = remote()->transact(MAKE_IDATA_SOURCE_FD, data, &reply);
64 ALOGV("fd:%d offset:%lld length:%lld ret:%d",
65 fd, (long long)offset, (long long)length, ret);
66 if (ret == NO_ERROR) {
67 return interface_cast<IDataSource>(reply.readStrongBinder());
68 }
69 return nullptr;
70 }
Marco Nelissenb2487f02015-09-01 13:23:23 -070071};
72
73IMPLEMENT_META_INTERFACE(MediaExtractorService, "android.media.IMediaExtractorService");
74
75// ----------------------------------------------------------------------
76
77status_t BnMediaExtractorService::onTransact(
78 uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
79{
80 switch (code) {
81
82 case MAKE_EXTRACTOR: {
83 CHECK_INTERFACE(IMediaExtractorService, data, reply);
Marco Nelissenc22c00c2015-11-12 10:36:51 -080084 sp<IBinder> b;
85 status_t ret = data.readStrongBinder(&b);
86 if (ret != NO_ERROR || b == NULL) {
87 ALOGE("Error reading source from parcel");
88 return ret;
89 }
Andy Hung4c3d1ee2016-07-29 19:25:07 -070090 // If we make an extractor through Binder, enabled shared memory
91 // for MediaBuffers for this process.
92 MediaBuffer::useSharedMemory();
Marco Nelissenc22c00c2015-11-12 10:36:51 -080093 sp<IDataSource> source = interface_cast<IDataSource>(b);
Marco Nelissenb2487f02015-09-01 13:23:23 -070094 const char *mime = data.readCString();
95 sp<IMediaExtractor> ex = makeExtractor(source, mime);
96 reply->writeStrongBinder(IInterface::asBinder(ex));
97 return NO_ERROR;
98 }
Andy Hungd49dbd62016-07-07 14:20:35 -070099
100 case MAKE_IDATA_SOURCE_FD: {
101 CHECK_INTERFACE(IMediaExtractorService, data, reply);
102 const int fd = dup(data.readFileDescriptor()); // -1 fd checked in makeIDataSource
103 const int64_t offset = data.readInt64();
104 const int64_t length = data.readInt64();
105 ALOGV("fd %d offset%lld length:%lld", fd, (long long)offset, (long long)length);
106 sp<IDataSource> source = makeIDataSource(fd, offset, length);
107 reply->writeStrongBinder(IInterface::asBinder(source));
108 // The FileSource closes the descriptor, so if it is not created
109 // we need to close the descriptor explicitly.
110 if (source.get() == nullptr && fd != -1) {
111 close(fd);
112 }
113 return NO_ERROR;
114 }
115
Marco Nelissenb2487f02015-09-01 13:23:23 -0700116 default:
117 return BBinder::onTransact(code, data, reply, flags);
118 }
119}
120
121// ----------------------------------------------------------------------------
122
123} // namespace android