blob: ba0b9b099aa90f6c3922ee994eb66e98f38688b5 [file] [log] [blame]
Amyfd4243a2019-08-16 16:01:27 -07001/*
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_DEMUX_H_
18#define ANDROID_HARDWARE_TV_TUNER_V1_0_DEMUX_H_
19
20#include <android/hardware/tv/tuner/1.0/IDemux.h>
Amya609d5a2019-08-23 14:38:31 -070021#include <fmq/MessageQueue.h>
Amy79125022019-10-10 15:30:17 -070022#include <math.h>
Amya4885292019-09-06 10:30:53 -070023#include <set>
Amy5094ae12019-10-04 18:43:21 -070024#include "Frontend.h"
25#include "Tuner.h"
Amyfd4243a2019-08-16 16:01:27 -070026
27using namespace std;
28
29namespace android {
30namespace hardware {
31namespace tv {
32namespace tuner {
33namespace V1_0 {
34namespace implementation {
35
Amya609d5a2019-08-23 14:38:31 -070036using ::android::hardware::EventFlag;
37using ::android::hardware::kSynchronizedReadWrite;
38using ::android::hardware::MessageQueue;
39using ::android::hardware::MQDescriptorSync;
Amyfd4243a2019-08-16 16:01:27 -070040using ::android::hardware::tv::tuner::V1_0::IDemux;
Amya609d5a2019-08-23 14:38:31 -070041using ::android::hardware::tv::tuner::V1_0::IDemuxCallback;
Amyfd4243a2019-08-16 16:01:27 -070042using ::android::hardware::tv::tuner::V1_0::Result;
43
Amya609d5a2019-08-23 14:38:31 -070044using FilterMQ = MessageQueue<uint8_t, kSynchronizedReadWrite>;
45
Amy5094ae12019-10-04 18:43:21 -070046class Tuner;
47class Frontend;
48
Amyfd4243a2019-08-16 16:01:27 -070049class Demux : public IDemux {
50 public:
Amy5094ae12019-10-04 18:43:21 -070051 Demux(uint32_t demuxId, sp<Tuner> tuner);
Amyfd4243a2019-08-16 16:01:27 -070052
Amya4885292019-09-06 10:30:53 -070053 ~Demux();
54
Amyfd4243a2019-08-16 16:01:27 -070055 virtual Return<Result> setFrontendDataSource(uint32_t frontendId) override;
56
57 virtual Return<Result> close() override;
58
Amya609d5a2019-08-23 14:38:31 -070059 virtual Return<void> addFilter(DemuxFilterType type, uint32_t bufferSize,
60 const sp<IDemuxCallback>& cb, addFilter_cb _hidl_cb) override;
61
62 virtual Return<void> getFilterQueueDesc(uint32_t filterId,
63 getFilterQueueDesc_cb _hidl_cb) override;
64
65 virtual Return<Result> configureFilter(uint32_t filterId,
66 const DemuxFilterSettings& settings) override;
67
68 virtual Return<Result> startFilter(uint32_t filterId) override;
69
70 virtual Return<Result> stopFilter(uint32_t filterId) override;
71
72 virtual Return<Result> flushFilter(uint32_t filterId) override;
73
74 virtual Return<Result> removeFilter(uint32_t filterId) override;
75
76 virtual Return<void> getAvSyncHwId(uint32_t filterId, getAvSyncHwId_cb _hidl_cb) override;
77
78 virtual Return<void> getAvSyncTime(AvSyncHwId avSyncHwId, getAvSyncTime_cb _hidl_cb) override;
79
Amya4885292019-09-06 10:30:53 -070080 virtual Return<Result> addInput(uint32_t bufferSize, const sp<IDemuxCallback>& cb) override;
81
82 virtual Return<void> getInputQueueDesc(getInputQueueDesc_cb _hidl_cb) override;
83
84 virtual Return<Result> configureInput(const DemuxInputSettings& settings) override;
85
86 virtual Return<Result> startInput() override;
87
88 virtual Return<Result> stopInput() override;
89
90 virtual Return<Result> flushInput() override;
91
92 virtual Return<Result> removeInput() override;
93
94 virtual Return<Result> addOutput(uint32_t bufferSize, const sp<IDemuxCallback>& cb) override;
95
96 virtual Return<void> getOutputQueueDesc(getOutputQueueDesc_cb _hidl_cb) override;
97
98 virtual Return<Result> configureOutput(const DemuxOutputSettings& settings) override;
99
Amy42a5b4b2019-10-03 16:49:48 -0700100 virtual Return<Result> attachOutputFilter(uint32_t filterId) override;
Amya4885292019-09-06 10:30:53 -0700101
Amy42a5b4b2019-10-03 16:49:48 -0700102 virtual Return<Result> detachOutputFilter(uint32_t filterId) override;
Amya4885292019-09-06 10:30:53 -0700103
104 virtual Return<Result> startOutput() override;
105
106 virtual Return<Result> stopOutput() override;
107
108 virtual Return<Result> flushOutput() override;
109
110 virtual Return<Result> removeOutput() override;
111
Amy5094ae12019-10-04 18:43:21 -0700112 // Functions interacts with Tuner Service
113 void stopBroadcastInput();
114
Amyfd4243a2019-08-16 16:01:27 -0700115 private:
Amy5094ae12019-10-04 18:43:21 -0700116 // Tuner service
117 sp<Tuner> mTunerService;
118
119 // Frontend source
120 sp<Frontend> mFrontend;
121 string mFrontendSourceFile;
122
Amya4885292019-09-06 10:30:53 -0700123 // A struct that passes the arguments to a newly created filter thread
124 struct ThreadArgs {
125 Demux* user;
126 uint32_t filterId;
127 };
128
129 /**
130 * Filter handlers to handle the data filtering.
131 * They are also responsible to write the filtered output into the filter FMQ
132 * and update the filterEvent bound with the same filterId.
133 */
Amy42a5b4b2019-10-03 16:49:48 -0700134 Result startSectionFilterHandler(uint32_t filterId);
Amya4885292019-09-06 10:30:53 -0700135 Result startPesFilterHandler(uint32_t filterId);
136 Result startTsFilterHandler();
137 Result startMediaFilterHandler(uint32_t filterId);
138 Result startRecordFilterHandler(uint32_t filterId);
139 Result startPcrFilterHandler();
140 Result startFilterLoop(uint32_t filterId);
Amy5094ae12019-10-04 18:43:21 -0700141 Result startBroadcastInputLoop();
Amya4885292019-09-06 10:30:53 -0700142
Amya609d5a2019-08-23 14:38:31 -0700143 /**
144 * To create a FilterMQ with the the next available Filter ID.
145 * Creating Event Flag at the same time.
146 * Add the successfully created/saved FilterMQ into the local list.
147 *
148 * Return false is any of the above processes fails.
149 */
Amya4885292019-09-06 10:30:53 -0700150 bool createFilterMQ(uint32_t bufferSize, uint32_t filterId);
151 bool createMQ(FilterMQ* queue, EventFlag* eventFlag, uint32_t bufferSize);
Amya609d5a2019-08-23 14:38:31 -0700152 void deleteEventFlag();
153 bool writeDataToFilterMQ(const std::vector<uint8_t>& data, uint32_t filterId);
Amya4885292019-09-06 10:30:53 -0700154 bool readDataFromMQ();
155 bool writeSectionsAndCreateEvent(uint32_t filterId, vector<uint8_t> data);
Amy42a5b4b2019-10-03 16:49:48 -0700156 void maySendInputStatusCallback();
Amy79125022019-10-10 15:30:17 -0700157 void maySendFilterStatusCallback(uint32_t filterId);
158 DemuxInputStatus checkInputStatusChange(uint32_t availableToWrite, uint32_t availableToRead,
159 uint32_t highThreshold, uint32_t lowThreshold);
160 DemuxFilterStatus checkFilterStatusChange(uint32_t filterId, uint32_t availableToWrite,
161 uint32_t availableToRead, uint32_t highThreshold,
162 uint32_t lowThreshold);
Amya4885292019-09-06 10:30:53 -0700163 /**
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 */
Amy5094ae12019-10-04 18:43:21 -0700167 bool readInputFMQ();
168 void startTsFilter(vector<uint8_t> data);
169 bool startFilterDispatcher();
Amya4885292019-09-06 10:30:53 -0700170 static void* __threadLoopFilter(void* data);
171 static void* __threadLoopInput(void* user);
Amy5094ae12019-10-04 18:43:21 -0700172 static void* __threadLoopBroadcast(void* user);
Amya4885292019-09-06 10:30:53 -0700173 void filterThreadLoop(uint32_t filterId);
174 void inputThreadLoop();
Amy5094ae12019-10-04 18:43:21 -0700175 void broadcastInputThreadLoop();
Amya609d5a2019-08-23 14:38:31 -0700176
Amyfd4243a2019-08-16 16:01:27 -0700177 uint32_t mDemuxId;
Amya609d5a2019-08-23 14:38:31 -0700178 /**
Amya4885292019-09-06 10:30:53 -0700179 * Record the last used filter id. Initial value is -1.
Amya609d5a2019-08-23 14:38:31 -0700180 * Filter Id starts with 0.
181 */
182 uint32_t mLastUsedFilterId = -1;
183 /**
Amya4885292019-09-06 10:30:53 -0700184 * Record all the used filter Ids.
185 * Any removed filter id should be removed from this set.
186 */
187 set<uint32_t> mUsedFilterIds;
188 /**
189 * Record all the unused filter Ids within mLastUsedFilterId.
190 * Removed filter Id should be added into this set.
191 * When this set is not empty, ids here should be allocated first
192 * and added into usedFilterIds.
193 */
194 set<uint32_t> mUnusedFilterIds;
195 /**
Amya609d5a2019-08-23 14:38:31 -0700196 * A list of created FilterMQ ptrs.
197 * The array number is the filter ID.
198 */
Amy42a5b4b2019-10-03 16:49:48 -0700199 vector<uint16_t> mFilterPids;
200 vector<vector<uint8_t>> mFilterOutputs;
Amya609d5a2019-08-23 14:38:31 -0700201 vector<unique_ptr<FilterMQ>> mFilterMQs;
Amya609d5a2019-08-23 14:38:31 -0700202 vector<EventFlag*> mFilterEventFlags;
Amya4885292019-09-06 10:30:53 -0700203 vector<DemuxFilterEvent> mFilterEvents;
204 unique_ptr<FilterMQ> mInputMQ;
205 unique_ptr<FilterMQ> mOutputMQ;
206 EventFlag* mInputEventFlag;
207 EventFlag* mOutputEventFlag;
Amya609d5a2019-08-23 14:38:31 -0700208 /**
209 * Demux callbacks used on filter events or IO buffer status
210 */
Amy79125022019-10-10 15:30:17 -0700211 vector<sp<IDemuxCallback>> mFilterCallbacks;
Amya4885292019-09-06 10:30:53 -0700212 sp<IDemuxCallback> mInputCallback;
213 sp<IDemuxCallback> mOutputCallback;
Amy42a5b4b2019-10-03 16:49:48 -0700214 bool mInputConfigured = false;
215 bool mOutputConfigured = false;
216 DemuxInputSettings mInputSettings;
217 DemuxOutputSettings mOutputSettings;
218
Amya4885292019-09-06 10:30:53 -0700219 // Thread handlers
220 pthread_t mInputThread;
221 pthread_t mOutputThread;
Amy5094ae12019-10-04 18:43:21 -0700222 pthread_t mBroadcastInputThread;
Amya4885292019-09-06 10:30:53 -0700223 vector<pthread_t> mFilterThreads;
Amy42a5b4b2019-10-03 16:49:48 -0700224
225 // FMQ status local records
226 DemuxInputStatus mIntputStatus;
Amy79125022019-10-10 15:30:17 -0700227 vector<DemuxFilterStatus> mFilterStatus;
Amya609d5a2019-08-23 14:38:31 -0700228 /**
229 * If a specific filter's writing loop is still running
230 */
Amya4885292019-09-06 10:30:53 -0700231 vector<bool> mFilterThreadRunning;
232 bool mInputThreadRunning;
Amy5094ae12019-10-04 18:43:21 -0700233 bool mBroadcastInputThreadRunning;
234 bool mKeepFetchingDataFromFrontend;
Amya609d5a2019-08-23 14:38:31 -0700235 /**
236 * Lock to protect writes to the FMQs
237 */
238 std::mutex mWriteLock;
239 /**
Amya4885292019-09-06 10:30:53 -0700240 * Lock to protect writes to the filter event
241 */
Amy42a5b4b2019-10-03 16:49:48 -0700242 // TODO make each filter separate event lock
Amya4885292019-09-06 10:30:53 -0700243 std::mutex mFilterEventLock;
244 /**
Amy42a5b4b2019-10-03 16:49:48 -0700245 * Lock to protect writes to the input status
246 */
247 std::mutex mInputStatusLock;
Amy79125022019-10-10 15:30:17 -0700248 std::mutex mFilterStatusLock;
Amy5094ae12019-10-04 18:43:21 -0700249 std::mutex mBroadcastInputThreadLock;
250 std::mutex mFilterThreadLock;
251 std::mutex mInputThreadLock;
Amy42a5b4b2019-10-03 16:49:48 -0700252 /**
Amya609d5a2019-08-23 14:38:31 -0700253 * How many times a filter should write
254 * TODO make this dynamic/random/can take as a parameter
255 */
256 const uint16_t SECTION_WRITE_COUNT = 10;
Amy1109e9f2019-10-10 18:30:28 -0700257
258 // temp handle single PES filter
259 // TODO handle mulptiple Pes filters
260 int mPesSizeLeft = 0;
261 vector<uint8_t> mPesOutput;
Amyfd4243a2019-08-16 16:01:27 -0700262};
263
264} // namespace implementation
265} // namespace V1_0
266} // namespace tuner
267} // namespace tv
268} // namespace hardware
269} // namespace android
270
271#endif // ANDROID_HARDWARE_TV_TUNER_V1_0_DEMUX_H_