| Marco Nelissen | b2487f0 | 2015-09-01 13:23:23 -0700 | [diff] [blame] | 1 | /* | 
 | 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> | 
| Dongwon Kang | d91dc5a | 2017-10-10 00:07:09 -0700 | [diff] [blame] | 26 | #include <media/MediaExtractor.h> | 
| Marco Nelissen | b2487f0 | 2015-09-01 13:23:23 -0700 | [diff] [blame] | 27 |  | 
 | 28 | namespace android { | 
 | 29 |  | 
 | 30 | enum { | 
| Andy Hung | d49dbd6 | 2016-07-07 14:20:35 -0700 | [diff] [blame] | 31 |     MAKE_EXTRACTOR = IBinder::FIRST_CALL_TRANSACTION, | 
 | 32 |     MAKE_IDATA_SOURCE_FD, | 
| Marco Nelissen | b2487f0 | 2015-09-01 13:23:23 -0700 | [diff] [blame] | 33 | }; | 
 | 34 |  | 
 | 35 | class BpMediaExtractorService : public BpInterface<IMediaExtractorService> | 
 | 36 | { | 
 | 37 | public: | 
| Chih-Hung Hsieh | 64a2870 | 2016-05-03 09:52:51 -0700 | [diff] [blame] | 38 |     explicit BpMediaExtractorService(const sp<IBinder>& impl) | 
| Marco Nelissen | b2487f0 | 2015-09-01 13:23:23 -0700 | [diff] [blame] | 39 |         : BpInterface<IMediaExtractorService>(impl) | 
 | 40 |     { | 
 | 41 |     } | 
 | 42 |  | 
 | 43 |     virtual sp<IMediaExtractor> makeExtractor(const sp<IDataSource> &source, const char *mime) { | 
 | 44 |         Parcel data, reply; | 
 | 45 |         data.writeInterfaceToken(IMediaExtractorService::getInterfaceDescriptor()); | 
 | 46 |         data.writeStrongBinder(IInterface::asBinder(source)); | 
 | 47 |         if (mime != NULL) { | 
 | 48 |             data.writeCString(mime); | 
 | 49 |         } | 
 | 50 |         status_t ret = remote()->transact(MAKE_EXTRACTOR, data, &reply); | 
 | 51 |         if (ret == NO_ERROR) { | 
 | 52 |             return interface_cast<IMediaExtractor>(reply.readStrongBinder()); | 
 | 53 |         } | 
 | 54 |         return NULL; | 
 | 55 |     } | 
 | 56 |  | 
| Andy Hung | d49dbd6 | 2016-07-07 14:20:35 -0700 | [diff] [blame] | 57 |     virtual sp<IDataSource> makeIDataSource(int fd, int64_t offset, int64_t length) | 
 | 58 |     { | 
 | 59 |         Parcel data, reply; | 
 | 60 |         data.writeInterfaceToken(IMediaExtractorService::getInterfaceDescriptor()); | 
 | 61 |         data.writeFileDescriptor(fd); | 
 | 62 |         data.writeInt64(offset); | 
 | 63 |         data.writeInt64(length); | 
 | 64 |         status_t ret = remote()->transact(MAKE_IDATA_SOURCE_FD, data, &reply); | 
 | 65 |         ALOGV("fd:%d offset:%lld length:%lld ret:%d", | 
 | 66 |                 fd, (long long)offset, (long long)length, ret); | 
 | 67 |         if (ret == NO_ERROR) { | 
 | 68 |             return interface_cast<IDataSource>(reply.readStrongBinder()); | 
 | 69 |         } | 
 | 70 |         return nullptr; | 
 | 71 |     } | 
| Marco Nelissen | b2487f0 | 2015-09-01 13:23:23 -0700 | [diff] [blame] | 72 | }; | 
 | 73 |  | 
 | 74 | IMPLEMENT_META_INTERFACE(MediaExtractorService, "android.media.IMediaExtractorService"); | 
 | 75 |  | 
 | 76 | // ---------------------------------------------------------------------- | 
 | 77 |  | 
 | 78 | status_t BnMediaExtractorService::onTransact( | 
 | 79 |     uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) | 
 | 80 | { | 
 | 81 |     switch (code) { | 
 | 82 |  | 
 | 83 |         case MAKE_EXTRACTOR: { | 
 | 84 |             CHECK_INTERFACE(IMediaExtractorService, data, reply); | 
| Marco Nelissen | c22c00c | 2015-11-12 10:36:51 -0800 | [diff] [blame] | 85 |             sp<IBinder> b; | 
 | 86 |             status_t ret = data.readStrongBinder(&b); | 
 | 87 |             if (ret != NO_ERROR || b == NULL) { | 
 | 88 |                 ALOGE("Error reading source from parcel"); | 
 | 89 |                 return ret; | 
 | 90 |             } | 
| Andy Hung | 4c3d1ee | 2016-07-29 19:25:07 -0700 | [diff] [blame] | 91 |             // If we make an extractor through Binder, enabled shared memory | 
 | 92 |             // for MediaBuffers for this process. | 
 | 93 |             MediaBuffer::useSharedMemory(); | 
| Marco Nelissen | c22c00c | 2015-11-12 10:36:51 -0800 | [diff] [blame] | 94 |             sp<IDataSource> source = interface_cast<IDataSource>(b); | 
| Marco Nelissen | b2487f0 | 2015-09-01 13:23:23 -0700 | [diff] [blame] | 95 |             const char *mime = data.readCString(); | 
 | 96 |             sp<IMediaExtractor> ex = makeExtractor(source, mime); | 
 | 97 |             reply->writeStrongBinder(IInterface::asBinder(ex)); | 
 | 98 |             return NO_ERROR; | 
 | 99 |         } | 
| Andy Hung | d49dbd6 | 2016-07-07 14:20:35 -0700 | [diff] [blame] | 100 |  | 
 | 101 |         case MAKE_IDATA_SOURCE_FD: { | 
 | 102 |             CHECK_INTERFACE(IMediaExtractorService, data, reply); | 
 | 103 |             const int fd = dup(data.readFileDescriptor()); // -1 fd checked in makeIDataSource | 
 | 104 |             const int64_t offset = data.readInt64(); | 
 | 105 |             const int64_t length = data.readInt64(); | 
 | 106 |             ALOGV("fd %d  offset%lld  length:%lld", fd, (long long)offset, (long long)length); | 
 | 107 |             sp<IDataSource> source = makeIDataSource(fd, offset, length); | 
 | 108 |             reply->writeStrongBinder(IInterface::asBinder(source)); | 
 | 109 |             // The FileSource closes the descriptor, so if it is not created | 
 | 110 |             // we need to close the descriptor explicitly. | 
 | 111 |             if (source.get() == nullptr && fd != -1) { | 
 | 112 |                 close(fd); | 
 | 113 |             } | 
 | 114 |             return NO_ERROR; | 
 | 115 |         } | 
 | 116 |  | 
| Marco Nelissen | b2487f0 | 2015-09-01 13:23:23 -0700 | [diff] [blame] | 117 |         default: | 
 | 118 |             return BBinder::onTransact(code, data, reply, flags); | 
 | 119 |     } | 
 | 120 | } | 
 | 121 |  | 
 | 122 | // ---------------------------------------------------------------------------- | 
 | 123 |  | 
 | 124 | } // namespace android |