Add the PTS field for recording-time indexing in the DemuxFilterEvent
Test: atest VtsHalTvTunerV1_1TargetTest
Bug: 158816517
Change-Id: Ib29fd0f55aaae2fb44b77f754cceb5152fc7158d
diff --git a/tv/tuner/1.1/default/Android.bp b/tv/tuner/1.1/default/Android.bp
index 7e45864..4401f7c 100644
--- a/tv/tuner/1.1/default/Android.bp
+++ b/tv/tuner/1.1/default/Android.bp
@@ -4,14 +4,14 @@
vendor: true,
relative_install_path: "hw",
srcs: [
+ "Demux.cpp",
+ "Descrambler.cpp",
+ "Dvr.cpp",
"Filter.cpp",
"Frontend.cpp",
- "Descrambler.cpp",
- "Demux.cpp",
- "Dvr.cpp",
+ "Lnb.cpp",
"TimeFilter.cpp",
"Tuner.cpp",
- "Lnb.cpp",
"service.cpp",
],
diff --git a/tv/tuner/1.1/default/Demux.cpp b/tv/tuner/1.1/default/Demux.cpp
index f501d74..007d5eb 100644
--- a/tv/tuner/1.1/default/Demux.cpp
+++ b/tv/tuner/1.1/default/Demux.cpp
@@ -312,6 +312,16 @@
}
}
+void Demux::sendFrontendInputToRecord(vector<uint8_t> data, uint16_t pid, uint64_t pts) {
+ sendFrontendInputToRecord(data);
+ set<uint64_t>::iterator it;
+ for (it = mRecordFilterIds.begin(); it != mRecordFilterIds.end(); it++) {
+ if (pid == mFilters[*it]->getTpid()) {
+ mFilters[*it]->updatePts(pts);
+ }
+ }
+}
+
bool Demux::startBroadcastFilterDispatcher() {
set<uint64_t>::iterator it;
@@ -389,9 +399,11 @@
ALOGE("[Demux] playback es data failed to be filtered. Ending thread");
break;
}
+ continue;
}
// Our current implementation filter the data and write it into the filter FMQ immediately
// after the DATA_READY from the VTS/framework
+ // This is for the non-ES data source, real playback use case handling.
if (!mDvrPlayback->readPlaybackFMQ(true /*isVirtualFrontend*/, mIsRecording) ||
!mDvrPlayback->startFilterDispatcher(true /*isVirtualFrontend*/, mIsRecording)) {
ALOGE("[Demux] playback data failed to be filtered. Ending thread");
diff --git a/tv/tuner/1.1/default/Demux.h b/tv/tuner/1.1/default/Demux.h
index f38f006..3623d0f 100644
--- a/tv/tuner/1.1/default/Demux.h
+++ b/tv/tuner/1.1/default/Demux.h
@@ -100,6 +100,7 @@
void startBroadcastTsFilter(vector<uint8_t> data);
void sendFrontendInputToRecord(vector<uint8_t> data);
+ void sendFrontendInputToRecord(vector<uint8_t> data, uint16_t pid, uint64_t pts);
bool startRecordFilterDispatcher();
private:
diff --git a/tv/tuner/1.1/default/Dvr.cpp b/tv/tuner/1.1/default/Dvr.cpp
index 02d6a42..bf4c77e 100644
--- a/tv/tuner/1.1/default/Dvr.cpp
+++ b/tv/tuner/1.1/default/Dvr.cpp
@@ -217,9 +217,11 @@
break;
}
maySendPlaybackStatusCallback();
+ continue;
}
// Our current implementation filter the data and write it into the filter FMQ immediately
// after the DATA_READY from the VTS/framework
+ // This is for the non-ES data source, real playback use case handling.
if (!readPlaybackFMQ(false /*isVirtualFrontend*/, false /*isRecording*/) ||
!startFilterDispatcher(false /*isVirtualFrontend*/, false /*isRecording*/)) {
ALOGE("[Dvr] playback data failed to be filtered. Ending thread");
@@ -380,20 +382,19 @@
for (int i = 0; i < totalFrames; i++) {
frameData.resize(esMeta[i].len);
pid = esMeta[i].isAudio ? audioPid : videoPid;
- memcpy(dataOutputBuffer.data() + esMeta[i].startIndex, frameData.data(), esMeta[i].len);
- // Send to the media filter
- if (isVirtualFrontend && isRecording) {
- // TODO validate record
- mDemux->sendFrontendInputToRecord(frameData);
- } else {
+ memcpy(frameData.data(), dataOutputBuffer.data() + esMeta[i].startIndex, esMeta[i].len);
+ // Send to the media filters or record filters
+ if (!isRecording) {
for (it = mFilters.begin(); it != mFilters.end(); it++) {
if (pid == mDemux->getFilterTpid(it->first)) {
mDemux->updateMediaFilterOutput(it->first, frameData,
static_cast<uint64_t>(esMeta[i].pts));
- startFilterDispatcher(isVirtualFrontend, isRecording);
}
}
+ } else {
+ mDemux->sendFrontendInputToRecord(frameData, pid, static_cast<uint64_t>(esMeta[i].pts));
}
+ startFilterDispatcher(isVirtualFrontend, isRecording);
}
return true;
diff --git a/tv/tuner/1.1/default/Filter.cpp b/tv/tuner/1.1/default/Filter.cpp
index 108baf7..2d6214d 100644
--- a/tv/tuner/1.1/default/Filter.cpp
+++ b/tv/tuner/1.1/default/Filter.cpp
@@ -35,7 +35,6 @@
mType = type;
mFilterId = filterId;
mBufferSize = bufferSize;
- mCallback = cb;
mDemux = demux;
switch (mType.mainType) {
@@ -69,6 +68,13 @@
default:
break;
}
+
+ sp<V1_1::IFilterCallback> filterCallback_v1_1 = V1_1::IFilterCallback::castFrom(cb);
+ if (filterCallback_v1_1 != NULL) {
+ mCallback_1_1 = filterCallback_v1_1;
+ } else {
+ mCallback = cb;
+ }
}
Filter::~Filter() {}
@@ -99,7 +105,7 @@
Return<void> Filter::getQueueDesc(getQueueDesc_cb _hidl_cb) {
ALOGV("%s", __FUNCTION__);
- mIsUsingFMQ = true;
+ mIsUsingFMQ = mIsRecordFilter ? false : true;
_hidl_cb(Result::SUCCESS, *mFilterMQ->getDesc());
return Void();
@@ -214,7 +220,7 @@
// For the first time of filter output, implementation needs to send the filter
// Event Callback without waiting for the DATA_CONSUMED to init the process.
while (mFilterThreadRunning) {
- if (mFilterEvent.events.size() == 0) {
+ if (mFilterEvent.events.size() == 0 && mFilterEvent_1_1.events.size() == 0) {
if (DEBUG_FILTER) {
ALOGD("[Filter] wait for filter data output.");
}
@@ -222,15 +228,26 @@
continue;
}
// After successfully write, send a callback and wait for the read to be done
- mCallback->onFilterEvent(mFilterEvent);
- freeAvHandle();
- mFilterEvent.events.resize(0);
- mFilterStatus = DemuxFilterStatus::DATA_READY;
- if (mCallback == nullptr) {
- ALOGD("[Filter] filter %" PRIu64 " does not hava callback. Ending thread", mFilterId);
- break;
+ if (mFilterEvent_1_1.events.size() > 0) {
+ if (mCallback_1_1 == nullptr) {
+ ALOGE("[Filter] IFilterCallback_1_1 has not been configured yet. Can't send event");
+ mFilterThreadRunning = false;
+ break;
+ }
+ mCallback_1_1->onFilterEvent_1_1(mFilterEvent_1_1);
+ mFilterEvent_1_1.events.resize(0);
+ } else {
+ mCallback->onFilterEvent(mFilterEvent);
+ mFilterEvent.events.resize(0);
}
- mCallback->onFilterStatus(mFilterStatus);
+
+ freeAvHandle();
+ mFilterStatus = DemuxFilterStatus::DATA_READY;
+ if (mCallback != nullptr) {
+ mCallback->onFilterStatus(mFilterStatus);
+ } else if (mCallback_1_1 != nullptr) {
+ mCallback_1_1->onFilterStatus(mFilterStatus);
+ }
break;
}
@@ -258,8 +275,13 @@
continue;
}
// After successfully write, send a callback and wait for the read to be done
- mCallback->onFilterEvent(mFilterEvent);
- mFilterEvent.events.resize(0);
+ if (mCallback != nullptr) {
+ mCallback->onFilterEvent(mFilterEvent);
+ mFilterEvent.events.resize(0);
+ } else if (mCallback_1_1 != nullptr) {
+ mCallback_1_1->onFilterEvent_1_1(mFilterEvent_1_1);
+ mFilterEvent_1_1.events.resize(0);
+ }
break;
}
// We do not wait for the last read to be done
@@ -297,7 +319,11 @@
DemuxFilterStatus newStatus = checkFilterStatusChange(
availableToWrite, availableToRead, ceil(fmqSize * 0.75), ceil(fmqSize * 0.25));
if (mFilterStatus != newStatus) {
- mCallback->onFilterStatus(newStatus);
+ if (mCallback != nullptr) {
+ mCallback->onFilterStatus(newStatus);
+ } else if (mCallback_1_1 != nullptr) {
+ mCallback_1_1->onFilterStatus(newStatus);
+ }
mFilterStatus = newStatus;
}
}
@@ -577,6 +603,27 @@
return Result::UNKNOWN_ERROR;
}
+ V1_0::DemuxFilterTsRecordEvent recordEvent;
+ recordEvent = {
+ .byteNumber = mRecordFilterOutput.size(),
+ };
+ V1_1::DemuxFilterTsRecordEvent recordEvent_1_1;
+ recordEvent_1_1 = {
+ .tsRecordEvent_1_0 = recordEvent,
+ .pts = (mPts == 0) ? time(NULL) * 900000 : mPts,
+ };
+
+ int size;
+ if (mCallback_1_1 != nullptr) {
+ size = mFilterEvent_1_1.events.size();
+ mFilterEvent_1_1.events.resize(size + 1);
+ mFilterEvent_1_1.events[size].tsRecord(recordEvent_1_1);
+ } else if (mCallback != nullptr) {
+ size = mFilterEvent.events.size();
+ mFilterEvent.events.resize(size + 1);
+ mFilterEvent.events[size].tsRecord(recordEvent);
+ }
+
mRecordFilterOutput.clear();
return Result::SUCCESS;
}
diff --git a/tv/tuner/1.1/default/Filter.h b/tv/tuner/1.1/default/Filter.h
index d5801d4..8e6fe38 100644
--- a/tv/tuner/1.1/default/Filter.h
+++ b/tv/tuner/1.1/default/Filter.h
@@ -18,6 +18,7 @@
#define ANDROID_HARDWARE_TV_TUNER_V1_1_FILTER_H_
#include <android/hardware/tv/tuner/1.1/IFilter.h>
+#include <android/hardware/tv/tuner/1.1/IFilterCallback.h>
#include <fmq/MessageQueue.h>
#include <inttypes.h>
#include <ion/ion.h>
@@ -102,7 +103,12 @@
/**
* Filter callbacks used on filter events or FMQ status
*/
- sp<IFilterCallback> mCallback;
+ sp<IFilterCallback> mCallback = nullptr;
+
+ /**
+ * V1_1 Filter callbacks used on filter events or FMQ status
+ */
+ sp<V1_1::IFilterCallback> mCallback_1_1 = nullptr;
uint64_t mFilterId;
uint32_t mBufferSize;
@@ -122,6 +128,7 @@
bool mIsUsingFMQ = false;
EventFlag* mFilterEventFlag;
DemuxFilterEvent mFilterEvent;
+ V1_1::DemuxFilterEvent mFilterEvent_1_1;
// Thread handlers
pthread_t mFilterThread;
diff --git a/tv/tuner/1.1/default/Tuner.cpp b/tv/tuner/1.1/default/Tuner.cpp
index 0a0667e..87a4d36 100644
--- a/tv/tuner/1.1/default/Tuner.cpp
+++ b/tv/tuner/1.1/default/Tuner.cpp
@@ -233,11 +233,10 @@
void Tuner::removeDemux(uint32_t demuxId) {
map<uint32_t, uint32_t>::iterator it;
- for (it = mFrontendToDemux.begin(); it != mFrontendToDemux.end();) {
+ for (it = mFrontendToDemux.begin(); it != mFrontendToDemux.end(); it++) {
if (it->second == demuxId) {
it = mFrontendToDemux.erase(it);
- } else {
- it++;
+ break;
}
}
mDemuxes.erase(demuxId);
diff --git a/tv/tuner/1.1/default/android.hardware.tv.tuner@1.1-service-lazy.rc b/tv/tuner/1.1/default/android.hardware.tv.tuner@1.1-service-lazy.rc
index 9e228f7..abff430 100644
--- a/tv/tuner/1.1/default/android.hardware.tv.tuner@1.1-service-lazy.rc
+++ b/tv/tuner/1.1/default/android.hardware.tv.tuner@1.1-service-lazy.rc
@@ -1,4 +1,5 @@
service vendor.tuner-hal-1-1 /vendor/bin/hw/android.hardware.tv.tuner@1.1-service-lazy
+ interface android.hardware.tv.tuner@1.0::ITuner default
interface android.hardware.tv.tuner@1.1::ITuner default
oneshot
disabled