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