Fix tune byte alignment
When reading data from the socket, one byte is read during tuning
and remaining data is read during playback. Since the same streamer
is used for reading data, there is an offset of 1 when tuning is
performed before playback. The extra byte is stored in a buffer
and prepended to the playback buffer.
Bug: 288170590
Test: atest VtsHalTvTunerTargetTest
Change-Id: Ie5d112dbc3c3e3bbb0bb07e60d15ddc26cacaf8c
diff --git a/tv/tuner/aidl/default/Demux.cpp b/tv/tuner/aidl/default/Demux.cpp
index 2445a3e..a9c205f 100644
--- a/tv/tuner/aidl/default/Demux.cpp
+++ b/tv/tuner/aidl/default/Demux.cpp
@@ -125,6 +125,7 @@
void Demux::frontendIptvInputThreadLoop(dtv_plugin* interface, dtv_streamer* streamer) {
Timer *timer, *fullBufferTimer;
+ bool isTuneBytePushedToDvr = false;
while (true) {
std::unique_lock<std::mutex> lock(mIsIptvThreadRunningMutex);
mIsIptvThreadRunningCv.wait(lock, [this] { return mIsIptvReadThreadRunning; });
@@ -137,10 +138,24 @@
}
timer = new Timer();
void* buf = malloc(sizeof(char) * IPTV_BUFFER_SIZE);
- if (buf == nullptr) ALOGI("Buffer allocation failed");
- ssize_t bytes_read =
- interface->read_stream(streamer, buf, IPTV_BUFFER_SIZE, IPTV_PLAYBACK_TIMEOUT);
- if (bytes_read == 0) {
+ if (buf == nullptr) {
+ ALOGE("[Demux] Buffer allocation failed");
+ return;
+ }
+ ssize_t bytes_read;
+ void* tuneByteBuffer = mFrontend->getTuneByteBuffer();
+ if (!isTuneBytePushedToDvr && tuneByteBuffer != nullptr) {
+ memcpy(buf, tuneByteBuffer, 1);
+ char* offsetBuf = (char*)buf + 1;
+ bytes_read = interface->read_stream(streamer, (void*)offsetBuf, IPTV_BUFFER_SIZE - 1,
+ IPTV_PLAYBACK_TIMEOUT);
+ isTuneBytePushedToDvr = true;
+ } else {
+ bytes_read =
+ interface->read_stream(streamer, buf, IPTV_BUFFER_SIZE, IPTV_PLAYBACK_TIMEOUT);
+ }
+
+ if (bytes_read <= 0) {
double elapsed_time = timer->get_elapsed_time_ms();
if (elapsed_time > IPTV_PLAYBACK_TIMEOUT) {
ALOGE("[Demux] timeout reached - elapsed_time: %f, timeout: %d", elapsed_time,
diff --git a/tv/tuner/aidl/default/Frontend.cpp b/tv/tuner/aidl/default/Frontend.cpp
index 5cee3c7..1031604 100644
--- a/tv/tuner/aidl/default/Frontend.cpp
+++ b/tv/tuner/aidl/default/Frontend.cpp
@@ -188,6 +188,9 @@
mCallback = nullptr;
mIsLocked = false;
mTuner = nullptr;
+ if (mTuneByteBuffer != nullptr) {
+ free(mTuneByteBuffer);
+ }
}
::ndk::ScopedAStatus Frontend::close() {
@@ -246,11 +249,12 @@
}
mCallback->onEvent(FrontendEventType::LOCKED);
mIsLocked = true;
+ mTuneByteBuffer = buf;
}
::ndk::ScopedAStatus Frontend::tune(const FrontendSettings& in_settings) {
if (mCallback == nullptr) {
- ALOGW("[ WARN ] Frontend callback is not set for tunin0g");
+ ALOGW("[ WARN ] Frontend callback is not set for tuning");
return ::ndk::ScopedAStatus::fromServiceSpecificError(
static_cast<int32_t>(Result::INVALID_STATE));
}
@@ -298,7 +302,6 @@
if (mIptvFrontendTuneThread.joinable()) {
mIptvFrontendTuneThread.join();
}
- free(buf);
}
return ::ndk::ScopedAStatus::ok();
diff --git a/tv/tuner/aidl/default/Frontend.h b/tv/tuner/aidl/default/Frontend.h
index 7622ec0..f3f8a87 100644
--- a/tv/tuner/aidl/default/Frontend.h
+++ b/tv/tuner/aidl/default/Frontend.h
@@ -68,6 +68,7 @@
string getIptvTransportDescription();
dtv_streamer* getIptvPluginStreamer();
void readTuneByte(void* buf);
+ void* getTuneByteBuffer() { return mTuneByteBuffer; };
dtv_streamer* createIptvPluginStreamer(dtv_plugin* interface, const char* transport_desc);
dtv_plugin* createIptvPluginInterface();
bool isLocked();
@@ -95,6 +96,7 @@
string mIptvTransportDescription;
dtv_streamer* mIptvPluginStreamer;
std::thread mIptvFrontendTuneThread;
+ void* mTuneByteBuffer = nullptr;
};
} // namespace tuner