blob: 759e348d931acc2ec5233b4e6b681a2f8f11f40d [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>
Amyb4b68012019-10-15 17:38:19 -070024#include "Dvr.h"
25#include "Filter.h"
Amy5094ae12019-10-04 18:43:21 -070026#include "Frontend.h"
Amyb4b68012019-10-15 17:38:19 -070027#include "TimeFilter.h"
Amy5094ae12019-10-04 18:43:21 -070028#include "Tuner.h"
Amyfd4243a2019-08-16 16:01:27 -070029
30using namespace std;
31
32namespace android {
33namespace hardware {
34namespace tv {
35namespace tuner {
36namespace V1_0 {
37namespace implementation {
38
Amya609d5a2019-08-23 14:38:31 -070039using ::android::hardware::EventFlag;
40using ::android::hardware::kSynchronizedReadWrite;
41using ::android::hardware::MessageQueue;
42using ::android::hardware::MQDescriptorSync;
Amyfd4243a2019-08-16 16:01:27 -070043using ::android::hardware::tv::tuner::V1_0::IDemux;
Amyb4b68012019-10-15 17:38:19 -070044using ::android::hardware::tv::tuner::V1_0::IDvrCallback;
45using ::android::hardware::tv::tuner::V1_0::IFilterCallback;
Amyfd4243a2019-08-16 16:01:27 -070046using ::android::hardware::tv::tuner::V1_0::Result;
47
Amya609d5a2019-08-23 14:38:31 -070048using FilterMQ = MessageQueue<uint8_t, kSynchronizedReadWrite>;
49
Amyb4b68012019-10-15 17:38:19 -070050class Dvr;
51class Filter;
Amy5094ae12019-10-04 18:43:21 -070052class Frontend;
Amyb4b68012019-10-15 17:38:19 -070053class TimeFilter;
54class Tuner;
Amy5094ae12019-10-04 18:43:21 -070055
Amyfd4243a2019-08-16 16:01:27 -070056class Demux : public IDemux {
57 public:
Amy5094ae12019-10-04 18:43:21 -070058 Demux(uint32_t demuxId, sp<Tuner> tuner);
Amyfd4243a2019-08-16 16:01:27 -070059
Amya4885292019-09-06 10:30:53 -070060 ~Demux();
61
Amyfd4243a2019-08-16 16:01:27 -070062 virtual Return<Result> setFrontendDataSource(uint32_t frontendId) override;
63
Amyb4b68012019-10-15 17:38:19 -070064 virtual Return<void> openFilter(const DemuxFilterType& type, uint32_t bufferSize,
65 const sp<IFilterCallback>& cb, openFilter_cb _hidl_cb) override;
Amyfd4243a2019-08-16 16:01:27 -070066
Amyb4b68012019-10-15 17:38:19 -070067 virtual Return<void> openTimeFilter(openTimeFilter_cb _hidl_cb) override;
Amya609d5a2019-08-23 14:38:31 -070068
Amyb4b68012019-10-15 17:38:19 -070069 virtual Return<void> getAvSyncHwId(const sp<IFilter>& filter,
70 getAvSyncHwId_cb _hidl_cb) override;
Amya609d5a2019-08-23 14:38:31 -070071
72 virtual Return<void> getAvSyncTime(AvSyncHwId avSyncHwId, getAvSyncTime_cb _hidl_cb) override;
73
Amyb4b68012019-10-15 17:38:19 -070074 virtual Return<Result> close() override;
Amya4885292019-09-06 10:30:53 -070075
Amyb4b68012019-10-15 17:38:19 -070076 virtual Return<void> openDvr(DvrType type, uint32_t bufferSize, const sp<IDvrCallback>& cb,
77 openDvr_cb _hidl_cb) override;
Amya4885292019-09-06 10:30:53 -070078
Henry Fang89f12f52019-11-05 13:48:59 -080079 virtual Return<Result> connectCiCam(uint32_t ciCamId) override;
80
81 virtual Return<Result> disconnectCiCam() override;
82
Amy5094ae12019-10-04 18:43:21 -070083 // Functions interacts with Tuner Service
Amy5ed13572019-12-11 15:33:51 -080084 void stopFrontendInput();
Amyb4b68012019-10-15 17:38:19 -070085 Result removeFilter(uint32_t filterId);
Amy5ed13572019-12-11 15:33:51 -080086 bool attachRecordFilter(int filterId);
87 bool detachRecordFilter(int filterId);
Amyb4b68012019-10-15 17:38:19 -070088 Result startFilterHandler(uint32_t filterId);
89 void updateFilterOutput(uint16_t filterId, vector<uint8_t> data);
90 uint16_t getFilterTpid(uint32_t filterId);
Amy5ed13572019-12-11 15:33:51 -080091 void setIsRecording(bool isRecording);
Amy Zhang0fe25be2020-04-08 17:30:52 -070092 void startFrontendInputLoop();
Amy5094ae12019-10-04 18:43:21 -070093
Amyfd4243a2019-08-16 16:01:27 -070094 private:
Amy5094ae12019-10-04 18:43:21 -070095 // Tuner service
96 sp<Tuner> mTunerService;
97
98 // Frontend source
99 sp<Frontend> mFrontend;
100 string mFrontendSourceFile;
101
Amya4885292019-09-06 10:30:53 -0700102 // A struct that passes the arguments to a newly created filter thread
103 struct ThreadArgs {
104 Demux* user;
105 uint32_t filterId;
106 };
107
Amy5ed13572019-12-11 15:33:51 -0800108 static void* __threadLoopFrontend(void* user);
109 void frontendInputThreadLoop();
Amya4885292019-09-06 10:30:53 -0700110
Amya609d5a2019-08-23 14:38:31 -0700111 /**
112 * To create a FilterMQ with the the next available Filter ID.
113 * Creating Event Flag at the same time.
114 * Add the successfully created/saved FilterMQ into the local list.
115 *
116 * Return false is any of the above processes fails.
117 */
Amya609d5a2019-08-23 14:38:31 -0700118 void deleteEventFlag();
Amya4885292019-09-06 10:30:53 -0700119 bool readDataFromMQ();
Amya4885292019-09-06 10:30:53 -0700120 /**
121 * A dispatcher to read and dispatch input data to all the started filters.
122 * Each filter handler handles the data filtering/output writing/filterEvent updating.
Amy5ed13572019-12-11 15:33:51 -0800123 * Note that recording filters are not included.
Amya4885292019-09-06 10:30:53 -0700124 */
Amy5ed13572019-12-11 15:33:51 -0800125 bool startBroadcastFilterDispatcher();
126 void startBroadcastTsFilter(vector<uint8_t> data);
127
128 void sendFrontendInputToRecord(vector<uint8_t> data);
129 bool startRecordFilterDispatcher();
Amya609d5a2019-08-23 14:38:31 -0700130
Amyfd4243a2019-08-16 16:01:27 -0700131 uint32_t mDemuxId;
Henry Fang89f12f52019-11-05 13:48:59 -0800132 uint32_t mCiCamId;
Amya609d5a2019-08-23 14:38:31 -0700133 /**
Amya4885292019-09-06 10:30:53 -0700134 * Record the last used filter id. Initial value is -1.
Amya609d5a2019-08-23 14:38:31 -0700135 * Filter Id starts with 0.
136 */
137 uint32_t mLastUsedFilterId = -1;
138 /**
Amya4885292019-09-06 10:30:53 -0700139 * Record all the used filter Ids.
140 * Any removed filter id should be removed from this set.
141 */
142 set<uint32_t> mUsedFilterIds;
143 /**
144 * Record all the unused filter Ids within mLastUsedFilterId.
145 * Removed filter Id should be added into this set.
146 * When this set is not empty, ids here should be allocated first
147 * and added into usedFilterIds.
148 */
149 set<uint32_t> mUnusedFilterIds;
150 /**
Amy5ed13572019-12-11 15:33:51 -0800151 * Record all the attached record filter Ids.
152 * Any removed filter id should be removed from this set.
153 */
154 set<uint32_t> mRecordFilterIds;
155 /**
Amya609d5a2019-08-23 14:38:31 -0700156 * A list of created FilterMQ ptrs.
157 * The array number is the filter ID.
158 */
Amyb4b68012019-10-15 17:38:19 -0700159 std::map<uint32_t, sp<Filter>> mFilters;
Amy42a5b4b2019-10-03 16:49:48 -0700160
Amy5ed13572019-12-11 15:33:51 -0800161 /**
162 * Local reference to the opened DVR object.
163 */
164 sp<Dvr> mDvr;
165
Amya4885292019-09-06 10:30:53 -0700166 // Thread handlers
Amy5ed13572019-12-11 15:33:51 -0800167 pthread_t mFrontendInputThread;
Amya609d5a2019-08-23 14:38:31 -0700168 /**
169 * If a specific filter's writing loop is still running
170 */
Amy5ed13572019-12-11 15:33:51 -0800171 bool mFrontendInputThreadRunning;
Amy5094ae12019-10-04 18:43:21 -0700172 bool mKeepFetchingDataFromFrontend;
Amya609d5a2019-08-23 14:38:31 -0700173 /**
Amy5ed13572019-12-11 15:33:51 -0800174 * If the dvr recording is running.
175 */
176 bool mIsRecording = false;
177 /**
Amya609d5a2019-08-23 14:38:31 -0700178 * Lock to protect writes to the FMQs
179 */
180 std::mutex mWriteLock;
181 /**
Amy42a5b4b2019-10-03 16:49:48 -0700182 * Lock to protect writes to the input status
183 */
Amy5ed13572019-12-11 15:33:51 -0800184 std::mutex mFrontendInputThreadLock;
Amy1109e9f2019-10-10 18:30:28 -0700185
186 // temp handle single PES filter
187 // TODO handle mulptiple Pes filters
188 int mPesSizeLeft = 0;
189 vector<uint8_t> mPesOutput;
Amyb4b68012019-10-15 17:38:19 -0700190
191 const bool DEBUG_FILTER = false;
Amyfd4243a2019-08-16 16:01:27 -0700192};
193
194} // namespace implementation
195} // namespace V1_0
196} // namespace tuner
197} // namespace tv
198} // namespace hardware
199} // namespace android
200
201#endif // ANDROID_HARDWARE_TV_TUNER_V1_0_DEMUX_H_