1*4d7e907cSAndroid Build Coastguard Worker /* 2*4d7e907cSAndroid Build Coastguard Worker * Copyright (C) 2019 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 #ifndef ANDROID_HARDWARE_TV_TUNER_V1_0_DVR_H_ 18*4d7e907cSAndroid Build Coastguard Worker #define ANDROID_HARDWARE_TV_TUNER_V1_0_DVR_H_ 19*4d7e907cSAndroid Build Coastguard Worker 20*4d7e907cSAndroid Build Coastguard Worker #include <android/hardware/tv/tuner/1.0/IDvr.h> 21*4d7e907cSAndroid Build Coastguard Worker #include <fmq/MessageQueue.h> 22*4d7e907cSAndroid Build Coastguard Worker #include <math.h> 23*4d7e907cSAndroid Build Coastguard Worker #include <atomic> 24*4d7e907cSAndroid Build Coastguard Worker #include <set> 25*4d7e907cSAndroid Build Coastguard Worker #include <thread> 26*4d7e907cSAndroid Build Coastguard Worker #include "Demux.h" 27*4d7e907cSAndroid Build Coastguard Worker #include "Frontend.h" 28*4d7e907cSAndroid Build Coastguard Worker #include "Tuner.h" 29*4d7e907cSAndroid Build Coastguard Worker 30*4d7e907cSAndroid Build Coastguard Worker using namespace std; 31*4d7e907cSAndroid Build Coastguard Worker 32*4d7e907cSAndroid Build Coastguard Worker namespace android { 33*4d7e907cSAndroid Build Coastguard Worker namespace hardware { 34*4d7e907cSAndroid Build Coastguard Worker namespace tv { 35*4d7e907cSAndroid Build Coastguard Worker namespace tuner { 36*4d7e907cSAndroid Build Coastguard Worker namespace V1_0 { 37*4d7e907cSAndroid Build Coastguard Worker namespace implementation { 38*4d7e907cSAndroid Build Coastguard Worker 39*4d7e907cSAndroid Build Coastguard Worker using ::android::hardware::EventFlag; 40*4d7e907cSAndroid Build Coastguard Worker using ::android::hardware::kSynchronizedReadWrite; 41*4d7e907cSAndroid Build Coastguard Worker using ::android::hardware::MessageQueue; 42*4d7e907cSAndroid Build Coastguard Worker using ::android::hardware::MQDescriptorSync; 43*4d7e907cSAndroid Build Coastguard Worker using ::android::hardware::tv::tuner::V1_0::IDemux; 44*4d7e907cSAndroid Build Coastguard Worker using ::android::hardware::tv::tuner::V1_0::IDvrCallback; 45*4d7e907cSAndroid Build Coastguard Worker using ::android::hardware::tv::tuner::V1_0::Result; 46*4d7e907cSAndroid Build Coastguard Worker 47*4d7e907cSAndroid Build Coastguard Worker using DvrMQ = MessageQueue<uint8_t, kSynchronizedReadWrite>; 48*4d7e907cSAndroid Build Coastguard Worker 49*4d7e907cSAndroid Build Coastguard Worker struct MediaEsMetaData { 50*4d7e907cSAndroid Build Coastguard Worker bool isAudio; 51*4d7e907cSAndroid Build Coastguard Worker int startIndex; 52*4d7e907cSAndroid Build Coastguard Worker int len; 53*4d7e907cSAndroid Build Coastguard Worker int pts; 54*4d7e907cSAndroid Build Coastguard Worker }; 55*4d7e907cSAndroid Build Coastguard Worker 56*4d7e907cSAndroid Build Coastguard Worker class Demux; 57*4d7e907cSAndroid Build Coastguard Worker class Filter; 58*4d7e907cSAndroid Build Coastguard Worker class Frontend; 59*4d7e907cSAndroid Build Coastguard Worker class Tuner; 60*4d7e907cSAndroid Build Coastguard Worker 61*4d7e907cSAndroid Build Coastguard Worker class Dvr : public IDvr { 62*4d7e907cSAndroid Build Coastguard Worker public: 63*4d7e907cSAndroid Build Coastguard Worker Dvr(); 64*4d7e907cSAndroid Build Coastguard Worker 65*4d7e907cSAndroid Build Coastguard Worker Dvr(DvrType type, uint32_t bufferSize, const sp<IDvrCallback>& cb, sp<Demux> demux); 66*4d7e907cSAndroid Build Coastguard Worker 67*4d7e907cSAndroid Build Coastguard Worker ~Dvr(); 68*4d7e907cSAndroid Build Coastguard Worker 69*4d7e907cSAndroid Build Coastguard Worker virtual Return<void> getQueueDesc(getQueueDesc_cb _hidl_cb) override; 70*4d7e907cSAndroid Build Coastguard Worker 71*4d7e907cSAndroid Build Coastguard Worker virtual Return<Result> configure(const DvrSettings& settings) override; 72*4d7e907cSAndroid Build Coastguard Worker 73*4d7e907cSAndroid Build Coastguard Worker virtual Return<Result> attachFilter(const sp<IFilter>& filter) override; 74*4d7e907cSAndroid Build Coastguard Worker 75*4d7e907cSAndroid Build Coastguard Worker virtual Return<Result> detachFilter(const sp<IFilter>& filter) override; 76*4d7e907cSAndroid Build Coastguard Worker 77*4d7e907cSAndroid Build Coastguard Worker virtual Return<Result> start() override; 78*4d7e907cSAndroid Build Coastguard Worker 79*4d7e907cSAndroid Build Coastguard Worker virtual Return<Result> stop() override; 80*4d7e907cSAndroid Build Coastguard Worker 81*4d7e907cSAndroid Build Coastguard Worker virtual Return<Result> flush() override; 82*4d7e907cSAndroid Build Coastguard Worker 83*4d7e907cSAndroid Build Coastguard Worker virtual Return<Result> close() override; 84*4d7e907cSAndroid Build Coastguard Worker 85*4d7e907cSAndroid Build Coastguard Worker /** 86*4d7e907cSAndroid Build Coastguard Worker * To create a DvrMQ and its Event Flag. 87*4d7e907cSAndroid Build Coastguard Worker * 88*4d7e907cSAndroid Build Coastguard Worker * Return false is any of the above processes fails. 89*4d7e907cSAndroid Build Coastguard Worker */ 90*4d7e907cSAndroid Build Coastguard Worker bool createDvrMQ(); 91*4d7e907cSAndroid Build Coastguard Worker void sendBroadcastInputToDvrRecord(vector<uint8_t> byteBuffer); 92*4d7e907cSAndroid Build Coastguard Worker bool writeRecordFMQ(const std::vector<uint8_t>& data); 93*4d7e907cSAndroid Build Coastguard Worker bool addPlaybackFilter(uint32_t filterId, sp<IFilter> filter); 94*4d7e907cSAndroid Build Coastguard Worker bool removePlaybackFilter(uint32_t filterId); 95*4d7e907cSAndroid Build Coastguard Worker bool readPlaybackFMQ(bool isVirtualFrontend, bool isRecording); 96*4d7e907cSAndroid Build Coastguard Worker bool processEsDataOnPlayback(bool isVirtualFrontend, bool isRecording); 97*4d7e907cSAndroid Build Coastguard Worker bool startFilterDispatcher(bool isVirtualFrontend, bool isRecording); 98*4d7e907cSAndroid Build Coastguard Worker EventFlag* getDvrEventFlag(); getSettings()99*4d7e907cSAndroid Build Coastguard Worker DvrSettings getSettings() { return mDvrSettings; } 100*4d7e907cSAndroid Build Coastguard Worker 101*4d7e907cSAndroid Build Coastguard Worker private: 102*4d7e907cSAndroid Build Coastguard Worker // Demux service 103*4d7e907cSAndroid Build Coastguard Worker sp<Demux> mDemux; 104*4d7e907cSAndroid Build Coastguard Worker 105*4d7e907cSAndroid Build Coastguard Worker DvrType mType; 106*4d7e907cSAndroid Build Coastguard Worker uint32_t mBufferSize; 107*4d7e907cSAndroid Build Coastguard Worker sp<IDvrCallback> mCallback; 108*4d7e907cSAndroid Build Coastguard Worker std::map<uint32_t, sp<IFilter>> mFilters; 109*4d7e907cSAndroid Build Coastguard Worker 110*4d7e907cSAndroid Build Coastguard Worker void deleteEventFlag(); 111*4d7e907cSAndroid Build Coastguard Worker bool readDataFromMQ(); 112*4d7e907cSAndroid Build Coastguard Worker void getMetaDataValue(int& index, uint8_t* dataOutputBuffer, int& value); 113*4d7e907cSAndroid Build Coastguard Worker void maySendPlaybackStatusCallback(); 114*4d7e907cSAndroid Build Coastguard Worker void maySendRecordStatusCallback(); 115*4d7e907cSAndroid Build Coastguard Worker PlaybackStatus checkPlaybackStatusChange(uint32_t availableToWrite, uint32_t availableToRead, 116*4d7e907cSAndroid Build Coastguard Worker uint32_t highThreshold, uint32_t lowThreshold); 117*4d7e907cSAndroid Build Coastguard Worker RecordStatus checkRecordStatusChange(uint32_t availableToWrite, uint32_t availableToRead, 118*4d7e907cSAndroid Build Coastguard Worker uint32_t highThreshold, uint32_t lowThreshold); 119*4d7e907cSAndroid Build Coastguard Worker /** 120*4d7e907cSAndroid Build Coastguard Worker * A dispatcher to read and dispatch input data to all the started filters. 121*4d7e907cSAndroid Build Coastguard Worker * Each filter handler handles the data filtering/output writing/filterEvent updating. 122*4d7e907cSAndroid Build Coastguard Worker */ 123*4d7e907cSAndroid Build Coastguard Worker void startTpidFilter(vector<uint8_t> data); 124*4d7e907cSAndroid Build Coastguard Worker void playbackThreadLoop(); 125*4d7e907cSAndroid Build Coastguard Worker 126*4d7e907cSAndroid Build Coastguard Worker unique_ptr<DvrMQ> mDvrMQ; 127*4d7e907cSAndroid Build Coastguard Worker EventFlag* mDvrEventFlag; 128*4d7e907cSAndroid Build Coastguard Worker /** 129*4d7e907cSAndroid Build Coastguard Worker * Demux callbacks used on filter events or IO buffer status 130*4d7e907cSAndroid Build Coastguard Worker */ 131*4d7e907cSAndroid Build Coastguard Worker bool mDvrConfigured = false; 132*4d7e907cSAndroid Build Coastguard Worker DvrSettings mDvrSettings; 133*4d7e907cSAndroid Build Coastguard Worker 134*4d7e907cSAndroid Build Coastguard Worker // Thread handlers 135*4d7e907cSAndroid Build Coastguard Worker std::thread mDvrThread; 136*4d7e907cSAndroid Build Coastguard Worker 137*4d7e907cSAndroid Build Coastguard Worker // FMQ status local records 138*4d7e907cSAndroid Build Coastguard Worker PlaybackStatus mPlaybackStatus; 139*4d7e907cSAndroid Build Coastguard Worker RecordStatus mRecordStatus; 140*4d7e907cSAndroid Build Coastguard Worker /** 141*4d7e907cSAndroid Build Coastguard Worker * If a specific filter's writing loop is still running 142*4d7e907cSAndroid Build Coastguard Worker */ 143*4d7e907cSAndroid Build Coastguard Worker std::atomic<bool> mDvrThreadRunning; 144*4d7e907cSAndroid Build Coastguard Worker bool mKeepFetchingDataFromFrontend; 145*4d7e907cSAndroid Build Coastguard Worker /** 146*4d7e907cSAndroid Build Coastguard Worker * Lock to protect writes to the FMQs 147*4d7e907cSAndroid Build Coastguard Worker */ 148*4d7e907cSAndroid Build Coastguard Worker std::mutex mWriteLock; 149*4d7e907cSAndroid Build Coastguard Worker /** 150*4d7e907cSAndroid Build Coastguard Worker * Lock to protect writes to the input status 151*4d7e907cSAndroid Build Coastguard Worker */ 152*4d7e907cSAndroid Build Coastguard Worker std::mutex mPlaybackStatusLock; 153*4d7e907cSAndroid Build Coastguard Worker std::mutex mRecordStatusLock; 154*4d7e907cSAndroid Build Coastguard Worker 155*4d7e907cSAndroid Build Coastguard Worker const bool DEBUG_DVR = false; 156*4d7e907cSAndroid Build Coastguard Worker }; 157*4d7e907cSAndroid Build Coastguard Worker 158*4d7e907cSAndroid Build Coastguard Worker } // namespace implementation 159*4d7e907cSAndroid Build Coastguard Worker } // namespace V1_0 160*4d7e907cSAndroid Build Coastguard Worker } // namespace tuner 161*4d7e907cSAndroid Build Coastguard Worker } // namespace tv 162*4d7e907cSAndroid Build Coastguard Worker } // namespace hardware 163*4d7e907cSAndroid Build Coastguard Worker } // namespace android 164*4d7e907cSAndroid Build Coastguard Worker 165*4d7e907cSAndroid Build Coastguard Worker #endif // ANDROID_HARDWARE_TV_TUNER_V1_0_DVR_H_ 166