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