1 /*
2  * Copyright 2020 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 #define LOG_TAG "android.hardware.tv.tuner@1.1-Filter"
18 
19 #include <BufferAllocator/BufferAllocator.h>
20 #include <utils/Log.h>
21 
22 #include "Filter.h"
23 
24 namespace android {
25 namespace hardware {
26 namespace tv {
27 namespace tuner {
28 namespace V1_0 {
29 namespace implementation {
30 
31 #define WAIT_TIMEOUT 3000000000
32 
Filter()33 Filter::Filter() {}
34 
Filter(DemuxFilterType type,uint64_t filterId,uint32_t bufferSize,const sp<IFilterCallback> & cb,sp<Demux> demux)35 Filter::Filter(DemuxFilterType type, uint64_t filterId, uint32_t bufferSize,
36                const sp<IFilterCallback>& cb, sp<Demux> demux) {
37     mType = type;
38     mFilterId = filterId;
39     mBufferSize = bufferSize;
40     mDemux = demux;
41 
42     switch (mType.mainType) {
43         case DemuxFilterMainType::TS:
44             if (mType.subType.tsFilterType() == DemuxTsFilterType::AUDIO ||
45                 mType.subType.tsFilterType() == DemuxTsFilterType::VIDEO) {
46                 mIsMediaFilter = true;
47             }
48             if (mType.subType.tsFilterType() == DemuxTsFilterType::PCR) {
49                 mIsPcrFilter = true;
50             }
51             if (mType.subType.tsFilterType() == DemuxTsFilterType::RECORD) {
52                 mIsRecordFilter = true;
53             }
54             break;
55         case DemuxFilterMainType::MMTP:
56             if (mType.subType.mmtpFilterType() == DemuxMmtpFilterType::AUDIO ||
57                 mType.subType.mmtpFilterType() == DemuxMmtpFilterType::VIDEO) {
58                 mIsMediaFilter = true;
59             }
60             if (mType.subType.mmtpFilterType() == DemuxMmtpFilterType::RECORD) {
61                 mIsRecordFilter = true;
62             }
63             break;
64         case DemuxFilterMainType::IP:
65             break;
66         case DemuxFilterMainType::TLV:
67             break;
68         case DemuxFilterMainType::ALP:
69             break;
70         default:
71             break;
72     }
73 
74     sp<V1_1::IFilterCallback> filterCallback_v1_1 = V1_1::IFilterCallback::castFrom(cb);
75     if (filterCallback_v1_1 != NULL) {
76         mCallback_1_1 = filterCallback_v1_1;
77     }
78     mCallback = cb;
79 }
80 
~Filter()81 Filter::~Filter() {
82     mFilterThreadRunning = false;
83     std::lock_guard<std::mutex> lock(mFilterThreadLock);
84 }
85 
getId64Bit(getId64Bit_cb _hidl_cb)86 Return<void> Filter::getId64Bit(getId64Bit_cb _hidl_cb) {
87     ALOGV("%s", __FUNCTION__);
88 
89     _hidl_cb(Result::SUCCESS, mFilterId);
90     return Void();
91 }
92 
getId(getId_cb _hidl_cb)93 Return<void> Filter::getId(getId_cb _hidl_cb) {
94     ALOGV("%s", __FUNCTION__);
95 
96     _hidl_cb(Result::SUCCESS, static_cast<uint32_t>(mFilterId));
97     return Void();
98 }
99 
setDataSource(const sp<V1_0::IFilter> & filter)100 Return<Result> Filter::setDataSource(const sp<V1_0::IFilter>& filter) {
101     ALOGV("%s", __FUNCTION__);
102 
103     mDataSource = filter;
104     mIsDataSourceDemux = false;
105 
106     return Result::SUCCESS;
107 }
108 
getQueueDesc(getQueueDesc_cb _hidl_cb)109 Return<void> Filter::getQueueDesc(getQueueDesc_cb _hidl_cb) {
110     ALOGV("%s", __FUNCTION__);
111 
112     mIsUsingFMQ = mIsRecordFilter ? false : true;
113 
114     _hidl_cb(Result::SUCCESS, *mFilterMQ->getDesc());
115     return Void();
116 }
117 
configure(const DemuxFilterSettings & settings)118 Return<Result> Filter::configure(const DemuxFilterSettings& settings) {
119     ALOGV("%s", __FUNCTION__);
120 
121     mFilterSettings = settings;
122     switch (mType.mainType) {
123         case DemuxFilterMainType::TS:
124             mTpid = settings.ts().tpid;
125             break;
126         case DemuxFilterMainType::MMTP:
127             break;
128         case DemuxFilterMainType::IP:
129             break;
130         case DemuxFilterMainType::TLV:
131             break;
132         case DemuxFilterMainType::ALP:
133             break;
134         default:
135             break;
136     }
137 
138     mConfigured = true;
139     return Result::SUCCESS;
140 }
141 
start()142 Return<Result> Filter::start() {
143     ALOGV("%s", __FUNCTION__);
144     mFilterThreadRunning = true;
145     // All the filter event callbacks in start are for testing purpose.
146     switch (mType.mainType) {
147         case DemuxFilterMainType::TS:
148             mCallback->onFilterEvent(createMediaEvent());
149             mCallback->onFilterEvent(createTsRecordEvent());
150             mCallback->onFilterEvent(createTemiEvent());
151             // clients could still pass 1.0 callback
152             if (mCallback_1_1 != NULL) {
153                 mCallback_1_1->onFilterEvent_1_1(createTsRecordEvent(), createTsRecordEventExt());
154             }
155             break;
156         case DemuxFilterMainType::MMTP:
157             mCallback->onFilterEvent(createDownloadEvent());
158             mCallback->onFilterEvent(createMmtpRecordEvent());
159             if (mCallback_1_1 != NULL) {
160                 mCallback_1_1->onFilterEvent_1_1(createMmtpRecordEvent(),
161                                                  createMmtpRecordEventExt());
162             }
163             break;
164         case DemuxFilterMainType::IP:
165             mCallback->onFilterEvent(createSectionEvent());
166             mCallback->onFilterEvent(createIpPayloadEvent());
167             break;
168         case DemuxFilterMainType::TLV: {
169             if (mCallback_1_1 != NULL) {
170                 DemuxFilterEvent emptyFilterEvent;
171                 mCallback_1_1->onFilterEvent_1_1(emptyFilterEvent, createMonitorEvent());
172             }
173             break;
174         }
175         case DemuxFilterMainType::ALP: {
176             if (mCallback_1_1 != NULL) {
177                 DemuxFilterEvent emptyFilterEvent;
178                 mCallback_1_1->onFilterEvent_1_1(emptyFilterEvent, createRestartEvent());
179             }
180             break;
181         }
182         default:
183             break;
184     }
185     return startFilterLoop();
186 }
187 
stop()188 Return<Result> Filter::stop() {
189     ALOGV("%s", __FUNCTION__);
190     mFilterThreadRunning = false;
191     std::lock_guard<std::mutex> lock(mFilterThreadLock);
192     return Result::SUCCESS;
193 }
194 
flush()195 Return<Result> Filter::flush() {
196     ALOGV("%s", __FUNCTION__);
197 
198     // temp implementation to flush the FMQ
199     int size = mFilterMQ->availableToRead();
200     char* buffer = new char[size];
201     mFilterMQ->read((unsigned char*)&buffer[0], size);
202     delete[] buffer;
203     mFilterStatus = DemuxFilterStatus::DATA_READY;
204 
205     return Result::SUCCESS;
206 }
207 
releaseAvHandle(const hidl_handle & avMemory,uint64_t avDataId)208 Return<Result> Filter::releaseAvHandle(const hidl_handle& avMemory, uint64_t avDataId) {
209     ALOGV("%s", __FUNCTION__);
210 
211     if (mSharedAvMemHandle != NULL && avMemory != NULL &&
212         (mSharedAvMemHandle.getNativeHandle()->numFds > 0) &&
213         (avMemory.getNativeHandle()->numFds > 0) &&
214         (sameFile(avMemory.getNativeHandle()->data[0],
215                   mSharedAvMemHandle.getNativeHandle()->data[0]))) {
216         freeSharedAvHandle();
217         return Result::SUCCESS;
218     }
219 
220     if (mDataId2Avfd.find(avDataId) == mDataId2Avfd.end()) {
221         return Result::INVALID_ARGUMENT;
222     }
223 
224     ::close(mDataId2Avfd[avDataId]);
225     return Result::SUCCESS;
226 }
227 
close()228 Return<Result> Filter::close() {
229     ALOGV("%s", __FUNCTION__);
230 
231     mFilterThreadRunning = false;
232     std::lock_guard<std::mutex> lock(mFilterThreadLock);
233     return mDemux->removeFilter(mFilterId);
234 }
235 
configureIpCid(uint32_t ipCid)236 Return<Result> Filter::configureIpCid(uint32_t ipCid) {
237     ALOGV("%s", __FUNCTION__);
238 
239     if (mType.mainType != DemuxFilterMainType::IP) {
240         return Result::INVALID_STATE;
241     }
242 
243     mCid = ipCid;
244     return Result::SUCCESS;
245 }
246 
getAvSharedHandle(getAvSharedHandle_cb _hidl_cb)247 Return<void> Filter::getAvSharedHandle(getAvSharedHandle_cb _hidl_cb) {
248     ALOGV("%s", __FUNCTION__);
249 
250     if (!mIsMediaFilter) {
251         _hidl_cb(Result::INVALID_STATE, NULL, BUFFER_SIZE_16M);
252         return Void();
253     }
254 
255     if (mSharedAvMemHandle.getNativeHandle() != nullptr) {
256         _hidl_cb(Result::SUCCESS, mSharedAvMemHandle, BUFFER_SIZE_16M);
257         mUsingSharedAvMem = true;
258         return Void();
259     }
260 
261     int av_fd = createAvIonFd(BUFFER_SIZE_16M);
262     if (av_fd == -1) {
263         _hidl_cb(Result::UNKNOWN_ERROR, NULL, 0);
264         return Void();
265     }
266 
267     native_handle_t* nativeHandle = createNativeHandle(av_fd);
268     if (nativeHandle == NULL) {
269         ::close(av_fd);
270         _hidl_cb(Result::UNKNOWN_ERROR, NULL, 0);
271         return Void();
272     }
273     mSharedAvMemHandle.setTo(nativeHandle, /*shouldOwn=*/true);
274     ::close(av_fd);
275 
276     _hidl_cb(Result::SUCCESS, mSharedAvMemHandle, BUFFER_SIZE_16M);
277     mUsingSharedAvMem = true;
278     return Void();
279 }
280 
configureAvStreamType(const V1_1::AvStreamType & avStreamType)281 Return<Result> Filter::configureAvStreamType(const V1_1::AvStreamType& avStreamType) {
282     ALOGV("%s", __FUNCTION__);
283 
284     if (!mIsMediaFilter) {
285         return Result::UNAVAILABLE;
286     }
287 
288     switch (avStreamType.getDiscriminator()) {
289         case V1_1::AvStreamType::hidl_discriminator::audio:
290             mAudioStreamType = static_cast<uint32_t>(avStreamType.audio());
291             break;
292         case V1_1::AvStreamType::hidl_discriminator::video:
293             mVideoStreamType = static_cast<uint32_t>(avStreamType.video());
294             break;
295         default:
296             break;
297     }
298 
299     return Result::SUCCESS;
300 }
301 
configureMonitorEvent(uint32_t monitorEventTypes)302 Return<Result> Filter::configureMonitorEvent(uint32_t monitorEventTypes) {
303     ALOGV("%s", __FUNCTION__);
304 
305     DemuxFilterEvent emptyFilterEvent;
306     V1_1::DemuxFilterMonitorEvent monitorEvent;
307     V1_1::DemuxFilterEventExt eventExt;
308 
309     uint32_t newScramblingStatus =
310             monitorEventTypes & V1_1::DemuxFilterMonitorEventType::SCRAMBLING_STATUS;
311     uint32_t newIpCid = monitorEventTypes & V1_1::DemuxFilterMonitorEventType::IP_CID_CHANGE;
312 
313     // if scrambling status monitoring flipped, record the new state and send msg on enabling
314     if (newScramblingStatus ^ mScramblingStatusMonitored) {
315         mScramblingStatusMonitored = newScramblingStatus;
316         if (mScramblingStatusMonitored) {
317             if (mCallback_1_1 != nullptr) {
318                 // Assuming current status is always NOT_SCRAMBLED
319                 monitorEvent.scramblingStatus(V1_1::ScramblingStatus::NOT_SCRAMBLED);
320                 eventExt.events.resize(1);
321                 eventExt.events[0].monitorEvent(monitorEvent);
322                 mCallback_1_1->onFilterEvent_1_1(emptyFilterEvent, eventExt);
323             } else {
324                 return Result::INVALID_STATE;
325             }
326         }
327     }
328 
329     // if ip cid monitoring flipped, record the new state and send msg on enabling
330     if (newIpCid ^ mIpCidMonitored) {
331         mIpCidMonitored = newIpCid;
332         if (mIpCidMonitored) {
333             if (mCallback_1_1 != nullptr) {
334                 // Return random cid
335                 monitorEvent.cid(1);
336                 eventExt.events.resize(1);
337                 eventExt.events[0].monitorEvent(monitorEvent);
338                 mCallback_1_1->onFilterEvent_1_1(emptyFilterEvent, eventExt);
339             } else {
340                 return Result::INVALID_STATE;
341             }
342         }
343     }
344 
345     return Result::SUCCESS;
346 }
347 
createFilterMQ()348 bool Filter::createFilterMQ() {
349     ALOGV("%s", __FUNCTION__);
350 
351     // Create a synchronized FMQ that supports blocking read/write
352     std::unique_ptr<FilterMQ> tmpFilterMQ =
353             std::unique_ptr<FilterMQ>(new (std::nothrow) FilterMQ(mBufferSize, true));
354     if (!tmpFilterMQ->isValid()) {
355         ALOGW("[Filter] Failed to create FMQ of filter with id: %" PRIu64, mFilterId);
356         return false;
357     }
358 
359     mFilterMQ = std::move(tmpFilterMQ);
360 
361     if (EventFlag::createEventFlag(mFilterMQ->getEventFlagWord(), &mFilterEventFlag) != OK) {
362         return false;
363     }
364 
365     return true;
366 }
367 
startFilterLoop()368 Result Filter::startFilterLoop() {
369     pthread_create(&mFilterThread, NULL, __threadLoopFilter, this);
370     pthread_setname_np(mFilterThread, "filter_waiting_loop");
371 
372     return Result::SUCCESS;
373 }
374 
__threadLoopFilter(void * user)375 void* Filter::__threadLoopFilter(void* user) {
376     Filter* const self = static_cast<Filter*>(user);
377     self->filterThreadLoop();
378     return 0;
379 }
380 
filterThreadLoop()381 void Filter::filterThreadLoop() {
382     if (!mFilterThreadRunning) {
383         return;
384     }
385     std::lock_guard<std::mutex> lock(mFilterThreadLock);
386     ALOGD("[Filter] filter %" PRIu64 " threadLoop start.", mFilterId);
387 
388     // For the first time of filter output, implementation needs to send the filter
389     // Event Callback without waiting for the DATA_CONSUMED to init the process.
390     while (mFilterThreadRunning) {
391         if (mFilterEvent.events.size() == 0 && mFilterEventExt.events.size() == 0) {
392             if (DEBUG_FILTER) {
393                 ALOGD("[Filter] wait for filter data output.");
394             }
395             usleep(1000 * 1000);
396             continue;
397         }
398 
399         // After successfully write, send a callback and wait for the read to be done
400         if (mCallback_1_1 != nullptr) {
401             if (mConfigured) {
402                 DemuxFilterEvent emptyEvent;
403                 V1_1::DemuxFilterEventExt startEvent;
404                 startEvent.events.resize(1);
405                 startEvent.events[0].startId(mStartId++);
406                 mCallback_1_1->onFilterEvent_1_1(emptyEvent, startEvent);
407                 mConfigured = false;
408             }
409             mCallback_1_1->onFilterEvent_1_1(mFilterEvent, mFilterEventExt);
410             mFilterEventExt.events.resize(0);
411         } else if (mCallback != nullptr) {
412             mCallback->onFilterEvent(mFilterEvent);
413         } else {
414             ALOGD("[Filter] filter callback is not configured yet.");
415             mFilterThreadRunning = false;
416             return;
417         }
418         mFilterEvent.events.resize(0);
419 
420         freeAvHandle();
421         mFilterStatus = DemuxFilterStatus::DATA_READY;
422         if (mCallback != nullptr) {
423             mCallback->onFilterStatus(mFilterStatus);
424         } else if (mCallback_1_1 != nullptr) {
425             mCallback_1_1->onFilterStatus(mFilterStatus);
426         }
427         break;
428     }
429 
430     while (mFilterThreadRunning) {
431         uint32_t efState = 0;
432         // We do not wait for the last round of written data to be read to finish the thread
433         // because the VTS can verify the reading itself.
434         for (int i = 0; i < SECTION_WRITE_COUNT; i++) {
435             if (!mFilterThreadRunning) {
436                 break;
437             }
438             while (mFilterThreadRunning && mIsUsingFMQ) {
439                 status_t status = mFilterEventFlag->wait(
440                         static_cast<uint32_t>(DemuxQueueNotifyBits::DATA_CONSUMED), &efState,
441                         WAIT_TIMEOUT, true /* retry on spurious wake */);
442                 if (status != OK) {
443                     ALOGD("[Filter] wait for data consumed");
444                     continue;
445                 }
446                 break;
447             }
448 
449             maySendFilterStatusCallback();
450 
451             while (mFilterThreadRunning) {
452                 std::lock_guard<std::mutex> lock(mFilterEventLock);
453                 if (mFilterEvent.events.size() == 0 && mFilterEventExt.events.size() == 0) {
454                     continue;
455                 }
456                 // After successfully write, send a callback and wait for the read to be done
457                 if (mCallback_1_1 != nullptr) {
458                     mCallback_1_1->onFilterEvent_1_1(mFilterEvent, mFilterEventExt);
459                     mFilterEventExt.events.resize(0);
460                 } else if (mCallback != nullptr) {
461                     mCallback->onFilterEvent(mFilterEvent);
462                 }
463                 mFilterEvent.events.resize(0);
464                 break;
465             }
466             // We do not wait for the last read to be done
467             // VTS can verify the read result itself.
468             if (i == SECTION_WRITE_COUNT - 1) {
469                 ALOGD("[Filter] filter %" PRIu64 " writing done. Ending thread", mFilterId);
470                 break;
471             }
472         }
473         break;
474     }
475     ALOGD("[Filter] filter thread ended.");
476 }
477 
freeAvHandle()478 void Filter::freeAvHandle() {
479     if (!mIsMediaFilter) {
480         return;
481     }
482     for (int i = 0; i < mFilterEvent.events.size(); i++) {
483         ::close(mFilterEvent.events[i].media().avMemory.getNativeHandle()->data[0]);
484         native_handle_delete(const_cast<native_handle_t*>(
485                 mFilterEvent.events[i].media().avMemory.getNativeHandle()));
486     }
487 }
488 
freeSharedAvHandle()489 void Filter::freeSharedAvHandle() {
490     if (!mIsMediaFilter) {
491         return;
492     }
493     ::close(mSharedAvMemHandle.getNativeHandle()->data[0]);
494     native_handle_delete(const_cast<native_handle_t*>(mSharedAvMemHandle.getNativeHandle()));
495 }
496 
maySendFilterStatusCallback()497 void Filter::maySendFilterStatusCallback() {
498     if (!mIsUsingFMQ) {
499         return;
500     }
501     std::lock_guard<std::mutex> lock(mFilterStatusLock);
502     int availableToRead = mFilterMQ->availableToRead();
503     int availableToWrite = mFilterMQ->availableToWrite();
504     int fmqSize = mFilterMQ->getQuantumCount();
505 
506     DemuxFilterStatus newStatus = checkFilterStatusChange(
507             availableToWrite, availableToRead, ceil(fmqSize * 0.75), ceil(fmqSize * 0.25));
508     if (mFilterStatus != newStatus) {
509         if (mCallback != nullptr) {
510             mCallback->onFilterStatus(newStatus);
511         } else if (mCallback_1_1 != nullptr) {
512             mCallback_1_1->onFilterStatus(newStatus);
513         }
514         mFilterStatus = newStatus;
515     }
516 }
517 
checkFilterStatusChange(uint32_t availableToWrite,uint32_t availableToRead,uint32_t highThreshold,uint32_t lowThreshold)518 DemuxFilterStatus Filter::checkFilterStatusChange(uint32_t availableToWrite,
519                                                   uint32_t availableToRead, uint32_t highThreshold,
520                                                   uint32_t lowThreshold) {
521     if (availableToWrite == 0) {
522         return DemuxFilterStatus::OVERFLOW;
523     } else if (availableToRead > highThreshold) {
524         return DemuxFilterStatus::HIGH_WATER;
525     } else if (availableToRead < lowThreshold) {
526         return DemuxFilterStatus::LOW_WATER;
527     }
528     return mFilterStatus;
529 }
530 
getTpid()531 uint16_t Filter::getTpid() {
532     return mTpid;
533 }
534 
updateFilterOutput(vector<uint8_t> data)535 void Filter::updateFilterOutput(vector<uint8_t> data) {
536     std::lock_guard<std::mutex> lock(mFilterOutputLock);
537     mFilterOutput.insert(mFilterOutput.end(), data.begin(), data.end());
538 }
539 
updatePts(uint64_t pts)540 void Filter::updatePts(uint64_t pts) {
541     std::lock_guard<std::mutex> lock(mFilterOutputLock);
542     mPts = pts;
543 }
544 
updateRecordOutput(vector<uint8_t> data)545 void Filter::updateRecordOutput(vector<uint8_t> data) {
546     std::lock_guard<std::mutex> lock(mRecordFilterOutputLock);
547     mRecordFilterOutput.insert(mRecordFilterOutput.end(), data.begin(), data.end());
548 }
549 
startFilterHandler()550 Result Filter::startFilterHandler() {
551     std::lock_guard<std::mutex> lock(mFilterOutputLock);
552     switch (mType.mainType) {
553         case DemuxFilterMainType::TS:
554             switch (mType.subType.tsFilterType()) {
555                 case DemuxTsFilterType::UNDEFINED:
556                     break;
557                 case DemuxTsFilterType::SECTION:
558                     startSectionFilterHandler();
559                     break;
560                 case DemuxTsFilterType::PES:
561                     startPesFilterHandler();
562                     break;
563                 case DemuxTsFilterType::TS:
564                     startTsFilterHandler();
565                     break;
566                 case DemuxTsFilterType::AUDIO:
567                 case DemuxTsFilterType::VIDEO:
568                     startMediaFilterHandler();
569                     break;
570                 case DemuxTsFilterType::PCR:
571                     startPcrFilterHandler();
572                     break;
573                 case DemuxTsFilterType::TEMI:
574                     startTemiFilterHandler();
575                     break;
576                 default:
577                     break;
578             }
579             break;
580         case DemuxFilterMainType::MMTP:
581             /*mmtpSettings*/
582             break;
583         case DemuxFilterMainType::IP:
584             /*ipSettings*/
585             break;
586         case DemuxFilterMainType::TLV:
587             /*tlvSettings*/
588             break;
589         case DemuxFilterMainType::ALP:
590             /*alpSettings*/
591             break;
592         default:
593             break;
594     }
595     return Result::SUCCESS;
596 }
597 
startSectionFilterHandler()598 Result Filter::startSectionFilterHandler() {
599     if (mFilterOutput.empty()) {
600         return Result::SUCCESS;
601     }
602     if (!writeSectionsAndCreateEvent(mFilterOutput)) {
603         ALOGD("[Filter] filter %" PRIu64 " fails to write into FMQ. Ending thread", mFilterId);
604         return Result::UNKNOWN_ERROR;
605     }
606 
607     mFilterOutput.clear();
608 
609     return Result::SUCCESS;
610 }
611 
startPesFilterHandler()612 Result Filter::startPesFilterHandler() {
613     std::lock_guard<std::mutex> lock(mFilterEventLock);
614     if (mFilterOutput.empty()) {
615         return Result::SUCCESS;
616     }
617 
618     for (int i = 0; i < mFilterOutput.size(); i += 188) {
619         if (mPesSizeLeft == 0) {
620             uint32_t prefix = (mFilterOutput[i + 4] << 16) | (mFilterOutput[i + 5] << 8) |
621                               mFilterOutput[i + 6];
622             if (DEBUG_FILTER) {
623                 ALOGD("[Filter] prefix %d", prefix);
624             }
625             if (prefix == 0x000001) {
626                 // TODO handle mulptiple Pes filters
627                 mPesSizeLeft = (mFilterOutput[i + 8] << 8) | mFilterOutput[i + 9];
628                 mPesSizeLeft += 6;
629                 if (DEBUG_FILTER) {
630                     ALOGD("[Filter] pes data length %d", mPesSizeLeft);
631                 }
632             } else {
633                 continue;
634             }
635         }
636 
637         int endPoint = min(184, mPesSizeLeft);
638         // append data and check size
639         vector<uint8_t>::const_iterator first = mFilterOutput.begin() + i + 4;
640         vector<uint8_t>::const_iterator last = mFilterOutput.begin() + i + 4 + endPoint;
641         mPesOutput.insert(mPesOutput.end(), first, last);
642         // size does not match then continue
643         mPesSizeLeft -= endPoint;
644         if (DEBUG_FILTER) {
645             ALOGD("[Filter] pes data left %d", mPesSizeLeft);
646         }
647         if (mPesSizeLeft > 0) {
648             continue;
649         }
650         // size match then create event
651         if (!writeDataToFilterMQ(mPesOutput)) {
652             ALOGD("[Filter] pes data write failed");
653             mFilterOutput.clear();
654             return Result::INVALID_STATE;
655         }
656         maySendFilterStatusCallback();
657         DemuxFilterPesEvent pesEvent;
658         pesEvent = {
659                 // temp dump meta data
660                 .streamId = mPesOutput[3],
661                 .dataLength = static_cast<uint16_t>(mPesOutput.size()),
662         };
663         if (DEBUG_FILTER) {
664             ALOGD("[Filter] assembled pes data length %d", pesEvent.dataLength);
665         }
666 
667         int size = mFilterEvent.events.size();
668         mFilterEvent.events.resize(size + 1);
669         mFilterEvent.events[size].pes(pesEvent);
670         mPesOutput.clear();
671     }
672 
673     mFilterOutput.clear();
674 
675     return Result::SUCCESS;
676 }
677 
startTsFilterHandler()678 Result Filter::startTsFilterHandler() {
679     // TODO handle starting TS filter
680     return Result::SUCCESS;
681 }
682 
startMediaFilterHandler()683 Result Filter::startMediaFilterHandler() {
684     std::lock_guard<std::mutex> lock(mFilterEventLock);
685     if (mFilterOutput.empty()) {
686         return Result::SUCCESS;
687     }
688 
689     Result result;
690     if (mPts) {
691         result = createMediaFilterEventWithIon(mFilterOutput);
692         if (result == Result::SUCCESS) {
693             mFilterOutput.clear();
694         }
695         return result;
696     }
697 
698     for (int i = 0; i < mFilterOutput.size(); i += 188) {
699         if (mPesSizeLeft == 0) {
700             uint32_t prefix = (mFilterOutput[i + 4] << 16) | (mFilterOutput[i + 5] << 8) |
701                               mFilterOutput[i + 6];
702             if (DEBUG_FILTER) {
703                 ALOGD("[Filter] prefix %d", prefix);
704             }
705             if (prefix == 0x000001) {
706                 // TODO handle mulptiple Pes filters
707                 mPesSizeLeft = (mFilterOutput[i + 8] << 8) | mFilterOutput[i + 9];
708                 mPesSizeLeft += 6;
709                 if (DEBUG_FILTER) {
710                     ALOGD("[Filter] pes data length %d", mPesSizeLeft);
711                 }
712             } else {
713                 continue;
714             }
715         }
716 
717         int endPoint = min(184, mPesSizeLeft);
718         // append data and check size
719         vector<uint8_t>::const_iterator first = mFilterOutput.begin() + i + 4;
720         vector<uint8_t>::const_iterator last = mFilterOutput.begin() + i + 4 + endPoint;
721         mPesOutput.insert(mPesOutput.end(), first, last);
722         // size does not match then continue
723         mPesSizeLeft -= endPoint;
724         if (DEBUG_FILTER) {
725             ALOGD("[Filter] pes data left %d", mPesSizeLeft);
726         }
727         if (mPesSizeLeft > 0 || mAvBufferCopyCount++ < 10) {
728             continue;
729         }
730 
731         result = createMediaFilterEventWithIon(mPesOutput);
732         if (result != Result::SUCCESS) {
733             return result;
734         }
735     }
736 
737     mFilterOutput.clear();
738 
739     return Result::SUCCESS;
740 }
741 
createMediaFilterEventWithIon(vector<uint8_t> output)742 Result Filter::createMediaFilterEventWithIon(vector<uint8_t> output) {
743     if (mUsingSharedAvMem) {
744         if (mSharedAvMemHandle.getNativeHandle() == nullptr) {
745             return Result::UNKNOWN_ERROR;
746         }
747         return createShareMemMediaEvents(output);
748     }
749 
750     return createIndependentMediaEvents(output);
751 }
752 
startRecordFilterHandler()753 Result Filter::startRecordFilterHandler() {
754     std::lock_guard<std::mutex> lock(mRecordFilterOutputLock);
755     if (mRecordFilterOutput.empty()) {
756         return Result::SUCCESS;
757     }
758 
759     if (mDvr == nullptr || !mDvr->writeRecordFMQ(mRecordFilterOutput)) {
760         ALOGD("[Filter] dvr fails to write into record FMQ.");
761         return Result::UNKNOWN_ERROR;
762     }
763 
764     V1_0::DemuxFilterTsRecordEvent recordEvent;
765     recordEvent = {
766             .byteNumber = mRecordFilterOutput.size(),
767     };
768     V1_1::DemuxFilterTsRecordEventExt recordEventExt;
769     recordEventExt = {
770             .pts = (mPts == 0) ? time(NULL) * 900000 : mPts,
771             .firstMbInSlice = 0,     // random address
772     };
773 
774     int size;
775     size = mFilterEventExt.events.size();
776     mFilterEventExt.events.resize(size + 1);
777     mFilterEventExt.events[size].tsRecord(recordEventExt);
778     size = mFilterEvent.events.size();
779     mFilterEvent.events.resize(size + 1);
780     mFilterEvent.events[size].tsRecord(recordEvent);
781 
782     mRecordFilterOutput.clear();
783     return Result::SUCCESS;
784 }
785 
startPcrFilterHandler()786 Result Filter::startPcrFilterHandler() {
787     // TODO handle starting PCR filter
788     return Result::SUCCESS;
789 }
790 
startTemiFilterHandler()791 Result Filter::startTemiFilterHandler() {
792     // TODO handle starting TEMI filter
793     return Result::SUCCESS;
794 }
795 
writeSectionsAndCreateEvent(vector<uint8_t> data)796 bool Filter::writeSectionsAndCreateEvent(vector<uint8_t> data) {
797     // TODO check how many sections has been read
798     ALOGD("[Filter] section handler");
799     std::lock_guard<std::mutex> lock(mFilterEventLock);
800     if (!writeDataToFilterMQ(data)) {
801         return false;
802     }
803     int size = mFilterEvent.events.size();
804     mFilterEvent.events.resize(size + 1);
805     DemuxFilterSectionEvent secEvent;
806     secEvent = {
807             // temp dump meta data
808             .tableId = 0,
809             .version = 1,
810             .sectionNum = 1,
811             .dataLength = static_cast<uint16_t>(data.size()),
812     };
813     mFilterEvent.events[size].section(secEvent);
814     return true;
815 }
816 
writeDataToFilterMQ(const std::vector<uint8_t> & data)817 bool Filter::writeDataToFilterMQ(const std::vector<uint8_t>& data) {
818     std::lock_guard<std::mutex> lock(mWriteLock);
819     if (mFilterMQ->write(data.data(), data.size())) {
820         return true;
821     }
822     return false;
823 }
824 
attachFilterToRecord(const sp<Dvr> dvr)825 void Filter::attachFilterToRecord(const sp<Dvr> dvr) {
826     mDvr = dvr;
827 }
828 
detachFilterFromRecord()829 void Filter::detachFilterFromRecord() {
830     mDvr = nullptr;
831 }
832 
createAvIonFd(int size)833 int Filter::createAvIonFd(int size) {
834     // Create an DMA-BUF fd and allocate an av fd mapped to a buffer to it.
835     auto buffer_allocator = std::make_unique<BufferAllocator>();
836     if (!buffer_allocator) {
837         ALOGE("[Filter] Unable to create BufferAllocator object");
838         return -1;
839     }
840     int av_fd = -1;
841     av_fd = buffer_allocator->Alloc("system-uncached", size);
842     if (av_fd < 0) {
843         ALOGE("[Filter] Failed to create av fd %d", errno);
844         return -1;
845     }
846     return av_fd;
847 }
848 
getIonBuffer(int fd,int size)849 uint8_t* Filter::getIonBuffer(int fd, int size) {
850     uint8_t* avBuf = static_cast<uint8_t*>(
851             mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0 /*offset*/));
852     if (avBuf == MAP_FAILED) {
853         ALOGE("[Filter] fail to allocate buffer %d", errno);
854         return NULL;
855     }
856     return avBuf;
857 }
858 
createNativeHandle(int fd)859 native_handle_t* Filter::createNativeHandle(int fd) {
860     native_handle_t* nativeHandle;
861     if (fd < 0) {
862         nativeHandle = native_handle_create(/*numFd*/ 0, 0);
863     } else {
864         // Create a native handle to pass the av fd via the callback event.
865         nativeHandle = native_handle_create(/*numFd*/ 1, 0);
866     }
867     if (nativeHandle == NULL) {
868         ALOGE("[Filter] Failed to create native_handle %d", errno);
869         return NULL;
870     }
871     if (nativeHandle->numFds > 0) {
872         nativeHandle->data[0] = dup(fd);
873     }
874     return nativeHandle;
875 }
876 
createIndependentMediaEvents(vector<uint8_t> output)877 Result Filter::createIndependentMediaEvents(vector<uint8_t> output) {
878     int av_fd = createAvIonFd(output.size());
879     if (av_fd == -1) {
880         return Result::UNKNOWN_ERROR;
881     }
882     // copy the filtered data to the buffer
883     uint8_t* avBuffer = getIonBuffer(av_fd, output.size());
884     if (avBuffer == NULL) {
885         return Result::UNKNOWN_ERROR;
886     }
887     memcpy(avBuffer, output.data(), output.size() * sizeof(uint8_t));
888 
889     native_handle_t* nativeHandle = createNativeHandle(av_fd);
890     if (nativeHandle == NULL) {
891         return Result::UNKNOWN_ERROR;
892     }
893     hidl_handle handle;
894     handle.setTo(nativeHandle, /*shouldOwn=*/true);
895 
896     // Create a dataId and add a <dataId, av_fd> pair into the dataId2Avfd map
897     uint64_t dataId = mLastUsedDataId++ /*createdUID*/;
898     mDataId2Avfd[dataId] = dup(av_fd);
899 
900     // Create mediaEvent and send callback
901     DemuxFilterMediaEvent mediaEvent;
902     mediaEvent = {
903             .avMemory = std::move(handle),
904             .dataLength = static_cast<uint32_t>(output.size()),
905             .avDataId = dataId,
906     };
907     if (mPts) {
908         mediaEvent.pts = mPts;
909         mPts = 0;
910     }
911     int size = mFilterEvent.events.size();
912     mFilterEvent.events.resize(size + 1);
913     mFilterEvent.events[size].media(mediaEvent);
914 
915     // Clear and log
916     output.clear();
917     mAvBufferCopyCount = 0;
918     ::close(av_fd);
919     if (DEBUG_FILTER) {
920         ALOGD("[Filter] av data length %d", mediaEvent.dataLength);
921     }
922     return Result::SUCCESS;
923 }
924 
createShareMemMediaEvents(vector<uint8_t> output)925 Result Filter::createShareMemMediaEvents(vector<uint8_t> output) {
926     // copy the filtered data to the shared buffer
927     uint8_t* sharedAvBuffer = getIonBuffer(mSharedAvMemHandle.getNativeHandle()->data[0],
928                                            output.size() + mSharedAvMemOffset);
929     if (sharedAvBuffer == NULL) {
930         return Result::UNKNOWN_ERROR;
931     }
932     memcpy(sharedAvBuffer + mSharedAvMemOffset, output.data(), output.size() * sizeof(uint8_t));
933 
934     // Create a memory handle with numFds == 0
935     native_handle_t* nativeHandle = createNativeHandle(-1);
936     if (nativeHandle == NULL) {
937         return Result::UNKNOWN_ERROR;
938     }
939     hidl_handle handle;
940     handle.setTo(nativeHandle, /*shouldOwn=*/true);
941 
942     // Create mediaEvent and send callback
943     DemuxFilterMediaEvent mediaEvent;
944     mediaEvent = {
945             .offset = static_cast<uint32_t>(mSharedAvMemOffset),
946             .dataLength = static_cast<uint32_t>(output.size()),
947             .avMemory = handle,
948     };
949     mSharedAvMemOffset += output.size();
950     if (mPts) {
951         mediaEvent.pts = mPts;
952         mPts = 0;
953     }
954     int size = mFilterEvent.events.size();
955     mFilterEvent.events.resize(size + 1);
956     mFilterEvent.events[size].media(mediaEvent);
957 
958     // Clear and log
959     output.clear();
960     if (DEBUG_FILTER) {
961         ALOGD("[Filter] shared av data length %d", mediaEvent.dataLength);
962     }
963     return Result::SUCCESS;
964 }
965 
sameFile(int fd1,int fd2)966 bool Filter::sameFile(int fd1, int fd2) {
967     struct stat stat1, stat2;
968     if (fstat(fd1, &stat1) < 0 || fstat(fd2, &stat2) < 0) {
969         return false;
970     }
971     return (stat1.st_dev == stat2.st_dev) && (stat1.st_ino == stat2.st_ino);
972 }
973 
createMediaEvent()974 DemuxFilterEvent Filter::createMediaEvent() {
975     DemuxFilterEvent event;
976     event.events.resize(1);
977 
978     event.events[0].media({
979             .streamId = 1,
980             .isPtsPresent = true,
981             .pts = 2,
982             .dataLength = 3,
983             .offset = 4,
984             .isSecureMemory = true,
985             .mpuSequenceNumber = 6,
986             .isPesPrivateData = true,
987     });
988 
989     event.events[0].media().extraMetaData.audio({
990             .adFade = 1,
991             .adPan = 2,
992             .versionTextTag = 3,
993             .adGainCenter = 4,
994             .adGainFront = 5,
995             .adGainSurround = 6,
996     });
997 
998     int av_fd = createAvIonFd(BUFFER_SIZE_16M);
999     if (av_fd == -1) {
1000         return event;
1001     }
1002 
1003     native_handle_t* nativeHandle = createNativeHandle(av_fd);
1004     if (nativeHandle == NULL) {
1005         ::close(av_fd);
1006         ALOGE("[Filter] Failed to create native_handle %d", errno);
1007         return event;
1008     }
1009 
1010     // Create a dataId and add a <dataId, av_fd> pair into the dataId2Avfd map
1011     uint64_t dataId = mLastUsedDataId++ /*createdUID*/;
1012     mDataId2Avfd[dataId] = dup(av_fd);
1013     event.events[0].media().avDataId = dataId;
1014 
1015     hidl_handle handle;
1016     handle.setTo(nativeHandle, /*shouldOwn=*/true);
1017     event.events[0].media().avMemory = std::move(handle);
1018     ::close(av_fd);
1019 
1020     return event;
1021 }
1022 
createTsRecordEvent()1023 DemuxFilterEvent Filter::createTsRecordEvent() {
1024     DemuxFilterEvent event;
1025     event.events.resize(1);
1026 
1027     DemuxPid pid;
1028     pid.tPid(1);
1029     DemuxFilterTsRecordEvent::ScIndexMask mask;
1030     mask.sc(1);
1031     event.events[0].tsRecord({
1032             .pid = pid,
1033             .tsIndexMask = 1,
1034             .scIndexMask = mask,
1035             .byteNumber = 2,
1036     });
1037     return event;
1038 }
1039 
createTsRecordEventExt()1040 V1_1::DemuxFilterEventExt Filter::createTsRecordEventExt() {
1041     V1_1::DemuxFilterEventExt event;
1042     event.events.resize(1);
1043 
1044     event.events[0].tsRecord({
1045             .pts = 1,
1046             .firstMbInSlice = 2,  // random address
1047     });
1048     return event;
1049 }
1050 
createMmtpRecordEvent()1051 DemuxFilterEvent Filter::createMmtpRecordEvent() {
1052     DemuxFilterEvent event;
1053     event.events.resize(1);
1054 
1055     event.events[0].mmtpRecord({
1056             .scHevcIndexMask = 1,
1057             .byteNumber = 2,
1058     });
1059     return event;
1060 }
1061 
createMmtpRecordEventExt()1062 V1_1::DemuxFilterEventExt Filter::createMmtpRecordEventExt() {
1063     V1_1::DemuxFilterEventExt event;
1064     event.events.resize(1);
1065 
1066     event.events[0].mmtpRecord({
1067             .pts = 1,
1068             .mpuSequenceNumber = 2,
1069             .firstMbInSlice = 3,
1070             .tsIndexMask = 4,
1071     });
1072     return event;
1073 }
1074 
createSectionEvent()1075 DemuxFilterEvent Filter::createSectionEvent() {
1076     DemuxFilterEvent event;
1077     event.events.resize(1);
1078 
1079     event.events[0].section({
1080             .tableId = 1,
1081             .version = 2,
1082             .sectionNum = 3,
1083             .dataLength = 0,
1084     });
1085     return event;
1086 }
1087 
createPesEvent()1088 DemuxFilterEvent Filter::createPesEvent() {
1089     DemuxFilterEvent event;
1090     event.events.resize(1);
1091 
1092     event.events[0].pes({
1093             .streamId = static_cast<DemuxStreamId>(1),
1094             .dataLength = 1,
1095             .mpuSequenceNumber = 2,
1096     });
1097     return event;
1098 }
1099 
createDownloadEvent()1100 DemuxFilterEvent Filter::createDownloadEvent() {
1101     DemuxFilterEvent event;
1102     event.events.resize(1);
1103 
1104     event.events[0].download({
1105             .itemId = 1,
1106             .mpuSequenceNumber = 2,
1107             .itemFragmentIndex = 3,
1108             .lastItemFragmentIndex = 4,
1109             .dataLength = 0,
1110     });
1111     return event;
1112 }
1113 
createIpPayloadEvent()1114 DemuxFilterEvent Filter::createIpPayloadEvent() {
1115     DemuxFilterEvent event;
1116     event.events.resize(1);
1117 
1118     event.events[0].ipPayload({
1119             .dataLength = 0,
1120     });
1121     return event;
1122 }
1123 
createTemiEvent()1124 DemuxFilterEvent Filter::createTemiEvent() {
1125     DemuxFilterEvent event;
1126     event.events.resize(1);
1127 
1128     event.events[0].temi({.pts = 1, .descrTag = 2, .descrData = {3}});
1129     return event;
1130 }
1131 
createMonitorEvent()1132 V1_1::DemuxFilterEventExt Filter::createMonitorEvent() {
1133     V1_1::DemuxFilterEventExt event;
1134     event.events.resize(1);
1135 
1136     V1_1::DemuxFilterMonitorEvent monitor;
1137     monitor.scramblingStatus(V1_1::ScramblingStatus::SCRAMBLED);
1138     event.events[0].monitorEvent(monitor);
1139     return event;
1140 }
1141 
createRestartEvent()1142 V1_1::DemuxFilterEventExt Filter::createRestartEvent() {
1143     V1_1::DemuxFilterEventExt event;
1144     event.events.resize(1);
1145 
1146     event.events[0].startId(1);
1147     return event;
1148 }
1149 }  // namespace implementation
1150 }  // namespace V1_0
1151 }  // namespace tuner
1152 }  // namespace tv
1153 }  // namespace hardware
1154 }  // namespace android
1155