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