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; }; setIptvDvrPlaybackStatus(PlaybackStatus newStatus)150 void setIptvDvrPlaybackStatus(PlaybackStatus newStatus) { mIptvDvrPlaybackStatus = newStatus; }; 151 152 private: 153 // Demux service 154 std::shared_ptr<Demux> mDemux; 155 // Dvr reference once the filter is attached to any 156 std::shared_ptr<Dvr> mDvr = nullptr; 157 158 FilterCallbackScheduler mCallbackScheduler; 159 160 int64_t mFilterId; 161 int32_t mCid = static_cast<int32_t>(Constant::INVALID_IP_FILTER_CONTEXT_ID); 162 uint32_t mBufferSize; 163 DemuxFilterType mType; 164 bool mIsMediaFilter = false; 165 bool mIsPcrFilter = false; 166 bool mIsRecordFilter = false; 167 DemuxFilterSettings mFilterSettings; 168 169 uint16_t mTpid; 170 std::shared_ptr<IFilter> mDataSource; 171 bool mIsDataSourceDemux = true; 172 vector<int8_t> mFilterOutput; 173 vector<int8_t> mRecordFilterOutput; 174 int64_t mPts = 0; 175 unique_ptr<FilterMQ> mFilterMQ; 176 bool mIsUsingFMQ = false; 177 EventFlag* mFilterEventsFlag; 178 vector<DemuxFilterEvent> mFilterEvents; 179 180 // Thread handlers 181 std::thread mFilterThread; 182 183 // FMQ status local records 184 DemuxFilterStatus mFilterStatus; 185 /** 186 * If a specific filter's writing loop is still running 187 */ 188 std::atomic<bool> mFilterThreadRunning; 189 190 /** 191 * How many times a filter should write 192 * TODO make this dynamic/random/can take as a parameter 193 */ 194 const uint16_t SECTION_WRITE_COUNT = 10; 195 196 bool DEBUG_FILTER = false; 197 198 /** 199 * Filter handlers to handle the data filtering. 200 * They are also responsible to write the filtered output into the filter FMQ 201 * and update the filterEvent bound with the same filterId. 202 */ 203 ::ndk::ScopedAStatus startSectionFilterHandler(); 204 ::ndk::ScopedAStatus startPesFilterHandler(); 205 ::ndk::ScopedAStatus startTsFilterHandler(); 206 ::ndk::ScopedAStatus startMediaFilterHandler(); 207 ::ndk::ScopedAStatus startPcrFilterHandler(); 208 ::ndk::ScopedAStatus startTemiFilterHandler(); 209 ::ndk::ScopedAStatus startFilterLoop(); 210 211 void deleteEventFlag(); 212 bool writeDataToFilterMQ(const std::vector<int8_t>& data); 213 bool readDataFromMQ(); 214 bool writeSectionsAndCreateEvent(vector<int8_t>& data); 215 void maySendFilterStatusCallback(); 216 DemuxFilterStatus checkFilterStatusChange(uint32_t availableToWrite, uint32_t availableToRead, 217 uint32_t highThreshold, uint32_t lowThreshold); 218 /** 219 * A dispatcher to read and dispatch input data to all the started filters. 220 * Each filter handler handles the data filtering/output writing/filterEvent updating. 221 */ 222 bool startFilterDispatcher(); 223 static void* __threadLoopFilter(void* user); 224 void filterThreadLoop(); 225 226 int createAvIonFd(int size); 227 uint8_t* getIonBuffer(int fd, int size); 228 native_handle_t* createNativeHandle(int fd); 229 ::ndk::ScopedAStatus createMediaFilterEventWithIon(vector<int8_t>& output); 230 ::ndk::ScopedAStatus createIndependentMediaEvents(vector<int8_t>& output); 231 ::ndk::ScopedAStatus createShareMemMediaEvents(vector<int8_t>& output); 232 bool sameFile(int fd1, int fd2); 233 234 void createMediaEvent(vector<DemuxFilterEvent>&, bool isAudioPresentation); 235 void createTsRecordEvent(vector<DemuxFilterEvent>&); 236 void createMmtpRecordEvent(vector<DemuxFilterEvent>&); 237 void createSectionEvent(vector<DemuxFilterEvent>&); 238 void createPesEvent(vector<DemuxFilterEvent>&); 239 void createDownloadEvent(vector<DemuxFilterEvent>&); 240 void createIpPayloadEvent(vector<DemuxFilterEvent>&); 241 void createTemiEvent(vector<DemuxFilterEvent>&); 242 void createMonitorEvent(vector<DemuxFilterEvent>&); 243 void createRestartEvent(vector<DemuxFilterEvent>&); 244 245 /** 246 * Lock to protect writes to the FMQs 247 */ 248 std::mutex mWriteLock; 249 /** 250 * Lock to protect writes to the filter event 251 */ 252 // TODO make each filter separate event lock 253 std::mutex mFilterEventsLock; 254 /** 255 * Lock to protect writes to the input status 256 */ 257 std::mutex mFilterStatusLock; 258 std::mutex mFilterOutputLock; 259 std::mutex mRecordFilterOutputLock; 260 261 // handle single Section filter 262 uint32_t mSectionSizeLeft = 0; 263 vector<int8_t> mSectionOutput; 264 265 // temp handle single PES filter 266 // TODO handle mulptiple Pes filters 267 uint32_t mPesSizeLeft = 0; 268 vector<int8_t> mPesOutput; 269 270 // A map from data id to ion handle 271 std::map<uint64_t, int> mDataId2Avfd; 272 uint64_t mLastUsedDataId = 1; 273 int mAvBufferCopyCount = 0; 274 275 // Shared A/V memory handle 276 native_handle_t* mSharedAvMemHandle = nullptr; 277 bool mUsingSharedAvMem = false; 278 int64_t mSharedAvMemOffset = 0; 279 280 uint32_t mAudioStreamType; 281 uint32_t mVideoStreamType; 282 283 // Scrambling status to be monitored 284 uint32_t mStatuses = 0; 285 286 bool mConfigured = false; 287 int mStartId = 0; 288 uint8_t mScramblingStatusMonitored = 0; 289 uint8_t mIpCidMonitored = 0; 290 291 PlaybackStatus mIptvDvrPlaybackStatus; 292 std::atomic<int> mFilterCount = 0; 293 }; 294 295 } // namespace tuner 296 } // namespace tv 297 } // namespace hardware 298 } // namespace android 299 } // namespace aidl 300