You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
195 lines
6.8 KiB
195 lines
6.8 KiB
/*
|
|
* Copyright 2020 The Android Open Source Project
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
#include <android-base/logging.h>
|
|
#include <android/hardware/tv/tuner/1.0/IDvr.h>
|
|
#include <android/hardware/tv/tuner/1.0/IDvrCallback.h>
|
|
#include <android/hardware/tv/tuner/1.0/ITuner.h>
|
|
#include <android/hardware/tv/tuner/1.0/types.h>
|
|
#include <fcntl.h>
|
|
#include <fmq/MessageQueue.h>
|
|
#include <gtest/gtest.h>
|
|
#include <hidl/HidlSupport.h>
|
|
#include <hidl/Status.h>
|
|
#include <utils/Condition.h>
|
|
#include <utils/Mutex.h>
|
|
#include <fstream>
|
|
#include <iostream>
|
|
#include <map>
|
|
|
|
#include "FilterTests.h"
|
|
|
|
using android::Condition;
|
|
using android::Mutex;
|
|
using android::sp;
|
|
using android::hardware::EventFlag;
|
|
using android::hardware::kSynchronizedReadWrite;
|
|
using android::hardware::MessageQueue;
|
|
using android::hardware::MQDescriptorSync;
|
|
using android::hardware::Return;
|
|
using android::hardware::Void;
|
|
using android::hardware::tv::tuner::V1_0::DemuxFilterStatus;
|
|
using android::hardware::tv::tuner::V1_0::DvrSettings;
|
|
using android::hardware::tv::tuner::V1_0::DvrType;
|
|
using android::hardware::tv::tuner::V1_0::IDvr;
|
|
using android::hardware::tv::tuner::V1_0::IDvrCallback;
|
|
using android::hardware::tv::tuner::V1_0::ITuner;
|
|
using android::hardware::tv::tuner::V1_0::PlaybackSettings;
|
|
using android::hardware::tv::tuner::V1_0::PlaybackStatus;
|
|
using android::hardware::tv::tuner::V1_0::RecordSettings;
|
|
using android::hardware::tv::tuner::V1_0::RecordStatus;
|
|
using android::hardware::tv::tuner::V1_0::Result;
|
|
|
|
using namespace std;
|
|
|
|
#define WAIT_TIMEOUT 3000000000
|
|
|
|
class DvrCallback : public IDvrCallback {
|
|
public:
|
|
virtual Return<void> onRecordStatus(DemuxFilterStatus status) override {
|
|
ALOGD("[vts] record status %hhu", status);
|
|
switch (status) {
|
|
case DemuxFilterStatus::DATA_READY:
|
|
break;
|
|
case DemuxFilterStatus::LOW_WATER:
|
|
break;
|
|
case DemuxFilterStatus::HIGH_WATER:
|
|
case DemuxFilterStatus::OVERFLOW:
|
|
ALOGD("[vts] record overflow. Flushing.");
|
|
EXPECT_TRUE(mDvr) << "Dvr callback is not set with an IDvr";
|
|
if (mDvr) {
|
|
Result result = mDvr->flush();
|
|
ALOGD("[vts] Flushing result %d.", result);
|
|
}
|
|
break;
|
|
}
|
|
return Void();
|
|
}
|
|
|
|
virtual Return<void> onPlaybackStatus(PlaybackStatus status) override {
|
|
// android::Mutex::Autolock autoLock(mMsgLock);
|
|
ALOGD("[vts] playback status %d", status);
|
|
switch (status) {
|
|
case PlaybackStatus::SPACE_EMPTY:
|
|
case PlaybackStatus::SPACE_ALMOST_EMPTY:
|
|
ALOGD("[vts] keep playback inputing %d", status);
|
|
mKeepWritingPlaybackFMQ = true;
|
|
break;
|
|
case PlaybackStatus::SPACE_ALMOST_FULL:
|
|
case PlaybackStatus::SPACE_FULL:
|
|
ALOGD("[vts] stop playback inputing %d", status);
|
|
mKeepWritingPlaybackFMQ = false;
|
|
break;
|
|
}
|
|
return Void();
|
|
}
|
|
|
|
void stopPlaybackThread();
|
|
void testRecordOutput();
|
|
void stopRecordThread();
|
|
|
|
void startPlaybackInputThread(string& dataInputFile, PlaybackSettings& settings,
|
|
MQDesc& playbackMQDescriptor);
|
|
void startRecordOutputThread(RecordSettings recordSettings, MQDesc& recordMQDescriptor);
|
|
static void* __threadLoopPlayback(void* user);
|
|
static void* __threadLoopRecord(void* threadArgs);
|
|
void playbackThreadLoop();
|
|
void recordThreadLoop(RecordSettings* recordSetting, bool* keepWritingPlaybackFMQ);
|
|
|
|
bool readRecordFMQ();
|
|
|
|
void setDvr(sp<IDvr> dvr) { mDvr = dvr; }
|
|
|
|
private:
|
|
struct RecordThreadArgs {
|
|
DvrCallback* user;
|
|
RecordSettings* recordSettings;
|
|
bool* keepReadingRecordFMQ;
|
|
};
|
|
// uint16_t mDataLength = 0;
|
|
std::vector<uint8_t> mDataOutputBuffer;
|
|
|
|
std::map<uint32_t, std::unique_ptr<FilterMQ>> mFilterMQ;
|
|
std::unique_ptr<FilterMQ> mPlaybackMQ;
|
|
std::unique_ptr<FilterMQ> mRecordMQ;
|
|
std::map<uint32_t, EventFlag*> mFilterMQEventFlag;
|
|
|
|
android::Mutex mMsgLock;
|
|
android::Mutex mPlaybackThreadLock;
|
|
android::Mutex mRecordThreadLock;
|
|
android::Condition mMsgCondition;
|
|
|
|
bool mKeepWritingPlaybackFMQ = true;
|
|
bool mKeepReadingRecordFMQ = true;
|
|
bool mPlaybackThreadRunning;
|
|
bool mRecordThreadRunning;
|
|
pthread_t mPlaybackThread;
|
|
pthread_t mRecordThread;
|
|
string mInputDataFile;
|
|
PlaybackSettings mPlaybackSettings;
|
|
|
|
sp<IDvr> mDvr = nullptr;
|
|
|
|
// int mPidFilterOutputCount = 0;
|
|
};
|
|
|
|
class DvrTests {
|
|
public:
|
|
void setService(sp<ITuner> tuner) { mService = tuner; }
|
|
void setDemux(sp<IDemux> demux) { mDemux = demux; }
|
|
|
|
void startPlaybackInputThread(string& dataInputFile, PlaybackSettings& settings) {
|
|
mDvrPlaybackCallback->startPlaybackInputThread(dataInputFile, settings,
|
|
mDvrPlaybackMQDescriptor);
|
|
};
|
|
|
|
void startRecordOutputThread(RecordSettings settings) {
|
|
mDvrRecordCallback->startRecordOutputThread(settings, mDvrRecordMQDescriptor);
|
|
};
|
|
|
|
void stopPlaybackThread() { mDvrPlaybackCallback->stopPlaybackThread(); }
|
|
void testRecordOutput() { mDvrRecordCallback->testRecordOutput(); }
|
|
void stopRecordThread() { mDvrRecordCallback->stopRecordThread(); }
|
|
|
|
AssertionResult openDvrInDemux(DvrType type, uint32_t bufferSize);
|
|
AssertionResult configDvrPlayback(DvrSettings setting);
|
|
AssertionResult configDvrRecord(DvrSettings setting);
|
|
AssertionResult getDvrPlaybackMQDescriptor();
|
|
AssertionResult getDvrRecordMQDescriptor();
|
|
AssertionResult attachFilterToDvr(sp<IFilter> filter);
|
|
AssertionResult detachFilterToDvr(sp<IFilter> filter);
|
|
AssertionResult stopDvrPlayback();
|
|
AssertionResult startDvrPlayback();
|
|
AssertionResult stopDvrRecord();
|
|
AssertionResult startDvrRecord();
|
|
void closeDvrPlayback();
|
|
void closeDvrRecord();
|
|
|
|
protected:
|
|
static AssertionResult failure() { return ::testing::AssertionFailure(); }
|
|
|
|
static AssertionResult success() { return ::testing::AssertionSuccess(); }
|
|
|
|
sp<ITuner> mService;
|
|
sp<IDvr> mDvrPlayback;
|
|
sp<IDvr> mDvrRecord;
|
|
sp<IDemux> mDemux;
|
|
sp<DvrCallback> mDvrPlaybackCallback;
|
|
sp<DvrCallback> mDvrRecordCallback;
|
|
MQDesc mDvrPlaybackMQDescriptor;
|
|
MQDesc mDvrRecordMQDescriptor;
|
|
};
|