blob: e4a4e2bdaed306e1568dd2b6927548827abd02ad [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>
Amya4885292019-09-06 10:30:53 -070022#include <set>
Amy5094ae12019-10-04 18:43:21 -070023#include "Frontend.h"
24#include "Tuner.h"
Amyfd4243a2019-08-16 16:01:27 -070025
26using namespace std;
27
28namespace android {
29namespace hardware {
30namespace tv {
31namespace tuner {
32namespace V1_0 {
33namespace implementation {
34
Amya609d5a2019-08-23 14:38:31 -070035using ::android::hardware::EventFlag;
36using ::android::hardware::kSynchronizedReadWrite;
37using ::android::hardware::MessageQueue;
38using ::android::hardware::MQDescriptorSync;
Amyfd4243a2019-08-16 16:01:27 -070039using ::android::hardware::tv::tuner::V1_0::IDemux;
Amya609d5a2019-08-23 14:38:31 -070040using ::android::hardware::tv::tuner::V1_0::IDemuxCallback;
Amyfd4243a2019-08-16 16:01:27 -070041using ::android::hardware::tv::tuner::V1_0::Result;
42
Amya609d5a2019-08-23 14:38:31 -070043using FilterMQ = MessageQueue<uint8_t, kSynchronizedReadWrite>;
44
Amy5094ae12019-10-04 18:43:21 -070045class Tuner;
46class Frontend;
47
Amyfd4243a2019-08-16 16:01:27 -070048class Demux : public IDemux {
49 public:
Amy5094ae12019-10-04 18:43:21 -070050 Demux(uint32_t demuxId, sp<Tuner> tuner);
Amyfd4243a2019-08-16 16:01:27 -070051
Amya4885292019-09-06 10:30:53 -070052 ~Demux();
53
Amyfd4243a2019-08-16 16:01:27 -070054 virtual Return<Result> setFrontendDataSource(uint32_t frontendId) override;
55
56 virtual Return<Result> close() override;
57
Amya609d5a2019-08-23 14:38:31 -070058 virtual Return<void> addFilter(DemuxFilterType type, uint32_t bufferSize,
59 const sp<IDemuxCallback>& cb, addFilter_cb _hidl_cb) override;
60
61 virtual Return<void> getFilterQueueDesc(uint32_t filterId,
62 getFilterQueueDesc_cb _hidl_cb) override;
63
64 virtual Return<Result> configureFilter(uint32_t filterId,
65 const DemuxFilterSettings& settings) override;
66
67 virtual Return<Result> startFilter(uint32_t filterId) override;
68
69 virtual Return<Result> stopFilter(uint32_t filterId) override;
70
71 virtual Return<Result> flushFilter(uint32_t filterId) override;
72
73 virtual Return<Result> removeFilter(uint32_t filterId) override;
74
75 virtual Return<void> getAvSyncHwId(uint32_t filterId, getAvSyncHwId_cb _hidl_cb) override;
76
77 virtual Return<void> getAvSyncTime(AvSyncHwId avSyncHwId, getAvSyncTime_cb _hidl_cb) override;
78
Amya4885292019-09-06 10:30:53 -070079 virtual Return<Result> addInput(uint32_t bufferSize, const sp<IDemuxCallback>& cb) override;
80
81 virtual Return<void> getInputQueueDesc(getInputQueueDesc_cb _hidl_cb) override;
82
83 virtual Return<Result> configureInput(const DemuxInputSettings& settings) override;
84
85 virtual Return<Result> startInput() override;
86
87 virtual Return<Result> stopInput() override;
88
89 virtual Return<Result> flushInput() override;
90
91 virtual Return<Result> removeInput() override;
92
93 virtual Return<Result> addOutput(uint32_t bufferSize, const sp<IDemuxCallback>& cb) override;
94
95 virtual Return<void> getOutputQueueDesc(getOutputQueueDesc_cb _hidl_cb) override;
96
97 virtual Return<Result> configureOutput(const DemuxOutputSettings& settings) override;
98
Amy42a5b4b2019-10-03 16:49:48 -070099 virtual Return<Result> attachOutputFilter(uint32_t filterId) override;
Amya4885292019-09-06 10:30:53 -0700100
Amy42a5b4b2019-10-03 16:49:48 -0700101 virtual Return<Result> detachOutputFilter(uint32_t filterId) override;
Amya4885292019-09-06 10:30:53 -0700102
103 virtual Return<Result> startOutput() override;
104
105 virtual Return<Result> stopOutput() override;
106
107 virtual Return<Result> flushOutput() override;
108
109 virtual Return<Result> removeOutput() override;
110
Amy5094ae12019-10-04 18:43:21 -0700111 // Functions interacts with Tuner Service
112 void stopBroadcastInput();
113
Amyfd4243a2019-08-16 16:01:27 -0700114 private:
Amy5094ae12019-10-04 18:43:21 -0700115 // Tuner service
116 sp<Tuner> mTunerService;
117
118 // Frontend source
119 sp<Frontend> mFrontend;
120 string mFrontendSourceFile;
121
Amya4885292019-09-06 10:30:53 -0700122 // A struct that passes the arguments to a newly created filter thread
123 struct ThreadArgs {
124 Demux* user;
125 uint32_t filterId;
126 };
127
128 /**
129 * Filter handlers to handle the data filtering.
130 * They are also responsible to write the filtered output into the filter FMQ
131 * and update the filterEvent bound with the same filterId.
132 */
Amy42a5b4b2019-10-03 16:49:48 -0700133 Result startSectionFilterHandler(uint32_t filterId);
Amya4885292019-09-06 10:30:53 -0700134 Result startPesFilterHandler(uint32_t filterId);
135 Result startTsFilterHandler();
136 Result startMediaFilterHandler(uint32_t filterId);
137 Result startRecordFilterHandler(uint32_t filterId);
138 Result startPcrFilterHandler();
139 Result startFilterLoop(uint32_t filterId);
Amy5094ae12019-10-04 18:43:21 -0700140 Result startBroadcastInputLoop();
Amya4885292019-09-06 10:30:53 -0700141
Amya609d5a2019-08-23 14:38:31 -0700142 /**
143 * To create a FilterMQ with the the next available Filter ID.
144 * Creating Event Flag at the same time.
145 * Add the successfully created/saved FilterMQ into the local list.
146 *
147 * Return false is any of the above processes fails.
148 */
Amya4885292019-09-06 10:30:53 -0700149 bool createFilterMQ(uint32_t bufferSize, uint32_t filterId);
150 bool createMQ(FilterMQ* queue, EventFlag* eventFlag, uint32_t bufferSize);
Amya609d5a2019-08-23 14:38:31 -0700151 void deleteEventFlag();
152 bool writeDataToFilterMQ(const std::vector<uint8_t>& data, uint32_t filterId);
Amya4885292019-09-06 10:30:53 -0700153 bool readDataFromMQ();
154 bool writeSectionsAndCreateEvent(uint32_t filterId, vector<uint8_t> data);
Amy42a5b4b2019-10-03 16:49:48 -0700155 void maySendInputStatusCallback();
156 DemuxInputStatus checkStatusChange(uint32_t availableToWrite, uint32_t availableToRead,
157 uint32_t highThreshold, uint32_t lowThreshold);
Amya4885292019-09-06 10:30:53 -0700158 /**
159 * A dispatcher to read and dispatch input data to all the started filters.
160 * Each filter handler handles the data filtering/output writing/filterEvent updating.
161 */
Amy5094ae12019-10-04 18:43:21 -0700162 bool readInputFMQ();
163 void startTsFilter(vector<uint8_t> data);
164 bool startFilterDispatcher();
Amya4885292019-09-06 10:30:53 -0700165 static void* __threadLoopFilter(void* data);
166 static void* __threadLoopInput(void* user);
Amy5094ae12019-10-04 18:43:21 -0700167 static void* __threadLoopBroadcast(void* user);
Amya4885292019-09-06 10:30:53 -0700168 void filterThreadLoop(uint32_t filterId);
169 void inputThreadLoop();
Amy5094ae12019-10-04 18:43:21 -0700170 void broadcastInputThreadLoop();
Amya609d5a2019-08-23 14:38:31 -0700171
Amyfd4243a2019-08-16 16:01:27 -0700172 uint32_t mDemuxId;
Amya609d5a2019-08-23 14:38:31 -0700173 /**
Amya4885292019-09-06 10:30:53 -0700174 * Record the last used filter id. Initial value is -1.
Amya609d5a2019-08-23 14:38:31 -0700175 * Filter Id starts with 0.
176 */
177 uint32_t mLastUsedFilterId = -1;
178 /**
Amya4885292019-09-06 10:30:53 -0700179 * Record all the used filter Ids.
180 * Any removed filter id should be removed from this set.
181 */
182 set<uint32_t> mUsedFilterIds;
183 /**
184 * Record all the unused filter Ids within mLastUsedFilterId.
185 * Removed filter Id should be added into this set.
186 * When this set is not empty, ids here should be allocated first
187 * and added into usedFilterIds.
188 */
189 set<uint32_t> mUnusedFilterIds;
190 /**
Amya609d5a2019-08-23 14:38:31 -0700191 * A list of created FilterMQ ptrs.
192 * The array number is the filter ID.
193 */
Amy42a5b4b2019-10-03 16:49:48 -0700194 vector<uint16_t> mFilterPids;
195 vector<vector<uint8_t>> mFilterOutputs;
Amya609d5a2019-08-23 14:38:31 -0700196 vector<unique_ptr<FilterMQ>> mFilterMQs;
Amya609d5a2019-08-23 14:38:31 -0700197 vector<EventFlag*> mFilterEventFlags;
Amya4885292019-09-06 10:30:53 -0700198 vector<DemuxFilterEvent> mFilterEvents;
199 unique_ptr<FilterMQ> mInputMQ;
200 unique_ptr<FilterMQ> mOutputMQ;
201 EventFlag* mInputEventFlag;
202 EventFlag* mOutputEventFlag;
Amya609d5a2019-08-23 14:38:31 -0700203 /**
204 * Demux callbacks used on filter events or IO buffer status
205 */
206 vector<sp<IDemuxCallback>> mDemuxCallbacks;
Amya4885292019-09-06 10:30:53 -0700207 sp<IDemuxCallback> mInputCallback;
208 sp<IDemuxCallback> mOutputCallback;
Amy42a5b4b2019-10-03 16:49:48 -0700209 bool mInputConfigured = false;
210 bool mOutputConfigured = false;
211 DemuxInputSettings mInputSettings;
212 DemuxOutputSettings mOutputSettings;
213
Amya4885292019-09-06 10:30:53 -0700214 // Thread handlers
215 pthread_t mInputThread;
216 pthread_t mOutputThread;
Amy5094ae12019-10-04 18:43:21 -0700217 pthread_t mBroadcastInputThread;
Amya4885292019-09-06 10:30:53 -0700218 vector<pthread_t> mFilterThreads;
Amy42a5b4b2019-10-03 16:49:48 -0700219
220 // FMQ status local records
221 DemuxInputStatus mIntputStatus;
Amya609d5a2019-08-23 14:38:31 -0700222 /**
223 * If a specific filter's writing loop is still running
224 */
Amya4885292019-09-06 10:30:53 -0700225 vector<bool> mFilterThreadRunning;
226 bool mInputThreadRunning;
Amy5094ae12019-10-04 18:43:21 -0700227 bool mBroadcastInputThreadRunning;
228 bool mKeepFetchingDataFromFrontend;
Amya609d5a2019-08-23 14:38:31 -0700229 /**
230 * Lock to protect writes to the FMQs
231 */
232 std::mutex mWriteLock;
233 /**
Amya4885292019-09-06 10:30:53 -0700234 * Lock to protect writes to the filter event
235 */
Amy42a5b4b2019-10-03 16:49:48 -0700236 // TODO make each filter separate event lock
Amya4885292019-09-06 10:30:53 -0700237 std::mutex mFilterEventLock;
238 /**
Amy42a5b4b2019-10-03 16:49:48 -0700239 * Lock to protect writes to the input status
240 */
241 std::mutex mInputStatusLock;
Amy5094ae12019-10-04 18:43:21 -0700242 std::mutex mBroadcastInputThreadLock;
243 std::mutex mFilterThreadLock;
244 std::mutex mInputThreadLock;
Amy42a5b4b2019-10-03 16:49:48 -0700245 /**
Amya609d5a2019-08-23 14:38:31 -0700246 * How many times a filter should write
247 * TODO make this dynamic/random/can take as a parameter
248 */
249 const uint16_t SECTION_WRITE_COUNT = 10;
Amyfd4243a2019-08-16 16:01:27 -0700250};
251
252} // namespace implementation
253} // namespace V1_0
254} // namespace tuner
255} // namespace tv
256} // namespace hardware
257} // namespace android
258
259#endif // ANDROID_HARDWARE_TV_TUNER_V1_0_DEMUX_H_