1 /*
2  * Copyright (C) 2019 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 #ifndef ANDROID_HARDWARE_TV_TUNER_V1_0_FILTER_H_
18 #define ANDROID_HARDWARE_TV_TUNER_V1_0_FILTER_H_
19 
20 #include <android/hardware/tv/tuner/1.0/IFilter.h>
21 #include <fmq/MessageQueue.h>
22 #include <ion/ion.h>
23 #include <math.h>
24 #include <set>
25 #include "Demux.h"
26 #include "Dvr.h"
27 #include "Frontend.h"
28 
29 using namespace std;
30 
31 namespace android {
32 namespace hardware {
33 namespace tv {
34 namespace tuner {
35 namespace V1_0 {
36 namespace implementation {
37 
38 using ::android::hardware::EventFlag;
39 using ::android::hardware::kSynchronizedReadWrite;
40 using ::android::hardware::MessageQueue;
41 using ::android::hardware::MQDescriptorSync;
42 using ::android::hardware::tv::tuner::V1_0::IDemux;
43 using ::android::hardware::tv::tuner::V1_0::IFilterCallback;
44 using ::android::hardware::tv::tuner::V1_0::Result;
45 
46 using FilterMQ = MessageQueue<uint8_t, kSynchronizedReadWrite>;
47 
48 class Demux;
49 class Dvr;
50 
51 class Filter : public IFilter {
52   public:
53     Filter();
54 
55     Filter(DemuxFilterType type, uint32_t filterId, uint32_t bufferSize,
56            const sp<IFilterCallback>& cb, sp<Demux> demux);
57 
58     ~Filter();
59 
60     virtual Return<void> getId(getId_cb _hidl_cb) override;
61 
62     virtual Return<Result> setDataSource(const sp<IFilter>& filter) override;
63 
64     virtual Return<void> getQueueDesc(getQueueDesc_cb _hidl_cb) override;
65 
66     virtual Return<Result> configure(const DemuxFilterSettings& settings) override;
67 
68     virtual Return<Result> start() override;
69 
70     virtual Return<Result> stop() override;
71 
72     virtual Return<Result> flush() override;
73 
74     virtual Return<Result> releaseAvHandle(const hidl_handle& avMemory, uint64_t avDataId) override;
75 
76     virtual Return<Result> close() override;
77 
78     /**
79      * To create a FilterMQ and its Event Flag.
80      *
81      * Return false is any of the above processes fails.
82      */
83     bool createFilterMQ();
84     uint16_t getTpid();
85     void updateFilterOutput(vector<uint8_t> data);
86     void updateRecordOutput(vector<uint8_t> data);
87     Result startFilterHandler();
88     Result startRecordFilterHandler();
89     void attachFilterToRecord(const sp<Dvr> dvr);
90     void detachFilterFromRecord();
91     void freeAvHandle();
isMediaFilter()92     bool isMediaFilter() { return mIsMediaFilter; };
isPcrFilter()93     bool isPcrFilter() { return mIsPcrFilter; };
isRecordFilter()94     bool isRecordFilter() { return mIsRecordFilter; };
95 
96   private:
97     // Tuner service
98     sp<Demux> mDemux;
99     // Dvr reference once the filter is attached to any
100     sp<Dvr> mDvr = nullptr;
101     /**
102      * Filter callbacks used on filter events or FMQ status
103      */
104     sp<IFilterCallback> mCallback;
105 
106     uint32_t mFilterId;
107     uint32_t mBufferSize;
108     DemuxFilterType mType;
109     bool mIsMediaFilter = false;
110     bool mIsPcrFilter = false;
111     bool mIsRecordFilter = false;
112     DemuxFilterSettings mFilterSettings;
113 
114     uint16_t mTpid;
115     sp<IFilter> mDataSource;
116     bool mIsDataSourceDemux = true;
117     vector<uint8_t> mFilterOutput;
118     vector<uint8_t> mRecordFilterOutput;
119     unique_ptr<FilterMQ> mFilterMQ;
120     bool mIsUsingFMQ = false;
121     EventFlag* mFilterEventFlag;
122     DemuxFilterEvent mFilterEvent;
123 
124     // Thread handlers
125     pthread_t mFilterThread;
126 
127     // FMQ status local records
128     DemuxFilterStatus mFilterStatus;
129     /**
130      * If a specific filter's writing loop is still running
131      */
132     bool mFilterThreadRunning;
133     bool mKeepFetchingDataFromFrontend;
134 
135     /**
136      * How many times a filter should write
137      * TODO make this dynamic/random/can take as a parameter
138      */
139     const uint16_t SECTION_WRITE_COUNT = 10;
140 
141     bool DEBUG_FILTER = false;
142 
143     /**
144      * Filter handlers to handle the data filtering.
145      * They are also responsible to write the filtered output into the filter FMQ
146      * and update the filterEvent bound with the same filterId.
147      */
148     Result startSectionFilterHandler();
149     Result startPesFilterHandler();
150     Result startTsFilterHandler();
151     Result startMediaFilterHandler();
152     Result startPcrFilterHandler();
153     Result startTemiFilterHandler();
154     Result startFilterLoop();
155 
156     void deleteEventFlag();
157     bool writeDataToFilterMQ(const std::vector<uint8_t>& data);
158     bool readDataFromMQ();
159     bool writeSectionsAndCreateEvent(vector<uint8_t> data);
160     void maySendFilterStatusCallback();
161     DemuxFilterStatus checkFilterStatusChange(uint32_t availableToWrite, uint32_t availableToRead,
162                                               uint32_t highThreshold, uint32_t lowThreshold);
163     /**
164      * A dispatcher to read and dispatch input data to all the started filters.
165      * Each filter handler handles the data filtering/output writing/filterEvent updating.
166      */
167     void startTsFilter(vector<uint8_t> data);
168     bool startFilterDispatcher();
169     static void* __threadLoopFilter(void* user);
170     void filterThreadLoop();
171 
172     int createAvIonFd(int size);
173     uint8_t* getIonBuffer(int fd, int size);
174     native_handle_t* createNativeHandle(int fd);
175 
176     /**
177      * Lock to protect writes to the FMQs
178      */
179     std::mutex mWriteLock;
180     /**
181      * Lock to protect writes to the filter event
182      */
183     // TODO make each filter separate event lock
184     std::mutex mFilterEventLock;
185     /**
186      * Lock to protect writes to the input status
187      */
188     std::mutex mFilterStatusLock;
189     std::mutex mFilterThreadLock;
190     std::mutex mFilterOutputLock;
191     std::mutex mRecordFilterOutputLock;
192 
193     // temp handle single PES filter
194     // TODO handle mulptiple Pes filters
195     int mPesSizeLeft = 0;
196     vector<uint8_t> mPesOutput;
197 
198     // A map from data id to ion handle
199     std::map<uint64_t, int> mDataId2Avfd;
200     uint64_t mLastUsedDataId = 1;
201     int mAvBufferCopyCount = 0;
202 };
203 
204 }  // namespace implementation
205 }  // namespace V1_0
206 }  // namespace tuner
207 }  // namespace tv
208 }  // namespace hardware
209 }  // namespace android
210 
211 #endif  // ANDROID_HARDWARE_TV_TUNER_V1_0_FILTER_H_
212