blob: 7e7f8e6da892c03c94e4c9dcd2617c6cca751975 [file] [log] [blame]
Amy Zhang0fe25be2020-04-08 17:30:52 -07001/*
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#include "DvrTests.h"
18
Amy Zhang6e8163a2020-04-24 15:41:21 -070019void DvrCallback::startPlaybackInputThread(string& dataInputFile, PlaybackSettings& settings,
Amy Zhang0fe25be2020-04-08 17:30:52 -070020 MQDesc& playbackMQDescriptor) {
Amy Zhang6e8163a2020-04-24 15:41:21 -070021 mInputDataFile = dataInputFile;
22 mPlaybackSettings = settings;
Amy Zhang0fe25be2020-04-08 17:30:52 -070023 mPlaybackMQ = std::make_unique<FilterMQ>(playbackMQDescriptor, true /* resetPointers */);
24 EXPECT_TRUE(mPlaybackMQ);
Amy Zhang6e8163a2020-04-24 15:41:21 -070025 pthread_create(&mPlaybackThread, NULL, __threadLoopPlayback, this);
Amy Zhang0fe25be2020-04-08 17:30:52 -070026 pthread_setname_np(mPlaybackThread, "test_playback_input_loop");
27}
28
29void DvrCallback::stopPlaybackThread() {
30 mPlaybackThreadRunning = false;
31 mKeepWritingPlaybackFMQ = false;
32
33 android::Mutex::Autolock autoLock(mPlaybackThreadLock);
34}
35
Amy Zhang6e8163a2020-04-24 15:41:21 -070036void* DvrCallback::__threadLoopPlayback(void* user) {
37 DvrCallback* const self = static_cast<DvrCallback*>(user);
38 self->playbackThreadLoop();
Amy Zhang0fe25be2020-04-08 17:30:52 -070039 return 0;
40}
41
Amy Zhang6e8163a2020-04-24 15:41:21 -070042void DvrCallback::playbackThreadLoop() {
Amy Zhang0fe25be2020-04-08 17:30:52 -070043 android::Mutex::Autolock autoLock(mPlaybackThreadLock);
44 mPlaybackThreadRunning = true;
45
46 // Create the EventFlag that is used to signal the HAL impl that data have been
47 // written into the Playback FMQ
48 EventFlag* playbackMQEventFlag;
49 EXPECT_TRUE(EventFlag::createEventFlag(mPlaybackMQ->getEventFlagWord(), &playbackMQEventFlag) ==
50 android::OK);
51
52 // open the stream and get its length
Amy Zhang6e8163a2020-04-24 15:41:21 -070053 std::ifstream inputData(mInputDataFile.c_str(), std::ifstream::binary);
54 int writeSize = mPlaybackSettings.packetSize * 6;
Amy Zhang0fe25be2020-04-08 17:30:52 -070055 char* buffer = new char[writeSize];
Amy Zhang6e8163a2020-04-24 15:41:21 -070056 ALOGW("[vts] playback thread loop start %s!", mInputDataFile.c_str());
Amy Zhang0fe25be2020-04-08 17:30:52 -070057 if (!inputData.is_open()) {
58 mPlaybackThreadRunning = false;
59 ALOGW("[vts] Error %s", strerror(errno));
60 }
61
62 while (mPlaybackThreadRunning) {
63 // move the stream pointer for packet size * 6 every read until the end
Amy Zhang6e8163a2020-04-24 15:41:21 -070064 while (mKeepWritingPlaybackFMQ) {
Amy Zhang0fe25be2020-04-08 17:30:52 -070065 inputData.read(buffer, writeSize);
66 if (!inputData) {
67 int leftSize = inputData.gcount();
68 if (leftSize == 0) {
69 mPlaybackThreadRunning = false;
70 break;
71 }
72 inputData.clear();
73 inputData.read(buffer, leftSize);
74 // Write the left over of the input data and quit the thread
75 if (leftSize > 0) {
76 EXPECT_TRUE(mPlaybackMQ->write((unsigned char*)&buffer[0], leftSize));
77 playbackMQEventFlag->wake(
78 static_cast<uint32_t>(DemuxQueueNotifyBits::DATA_READY));
79 }
80 mPlaybackThreadRunning = false;
81 break;
82 }
83 // Write input FMQ and notify the Tuner Implementation
84 EXPECT_TRUE(mPlaybackMQ->write((unsigned char*)&buffer[0], writeSize));
85 playbackMQEventFlag->wake(static_cast<uint32_t>(DemuxQueueNotifyBits::DATA_READY));
86 inputData.seekg(writeSize, inputData.cur);
87 sleep(1);
88 }
89 }
90
91 ALOGW("[vts] Playback thread end.");
92
93 delete[] buffer;
94 inputData.close();
95}
96
97void DvrCallback::testRecordOutput() {
98 android::Mutex::Autolock autoLock(mMsgLock);
99 while (mDataOutputBuffer.empty()) {
100 if (-ETIMEDOUT == mMsgCondition.waitRelative(mMsgLock, WAIT_TIMEOUT)) {
101 EXPECT_TRUE(false) << "record output matching pid does not output within timeout";
Amy Zhang6e8163a2020-04-24 15:41:21 -0700102 stopRecordThread();
Amy Zhang0fe25be2020-04-08 17:30:52 -0700103 return;
104 }
105 }
106 stopRecordThread();
107 ALOGW("[vts] record pass and stop");
108}
109
110void DvrCallback::startRecordOutputThread(RecordSettings recordSettings,
111 MQDesc& recordMQDescriptor) {
112 mRecordMQ = std::make_unique<FilterMQ>(recordMQDescriptor, true /* resetPointers */);
113 EXPECT_TRUE(mRecordMQ);
114 struct RecordThreadArgs* threadArgs =
115 (struct RecordThreadArgs*)malloc(sizeof(struct RecordThreadArgs));
116 threadArgs->user = this;
117 threadArgs->recordSettings = &recordSettings;
118 threadArgs->keepReadingRecordFMQ = &mKeepReadingRecordFMQ;
119
120 pthread_create(&mRecordThread, NULL, __threadLoopRecord, (void*)threadArgs);
121 pthread_setname_np(mRecordThread, "test_record_input_loop");
122}
123
124void* DvrCallback::__threadLoopRecord(void* threadArgs) {
125 DvrCallback* const self =
126 static_cast<DvrCallback*>(((struct RecordThreadArgs*)threadArgs)->user);
127 self->recordThreadLoop(((struct RecordThreadArgs*)threadArgs)->recordSettings,
128 ((struct RecordThreadArgs*)threadArgs)->keepReadingRecordFMQ);
129 return 0;
130}
131
132void DvrCallback::recordThreadLoop(RecordSettings* /*recordSettings*/, bool* keepReadingRecordFMQ) {
133 ALOGD("[vts] DvrCallback record threadLoop start.");
134 android::Mutex::Autolock autoLock(mRecordThreadLock);
135 mRecordThreadRunning = true;
Amy Zhang6e8163a2020-04-24 15:41:21 -0700136 mKeepReadingRecordFMQ = true;
Amy Zhang0fe25be2020-04-08 17:30:52 -0700137
138 // Create the EventFlag that is used to signal the HAL impl that data have been
139 // read from the Record FMQ
140 EventFlag* recordMQEventFlag;
141 EXPECT_TRUE(EventFlag::createEventFlag(mRecordMQ->getEventFlagWord(), &recordMQEventFlag) ==
142 android::OK);
143
144 while (mRecordThreadRunning) {
145 while (*keepReadingRecordFMQ) {
146 uint32_t efState = 0;
147 android::status_t status = recordMQEventFlag->wait(
148 static_cast<uint32_t>(DemuxQueueNotifyBits::DATA_READY), &efState, WAIT_TIMEOUT,
149 true /* retry on spurious wake */);
150 if (status != android::OK) {
151 ALOGD("[vts] wait for data ready on the record FMQ");
152 continue;
153 }
154 // Our current implementation filter the data and write it into the filter FMQ
155 // immediately after the DATA_READY from the VTS/framework
156 if (!readRecordFMQ()) {
157 ALOGD("[vts] record data failed to be filtered. Ending thread");
158 mRecordThreadRunning = false;
159 break;
160 }
161 }
162 }
163
164 mRecordThreadRunning = false;
165 ALOGD("[vts] record thread ended.");
166}
167
168bool DvrCallback::readRecordFMQ() {
169 android::Mutex::Autolock autoLock(mMsgLock);
170 bool result = false;
171 mDataOutputBuffer.clear();
172 mDataOutputBuffer.resize(mRecordMQ->availableToRead());
173 result = mRecordMQ->read(mDataOutputBuffer.data(), mRecordMQ->availableToRead());
174 EXPECT_TRUE(result) << "can't read from Record MQ";
175 mMsgCondition.signal();
176 return result;
177}
178
179void DvrCallback::stopRecordThread() {
180 mKeepReadingRecordFMQ = false;
181 mRecordThreadRunning = false;
Amy Zhang0fe25be2020-04-08 17:30:52 -0700182}
183
Amy Zhanga305c1c2020-04-20 17:59:26 -0700184AssertionResult DvrTests::openDvrInDemux(DvrType type, uint32_t bufferSize) {
Amy Zhang0fe25be2020-04-08 17:30:52 -0700185 Result status;
186 EXPECT_TRUE(mDemux) << "Test with openDemux first.";
187
188 // Create dvr callback
189 mDvrCallback = new DvrCallback();
190
Amy Zhanga305c1c2020-04-20 17:59:26 -0700191 mDemux->openDvr(type, bufferSize, mDvrCallback, [&](Result result, const sp<IDvr>& dvr) {
Amy Zhang0fe25be2020-04-08 17:30:52 -0700192 mDvr = dvr;
193 status = result;
194 });
195
Amy Zhang6e8163a2020-04-24 15:41:21 -0700196 if (status == Result::SUCCESS) {
197 mDvrCallback->setDvr(mDvr);
198 }
Amy Zhang0fe25be2020-04-08 17:30:52 -0700199 return AssertionResult(status == Result::SUCCESS);
200}
201
202AssertionResult DvrTests::configDvr(DvrSettings setting) {
203 Result status = mDvr->configure(setting);
204
205 return AssertionResult(status == Result::SUCCESS);
206}
207
208AssertionResult DvrTests::getDvrMQDescriptor() {
209 Result status;
210 EXPECT_TRUE(mDemux) << "Test with openDemux first.";
211 EXPECT_TRUE(mDvr) << "Test with openDvr first.";
212
213 mDvr->getQueueDesc([&](Result result, const MQDesc& dvrMQDesc) {
214 mDvrMQDescriptor = dvrMQDesc;
215 status = result;
216 });
217
218 return AssertionResult(status == Result::SUCCESS);
219}
220
221AssertionResult DvrTests::attachFilterToDvr(sp<IFilter> filter) {
222 Result status;
223 EXPECT_TRUE(mDemux) << "Test with openDemux first.";
224 EXPECT_TRUE(mDvr) << "Test with openDvr first.";
225
226 status = mDvr->attachFilter(filter);
227
228 return AssertionResult(status == Result::SUCCESS);
229}
230
231AssertionResult DvrTests::detachFilterToDvr(sp<IFilter> filter) {
232 Result status;
233 EXPECT_TRUE(mDemux) << "Test with openDemux first.";
234 EXPECT_TRUE(mDvr) << "Test with openDvr first.";
235
236 status = mDvr->detachFilter(filter);
237
238 return AssertionResult(status == Result::SUCCESS);
239}
240
241AssertionResult DvrTests::startDvr() {
242 Result status;
243 EXPECT_TRUE(mDemux) << "Test with openDemux first.";
244 EXPECT_TRUE(mDvr) << "Test with openDvr first.";
245
246 status = mDvr->start();
247
248 return AssertionResult(status == Result::SUCCESS);
249}
250
251AssertionResult DvrTests::stopDvr() {
252 Result status;
253 EXPECT_TRUE(mDemux) << "Test with openDemux first.";
254 EXPECT_TRUE(mDvr) << "Test with openDvr first.";
255
256 status = mDvr->stop();
257
258 return AssertionResult(status == Result::SUCCESS);
259}
260
261void DvrTests::closeDvr() {
262 ASSERT_TRUE(mDemux);
263 ASSERT_TRUE(mDvr);
264 ASSERT_TRUE(mDvr->close() == Result::SUCCESS);
Amy Zhanga305c1c2020-04-20 17:59:26 -0700265}