xref: /aosp_15_r20/hardware/interfaces/tv/tuner/1.1/default/Demux.cpp (revision 4d7e907c777eeecc4c5bd7cf640a754fac206ff7)
1*4d7e907cSAndroid Build Coastguard Worker /*
2*4d7e907cSAndroid Build Coastguard Worker  * Copyright 2020 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 #define LOG_TAG "[email protected]"
18*4d7e907cSAndroid Build Coastguard Worker 
19*4d7e907cSAndroid Build Coastguard Worker #include "Demux.h"
20*4d7e907cSAndroid Build Coastguard Worker #include <utils/Log.h>
21*4d7e907cSAndroid Build Coastguard Worker 
22*4d7e907cSAndroid Build Coastguard Worker namespace android {
23*4d7e907cSAndroid Build Coastguard Worker namespace hardware {
24*4d7e907cSAndroid Build Coastguard Worker namespace tv {
25*4d7e907cSAndroid Build Coastguard Worker namespace tuner {
26*4d7e907cSAndroid Build Coastguard Worker namespace V1_0 {
27*4d7e907cSAndroid Build Coastguard Worker namespace implementation {
28*4d7e907cSAndroid Build Coastguard Worker 
29*4d7e907cSAndroid Build Coastguard Worker #define WAIT_TIMEOUT 3000000000
30*4d7e907cSAndroid Build Coastguard Worker 
Demux(uint32_t demuxId,sp<Tuner> tuner)31*4d7e907cSAndroid Build Coastguard Worker Demux::Demux(uint32_t demuxId, sp<Tuner> tuner) {
32*4d7e907cSAndroid Build Coastguard Worker     mDemuxId = demuxId;
33*4d7e907cSAndroid Build Coastguard Worker     mTunerService = tuner;
34*4d7e907cSAndroid Build Coastguard Worker }
35*4d7e907cSAndroid Build Coastguard Worker 
~Demux()36*4d7e907cSAndroid Build Coastguard Worker Demux::~Demux() {
37*4d7e907cSAndroid Build Coastguard Worker     mFrontendInputThreadRunning = false;
38*4d7e907cSAndroid Build Coastguard Worker     std::lock_guard<std::mutex> lock(mFrontendInputThreadLock);
39*4d7e907cSAndroid Build Coastguard Worker }
40*4d7e907cSAndroid Build Coastguard Worker 
setFrontendDataSource(uint32_t frontendId)41*4d7e907cSAndroid Build Coastguard Worker Return<Result> Demux::setFrontendDataSource(uint32_t frontendId) {
42*4d7e907cSAndroid Build Coastguard Worker     ALOGV("%s", __FUNCTION__);
43*4d7e907cSAndroid Build Coastguard Worker 
44*4d7e907cSAndroid Build Coastguard Worker     if (mTunerService == nullptr) {
45*4d7e907cSAndroid Build Coastguard Worker         return Result::NOT_INITIALIZED;
46*4d7e907cSAndroid Build Coastguard Worker     }
47*4d7e907cSAndroid Build Coastguard Worker 
48*4d7e907cSAndroid Build Coastguard Worker     mFrontend = mTunerService->getFrontendById(frontendId);
49*4d7e907cSAndroid Build Coastguard Worker 
50*4d7e907cSAndroid Build Coastguard Worker     if (mFrontend == nullptr) {
51*4d7e907cSAndroid Build Coastguard Worker         return Result::INVALID_STATE;
52*4d7e907cSAndroid Build Coastguard Worker     }
53*4d7e907cSAndroid Build Coastguard Worker 
54*4d7e907cSAndroid Build Coastguard Worker     mTunerService->setFrontendAsDemuxSource(frontendId, mDemuxId);
55*4d7e907cSAndroid Build Coastguard Worker 
56*4d7e907cSAndroid Build Coastguard Worker     return Result::SUCCESS;
57*4d7e907cSAndroid Build Coastguard Worker }
58*4d7e907cSAndroid Build Coastguard Worker 
openFilter(const DemuxFilterType & type,uint32_t bufferSize,const sp<IFilterCallback> & cb,openFilter_cb _hidl_cb)59*4d7e907cSAndroid Build Coastguard Worker Return<void> Demux::openFilter(const DemuxFilterType& type, uint32_t bufferSize,
60*4d7e907cSAndroid Build Coastguard Worker                                const sp<IFilterCallback>& cb, openFilter_cb _hidl_cb) {
61*4d7e907cSAndroid Build Coastguard Worker     ALOGV("%s", __FUNCTION__);
62*4d7e907cSAndroid Build Coastguard Worker 
63*4d7e907cSAndroid Build Coastguard Worker     uint64_t filterId;
64*4d7e907cSAndroid Build Coastguard Worker     filterId = ++mLastUsedFilterId;
65*4d7e907cSAndroid Build Coastguard Worker 
66*4d7e907cSAndroid Build Coastguard Worker     if (cb == nullptr) {
67*4d7e907cSAndroid Build Coastguard Worker         ALOGW("[Demux] callback can't be null");
68*4d7e907cSAndroid Build Coastguard Worker         _hidl_cb(Result::INVALID_ARGUMENT, new Filter());
69*4d7e907cSAndroid Build Coastguard Worker         return Void();
70*4d7e907cSAndroid Build Coastguard Worker     }
71*4d7e907cSAndroid Build Coastguard Worker 
72*4d7e907cSAndroid Build Coastguard Worker     sp<Filter> filter = new Filter(type, filterId, bufferSize, cb, this);
73*4d7e907cSAndroid Build Coastguard Worker 
74*4d7e907cSAndroid Build Coastguard Worker     if (!filter->createFilterMQ()) {
75*4d7e907cSAndroid Build Coastguard Worker         _hidl_cb(Result::UNKNOWN_ERROR, filter);
76*4d7e907cSAndroid Build Coastguard Worker         return Void();
77*4d7e907cSAndroid Build Coastguard Worker     }
78*4d7e907cSAndroid Build Coastguard Worker 
79*4d7e907cSAndroid Build Coastguard Worker     mFilters[filterId] = filter;
80*4d7e907cSAndroid Build Coastguard Worker     if (filter->isPcrFilter()) {
81*4d7e907cSAndroid Build Coastguard Worker         mPcrFilterIds.insert(filterId);
82*4d7e907cSAndroid Build Coastguard Worker     }
83*4d7e907cSAndroid Build Coastguard Worker     bool result = true;
84*4d7e907cSAndroid Build Coastguard Worker     if (!filter->isRecordFilter()) {
85*4d7e907cSAndroid Build Coastguard Worker         // Only save non-record filters for now. Record filters are saved when the
86*4d7e907cSAndroid Build Coastguard Worker         // IDvr.attacheFilter is called.
87*4d7e907cSAndroid Build Coastguard Worker         mPlaybackFilterIds.insert(filterId);
88*4d7e907cSAndroid Build Coastguard Worker         if (mDvrPlayback != nullptr) {
89*4d7e907cSAndroid Build Coastguard Worker             result = mDvrPlayback->addPlaybackFilter(filterId, filter);
90*4d7e907cSAndroid Build Coastguard Worker         }
91*4d7e907cSAndroid Build Coastguard Worker     }
92*4d7e907cSAndroid Build Coastguard Worker 
93*4d7e907cSAndroid Build Coastguard Worker     _hidl_cb(result ? Result::SUCCESS : Result::INVALID_ARGUMENT, filter);
94*4d7e907cSAndroid Build Coastguard Worker     return Void();
95*4d7e907cSAndroid Build Coastguard Worker }
96*4d7e907cSAndroid Build Coastguard Worker 
openTimeFilter(openTimeFilter_cb _hidl_cb)97*4d7e907cSAndroid Build Coastguard Worker Return<void> Demux::openTimeFilter(openTimeFilter_cb _hidl_cb) {
98*4d7e907cSAndroid Build Coastguard Worker     ALOGV("%s", __FUNCTION__);
99*4d7e907cSAndroid Build Coastguard Worker 
100*4d7e907cSAndroid Build Coastguard Worker     mTimeFilter = new TimeFilter(this);
101*4d7e907cSAndroid Build Coastguard Worker 
102*4d7e907cSAndroid Build Coastguard Worker     _hidl_cb(Result::SUCCESS, mTimeFilter);
103*4d7e907cSAndroid Build Coastguard Worker     return Void();
104*4d7e907cSAndroid Build Coastguard Worker }
105*4d7e907cSAndroid Build Coastguard Worker 
getAvSyncHwId(const sp<IFilter> & filter,getAvSyncHwId_cb _hidl_cb)106*4d7e907cSAndroid Build Coastguard Worker Return<void> Demux::getAvSyncHwId(const sp<IFilter>& filter, getAvSyncHwId_cb _hidl_cb) {
107*4d7e907cSAndroid Build Coastguard Worker     ALOGV("%s", __FUNCTION__);
108*4d7e907cSAndroid Build Coastguard Worker 
109*4d7e907cSAndroid Build Coastguard Worker     uint32_t avSyncHwId = -1;
110*4d7e907cSAndroid Build Coastguard Worker     uint64_t id;
111*4d7e907cSAndroid Build Coastguard Worker     Result status;
112*4d7e907cSAndroid Build Coastguard Worker 
113*4d7e907cSAndroid Build Coastguard Worker     sp<V1_1::IFilter> filter_v1_1 = V1_1::IFilter::castFrom(filter);
114*4d7e907cSAndroid Build Coastguard Worker     if (filter_v1_1 != NULL) {
115*4d7e907cSAndroid Build Coastguard Worker         filter_v1_1->getId64Bit([&](Result result, uint64_t filterId) {
116*4d7e907cSAndroid Build Coastguard Worker             id = filterId;
117*4d7e907cSAndroid Build Coastguard Worker             status = result;
118*4d7e907cSAndroid Build Coastguard Worker         });
119*4d7e907cSAndroid Build Coastguard Worker     } else {
120*4d7e907cSAndroid Build Coastguard Worker         filter->getId([&](Result result, uint32_t filterId) {
121*4d7e907cSAndroid Build Coastguard Worker             id = filterId;
122*4d7e907cSAndroid Build Coastguard Worker             status = result;
123*4d7e907cSAndroid Build Coastguard Worker         });
124*4d7e907cSAndroid Build Coastguard Worker     }
125*4d7e907cSAndroid Build Coastguard Worker 
126*4d7e907cSAndroid Build Coastguard Worker     if (status != Result::SUCCESS) {
127*4d7e907cSAndroid Build Coastguard Worker         ALOGE("[Demux] Can't get filter Id.");
128*4d7e907cSAndroid Build Coastguard Worker         _hidl_cb(Result::INVALID_STATE, avSyncHwId);
129*4d7e907cSAndroid Build Coastguard Worker         return Void();
130*4d7e907cSAndroid Build Coastguard Worker     }
131*4d7e907cSAndroid Build Coastguard Worker 
132*4d7e907cSAndroid Build Coastguard Worker     if (!mFilters[id]->isMediaFilter()) {
133*4d7e907cSAndroid Build Coastguard Worker         ALOGE("[Demux] Given filter is not a media filter.");
134*4d7e907cSAndroid Build Coastguard Worker         _hidl_cb(Result::INVALID_ARGUMENT, avSyncHwId);
135*4d7e907cSAndroid Build Coastguard Worker         return Void();
136*4d7e907cSAndroid Build Coastguard Worker     }
137*4d7e907cSAndroid Build Coastguard Worker 
138*4d7e907cSAndroid Build Coastguard Worker     if (!mPcrFilterIds.empty()) {
139*4d7e907cSAndroid Build Coastguard Worker         // Return the lowest pcr filter id in the default implementation as the av sync id
140*4d7e907cSAndroid Build Coastguard Worker         _hidl_cb(Result::SUCCESS, *mPcrFilterIds.begin());
141*4d7e907cSAndroid Build Coastguard Worker         return Void();
142*4d7e907cSAndroid Build Coastguard Worker     }
143*4d7e907cSAndroid Build Coastguard Worker 
144*4d7e907cSAndroid Build Coastguard Worker     ALOGE("[Demux] No PCR filter opened.");
145*4d7e907cSAndroid Build Coastguard Worker     _hidl_cb(Result::INVALID_STATE, avSyncHwId);
146*4d7e907cSAndroid Build Coastguard Worker     return Void();
147*4d7e907cSAndroid Build Coastguard Worker }
148*4d7e907cSAndroid Build Coastguard Worker 
getAvSyncTime(AvSyncHwId avSyncHwId,getAvSyncTime_cb _hidl_cb)149*4d7e907cSAndroid Build Coastguard Worker Return<void> Demux::getAvSyncTime(AvSyncHwId avSyncHwId, getAvSyncTime_cb _hidl_cb) {
150*4d7e907cSAndroid Build Coastguard Worker     ALOGV("%s", __FUNCTION__);
151*4d7e907cSAndroid Build Coastguard Worker 
152*4d7e907cSAndroid Build Coastguard Worker     uint64_t avSyncTime = -1;
153*4d7e907cSAndroid Build Coastguard Worker     if (mPcrFilterIds.empty()) {
154*4d7e907cSAndroid Build Coastguard Worker         _hidl_cb(Result::INVALID_STATE, avSyncTime);
155*4d7e907cSAndroid Build Coastguard Worker         return Void();
156*4d7e907cSAndroid Build Coastguard Worker     }
157*4d7e907cSAndroid Build Coastguard Worker     if (avSyncHwId != *mPcrFilterIds.begin()) {
158*4d7e907cSAndroid Build Coastguard Worker         _hidl_cb(Result::INVALID_ARGUMENT, avSyncTime);
159*4d7e907cSAndroid Build Coastguard Worker         return Void();
160*4d7e907cSAndroid Build Coastguard Worker     }
161*4d7e907cSAndroid Build Coastguard Worker 
162*4d7e907cSAndroid Build Coastguard Worker     _hidl_cb(Result::SUCCESS, avSyncTime);
163*4d7e907cSAndroid Build Coastguard Worker     return Void();
164*4d7e907cSAndroid Build Coastguard Worker }
165*4d7e907cSAndroid Build Coastguard Worker 
close()166*4d7e907cSAndroid Build Coastguard Worker Return<Result> Demux::close() {
167*4d7e907cSAndroid Build Coastguard Worker     ALOGV("%s", __FUNCTION__);
168*4d7e907cSAndroid Build Coastguard Worker 
169*4d7e907cSAndroid Build Coastguard Worker     set<uint64_t>::iterator it;
170*4d7e907cSAndroid Build Coastguard Worker     for (it = mPlaybackFilterIds.begin(); it != mPlaybackFilterIds.end(); it++) {
171*4d7e907cSAndroid Build Coastguard Worker         mDvrPlayback->removePlaybackFilter(*it);
172*4d7e907cSAndroid Build Coastguard Worker     }
173*4d7e907cSAndroid Build Coastguard Worker     mPlaybackFilterIds.clear();
174*4d7e907cSAndroid Build Coastguard Worker     mRecordFilterIds.clear();
175*4d7e907cSAndroid Build Coastguard Worker     mFilters.clear();
176*4d7e907cSAndroid Build Coastguard Worker     mLastUsedFilterId = -1;
177*4d7e907cSAndroid Build Coastguard Worker     mTunerService->removeDemux(mDemuxId);
178*4d7e907cSAndroid Build Coastguard Worker     mFrontendInputThreadRunning = false;
179*4d7e907cSAndroid Build Coastguard Worker     std::lock_guard<std::mutex> lock(mFrontendInputThreadLock);
180*4d7e907cSAndroid Build Coastguard Worker 
181*4d7e907cSAndroid Build Coastguard Worker     return Result::SUCCESS;
182*4d7e907cSAndroid Build Coastguard Worker }
183*4d7e907cSAndroid Build Coastguard Worker 
openDvr(DvrType type,uint32_t bufferSize,const sp<IDvrCallback> & cb,openDvr_cb _hidl_cb)184*4d7e907cSAndroid Build Coastguard Worker Return<void> Demux::openDvr(DvrType type, uint32_t bufferSize, const sp<IDvrCallback>& cb,
185*4d7e907cSAndroid Build Coastguard Worker                             openDvr_cb _hidl_cb) {
186*4d7e907cSAndroid Build Coastguard Worker     ALOGV("%s", __FUNCTION__);
187*4d7e907cSAndroid Build Coastguard Worker 
188*4d7e907cSAndroid Build Coastguard Worker     if (cb == nullptr) {
189*4d7e907cSAndroid Build Coastguard Worker         ALOGW("[Demux] DVR callback can't be null");
190*4d7e907cSAndroid Build Coastguard Worker         _hidl_cb(Result::INVALID_ARGUMENT, new Dvr());
191*4d7e907cSAndroid Build Coastguard Worker         return Void();
192*4d7e907cSAndroid Build Coastguard Worker     }
193*4d7e907cSAndroid Build Coastguard Worker 
194*4d7e907cSAndroid Build Coastguard Worker     set<uint64_t>::iterator it;
195*4d7e907cSAndroid Build Coastguard Worker     switch (type) {
196*4d7e907cSAndroid Build Coastguard Worker         case DvrType::PLAYBACK:
197*4d7e907cSAndroid Build Coastguard Worker             mDvrPlayback = new Dvr(type, bufferSize, cb, this);
198*4d7e907cSAndroid Build Coastguard Worker             if (!mDvrPlayback->createDvrMQ()) {
199*4d7e907cSAndroid Build Coastguard Worker                 _hidl_cb(Result::UNKNOWN_ERROR, mDvrPlayback);
200*4d7e907cSAndroid Build Coastguard Worker                 return Void();
201*4d7e907cSAndroid Build Coastguard Worker             }
202*4d7e907cSAndroid Build Coastguard Worker 
203*4d7e907cSAndroid Build Coastguard Worker             for (it = mPlaybackFilterIds.begin(); it != mPlaybackFilterIds.end(); it++) {
204*4d7e907cSAndroid Build Coastguard Worker                 if (!mDvrPlayback->addPlaybackFilter(*it, mFilters[*it])) {
205*4d7e907cSAndroid Build Coastguard Worker                     ALOGE("[Demux] Can't get filter info for DVR playback");
206*4d7e907cSAndroid Build Coastguard Worker                     _hidl_cb(Result::UNKNOWN_ERROR, mDvrPlayback);
207*4d7e907cSAndroid Build Coastguard Worker                     return Void();
208*4d7e907cSAndroid Build Coastguard Worker                 }
209*4d7e907cSAndroid Build Coastguard Worker             }
210*4d7e907cSAndroid Build Coastguard Worker 
211*4d7e907cSAndroid Build Coastguard Worker             _hidl_cb(Result::SUCCESS, mDvrPlayback);
212*4d7e907cSAndroid Build Coastguard Worker             return Void();
213*4d7e907cSAndroid Build Coastguard Worker         case DvrType::RECORD:
214*4d7e907cSAndroid Build Coastguard Worker             mDvrRecord = new Dvr(type, bufferSize, cb, this);
215*4d7e907cSAndroid Build Coastguard Worker             if (!mDvrRecord->createDvrMQ()) {
216*4d7e907cSAndroid Build Coastguard Worker                 _hidl_cb(Result::UNKNOWN_ERROR, mDvrRecord);
217*4d7e907cSAndroid Build Coastguard Worker                 return Void();
218*4d7e907cSAndroid Build Coastguard Worker             }
219*4d7e907cSAndroid Build Coastguard Worker 
220*4d7e907cSAndroid Build Coastguard Worker             _hidl_cb(Result::SUCCESS, mDvrRecord);
221*4d7e907cSAndroid Build Coastguard Worker             return Void();
222*4d7e907cSAndroid Build Coastguard Worker         default:
223*4d7e907cSAndroid Build Coastguard Worker             _hidl_cb(Result::INVALID_ARGUMENT, nullptr);
224*4d7e907cSAndroid Build Coastguard Worker             return Void();
225*4d7e907cSAndroid Build Coastguard Worker     }
226*4d7e907cSAndroid Build Coastguard Worker }
227*4d7e907cSAndroid Build Coastguard Worker 
connectCiCam(uint32_t ciCamId)228*4d7e907cSAndroid Build Coastguard Worker Return<Result> Demux::connectCiCam(uint32_t ciCamId) {
229*4d7e907cSAndroid Build Coastguard Worker     ALOGV("%s", __FUNCTION__);
230*4d7e907cSAndroid Build Coastguard Worker 
231*4d7e907cSAndroid Build Coastguard Worker     mCiCamId = ciCamId;
232*4d7e907cSAndroid Build Coastguard Worker 
233*4d7e907cSAndroid Build Coastguard Worker     return Result::SUCCESS;
234*4d7e907cSAndroid Build Coastguard Worker }
235*4d7e907cSAndroid Build Coastguard Worker 
disconnectCiCam()236*4d7e907cSAndroid Build Coastguard Worker Return<Result> Demux::disconnectCiCam() {
237*4d7e907cSAndroid Build Coastguard Worker     ALOGV("%s", __FUNCTION__);
238*4d7e907cSAndroid Build Coastguard Worker 
239*4d7e907cSAndroid Build Coastguard Worker     return Result::SUCCESS;
240*4d7e907cSAndroid Build Coastguard Worker }
241*4d7e907cSAndroid Build Coastguard Worker 
removeFilter(uint64_t filterId)242*4d7e907cSAndroid Build Coastguard Worker Result Demux::removeFilter(uint64_t filterId) {
243*4d7e907cSAndroid Build Coastguard Worker     ALOGV("%s", __FUNCTION__);
244*4d7e907cSAndroid Build Coastguard Worker 
245*4d7e907cSAndroid Build Coastguard Worker     if (mDvrPlayback != nullptr) {
246*4d7e907cSAndroid Build Coastguard Worker         mDvrPlayback->removePlaybackFilter(filterId);
247*4d7e907cSAndroid Build Coastguard Worker     }
248*4d7e907cSAndroid Build Coastguard Worker     mPlaybackFilterIds.erase(filterId);
249*4d7e907cSAndroid Build Coastguard Worker     mRecordFilterIds.erase(filterId);
250*4d7e907cSAndroid Build Coastguard Worker     mFilters.erase(filterId);
251*4d7e907cSAndroid Build Coastguard Worker 
252*4d7e907cSAndroid Build Coastguard Worker     return Result::SUCCESS;
253*4d7e907cSAndroid Build Coastguard Worker }
254*4d7e907cSAndroid Build Coastguard Worker 
startBroadcastTsFilter(vector<uint8_t> data)255*4d7e907cSAndroid Build Coastguard Worker void Demux::startBroadcastTsFilter(vector<uint8_t> data) {
256*4d7e907cSAndroid Build Coastguard Worker     set<uint64_t>::iterator it;
257*4d7e907cSAndroid Build Coastguard Worker     uint16_t pid = ((data[1] & 0x1f) << 8) | ((data[2] & 0xff));
258*4d7e907cSAndroid Build Coastguard Worker     if (DEBUG_DEMUX) {
259*4d7e907cSAndroid Build Coastguard Worker         ALOGW("[Demux] start ts filter pid: %d", pid);
260*4d7e907cSAndroid Build Coastguard Worker     }
261*4d7e907cSAndroid Build Coastguard Worker     for (it = mPlaybackFilterIds.begin(); it != mPlaybackFilterIds.end(); it++) {
262*4d7e907cSAndroid Build Coastguard Worker         if (pid == mFilters[*it]->getTpid()) {
263*4d7e907cSAndroid Build Coastguard Worker             mFilters[*it]->updateFilterOutput(data);
264*4d7e907cSAndroid Build Coastguard Worker         }
265*4d7e907cSAndroid Build Coastguard Worker     }
266*4d7e907cSAndroid Build Coastguard Worker }
267*4d7e907cSAndroid Build Coastguard Worker 
sendFrontendInputToRecord(vector<uint8_t> data)268*4d7e907cSAndroid Build Coastguard Worker void Demux::sendFrontendInputToRecord(vector<uint8_t> data) {
269*4d7e907cSAndroid Build Coastguard Worker     set<uint64_t>::iterator it;
270*4d7e907cSAndroid Build Coastguard Worker     if (DEBUG_DEMUX) {
271*4d7e907cSAndroid Build Coastguard Worker         ALOGW("[Demux] update record filter output");
272*4d7e907cSAndroid Build Coastguard Worker     }
273*4d7e907cSAndroid Build Coastguard Worker     for (it = mRecordFilterIds.begin(); it != mRecordFilterIds.end(); it++) {
274*4d7e907cSAndroid Build Coastguard Worker         mFilters[*it]->updateRecordOutput(data);
275*4d7e907cSAndroid Build Coastguard Worker     }
276*4d7e907cSAndroid Build Coastguard Worker }
277*4d7e907cSAndroid Build Coastguard Worker 
sendFrontendInputToRecord(vector<uint8_t> data,uint16_t pid,uint64_t pts)278*4d7e907cSAndroid Build Coastguard Worker void Demux::sendFrontendInputToRecord(vector<uint8_t> data, uint16_t pid, uint64_t pts) {
279*4d7e907cSAndroid Build Coastguard Worker     sendFrontendInputToRecord(data);
280*4d7e907cSAndroid Build Coastguard Worker     set<uint64_t>::iterator it;
281*4d7e907cSAndroid Build Coastguard Worker     for (it = mRecordFilterIds.begin(); it != mRecordFilterIds.end(); it++) {
282*4d7e907cSAndroid Build Coastguard Worker         if (pid == mFilters[*it]->getTpid()) {
283*4d7e907cSAndroid Build Coastguard Worker             mFilters[*it]->updatePts(pts);
284*4d7e907cSAndroid Build Coastguard Worker         }
285*4d7e907cSAndroid Build Coastguard Worker     }
286*4d7e907cSAndroid Build Coastguard Worker }
287*4d7e907cSAndroid Build Coastguard Worker 
startBroadcastFilterDispatcher()288*4d7e907cSAndroid Build Coastguard Worker bool Demux::startBroadcastFilterDispatcher() {
289*4d7e907cSAndroid Build Coastguard Worker     set<uint64_t>::iterator it;
290*4d7e907cSAndroid Build Coastguard Worker 
291*4d7e907cSAndroid Build Coastguard Worker     // Handle the output data per filter type
292*4d7e907cSAndroid Build Coastguard Worker     for (it = mPlaybackFilterIds.begin(); it != mPlaybackFilterIds.end(); it++) {
293*4d7e907cSAndroid Build Coastguard Worker         if (mFilters[*it]->startFilterHandler() != Result::SUCCESS) {
294*4d7e907cSAndroid Build Coastguard Worker             return false;
295*4d7e907cSAndroid Build Coastguard Worker         }
296*4d7e907cSAndroid Build Coastguard Worker     }
297*4d7e907cSAndroid Build Coastguard Worker 
298*4d7e907cSAndroid Build Coastguard Worker     return true;
299*4d7e907cSAndroid Build Coastguard Worker }
300*4d7e907cSAndroid Build Coastguard Worker 
startRecordFilterDispatcher()301*4d7e907cSAndroid Build Coastguard Worker bool Demux::startRecordFilterDispatcher() {
302*4d7e907cSAndroid Build Coastguard Worker     set<uint64_t>::iterator it;
303*4d7e907cSAndroid Build Coastguard Worker 
304*4d7e907cSAndroid Build Coastguard Worker     for (it = mRecordFilterIds.begin(); it != mRecordFilterIds.end(); it++) {
305*4d7e907cSAndroid Build Coastguard Worker         if (mFilters[*it]->startRecordFilterHandler() != Result::SUCCESS) {
306*4d7e907cSAndroid Build Coastguard Worker             return false;
307*4d7e907cSAndroid Build Coastguard Worker         }
308*4d7e907cSAndroid Build Coastguard Worker     }
309*4d7e907cSAndroid Build Coastguard Worker 
310*4d7e907cSAndroid Build Coastguard Worker     return true;
311*4d7e907cSAndroid Build Coastguard Worker }
312*4d7e907cSAndroid Build Coastguard Worker 
startFilterHandler(uint64_t filterId)313*4d7e907cSAndroid Build Coastguard Worker Result Demux::startFilterHandler(uint64_t filterId) {
314*4d7e907cSAndroid Build Coastguard Worker     return mFilters[filterId]->startFilterHandler();
315*4d7e907cSAndroid Build Coastguard Worker }
316*4d7e907cSAndroid Build Coastguard Worker 
updateFilterOutput(uint64_t filterId,vector<uint8_t> data)317*4d7e907cSAndroid Build Coastguard Worker void Demux::updateFilterOutput(uint64_t filterId, vector<uint8_t> data) {
318*4d7e907cSAndroid Build Coastguard Worker     mFilters[filterId]->updateFilterOutput(data);
319*4d7e907cSAndroid Build Coastguard Worker }
320*4d7e907cSAndroid Build Coastguard Worker 
updateMediaFilterOutput(uint64_t filterId,vector<uint8_t> data,uint64_t pts)321*4d7e907cSAndroid Build Coastguard Worker void Demux::updateMediaFilterOutput(uint64_t filterId, vector<uint8_t> data, uint64_t pts) {
322*4d7e907cSAndroid Build Coastguard Worker     updateFilterOutput(filterId, data);
323*4d7e907cSAndroid Build Coastguard Worker     mFilters[filterId]->updatePts(pts);
324*4d7e907cSAndroid Build Coastguard Worker }
325*4d7e907cSAndroid Build Coastguard Worker 
getFilterTpid(uint64_t filterId)326*4d7e907cSAndroid Build Coastguard Worker uint16_t Demux::getFilterTpid(uint64_t filterId) {
327*4d7e907cSAndroid Build Coastguard Worker     return mFilters[filterId]->getTpid();
328*4d7e907cSAndroid Build Coastguard Worker }
329*4d7e907cSAndroid Build Coastguard Worker 
startFrontendInputLoop()330*4d7e907cSAndroid Build Coastguard Worker void Demux::startFrontendInputLoop() {
331*4d7e907cSAndroid Build Coastguard Worker     mFrontendInputThreadRunning = true;
332*4d7e907cSAndroid Build Coastguard Worker     pthread_create(&mFrontendInputThread, NULL, __threadLoopFrontend, this);
333*4d7e907cSAndroid Build Coastguard Worker     pthread_setname_np(mFrontendInputThread, "frontend_input_thread");
334*4d7e907cSAndroid Build Coastguard Worker }
335*4d7e907cSAndroid Build Coastguard Worker 
__threadLoopFrontend(void * user)336*4d7e907cSAndroid Build Coastguard Worker void* Demux::__threadLoopFrontend(void* user) {
337*4d7e907cSAndroid Build Coastguard Worker     Demux* const self = static_cast<Demux*>(user);
338*4d7e907cSAndroid Build Coastguard Worker     self->frontendInputThreadLoop();
339*4d7e907cSAndroid Build Coastguard Worker     return 0;
340*4d7e907cSAndroid Build Coastguard Worker }
341*4d7e907cSAndroid Build Coastguard Worker 
frontendInputThreadLoop()342*4d7e907cSAndroid Build Coastguard Worker void Demux::frontendInputThreadLoop() {
343*4d7e907cSAndroid Build Coastguard Worker     if (!mFrontendInputThreadRunning) {
344*4d7e907cSAndroid Build Coastguard Worker         return;
345*4d7e907cSAndroid Build Coastguard Worker     }
346*4d7e907cSAndroid Build Coastguard Worker 
347*4d7e907cSAndroid Build Coastguard Worker     std::lock_guard<std::mutex> lock(mFrontendInputThreadLock);
348*4d7e907cSAndroid Build Coastguard Worker     if (!mDvrPlayback) {
349*4d7e907cSAndroid Build Coastguard Worker         ALOGW("[Demux] No software Frontend input configured. Ending Frontend thread loop.");
350*4d7e907cSAndroid Build Coastguard Worker         mFrontendInputThreadRunning = false;
351*4d7e907cSAndroid Build Coastguard Worker         return;
352*4d7e907cSAndroid Build Coastguard Worker     }
353*4d7e907cSAndroid Build Coastguard Worker 
354*4d7e907cSAndroid Build Coastguard Worker     while (mFrontendInputThreadRunning) {
355*4d7e907cSAndroid Build Coastguard Worker         uint32_t efState = 0;
356*4d7e907cSAndroid Build Coastguard Worker         status_t status = mDvrPlayback->getDvrEventFlag()->wait(
357*4d7e907cSAndroid Build Coastguard Worker                 static_cast<uint32_t>(DemuxQueueNotifyBits::DATA_READY), &efState, WAIT_TIMEOUT,
358*4d7e907cSAndroid Build Coastguard Worker                 true /* retry on spurious wake */);
359*4d7e907cSAndroid Build Coastguard Worker         if (status != OK) {
360*4d7e907cSAndroid Build Coastguard Worker             ALOGD("[Demux] wait for data ready on the playback FMQ");
361*4d7e907cSAndroid Build Coastguard Worker             continue;
362*4d7e907cSAndroid Build Coastguard Worker         }
363*4d7e907cSAndroid Build Coastguard Worker         if (mDvrPlayback->getSettings().playback().dataFormat == DataFormat::ES) {
364*4d7e907cSAndroid Build Coastguard Worker             if (!mDvrPlayback->processEsDataOnPlayback(true /*isVirtualFrontend*/, mIsRecording)) {
365*4d7e907cSAndroid Build Coastguard Worker                 ALOGE("[Demux] playback es data failed to be filtered. Ending thread");
366*4d7e907cSAndroid Build Coastguard Worker                 break;
367*4d7e907cSAndroid Build Coastguard Worker             }
368*4d7e907cSAndroid Build Coastguard Worker             continue;
369*4d7e907cSAndroid Build Coastguard Worker         }
370*4d7e907cSAndroid Build Coastguard Worker         // Our current implementation filter the data and write it into the filter FMQ immediately
371*4d7e907cSAndroid Build Coastguard Worker         // after the DATA_READY from the VTS/framework
372*4d7e907cSAndroid Build Coastguard Worker         // This is for the non-ES data source, real playback use case handling.
373*4d7e907cSAndroid Build Coastguard Worker         if (!mDvrPlayback->readPlaybackFMQ(true /*isVirtualFrontend*/, mIsRecording) ||
374*4d7e907cSAndroid Build Coastguard Worker             !mDvrPlayback->startFilterDispatcher(true /*isVirtualFrontend*/, mIsRecording)) {
375*4d7e907cSAndroid Build Coastguard Worker             ALOGE("[Demux] playback data failed to be filtered. Ending thread");
376*4d7e907cSAndroid Build Coastguard Worker             break;
377*4d7e907cSAndroid Build Coastguard Worker         }
378*4d7e907cSAndroid Build Coastguard Worker     }
379*4d7e907cSAndroid Build Coastguard Worker 
380*4d7e907cSAndroid Build Coastguard Worker     mFrontendInputThreadRunning = false;
381*4d7e907cSAndroid Build Coastguard Worker     ALOGW("[Demux] Frontend Input thread end.");
382*4d7e907cSAndroid Build Coastguard Worker }
383*4d7e907cSAndroid Build Coastguard Worker 
stopFrontendInput()384*4d7e907cSAndroid Build Coastguard Worker void Demux::stopFrontendInput() {
385*4d7e907cSAndroid Build Coastguard Worker     ALOGD("[Demux] stop frontend on demux");
386*4d7e907cSAndroid Build Coastguard Worker     mKeepFetchingDataFromFrontend = false;
387*4d7e907cSAndroid Build Coastguard Worker     mFrontendInputThreadRunning = false;
388*4d7e907cSAndroid Build Coastguard Worker     std::lock_guard<std::mutex> lock(mFrontendInputThreadLock);
389*4d7e907cSAndroid Build Coastguard Worker }
390*4d7e907cSAndroid Build Coastguard Worker 
setIsRecording(bool isRecording)391*4d7e907cSAndroid Build Coastguard Worker void Demux::setIsRecording(bool isRecording) {
392*4d7e907cSAndroid Build Coastguard Worker     mIsRecording = isRecording;
393*4d7e907cSAndroid Build Coastguard Worker }
394*4d7e907cSAndroid Build Coastguard Worker 
isRecording()395*4d7e907cSAndroid Build Coastguard Worker bool Demux::isRecording() {
396*4d7e907cSAndroid Build Coastguard Worker     return mIsRecording;
397*4d7e907cSAndroid Build Coastguard Worker }
398*4d7e907cSAndroid Build Coastguard Worker 
attachRecordFilter(uint64_t filterId)399*4d7e907cSAndroid Build Coastguard Worker bool Demux::attachRecordFilter(uint64_t filterId) {
400*4d7e907cSAndroid Build Coastguard Worker     if (mFilters[filterId] == nullptr || mDvrRecord == nullptr ||
401*4d7e907cSAndroid Build Coastguard Worker         !mFilters[filterId]->isRecordFilter()) {
402*4d7e907cSAndroid Build Coastguard Worker         return false;
403*4d7e907cSAndroid Build Coastguard Worker     }
404*4d7e907cSAndroid Build Coastguard Worker 
405*4d7e907cSAndroid Build Coastguard Worker     mRecordFilterIds.insert(filterId);
406*4d7e907cSAndroid Build Coastguard Worker     mFilters[filterId]->attachFilterToRecord(mDvrRecord);
407*4d7e907cSAndroid Build Coastguard Worker 
408*4d7e907cSAndroid Build Coastguard Worker     return true;
409*4d7e907cSAndroid Build Coastguard Worker }
410*4d7e907cSAndroid Build Coastguard Worker 
detachRecordFilter(uint64_t filterId)411*4d7e907cSAndroid Build Coastguard Worker bool Demux::detachRecordFilter(uint64_t filterId) {
412*4d7e907cSAndroid Build Coastguard Worker     if (mFilters[filterId] == nullptr || mDvrRecord == nullptr) {
413*4d7e907cSAndroid Build Coastguard Worker         return false;
414*4d7e907cSAndroid Build Coastguard Worker     }
415*4d7e907cSAndroid Build Coastguard Worker 
416*4d7e907cSAndroid Build Coastguard Worker     mRecordFilterIds.erase(filterId);
417*4d7e907cSAndroid Build Coastguard Worker     mFilters[filterId]->detachFilterFromRecord();
418*4d7e907cSAndroid Build Coastguard Worker 
419*4d7e907cSAndroid Build Coastguard Worker     return true;
420*4d7e907cSAndroid Build Coastguard Worker }
421*4d7e907cSAndroid Build Coastguard Worker 
422*4d7e907cSAndroid Build Coastguard Worker }  // namespace implementation
423*4d7e907cSAndroid Build Coastguard Worker }  // namespace V1_0
424*4d7e907cSAndroid Build Coastguard Worker }  // namespace tuner
425*4d7e907cSAndroid Build Coastguard Worker }  // namespace tv
426*4d7e907cSAndroid Build Coastguard Worker }  // namespace hardware
427*4d7e907cSAndroid Build Coastguard Worker }  // namespace android
428