1 /* 2 * Copyright 2021 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #pragma once 18 19 #include <aidl/android/hardware/tv/tuner/BnFilter.h> 20 #include <aidl/android/hardware/tv/tuner/Constant.h> 21 #include <aidl/android/hardware/tv/tuner/DemuxFilterEvent.h> 22 #include <aidl/android/hardware/tv/tuner/DemuxFilterStatus.h> 23 24 #include <fmq/AidlMessageQueue.h> 25 #include <inttypes.h> 26 #include <ion/ion.h> 27 #include <math.h> 28 #include <sys/stat.h> 29 #include <atomic> 30 #include <condition_variable> 31 #include <set> 32 #include <thread> 33 34 #include "Demux.h" 35 #include "Dvr.h" 36 #include "Frontend.h" 37 38 using namespace std; 39 40 namespace aidl { 41 namespace android { 42 namespace hardware { 43 namespace tv { 44 namespace tuner { 45 46 using ::aidl::android::hardware::common::NativeHandle; 47 using ::aidl::android::hardware::common::fmq::MQDescriptor; 48 using ::aidl::android::hardware::common::fmq::SynchronizedReadWrite; 49 using ::android::AidlMessageQueue; 50 using ::android::hardware::EventFlag; 51 52 using FilterMQ = AidlMessageQueue<int8_t, SynchronizedReadWrite>; 53 54 const uint32_t BUFFER_SIZE = 0x800000; // 8 MB 55 56 class Demux; 57 class Dvr; 58 59 class FilterCallbackScheduler final { 60 public: 61 FilterCallbackScheduler(const std::shared_ptr<IFilterCallback>& cb); 62 ~FilterCallbackScheduler(); 63 64 void onFilterEvent(DemuxFilterEvent&& event); 65 void onFilterStatus(const DemuxFilterStatus& status); 66 67 void setTimeDelayHint(int timeDelay); 68 void setDataSizeDelayHint(int dataSizeDelay); 69 70 bool hasCallbackRegistered() const; 71 72 void flushEvents(); 73 74 private: 75 void start(); 76 void stop(); 77 78 void threadLoop(); 79 void threadLoopOnce(); 80 81 // function needs to be called while holding mLock 82 bool isDataSizeDelayConditionMetLocked(); 83 84 static int getDemuxFilterEventDataLength(const DemuxFilterEvent& event); 85 86 private: 87 std::shared_ptr<IFilterCallback> mCallback; 88 std::thread mCallbackThread; 89 std::atomic<bool> mIsRunning; 90 91 // mLock protects mCallbackBuffer, mIsConditionMet, mCv, mDataLength, 92 // mTimeDelayInMs, and mDataSizeDelayInBytes 93 std::mutex mLock; 94 std::vector<DemuxFilterEvent> mCallbackBuffer; 95 bool mIsConditionMet; 96 std::condition_variable mCv; 97 int mDataLength; 98 int mTimeDelayInMs; 99 int mDataSizeDelayInBytes; 100 }; 101 102 class Filter : public BnFilter { 103 friend class FilterCallbackScheduler; 104 105 public: 106 Filter(DemuxFilterType type, int64_t filterId, uint32_t bufferSize, 107 const std::shared_ptr<IFilterCallback>& cb, std::shared_ptr<Demux> demux); 108 109 ~Filter(); 110 111 ::ndk::ScopedAStatus getQueueDesc( 112 MQDescriptor<int8_t, SynchronizedReadWrite>* out_queue) override; 113 ::ndk::ScopedAStatus close() override; 114 ::ndk::ScopedAStatus configure(const DemuxFilterSettings& in_settings) override; 115 ::ndk::ScopedAStatus configureAvStreamType(const AvStreamType& in_avStreamType) override; 116 ::ndk::ScopedAStatus configureIpCid(int32_t in_ipCid) override; 117 ::ndk::ScopedAStatus configureMonitorEvent(int32_t in_monitorEventTypes) override; 118 ::ndk::ScopedAStatus start() override; 119 ::ndk::ScopedAStatus stop() override; 120 ::ndk::ScopedAStatus flush() override; 121 ::ndk::ScopedAStatus getAvSharedHandle(NativeHandle* out_avMemory, 122 int64_t* _aidl_return) override; 123 ::ndk::ScopedAStatus getId(int32_t* _aidl_return) override; 124 ::ndk::ScopedAStatus getId64Bit(int64_t* _aidl_return) override; 125 ::ndk::ScopedAStatus releaseAvHandle(const NativeHandle& in_avMemory, 126 int64_t in_avDataId) override; 127 ::ndk::ScopedAStatus setDataSource(const std::shared_ptr<IFilter>& in_filter) override; 128 ::ndk::ScopedAStatus setDelayHint(const FilterDelayHint& in_hint) override; 129 130 binder_status_t dump(int fd, const char** args, uint32_t numArgs) override; 131 132 /** 133 * To create a FilterMQ and its Event Flag. 134 * 135 * Return false is any of the above processes fails. 136 */ 137 bool createFilterMQ(); 138 uint16_t getTpid(); 139 void updateFilterOutput(vector<int8_t>& data); 140 void updateRecordOutput(vector<int8_t>& data); 141 void updatePts(uint64_t pts); 142 ::ndk::ScopedAStatus startFilterHandler(); 143 ::ndk::ScopedAStatus startRecordFilterHandler(); 144 void attachFilterToRecord(const std::shared_ptr<Dvr> dvr); 145 void detachFilterFromRecord(); 146 void freeSharedAvHandle(); isMediaFilter()147 bool isMediaFilter() { return mIsMediaFilter; }; isPcrFilter()148 bool isPcrFilter() { return mIsPcrFilter; }; isRecordFilter()149 bool isRecordFilter() { return mIsRecordFilter; }; 150 151 private: 152 // Demux service 153 std::shared_ptr<Demux> mDemux; 154 // Dvr reference once the filter is attached to any 155 std::shared_ptr<Dvr> mDvr = nullptr; 156 157 FilterCallbackScheduler mCallbackScheduler; 158 159 int64_t mFilterId; 160 int32_t mCid = static_cast<int32_t>(Constant::INVALID_IP_FILTER_CONTEXT_ID); 161 uint32_t mBufferSize; 162 DemuxFilterType mType; 163 bool mIsMediaFilter = false; 164 bool mIsPcrFilter = false; 165 bool mIsRecordFilter = false; 166 DemuxFilterSettings mFilterSettings; 167 168 uint16_t mTpid; 169 std::shared_ptr<IFilter> mDataSource; 170 bool mIsDataSourceDemux = true; 171 vector<int8_t> mFilterOutput; 172 vector<int8_t> mRecordFilterOutput; 173 int64_t mPts = 0; 174 unique_ptr<FilterMQ> mFilterMQ; 175 bool mIsUsingFMQ = false; 176 EventFlag* mFilterEventsFlag; 177 vector<DemuxFilterEvent> mFilterEvents; 178 179 // Thread handlers 180 std::thread mFilterThread; 181 182 // FMQ status local records 183 DemuxFilterStatus mFilterStatus; 184 /** 185 * If a specific filter's writing loop is still running 186 */ 187 std::atomic<bool> mFilterThreadRunning; 188 189 /** 190 * How many times a filter should write 191 * TODO make this dynamic/random/can take as a parameter 192 */ 193 const uint16_t SECTION_WRITE_COUNT = 10; 194 195 bool DEBUG_FILTER = false; 196 197 /** 198 * Filter handlers to handle the data filtering. 199 * They are also responsible to write the filtered output into the filter FMQ 200 * and update the filterEvent bound with the same filterId. 201 */ 202 ::ndk::ScopedAStatus startSectionFilterHandler(); 203 ::ndk::ScopedAStatus startPesFilterHandler(); 204 ::ndk::ScopedAStatus startTsFilterHandler(); 205 ::ndk::ScopedAStatus startMediaFilterHandler(); 206 ::ndk::ScopedAStatus startPcrFilterHandler(); 207 ::ndk::ScopedAStatus startTemiFilterHandler(); 208 ::ndk::ScopedAStatus startFilterLoop(); 209 210 void deleteEventFlag(); 211 bool writeDataToFilterMQ(const std::vector<int8_t>& data); 212 bool readDataFromMQ(); 213 bool writeSectionsAndCreateEvent(vector<int8_t>& data); 214 void maySendFilterStatusCallback(); 215 DemuxFilterStatus checkFilterStatusChange(uint32_t availableToWrite, uint32_t availableToRead, 216 uint32_t highThreshold, uint32_t lowThreshold); 217 /** 218 * A dispatcher to read and dispatch input data to all the started filters. 219 * Each filter handler handles the data filtering/output writing/filterEvent updating. 220 */ 221 bool startFilterDispatcher(); 222 static void* __threadLoopFilter(void* user); 223 void filterThreadLoop(); 224 225 int createAvIonFd(int size); 226 uint8_t* getIonBuffer(int fd, int size); 227 native_handle_t* createNativeHandle(int fd); 228 ::ndk::ScopedAStatus createMediaFilterEventWithIon(vector<int8_t>& output); 229 ::ndk::ScopedAStatus createIndependentMediaEvents(vector<int8_t>& output); 230 ::ndk::ScopedAStatus createShareMemMediaEvents(vector<int8_t>& output); 231 bool sameFile(int fd1, int fd2); 232 233 void createMediaEvent(vector<DemuxFilterEvent>&, bool isAudioPresentation); 234 void createTsRecordEvent(vector<DemuxFilterEvent>&); 235 void createMmtpRecordEvent(vector<DemuxFilterEvent>&); 236 void createSectionEvent(vector<DemuxFilterEvent>&); 237 void createPesEvent(vector<DemuxFilterEvent>&); 238 void createDownloadEvent(vector<DemuxFilterEvent>&); 239 void createIpPayloadEvent(vector<DemuxFilterEvent>&); 240 void createTemiEvent(vector<DemuxFilterEvent>&); 241 void createMonitorEvent(vector<DemuxFilterEvent>&); 242 void createRestartEvent(vector<DemuxFilterEvent>&); 243 244 /** 245 * Lock to protect writes to the FMQs 246 */ 247 std::mutex mWriteLock; 248 /** 249 * Lock to protect writes to the filter event 250 */ 251 // TODO make each filter separate event lock 252 std::mutex mFilterEventsLock; 253 /** 254 * Lock to protect writes to the input status 255 */ 256 std::mutex mFilterStatusLock; 257 std::mutex mFilterOutputLock; 258 std::mutex mRecordFilterOutputLock; 259 260 // handle single Section filter 261 uint32_t mSectionSizeLeft = 0; 262 vector<int8_t> mSectionOutput; 263 264 // temp handle single PES filter 265 // TODO handle mulptiple Pes filters 266 uint32_t mPesSizeLeft = 0; 267 vector<int8_t> mPesOutput; 268 269 // A map from data id to ion handle 270 std::map<uint64_t, int> mDataId2Avfd; 271 uint64_t mLastUsedDataId = 1; 272 int mAvBufferCopyCount = 0; 273 274 // Shared A/V memory handle 275 native_handle_t* mSharedAvMemHandle = nullptr; 276 bool mUsingSharedAvMem = false; 277 int64_t mSharedAvMemOffset = 0; 278 279 uint32_t mAudioStreamType; 280 uint32_t mVideoStreamType; 281 282 // Scrambling status to be monitored 283 uint32_t mStatuses = 0; 284 285 bool mConfigured = false; 286 int mStartId = 0; 287 uint8_t mScramblingStatusMonitored = 0; 288 uint8_t mIpCidMonitored = 0; 289 }; 290 291 } // namespace tuner 292 } // namespace tv 293 } // namespace hardware 294 } // namespace android 295 } // namespace aidl 296