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_DEMUX_H_
18 #define ANDROID_HARDWARE_TV_TUNER_V1_0_DEMUX_H_
19 
20 #include <android/hardware/tv/tuner/1.0/IDemux.h>
21 #include <fmq/MessageQueue.h>
22 #include <math.h>
23 #include <set>
24 #include "Dvr.h"
25 #include "Filter.h"
26 #include "Frontend.h"
27 #include "TimeFilter.h"
28 #include "Tuner.h"
29 
30 using namespace std;
31 
32 namespace android {
33 namespace hardware {
34 namespace tv {
35 namespace tuner {
36 namespace V1_0 {
37 namespace implementation {
38 
39 using ::android::hardware::EventFlag;
40 using ::android::hardware::kSynchronizedReadWrite;
41 using ::android::hardware::MessageQueue;
42 using ::android::hardware::MQDescriptorSync;
43 using ::android::hardware::tv::tuner::V1_0::IDemux;
44 using ::android::hardware::tv::tuner::V1_0::IDvrCallback;
45 using ::android::hardware::tv::tuner::V1_0::IFilterCallback;
46 using ::android::hardware::tv::tuner::V1_0::Result;
47 
48 using FilterMQ = MessageQueue<uint8_t, kSynchronizedReadWrite>;
49 
50 class Dvr;
51 class Filter;
52 class Frontend;
53 class TimeFilter;
54 class Tuner;
55 
56 class Demux : public IDemux {
57   public:
58     Demux(uint32_t demuxId, sp<Tuner> tuner);
59 
60     ~Demux();
61 
62     virtual Return<Result> setFrontendDataSource(uint32_t frontendId) override;
63 
64     virtual Return<void> openFilter(const DemuxFilterType& type, uint32_t bufferSize,
65                                     const sp<IFilterCallback>& cb, openFilter_cb _hidl_cb) override;
66 
67     virtual Return<void> openTimeFilter(openTimeFilter_cb _hidl_cb) override;
68 
69     virtual Return<void> getAvSyncHwId(const sp<IFilter>& filter,
70                                        getAvSyncHwId_cb _hidl_cb) override;
71 
72     virtual Return<void> getAvSyncTime(AvSyncHwId avSyncHwId, getAvSyncTime_cb _hidl_cb) override;
73 
74     virtual Return<Result> close() override;
75 
76     virtual Return<void> openDvr(DvrType type, uint32_t bufferSize, const sp<IDvrCallback>& cb,
77                                  openDvr_cb _hidl_cb) override;
78 
79     virtual Return<Result> connectCiCam(uint32_t ciCamId) override;
80 
81     virtual Return<Result> disconnectCiCam() override;
82 
83     // Functions interacts with Tuner Service
84     void stopFrontendInput();
85     Result removeFilter(uint32_t filterId);
86     bool attachRecordFilter(int filterId);
87     bool detachRecordFilter(int filterId);
88     Result startFilterHandler(uint32_t filterId);
89     void updateFilterOutput(uint16_t filterId, vector<uint8_t> data);
90     uint16_t getFilterTpid(uint32_t filterId);
91     void setIsRecording(bool isRecording);
92 
93   private:
94     // Tuner service
95     sp<Tuner> mTunerService;
96 
97     // Frontend source
98     sp<Frontend> mFrontend;
99     string mFrontendSourceFile;
100 
101     // A struct that passes the arguments to a newly created filter thread
102     struct ThreadArgs {
103         Demux* user;
104         uint32_t filterId;
105     };
106 
107     Result startFrontendInputLoop();
108     static void* __threadLoopFrontend(void* user);
109     void frontendInputThreadLoop();
110 
111     /**
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      */
118     void deleteEventFlag();
119     bool readDataFromMQ();
120     /**
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.
123      * Note that recording filters are not included.
124      */
125     bool startBroadcastFilterDispatcher();
126     void startBroadcastTsFilter(vector<uint8_t> data);
127 
128     void sendFrontendInputToRecord(vector<uint8_t> data);
129     bool startRecordFilterDispatcher();
130 
131     uint32_t mDemuxId;
132     uint32_t mCiCamId;
133     /**
134      * Record the last used filter id. Initial value is -1.
135      * Filter Id starts with 0.
136      */
137     uint32_t mLastUsedFilterId = -1;
138     /**
139      * 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     /**
151      * 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     /**
156      * A list of created FilterMQ ptrs.
157      * The array number is the filter ID.
158      */
159     std::map<uint32_t, sp<Filter>> mFilters;
160 
161     /**
162      * Local reference to the opened DVR object.
163      */
164     sp<Dvr> mDvr;
165 
166     // Thread handlers
167     pthread_t mFrontendInputThread;
168     /**
169      * If a specific filter's writing loop is still running
170      */
171     bool mFrontendInputThreadRunning;
172     bool mKeepFetchingDataFromFrontend;
173     /**
174      * If the dvr recording is running.
175      */
176     bool mIsRecording = false;
177     /**
178      * Lock to protect writes to the FMQs
179      */
180     std::mutex mWriteLock;
181     /**
182      * Lock to protect writes to the input status
183      */
184     std::mutex mFrontendInputThreadLock;
185 
186     // temp handle single PES filter
187     // TODO handle mulptiple Pes filters
188     int mPesSizeLeft = 0;
189     vector<uint8_t> mPesOutput;
190 
191     const bool DEBUG_FILTER = false;
192 };
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_
202