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/BnDvr.h> 20*4d7e907cSAndroid Build Coastguard Worker #include <aidl/android/hardware/tv/tuner/RecordStatus.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 #include "Demux.h" 28*4d7e907cSAndroid Build Coastguard Worker #include "Frontend.h" 29*4d7e907cSAndroid Build Coastguard Worker #include "Tuner.h" 30*4d7e907cSAndroid Build Coastguard Worker 31*4d7e907cSAndroid Build Coastguard Worker using namespace std; 32*4d7e907cSAndroid Build Coastguard Worker 33*4d7e907cSAndroid Build Coastguard Worker namespace aidl { 34*4d7e907cSAndroid Build Coastguard Worker namespace android { 35*4d7e907cSAndroid Build Coastguard Worker namespace hardware { 36*4d7e907cSAndroid Build Coastguard Worker namespace tv { 37*4d7e907cSAndroid Build Coastguard Worker namespace tuner { 38*4d7e907cSAndroid Build Coastguard Worker 39*4d7e907cSAndroid Build Coastguard Worker using ::aidl::android::hardware::common::fmq::MQDescriptor; 40*4d7e907cSAndroid Build Coastguard Worker using ::aidl::android::hardware::common::fmq::SynchronizedReadWrite; 41*4d7e907cSAndroid Build Coastguard Worker using ::android::AidlMessageQueue; 42*4d7e907cSAndroid Build Coastguard Worker using ::android::hardware::EventFlag; 43*4d7e907cSAndroid Build Coastguard Worker 44*4d7e907cSAndroid Build Coastguard Worker using DvrMQ = AidlMessageQueue<int8_t, SynchronizedReadWrite>; 45*4d7e907cSAndroid Build Coastguard Worker 46*4d7e907cSAndroid Build Coastguard Worker const int DVR_WRITE_SUCCESS = 0; 47*4d7e907cSAndroid Build Coastguard Worker const int DVR_WRITE_FAILURE_REASON_FMQ_FULL = 1; 48*4d7e907cSAndroid Build Coastguard Worker const int DVR_WRITE_FAILURE_REASON_UNKNOWN = 2; 49*4d7e907cSAndroid Build Coastguard Worker 50*4d7e907cSAndroid Build Coastguard Worker const int TS_SIZE = 188; 51*4d7e907cSAndroid Build Coastguard Worker const int IPTV_BUFFER_SIZE = TS_SIZE * 7 * 8; // defined in service_streamer_udp in cbs v3 project 52*4d7e907cSAndroid Build Coastguard Worker 53*4d7e907cSAndroid Build Coastguard Worker // Thresholds are defined to indicate how full the buffers are. 54*4d7e907cSAndroid Build Coastguard Worker const double HIGH_THRESHOLD_PERCENT = 0.90; 55*4d7e907cSAndroid Build Coastguard Worker const double LOW_THRESHOLD_PERCENT = 0.15; 56*4d7e907cSAndroid Build Coastguard Worker const int IPTV_PLAYBACK_STATUS_THRESHOLD_HIGH = IPTV_BUFFER_SIZE * HIGH_THRESHOLD_PERCENT; 57*4d7e907cSAndroid Build Coastguard Worker const int IPTV_PLAYBACK_STATUS_THRESHOLD_LOW = IPTV_BUFFER_SIZE * LOW_THRESHOLD_PERCENT; 58*4d7e907cSAndroid Build Coastguard Worker 59*4d7e907cSAndroid Build Coastguard Worker struct MediaEsMetaData { 60*4d7e907cSAndroid Build Coastguard Worker bool isAudio; 61*4d7e907cSAndroid Build Coastguard Worker int startIndex; 62*4d7e907cSAndroid Build Coastguard Worker int len; 63*4d7e907cSAndroid Build Coastguard Worker int pts; 64*4d7e907cSAndroid Build Coastguard Worker }; 65*4d7e907cSAndroid Build Coastguard Worker 66*4d7e907cSAndroid Build Coastguard Worker class Demux; 67*4d7e907cSAndroid Build Coastguard Worker class Filter; 68*4d7e907cSAndroid Build Coastguard Worker class Frontend; 69*4d7e907cSAndroid Build Coastguard Worker class Tuner; 70*4d7e907cSAndroid Build Coastguard Worker 71*4d7e907cSAndroid Build Coastguard Worker class Dvr : public BnDvr { 72*4d7e907cSAndroid Build Coastguard Worker public: 73*4d7e907cSAndroid Build Coastguard Worker Dvr(DvrType type, uint32_t bufferSize, const std::shared_ptr<IDvrCallback>& cb, 74*4d7e907cSAndroid Build Coastguard Worker std::shared_ptr<Demux> demux); 75*4d7e907cSAndroid Build Coastguard Worker ~Dvr(); 76*4d7e907cSAndroid Build Coastguard Worker 77*4d7e907cSAndroid Build Coastguard Worker ::ndk::ScopedAStatus getQueueDesc( 78*4d7e907cSAndroid Build Coastguard Worker MQDescriptor<int8_t, SynchronizedReadWrite>* out_queue) override; 79*4d7e907cSAndroid Build Coastguard Worker ::ndk::ScopedAStatus configure(const DvrSettings& in_settings) override; 80*4d7e907cSAndroid Build Coastguard Worker ::ndk::ScopedAStatus attachFilter(const std::shared_ptr<IFilter>& in_filter) override; 81*4d7e907cSAndroid Build Coastguard Worker ::ndk::ScopedAStatus detachFilter(const std::shared_ptr<IFilter>& in_filter) override; 82*4d7e907cSAndroid Build Coastguard Worker ::ndk::ScopedAStatus start() override; 83*4d7e907cSAndroid Build Coastguard Worker ::ndk::ScopedAStatus stop() override; 84*4d7e907cSAndroid Build Coastguard Worker ::ndk::ScopedAStatus flush() override; 85*4d7e907cSAndroid Build Coastguard Worker ::ndk::ScopedAStatus close() override; 86*4d7e907cSAndroid Build Coastguard Worker ::ndk::ScopedAStatus setStatusCheckIntervalHint(int64_t in_milliseconds) override; 87*4d7e907cSAndroid Build Coastguard Worker 88*4d7e907cSAndroid Build Coastguard Worker binder_status_t dump(int fd, const char** args, uint32_t numArgs) override; 89*4d7e907cSAndroid Build Coastguard Worker 90*4d7e907cSAndroid Build Coastguard Worker /** 91*4d7e907cSAndroid Build Coastguard Worker * To create a DvrMQ and its Event Flag. 92*4d7e907cSAndroid Build Coastguard Worker * 93*4d7e907cSAndroid Build Coastguard Worker * Return false is any of the above processes fails. 94*4d7e907cSAndroid Build Coastguard Worker */ 95*4d7e907cSAndroid Build Coastguard Worker bool createDvrMQ(); 96*4d7e907cSAndroid Build Coastguard Worker int writePlaybackFMQ(void* buf, size_t size); 97*4d7e907cSAndroid Build Coastguard Worker bool writeRecordFMQ(const std::vector<int8_t>& data); 98*4d7e907cSAndroid Build Coastguard Worker bool addPlaybackFilter(int64_t filterId, std::shared_ptr<Filter> filter); 99*4d7e907cSAndroid Build Coastguard Worker bool removePlaybackFilter(int64_t filterId); 100*4d7e907cSAndroid Build Coastguard Worker bool readPlaybackFMQ(bool isVirtualFrontend, bool isRecording); 101*4d7e907cSAndroid Build Coastguard Worker bool processEsDataOnPlayback(bool isVirtualFrontend, bool isRecording); 102*4d7e907cSAndroid Build Coastguard Worker bool startFilterDispatcher(bool isVirtualFrontend, bool isRecording); 103*4d7e907cSAndroid Build Coastguard Worker EventFlag* getDvrEventFlag(); getSettings()104*4d7e907cSAndroid Build Coastguard Worker DvrSettings getSettings() { return mDvrSettings; } 105*4d7e907cSAndroid Build Coastguard Worker 106*4d7e907cSAndroid Build Coastguard Worker private: 107*4d7e907cSAndroid Build Coastguard Worker // Demux service 108*4d7e907cSAndroid Build Coastguard Worker std::shared_ptr<Demux> mDemux; 109*4d7e907cSAndroid Build Coastguard Worker 110*4d7e907cSAndroid Build Coastguard Worker DvrType mType; 111*4d7e907cSAndroid Build Coastguard Worker uint32_t mBufferSize; 112*4d7e907cSAndroid Build Coastguard Worker std::shared_ptr<IDvrCallback> mCallback; 113*4d7e907cSAndroid Build Coastguard Worker std::map<int64_t, std::shared_ptr<Filter>> mFilters; 114*4d7e907cSAndroid Build Coastguard Worker 115*4d7e907cSAndroid Build Coastguard Worker void deleteEventFlag(); 116*4d7e907cSAndroid Build Coastguard Worker bool readDataFromMQ(); 117*4d7e907cSAndroid Build Coastguard Worker void getMetaDataValue(int& index, int8_t* dataOutputBuffer, int& value); 118*4d7e907cSAndroid Build Coastguard Worker void maySendPlaybackStatusCallback(); 119*4d7e907cSAndroid Build Coastguard Worker void maySendIptvPlaybackStatusCallback(); 120*4d7e907cSAndroid Build Coastguard Worker void maySendRecordStatusCallback(); 121*4d7e907cSAndroid Build Coastguard Worker PlaybackStatus checkPlaybackStatusChange(uint32_t availableToWrite, uint32_t availableToRead, 122*4d7e907cSAndroid Build Coastguard Worker int64_t highThreshold, int64_t lowThreshold); 123*4d7e907cSAndroid Build Coastguard Worker RecordStatus checkRecordStatusChange(uint32_t availableToWrite, uint32_t availableToRead, 124*4d7e907cSAndroid Build Coastguard Worker int64_t highThreshold, int64_t lowThreshold); 125*4d7e907cSAndroid Build Coastguard Worker /** 126*4d7e907cSAndroid Build Coastguard Worker * A dispatcher to read and dispatch input data to all the started filters. 127*4d7e907cSAndroid Build Coastguard Worker * Each filter handler handles the data filtering/output writing/filterEvent updating. 128*4d7e907cSAndroid Build Coastguard Worker */ 129*4d7e907cSAndroid Build Coastguard Worker void startTpidFilter(vector<int8_t> data); 130*4d7e907cSAndroid Build Coastguard Worker void playbackThreadLoop(); 131*4d7e907cSAndroid Build Coastguard Worker 132*4d7e907cSAndroid Build Coastguard Worker unique_ptr<DvrMQ> mDvrMQ; 133*4d7e907cSAndroid Build Coastguard Worker EventFlag* mDvrEventFlag; 134*4d7e907cSAndroid Build Coastguard Worker /** 135*4d7e907cSAndroid Build Coastguard Worker * Demux callbacks used on filter events or IO buffer status 136*4d7e907cSAndroid Build Coastguard Worker */ 137*4d7e907cSAndroid Build Coastguard Worker bool mDvrConfigured = false; 138*4d7e907cSAndroid Build Coastguard Worker DvrSettings mDvrSettings; 139*4d7e907cSAndroid Build Coastguard Worker 140*4d7e907cSAndroid Build Coastguard Worker // Thread handlers 141*4d7e907cSAndroid Build Coastguard Worker std::thread mDvrThread; 142*4d7e907cSAndroid Build Coastguard Worker 143*4d7e907cSAndroid Build Coastguard Worker // FMQ status local records 144*4d7e907cSAndroid Build Coastguard Worker PlaybackStatus mPlaybackStatus; 145*4d7e907cSAndroid Build Coastguard Worker RecordStatus mRecordStatus; 146*4d7e907cSAndroid Build Coastguard Worker /** 147*4d7e907cSAndroid Build Coastguard Worker * If a specific filter's writing loop is still running 148*4d7e907cSAndroid Build Coastguard Worker */ 149*4d7e907cSAndroid Build Coastguard Worker std::atomic<bool> mDvrThreadRunning; 150*4d7e907cSAndroid Build Coastguard Worker 151*4d7e907cSAndroid Build Coastguard Worker /** 152*4d7e907cSAndroid Build Coastguard Worker * Lock to protect writes to the FMQs 153*4d7e907cSAndroid Build Coastguard Worker */ 154*4d7e907cSAndroid Build Coastguard Worker std::mutex mWriteLock; 155*4d7e907cSAndroid Build Coastguard Worker /** 156*4d7e907cSAndroid Build Coastguard Worker * Lock to protect writes to the input status 157*4d7e907cSAndroid Build Coastguard Worker */ 158*4d7e907cSAndroid Build Coastguard Worker std::mutex mPlaybackStatusLock; 159*4d7e907cSAndroid Build Coastguard Worker std::mutex mRecordStatusLock; 160*4d7e907cSAndroid Build Coastguard Worker 161*4d7e907cSAndroid Build Coastguard Worker const bool DEBUG_DVR = false; 162*4d7e907cSAndroid Build Coastguard Worker }; 163*4d7e907cSAndroid Build Coastguard Worker 164*4d7e907cSAndroid Build Coastguard Worker } // namespace tuner 165*4d7e907cSAndroid Build Coastguard Worker } // namespace tv 166*4d7e907cSAndroid Build Coastguard Worker } // namespace hardware 167*4d7e907cSAndroid Build Coastguard Worker } // namespace android 168*4d7e907cSAndroid Build Coastguard Worker } // namespace aidl 169