xref: /aosp_15_r20/hardware/interfaces/tv/tuner/aidl/default/Demux.h (revision 4d7e907c777eeecc4c5bd7cf640a754fac206ff7)
1*4d7e907cSAndroid Build Coastguard Worker /*
2*4d7e907cSAndroid Build Coastguard Worker  * Copyright 2021 The Android Open Source Project
3*4d7e907cSAndroid Build Coastguard Worker  *
4*4d7e907cSAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*4d7e907cSAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*4d7e907cSAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*4d7e907cSAndroid Build Coastguard Worker  *
8*4d7e907cSAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*4d7e907cSAndroid Build Coastguard Worker  *
10*4d7e907cSAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*4d7e907cSAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*4d7e907cSAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*4d7e907cSAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*4d7e907cSAndroid Build Coastguard Worker  * limitations under the License.
15*4d7e907cSAndroid Build Coastguard Worker  */
16*4d7e907cSAndroid Build Coastguard Worker 
17*4d7e907cSAndroid Build Coastguard Worker #pragma once
18*4d7e907cSAndroid Build Coastguard Worker 
19*4d7e907cSAndroid Build Coastguard Worker #include <aidl/android/hardware/tv/tuner/BnDemux.h>
20*4d7e907cSAndroid Build Coastguard Worker #include <aidl/android/hardware/tv/tuner/BnDvrCallback.h>
21*4d7e907cSAndroid Build Coastguard Worker 
22*4d7e907cSAndroid Build Coastguard Worker #include <fmq/AidlMessageQueue.h>
23*4d7e907cSAndroid Build Coastguard Worker #include <math.h>
24*4d7e907cSAndroid Build Coastguard Worker #include <atomic>
25*4d7e907cSAndroid Build Coastguard Worker #include <set>
26*4d7e907cSAndroid Build Coastguard Worker #include <thread>
27*4d7e907cSAndroid Build Coastguard Worker 
28*4d7e907cSAndroid Build Coastguard Worker #include "Dvr.h"
29*4d7e907cSAndroid Build Coastguard Worker #include "Filter.h"
30*4d7e907cSAndroid Build Coastguard Worker #include "Frontend.h"
31*4d7e907cSAndroid Build Coastguard Worker #include "TimeFilter.h"
32*4d7e907cSAndroid Build Coastguard Worker #include "Timer.h"
33*4d7e907cSAndroid Build Coastguard Worker #include "Tuner.h"
34*4d7e907cSAndroid Build Coastguard Worker #include "dtv_plugin.h"
35*4d7e907cSAndroid Build Coastguard Worker 
36*4d7e907cSAndroid Build Coastguard Worker using namespace std;
37*4d7e907cSAndroid Build Coastguard Worker 
38*4d7e907cSAndroid Build Coastguard Worker namespace aidl {
39*4d7e907cSAndroid Build Coastguard Worker namespace android {
40*4d7e907cSAndroid Build Coastguard Worker namespace hardware {
41*4d7e907cSAndroid Build Coastguard Worker namespace tv {
42*4d7e907cSAndroid Build Coastguard Worker namespace tuner {
43*4d7e907cSAndroid Build Coastguard Worker 
44*4d7e907cSAndroid Build Coastguard Worker using ::aidl::android::hardware::common::fmq::MQDescriptor;
45*4d7e907cSAndroid Build Coastguard Worker using ::aidl::android::hardware::common::fmq::SynchronizedReadWrite;
46*4d7e907cSAndroid Build Coastguard Worker using ::android::AidlMessageQueue;
47*4d7e907cSAndroid Build Coastguard Worker using ::android::hardware::EventFlag;
48*4d7e907cSAndroid Build Coastguard Worker 
49*4d7e907cSAndroid Build Coastguard Worker using FilterMQ = AidlMessageQueue<int8_t, SynchronizedReadWrite>;
50*4d7e907cSAndroid Build Coastguard Worker using AidlMQ = AidlMessageQueue<int8_t, SynchronizedReadWrite>;
51*4d7e907cSAndroid Build Coastguard Worker using AidlMQDesc = MQDescriptor<int8_t, SynchronizedReadWrite>;
52*4d7e907cSAndroid Build Coastguard Worker 
53*4d7e907cSAndroid Build Coastguard Worker class Dvr;
54*4d7e907cSAndroid Build Coastguard Worker class Filter;
55*4d7e907cSAndroid Build Coastguard Worker class Frontend;
56*4d7e907cSAndroid Build Coastguard Worker class TimeFilter;
57*4d7e907cSAndroid Build Coastguard Worker class Tuner;
58*4d7e907cSAndroid Build Coastguard Worker 
59*4d7e907cSAndroid Build Coastguard Worker const int IPTV_PLAYBACK_TIMEOUT = 20;            // ms
60*4d7e907cSAndroid Build Coastguard Worker const int IPTV_PLAYBACK_BUFFER_TIMEOUT = 20000;  // ms
61*4d7e907cSAndroid Build Coastguard Worker 
62*4d7e907cSAndroid Build Coastguard Worker class DvrPlaybackCallback : public BnDvrCallback {
63*4d7e907cSAndroid Build Coastguard Worker   public:
onPlaybackStatus(PlaybackStatus status)64*4d7e907cSAndroid Build Coastguard Worker     virtual ::ndk::ScopedAStatus onPlaybackStatus(PlaybackStatus status) override {
65*4d7e907cSAndroid Build Coastguard Worker         ALOGD("demux.h: playback status %d", status);
66*4d7e907cSAndroid Build Coastguard Worker         return ndk::ScopedAStatus::ok();
67*4d7e907cSAndroid Build Coastguard Worker     }
68*4d7e907cSAndroid Build Coastguard Worker 
onRecordStatus(RecordStatus status)69*4d7e907cSAndroid Build Coastguard Worker     virtual ::ndk::ScopedAStatus onRecordStatus(RecordStatus status) override {
70*4d7e907cSAndroid Build Coastguard Worker         ALOGD("Record Status %hhd", status);
71*4d7e907cSAndroid Build Coastguard Worker         return ndk::ScopedAStatus::ok();
72*4d7e907cSAndroid Build Coastguard Worker     }
73*4d7e907cSAndroid Build Coastguard Worker };
74*4d7e907cSAndroid Build Coastguard Worker 
75*4d7e907cSAndroid Build Coastguard Worker class Demux : public BnDemux {
76*4d7e907cSAndroid Build Coastguard Worker   public:
77*4d7e907cSAndroid Build Coastguard Worker     Demux(int32_t demuxId, uint32_t filterTypes);
78*4d7e907cSAndroid Build Coastguard Worker     ~Demux();
79*4d7e907cSAndroid Build Coastguard Worker 
80*4d7e907cSAndroid Build Coastguard Worker     ::ndk::ScopedAStatus setFrontendDataSource(int32_t in_frontendId) override;
81*4d7e907cSAndroid Build Coastguard Worker     ::ndk::ScopedAStatus openFilter(const DemuxFilterType& in_type, int32_t in_bufferSize,
82*4d7e907cSAndroid Build Coastguard Worker                                     const std::shared_ptr<IFilterCallback>& in_cb,
83*4d7e907cSAndroid Build Coastguard Worker                                     std::shared_ptr<IFilter>* _aidl_return) override;
84*4d7e907cSAndroid Build Coastguard Worker     ::ndk::ScopedAStatus openTimeFilter(std::shared_ptr<ITimeFilter>* _aidl_return) override;
85*4d7e907cSAndroid Build Coastguard Worker     ::ndk::ScopedAStatus getAvSyncHwId(const std::shared_ptr<IFilter>& in_filter,
86*4d7e907cSAndroid Build Coastguard Worker                                        int32_t* _aidl_return) override;
87*4d7e907cSAndroid Build Coastguard Worker     ::ndk::ScopedAStatus getAvSyncTime(int32_t in_avSyncHwId, int64_t* _aidl_return) override;
88*4d7e907cSAndroid Build Coastguard Worker     ::ndk::ScopedAStatus close() override;
89*4d7e907cSAndroid Build Coastguard Worker     ::ndk::ScopedAStatus openDvr(DvrType in_type, int32_t in_bufferSize,
90*4d7e907cSAndroid Build Coastguard Worker                                  const std::shared_ptr<IDvrCallback>& in_cb,
91*4d7e907cSAndroid Build Coastguard Worker                                  std::shared_ptr<IDvr>* _aidl_return) override;
92*4d7e907cSAndroid Build Coastguard Worker     ::ndk::ScopedAStatus connectCiCam(int32_t in_ciCamId) override;
93*4d7e907cSAndroid Build Coastguard Worker     ::ndk::ScopedAStatus disconnectCiCam() override;
94*4d7e907cSAndroid Build Coastguard Worker 
95*4d7e907cSAndroid Build Coastguard Worker     binder_status_t dump(int fd, const char** args, uint32_t numArgs) override;
96*4d7e907cSAndroid Build Coastguard Worker 
97*4d7e907cSAndroid Build Coastguard Worker     // Functions interacts with Tuner Service
98*4d7e907cSAndroid Build Coastguard Worker     void stopFrontendInput();
99*4d7e907cSAndroid Build Coastguard Worker     ::ndk::ScopedAStatus removeFilter(int64_t filterId);
100*4d7e907cSAndroid Build Coastguard Worker     bool attachRecordFilter(int64_t filterId);
101*4d7e907cSAndroid Build Coastguard Worker     bool detachRecordFilter(int64_t filterId);
102*4d7e907cSAndroid Build Coastguard Worker     ::ndk::ScopedAStatus startFilterHandler(int64_t filterId);
103*4d7e907cSAndroid Build Coastguard Worker     void updateFilterOutput(int64_t filterId, vector<int8_t> data);
104*4d7e907cSAndroid Build Coastguard Worker     void updateMediaFilterOutput(int64_t filterId, vector<int8_t> data, uint64_t pts);
105*4d7e907cSAndroid Build Coastguard Worker     uint16_t getFilterTpid(int64_t filterId);
106*4d7e907cSAndroid Build Coastguard Worker     void setIsRecording(bool isRecording);
107*4d7e907cSAndroid Build Coastguard Worker     bool isRecording();
108*4d7e907cSAndroid Build Coastguard Worker     void startFrontendInputLoop();
109*4d7e907cSAndroid Build Coastguard Worker     void frontendIptvInputThreadLoop(dtv_plugin* interface, dtv_streamer* streamer, void* buf);
110*4d7e907cSAndroid Build Coastguard Worker 
111*4d7e907cSAndroid Build Coastguard Worker     /**
112*4d7e907cSAndroid Build Coastguard Worker      * A dispatcher to read and dispatch input data to all the started filters.
113*4d7e907cSAndroid Build Coastguard Worker      * Each filter handler handles the data filtering/output writing/filterEvent updating.
114*4d7e907cSAndroid Build Coastguard Worker      * Note that recording filters are not included.
115*4d7e907cSAndroid Build Coastguard Worker      */
116*4d7e907cSAndroid Build Coastguard Worker     bool startBroadcastFilterDispatcher();
117*4d7e907cSAndroid Build Coastguard Worker     void startBroadcastTsFilter(vector<int8_t> data);
118*4d7e907cSAndroid Build Coastguard Worker 
119*4d7e907cSAndroid Build Coastguard Worker     void sendFrontendInputToRecord(vector<int8_t> data);
120*4d7e907cSAndroid Build Coastguard Worker     void sendFrontendInputToRecord(vector<int8_t> data, uint16_t pid, uint64_t pts);
121*4d7e907cSAndroid Build Coastguard Worker     bool startRecordFilterDispatcher();
122*4d7e907cSAndroid Build Coastguard Worker 
123*4d7e907cSAndroid Build Coastguard Worker     void getDemuxInfo(DemuxInfo* demuxInfo);
124*4d7e907cSAndroid Build Coastguard Worker     int32_t getDemuxId();
125*4d7e907cSAndroid Build Coastguard Worker     bool isInUse();
126*4d7e907cSAndroid Build Coastguard Worker     void setInUse(bool inUse);
127*4d7e907cSAndroid Build Coastguard Worker     void setTunerService(std::shared_ptr<Tuner> tuner);
128*4d7e907cSAndroid Build Coastguard Worker 
129*4d7e907cSAndroid Build Coastguard Worker     /**
130*4d7e907cSAndroid Build Coastguard Worker      * Setter for IPTV Reading thread
131*4d7e907cSAndroid Build Coastguard Worker      */
132*4d7e907cSAndroid Build Coastguard Worker     void setIptvThreadRunning(bool isIptvThreadRunning);
133*4d7e907cSAndroid Build Coastguard Worker     /**
134*4d7e907cSAndroid Build Coastguard Worker      * Stops IPTV playback reading thread.
135*4d7e907cSAndroid Build Coastguard Worker      */
136*4d7e907cSAndroid Build Coastguard Worker     void stopIptvFrontendInput();
137*4d7e907cSAndroid Build Coastguard Worker 
138*4d7e907cSAndroid Build Coastguard Worker   private:
139*4d7e907cSAndroid Build Coastguard Worker     // Tuner service
140*4d7e907cSAndroid Build Coastguard Worker     std::shared_ptr<Tuner> mTuner;
141*4d7e907cSAndroid Build Coastguard Worker 
142*4d7e907cSAndroid Build Coastguard Worker     // Frontend source
143*4d7e907cSAndroid Build Coastguard Worker     std::shared_ptr<Frontend> mFrontend;
144*4d7e907cSAndroid Build Coastguard Worker 
145*4d7e907cSAndroid Build Coastguard Worker     // A struct that passes the arguments to a newly created filter thread
146*4d7e907cSAndroid Build Coastguard Worker     struct ThreadArgs {
147*4d7e907cSAndroid Build Coastguard Worker         Demux* user;
148*4d7e907cSAndroid Build Coastguard Worker         int64_t filterId;
149*4d7e907cSAndroid Build Coastguard Worker     };
150*4d7e907cSAndroid Build Coastguard Worker 
151*4d7e907cSAndroid Build Coastguard Worker     static void* __threadLoopFrontend(void* user);
152*4d7e907cSAndroid Build Coastguard Worker     void frontendInputThreadLoop();
153*4d7e907cSAndroid Build Coastguard Worker 
154*4d7e907cSAndroid Build Coastguard Worker     /**
155*4d7e907cSAndroid Build Coastguard Worker      * To create a FilterMQ with the next available Filter ID.
156*4d7e907cSAndroid Build Coastguard Worker      * Creating Event Flag at the same time.
157*4d7e907cSAndroid Build Coastguard Worker      * Add the successfully created/saved FilterMQ into the local list.
158*4d7e907cSAndroid Build Coastguard Worker      *
159*4d7e907cSAndroid Build Coastguard Worker      * Return false is any of the above processes fails.
160*4d7e907cSAndroid Build Coastguard Worker      */
161*4d7e907cSAndroid Build Coastguard Worker     void deleteEventFlag();
162*4d7e907cSAndroid Build Coastguard Worker     bool readDataFromMQ();
163*4d7e907cSAndroid Build Coastguard Worker 
164*4d7e907cSAndroid Build Coastguard Worker     int32_t mDemuxId = -1;
165*4d7e907cSAndroid Build Coastguard Worker     int32_t mCiCamId;
166*4d7e907cSAndroid Build Coastguard Worker     set<int64_t> mPcrFilterIds;
167*4d7e907cSAndroid Build Coastguard Worker     /**
168*4d7e907cSAndroid Build Coastguard Worker      * Record the last used filter id. Initial value is -1.
169*4d7e907cSAndroid Build Coastguard Worker      * Filter Id starts with 0.
170*4d7e907cSAndroid Build Coastguard Worker      */
171*4d7e907cSAndroid Build Coastguard Worker     int64_t mLastUsedFilterId = -1;
172*4d7e907cSAndroid Build Coastguard Worker     /**
173*4d7e907cSAndroid Build Coastguard Worker      * Record all the used playback filter Ids.
174*4d7e907cSAndroid Build Coastguard Worker      * Any removed filter id should be removed from this set.
175*4d7e907cSAndroid Build Coastguard Worker      */
176*4d7e907cSAndroid Build Coastguard Worker     set<int64_t> mPlaybackFilterIds;
177*4d7e907cSAndroid Build Coastguard Worker     /**
178*4d7e907cSAndroid Build Coastguard Worker      * Record all the attached record filter Ids.
179*4d7e907cSAndroid Build Coastguard Worker      * Any removed filter id should be removed from this set.
180*4d7e907cSAndroid Build Coastguard Worker      */
181*4d7e907cSAndroid Build Coastguard Worker     set<int64_t> mRecordFilterIds;
182*4d7e907cSAndroid Build Coastguard Worker     /**
183*4d7e907cSAndroid Build Coastguard Worker      * A list of created Filter sp.
184*4d7e907cSAndroid Build Coastguard Worker      * The array number is the filter ID.
185*4d7e907cSAndroid Build Coastguard Worker      */
186*4d7e907cSAndroid Build Coastguard Worker     std::map<int64_t, std::shared_ptr<Filter>> mFilters;
187*4d7e907cSAndroid Build Coastguard Worker 
188*4d7e907cSAndroid Build Coastguard Worker     /**
189*4d7e907cSAndroid Build Coastguard Worker      * Local reference to the opened Timer Filter instance.
190*4d7e907cSAndroid Build Coastguard Worker      */
191*4d7e907cSAndroid Build Coastguard Worker     std::shared_ptr<TimeFilter> mTimeFilter;
192*4d7e907cSAndroid Build Coastguard Worker 
193*4d7e907cSAndroid Build Coastguard Worker     /**
194*4d7e907cSAndroid Build Coastguard Worker      * Local reference to the opened DVR object.
195*4d7e907cSAndroid Build Coastguard Worker      */
196*4d7e907cSAndroid Build Coastguard Worker     std::shared_ptr<Dvr> mDvrPlayback;
197*4d7e907cSAndroid Build Coastguard Worker     std::shared_ptr<Dvr> mDvrRecord;
198*4d7e907cSAndroid Build Coastguard Worker 
199*4d7e907cSAndroid Build Coastguard Worker     // Thread handlers
200*4d7e907cSAndroid Build Coastguard Worker     std::thread mFrontendInputThread;
201*4d7e907cSAndroid Build Coastguard Worker     std::thread mDemuxIptvReadThread;
202*4d7e907cSAndroid Build Coastguard Worker 
203*4d7e907cSAndroid Build Coastguard Worker     // track whether the DVR FMQ for IPTV Playback is full
204*4d7e907cSAndroid Build Coastguard Worker     bool mIsIptvDvrFMQFull = false;
205*4d7e907cSAndroid Build Coastguard Worker 
206*4d7e907cSAndroid Build Coastguard Worker     /**
207*4d7e907cSAndroid Build Coastguard Worker      * If a specific filter's writing loop is still running
208*4d7e907cSAndroid Build Coastguard Worker      */
209*4d7e907cSAndroid Build Coastguard Worker     std::atomic<bool> mFrontendInputThreadRunning;
210*4d7e907cSAndroid Build Coastguard Worker     std::atomic<bool> mKeepFetchingDataFromFrontend;
211*4d7e907cSAndroid Build Coastguard Worker 
212*4d7e907cSAndroid Build Coastguard Worker     /**
213*4d7e907cSAndroid Build Coastguard Worker      * Controls IPTV reading thread status
214*4d7e907cSAndroid Build Coastguard Worker      */
215*4d7e907cSAndroid Build Coastguard Worker     bool mIsIptvReadThreadRunning = false;
216*4d7e907cSAndroid Build Coastguard Worker     std::atomic<bool> mIsIptvReadThreadTerminated = false;
217*4d7e907cSAndroid Build Coastguard Worker     std::mutex mIsIptvThreadRunningMutex;
218*4d7e907cSAndroid Build Coastguard Worker     std::condition_variable mIsIptvThreadRunningCv;
219*4d7e907cSAndroid Build Coastguard Worker 
220*4d7e907cSAndroid Build Coastguard Worker     /**
221*4d7e907cSAndroid Build Coastguard Worker      * If the dvr recording is running.
222*4d7e907cSAndroid Build Coastguard Worker      */
223*4d7e907cSAndroid Build Coastguard Worker     bool mIsRecording = false;
224*4d7e907cSAndroid Build Coastguard Worker     /**
225*4d7e907cSAndroid Build Coastguard Worker      * Lock to protect writes to the FMQs
226*4d7e907cSAndroid Build Coastguard Worker      */
227*4d7e907cSAndroid Build Coastguard Worker     std::mutex mWriteLock;
228*4d7e907cSAndroid Build Coastguard Worker 
229*4d7e907cSAndroid Build Coastguard Worker     // temp handle single PES filter
230*4d7e907cSAndroid Build Coastguard Worker     // TODO handle mulptiple Pes filters
231*4d7e907cSAndroid Build Coastguard Worker     int mPesSizeLeft = 0;
232*4d7e907cSAndroid Build Coastguard Worker     vector<uint8_t> mPesOutput;
233*4d7e907cSAndroid Build Coastguard Worker 
234*4d7e907cSAndroid Build Coastguard Worker     const bool DEBUG_DEMUX = false;
235*4d7e907cSAndroid Build Coastguard Worker 
236*4d7e907cSAndroid Build Coastguard Worker     int32_t mFilterTypes;
237*4d7e907cSAndroid Build Coastguard Worker     bool mInUse = false;
238*4d7e907cSAndroid Build Coastguard Worker };
239*4d7e907cSAndroid Build Coastguard Worker 
240*4d7e907cSAndroid Build Coastguard Worker }  // namespace tuner
241*4d7e907cSAndroid Build Coastguard Worker }  // namespace tv
242*4d7e907cSAndroid Build Coastguard Worker }  // namespace hardware
243*4d7e907cSAndroid Build Coastguard Worker }  // namespace android
244*4d7e907cSAndroid Build Coastguard Worker }  // namespace aidl
245