blob: 07f95ad966ec8f90e3c0b5265208a4d117abfdf5 [file] [log] [blame]
Hongguang4092f2f2021-07-08 18:49:12 -07001/*
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>
Hongguange423acd2021-07-27 16:56:47 -070024#include <atomic>
Hongguang4092f2f2021-07-08 18:49:12 -070025#include <set>
Hongguange423acd2021-07-27 16:56:47 -070026#include <thread>
Hongguang4092f2f2021-07-08 18:49:12 -070027#include "Demux.h"
28#include "Frontend.h"
29#include "Tuner.h"
30
31using namespace std;
32
33namespace aidl {
34namespace android {
35namespace hardware {
36namespace tv {
37namespace tuner {
38
39using ::aidl::android::hardware::common::fmq::MQDescriptor;
40using ::aidl::android::hardware::common::fmq::SynchronizedReadWrite;
41using ::android::AidlMessageQueue;
42using ::android::hardware::EventFlag;
43
44using DvrMQ = AidlMessageQueue<int8_t, SynchronizedReadWrite>;
45
sadiqsada56c98292023-11-02 16:45:31 -070046const int DVR_WRITE_SUCCESS = 0;
47const int DVR_WRITE_FAILURE_REASON_FMQ_FULL = 1;
48const int DVR_WRITE_FAILURE_REASON_UNKNOWN = 2;
49
50const int TS_SIZE = 188;
51const 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.
54const double HIGH_THRESHOLD_PERCENT = 0.90;
55const double LOW_THRESHOLD_PERCENT = 0.15;
56const int IPTV_PLAYBACK_STATUS_THRESHOLD_HIGH = IPTV_BUFFER_SIZE * HIGH_THRESHOLD_PERCENT;
57const int IPTV_PLAYBACK_STATUS_THRESHOLD_LOW = IPTV_BUFFER_SIZE * LOW_THRESHOLD_PERCENT;
58
Hongguang4092f2f2021-07-08 18:49:12 -070059struct MediaEsMetaData {
60 bool isAudio;
61 int startIndex;
62 int len;
63 int pts;
64};
65
66class Demux;
67class Filter;
68class Frontend;
69class Tuner;
70
71class Dvr : public BnDvr {
72 public:
Hongguang Chenff2c6b02021-08-07 00:12:26 +000073 Dvr(DvrType type, uint32_t bufferSize, const std::shared_ptr<IDvrCallback>& cb,
74 std::shared_ptr<Demux> demux);
Hongguang4092f2f2021-07-08 18:49:12 -070075 ~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;
Ray Chin62ab6c92022-09-15 15:07:33 +080086 ::ndk::ScopedAStatus setStatusCheckIntervalHint(int64_t in_milliseconds) override;
Hongguang4092f2f2021-07-08 18:49:12 -070087
Hongguang2ecfc392021-11-23 10:29:15 -080088 binder_status_t dump(int fd, const char** args, uint32_t numArgs) override;
89
Hongguang4092f2f2021-07-08 18:49:12 -070090 /**
91 * To create a DvrMQ and its Event Flag.
92 *
93 * Return false is any of the above processes fails.
94 */
95 bool createDvrMQ();
sadiqsada56c98292023-11-02 16:45:31 -070096 int writePlaybackFMQ(void* buf, size_t size);
Hongguang4092f2f2021-07-08 18:49:12 -070097 bool writeRecordFMQ(const std::vector<int8_t>& data);
sadiqsada52b7f342023-10-31 15:01:02 -070098 bool addPlaybackFilter(int64_t filterId, std::shared_ptr<Filter> filter);
Hongguang4092f2f2021-07-08 18:49:12 -070099 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();
104 DvrSettings getSettings() { return mDvrSettings; }
105
106 private:
107 // Demux service
Hongguang Chenff2c6b02021-08-07 00:12:26 +0000108 std::shared_ptr<Demux> mDemux;
Hongguang4092f2f2021-07-08 18:49:12 -0700109
110 DvrType mType;
111 uint32_t mBufferSize;
112 std::shared_ptr<IDvrCallback> mCallback;
sadiqsada52b7f342023-10-31 15:01:02 -0700113 std::map<int64_t, std::shared_ptr<Filter>> mFilters;
Hongguang4092f2f2021-07-08 18:49:12 -0700114
115 void deleteEventFlag();
116 bool readDataFromMQ();
117 void getMetaDataValue(int& index, int8_t* dataOutputBuffer, int& value);
118 void maySendPlaybackStatusCallback();
sadiqsada56c98292023-11-02 16:45:31 -0700119 void maySendIptvPlaybackStatusCallback();
Hongguang4092f2f2021-07-08 18:49:12 -0700120 void maySendRecordStatusCallback();
121 PlaybackStatus checkPlaybackStatusChange(uint32_t availableToWrite, uint32_t availableToRead,
Hongguang11da2cb2021-08-05 19:05:12 -0700122 int64_t highThreshold, int64_t lowThreshold);
Hongguang4092f2f2021-07-08 18:49:12 -0700123 RecordStatus checkRecordStatusChange(uint32_t availableToWrite, uint32_t availableToRead,
Hongguang11da2cb2021-08-05 19:05:12 -0700124 int64_t highThreshold, int64_t lowThreshold);
Hongguang4092f2f2021-07-08 18:49:12 -0700125 /**
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);
Hongguang4092f2f2021-07-08 18:49:12 -0700130 void playbackThreadLoop();
Hongguang4092f2f2021-07-08 18:49:12 -0700131
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
Hongguange423acd2021-07-27 16:56:47 -0700141 std::thread mDvrThread;
Hongguang4092f2f2021-07-08 18:49:12 -0700142
143 // FMQ status local records
144 PlaybackStatus mPlaybackStatus;
145 RecordStatus mRecordStatus;
146 /**
147 * If a specific filter's writing loop is still running
148 */
Hongguange423acd2021-07-27 16:56:47 -0700149 std::atomic<bool> mDvrThreadRunning;
Hongguang901aa7b2021-08-26 12:20:56 -0700150
Hongguang4092f2f2021-07-08 18:49:12 -0700151 /**
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;
Hongguang4092f2f2021-07-08 18:49:12 -0700160
161 const bool DEBUG_DVR = false;
Hongguang4092f2f2021-07-08 18:49:12 -0700162};
163
164} // namespace tuner
165} // namespace tv
166} // namespace hardware
167} // namespace android
168} // namespace aidl