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