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