• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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