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     void updateMediaFilterOutput(uint16_t filterId, vector<uint8_t> data, uint64_t pts);
91     uint16_t getFilterTpid(uint32_t filterId);
92     void setIsRecording(bool isRecording);
93     void startFrontendInputLoop();
94 
95     /**
96      * A dispatcher to read and dispatch input data to all the started filters.
97      * Each filter handler handles the data filtering/output writing/filterEvent updating.
98      * Note that recording filters are not included.
99      */
100     bool startBroadcastFilterDispatcher();
101     void startBroadcastTsFilter(vector<uint8_t> data);
102 
103     void sendFrontendInputToRecord(vector<uint8_t> data);
104     bool startRecordFilterDispatcher();
105 
106   private:
107     // Tuner service
108     sp<Tuner> mTunerService;
109 
110     // Frontend source
111     sp<Frontend> mFrontend;
112 
113     // A struct that passes the arguments to a newly created filter thread
114     struct ThreadArgs {
115         Demux* user;
116         uint32_t filterId;
117     };
118 
119     static void* __threadLoopFrontend(void* user);
120     void frontendInputThreadLoop();
121 
122     /**
123      * To create a FilterMQ with the the next available Filter ID.
124      * Creating Event Flag at the same time.
125      * Add the successfully created/saved FilterMQ into the local list.
126      *
127      * Return false is any of the above processes fails.
128      */
129     void deleteEventFlag();
130     bool readDataFromMQ();
131 
132     uint32_t mDemuxId;
133     uint32_t mCiCamId;
134     set<uint32_t> mPcrFilterIds;
135     /**
136      * Record the last used filter id. Initial value is -1.
137      * Filter Id starts with 0.
138      */
139     uint32_t mLastUsedFilterId = -1;
140     /**
141      * Record all the used playback filter Ids.
142      * Any removed filter id should be removed from this set.
143      */
144     set<uint32_t> mPlaybackFilterIds;
145     /**
146      * Record all the attached record filter Ids.
147      * Any removed filter id should be removed from this set.
148      */
149     set<uint32_t> mRecordFilterIds;
150     /**
151      * A list of created Filter sp.
152      * The array number is the filter ID.
153      */
154     std::map<uint32_t, sp<Filter>> mFilters;
155 
156     /**
157      * Local reference to the opened Timer Filter instance.
158      */
159     sp<TimeFilter> mTimeFilter;
160 
161     /**
162      * Local reference to the opened DVR object.
163      */
164     sp<Dvr> mDvrPlayback;
165     sp<Dvr> mDvrRecord;
166 
167     // Thread handlers
168     pthread_t mFrontendInputThread;
169     /**
170      * If a specific filter's writing loop is still running
171      */
172     bool mFrontendInputThreadRunning;
173     bool mKeepFetchingDataFromFrontend;
174     /**
175      * If the dvr recording is running.
176      */
177     bool mIsRecording = false;
178     /**
179      * Lock to protect writes to the FMQs
180      */
181     std::mutex mWriteLock;
182     /**
183      * Lock to protect writes to the input status
184      */
185     std::mutex mFrontendInputThreadLock;
186 
187     // temp handle single PES filter
188     // TODO handle mulptiple Pes filters
189     int mPesSizeLeft = 0;
190     vector<uint8_t> mPesOutput;
191 
192     const bool DEBUG_DEMUX = false;
193 };
194 
195 }  // namespace implementation
196 }  // namespace V1_0
197 }  // namespace tuner
198 }  // namespace tv
199 }  // namespace hardware
200 }  // namespace android
201 
202 #endif  // ANDROID_HARDWARE_TV_TUNER_V1_0_DEMUX_H_
203