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