1 /*
2  * Copyright 2020 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_1_DEMUX_H_
18 #define ANDROID_HARDWARE_TV_TUNER_V1_1_DEMUX_H_
19 
20 #include <fmq/MessageQueue.h>
21 #include <math.h>
22 #include <set>
23 #include "Dvr.h"
24 #include "Filter.h"
25 #include "Frontend.h"
26 #include "TimeFilter.h"
27 #include "Tuner.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 
43 using FilterMQ = MessageQueue<uint8_t, kSynchronizedReadWrite>;
44 
45 class Dvr;
46 class Filter;
47 class Frontend;
48 class TimeFilter;
49 class Tuner;
50 
51 class Demux : public IDemux {
52   public:
53     Demux(uint32_t demuxId, sp<Tuner> tuner);
54 
55     ~Demux();
56 
57     virtual Return<Result> setFrontendDataSource(uint32_t frontendId) override;
58 
59     virtual Return<void> openFilter(const DemuxFilterType& type, uint32_t bufferSize,
60                                     const sp<IFilterCallback>& cb, openFilter_cb _hidl_cb) override;
61 
62     virtual Return<void> openTimeFilter(openTimeFilter_cb _hidl_cb) override;
63 
64     virtual Return<void> getAvSyncHwId(const sp<IFilter>& filter,
65                                        getAvSyncHwId_cb _hidl_cb) override;
66 
67     virtual Return<void> getAvSyncTime(AvSyncHwId avSyncHwId, getAvSyncTime_cb _hidl_cb) override;
68 
69     virtual Return<Result> close() override;
70 
71     virtual Return<void> openDvr(DvrType type, uint32_t bufferSize, const sp<IDvrCallback>& cb,
72                                  openDvr_cb _hidl_cb) override;
73 
74     virtual Return<Result> connectCiCam(uint32_t ciCamId) override;
75 
76     virtual Return<Result> disconnectCiCam() override;
77 
78     // Functions interacts with Tuner Service
79     void stopFrontendInput();
80     Result removeFilter(uint64_t filterId);
81     bool attachRecordFilter(uint64_t filterId);
82     bool detachRecordFilter(uint64_t filterId);
83     Result startFilterHandler(uint64_t filterId);
84     void updateFilterOutput(uint64_t filterId, vector<uint8_t> data);
85     void updateMediaFilterOutput(uint64_t filterId, vector<uint8_t> data, uint64_t pts);
86     uint16_t getFilterTpid(uint64_t filterId);
87     void setIsRecording(bool isRecording);
88     bool isRecording();
89     void startFrontendInputLoop();
90 
91     /**
92      * A dispatcher to read and dispatch input data to all the started filters.
93      * Each filter handler handles the data filtering/output writing/filterEvent updating.
94      * Note that recording filters are not included.
95      */
96     bool startBroadcastFilterDispatcher();
97     void startBroadcastTsFilter(vector<uint8_t> data);
98 
99     void sendFrontendInputToRecord(vector<uint8_t> data);
100     void sendFrontendInputToRecord(vector<uint8_t> data, uint16_t pid, uint64_t pts);
101     bool startRecordFilterDispatcher();
102 
103   private:
104     // Tuner service
105     sp<Tuner> mTunerService;
106 
107     // Frontend source
108     sp<Frontend> mFrontend;
109 
110     // A struct that passes the arguments to a newly created filter thread
111     struct ThreadArgs {
112         Demux* user;
113         uint64_t filterId;
114     };
115 
116     static void* __threadLoopFrontend(void* user);
117     void frontendInputThreadLoop();
118 
119     /**
120      * To create a FilterMQ with the next available Filter ID.
121      * Creating Event Flag at the same time.
122      * Add the successfully created/saved FilterMQ into the local list.
123      *
124      * Return false is any of the above processes fails.
125      */
126     void deleteEventFlag();
127     bool readDataFromMQ();
128 
129     uint32_t mDemuxId = -1;
130     uint32_t mCiCamId;
131     set<uint64_t> mPcrFilterIds;
132     /**
133      * Record the last used filter id. Initial value is -1.
134      * Filter Id starts with 0.
135      */
136     uint64_t mLastUsedFilterId = -1;
137     /**
138      * Record all the used playback filter Ids.
139      * Any removed filter id should be removed from this set.
140      */
141     set<uint64_t> mPlaybackFilterIds;
142     /**
143      * Record all the attached record filter Ids.
144      * Any removed filter id should be removed from this set.
145      */
146     set<uint64_t> mRecordFilterIds;
147     /**
148      * A list of created Filter sp.
149      * The array number is the filter ID.
150      */
151     std::map<uint64_t, sp<Filter>> mFilters;
152 
153     /**
154      * Local reference to the opened Timer Filter instance.
155      */
156     sp<TimeFilter> mTimeFilter;
157 
158     /**
159      * Local reference to the opened DVR object.
160      */
161     sp<Dvr> mDvrPlayback;
162     sp<Dvr> mDvrRecord;
163 
164     // Thread handlers
165     pthread_t mFrontendInputThread;
166     /**
167      * If a specific filter's writing loop is still running
168      */
169     bool mFrontendInputThreadRunning;
170     bool mKeepFetchingDataFromFrontend;
171     /**
172      * If the dvr recording is running.
173      */
174     bool mIsRecording = false;
175     /**
176      * Lock to protect writes to the FMQs
177      */
178     std::mutex mWriteLock;
179     /**
180      * Lock to protect writes to the input status
181      */
182     std::mutex mFrontendInputThreadLock;
183 
184     // temp handle single PES filter
185     // TODO handle mulptiple Pes filters
186     int mPesSizeLeft = 0;
187     vector<uint8_t> mPesOutput;
188 
189     const bool DEBUG_DEMUX = false;
190 };
191 
192 }  // namespace implementation
193 }  // namespace V1_0
194 }  // namespace tuner
195 }  // namespace tv
196 }  // namespace hardware
197 }  // namespace android
198 
199 #endif  // ANDROID_HARDWARE_TV_TUNER_V1_1_DEMUX_H_
200