Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 6bfeaa0e authored by Amy Zhang's avatar Amy Zhang
Browse files

Add an initial Demxu client and Filter Client interface

Test: make libmedia_tv_tuner
Bug: 174095851

Change-Id: I8af379bf2810bee3dedf69ea0187766300b05370
parent a673468e
Loading
Loading
Loading
Loading
+2 −0
Original line number Original line Diff line number Diff line
@@ -139,6 +139,8 @@ cc_library_shared {
    name: "libmedia_tv_tuner",
    name: "libmedia_tv_tuner",
    srcs: [
    srcs: [
        "android_media_tv_Tuner.cpp",
        "android_media_tv_Tuner.cpp",
        "tuner/DemuxClient.cpp",
        "tuner/FilterClient.cpp",
        "tuner/FrontendClient.cpp",
        "tuner/FrontendClient.cpp",
        "tuner/TunerClient.cpp",
        "tuner/TunerClient.cpp",
    ],
    ],
+123 −0
Original line number Original line Diff line number Diff line
/*
 * 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.
 */

#define LOG_TAG "FrontendClient"

#include <android-base/logging.h>
#include <utils/Log.h>

#include "DemuxClient.h"

using ::aidl::android::media::tv::tuner::TunerFrontendSettings;

using ::android::hardware::tv::tuner::V1_0::Result;

namespace android {

/////////////// DemuxClient ///////////////////////

// TODO: pending aidl interface
DemuxClient::DemuxClient() {
    //mTunerDemux = tunerDemux;
}

DemuxClient::~DemuxClient() {
    //mTunerDemux = NULL;
    mDemux = NULL;
}

// TODO: remove after migration to Tuner Service is done.
void DemuxClient::setHidlDemux(sp<IDemux> demux) {
    mDemux = demux;
}

Result DemuxClient::setFrontendDataSource(sp<FrontendClient> tunerFrontend) {
    // TODO: pending aidl interface
    /*if (mTunerDemux != NULL) {
        // TODO: handle error message
        mTunerDemux->setFrontendDataSource(tunerFrontend->getAidlFrontend());
        return (int) Result::SUCCESS;
    }*/

    if (mDemux != NULL) {
        Result res = mDemux->setFrontendDataSource(tunerFrontend->getId());
        return res;
    }

    return Result::INVALID_STATE;
}

//FilterClient openFilter(int mainType, int subType, int bufferSize, FilterClientCallback cb);

int DemuxClient::getAvSyncHwId(FilterClient /*tunerFilter*/) {
    return 0;
}

long DemuxClient::getAvSyncTime(int avSyncHwId) {
    // pending aidl interface

    if (mDemux != NULL) {
        uint64_t time;
        Result res;
        mDemux->getAvSyncTime(static_cast<uint32_t>(avSyncHwId),
                [&](Result r, uint64_t ts) {
                    res = r;
                    time = ts;
                });
        if (res == Result::SUCCESS) {
            return (long) time;
        }
    }

    return -1;
}

//DvrClient openDvr(int dvbType, int bufferSize, DvrClientCallback cb);

Result DemuxClient::connectCiCam(int ciCamId) {
    // pending aidl interface

    if (mDemux != NULL) {
        return mDemux->connectCiCam(static_cast<uint32_t>(ciCamId));
    }

    return Result::INVALID_STATE;
}

Result DemuxClient::disconnectCiCam() {
    // pending aidl interface

    if (mDemux != NULL) {
        return mDemux->disconnectCiCam();
    }

    return Result::INVALID_STATE;
}

Result DemuxClient::close() {
    // pending aidl interface

    if (mDemux != NULL) {
        Result res = mDemux->close();
        if (res == Result::SUCCESS) {
            mDemux = NULL;
        }
        return res;
    }

    return Result::INVALID_STATE;
}
}  // namespace android
+104 −0
Original line number Original line Diff line number Diff line
/*
 * 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.
 */

#ifndef _ANDROID_MEDIA_TV_DEMUX_CLIENT_H_
#define _ANDROID_MEDIA_TV_DEMUX_CLIENT_H_

//#include <aidl/android/media/tv/tuner/ITunerDemux.h>
#include <android/hardware/tv/tuner/1.0/IDemux.h>
#include <android/hardware/tv/tuner/1.1/types.h>

#include "FilterClient.h"
#include "FrontendClient.h"

//using ::aidl::android::media::tv::tuner::ITunerDemux;

using ::android::hardware::tv::tuner::V1_0::IDemux;

using namespace std;

namespace android {

struct DemuxClient : public RefBase {

public:
    DemuxClient();
    ~DemuxClient();

    // TODO: remove after migration to Tuner Service is done.
    void setHidlDemux(sp<IDemux> demux);

    /**
     * Set a frontend resource as data input of the demux.
     */
    Result setFrontendDataSource(sp<FrontendClient> tunerFrontend);

    /**
     * Open a new filter client.
     */
    //FilterClient openFilter(int mainType, int subType, int bufferSize, FilterClientCallback cb);

    // TODO: handle TimeFilterClient

    /**
     * Get hardware sync ID for audio and video.
     */
    int getAvSyncHwId(FilterClient tunerFilter);

    /**
     * Get current time stamp to use for A/V sync.
     */
    long getAvSyncTime(int avSyncHwId);

    /**
     * Open a DVR (Digital Video Record) client.
     */
    // TODO: handle DvrClient and callback
    //DvrClient openDvr(int dvbType, int bufferSize, DvrClientCallback cb);  

    /**
     * Connect Conditional Access Modules (CAM) through Common Interface (CI).
     */
    Result connectCiCam(int ciCamId);

    /**
     * Disconnect Conditional Access Modules (CAM).
     */
    Result disconnectCiCam();

    /**
     * Release the Demux Client.
     */
    Result close();

private:
    /**
     * An AIDL Tuner Demux Singleton assigned at the first time the Tuner Client
     * opens a demux. Default null when demux is not opened.
     */
    // TODO: pending on aidl interface
    //shared_ptr<ITunerDemux> mTunerDemux;

    /**
     * A Demux HAL interface that is ready before migrating to the TunerDemux.
     * This is a temprary interface before Tuner Framework migrates to use TunerService.
     * Default null when the HAL service does not exist.
     */
    sp<IDemux> mDemux;
};
}  // namespace android

#endif  // _ANDROID_MEDIA_TV_DEMUX_CLIENT_H_
+243 −0
Original line number Original line Diff line number Diff line
/*
 * 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.
 */

#define LOG_TAG "FrontendClient"

#include <android-base/logging.h>
#include <utils/Log.h>

#include "FilterClient.h"

using ::android::hardware::tv::tuner::V1_0::DemuxQueueNotifyBits;

namespace android {

//shared_ptr<ITunerFilter> FilterClient::mTunerFilter;
sp<IFilter> FilterClient::mFilter;
sp<::android::hardware::tv::tuner::V1_1::IFilter> FilterClient::mFilter_1_1;

/////////////// FilterClient ///////////////////////

// TODO: pending aidl interface
// TODO: add filter callback
FilterClient::FilterClient() {
    //mTunerFilter = tunerFilter;
}

FilterClient::~FilterClient() {
    //mTunerFilter = NULL;
    mFilter = NULL;
    mFilter_1_1 = NULL;
}

// TODO: remove after migration to Tuner Service is done.
void FilterClient::setHidlFilter(sp<IFilter> filter) {
    mFilter = filter;
    mFilter_1_1 = ::android::hardware::tv::tuner::V1_1::IFilter::castFrom(mFilter);
}

//Result setCallback(FilterClientCallback filterClientCallback);

int FilterClient::read(uint8_t* buffer, int size) {
    // TODO: pending aidl interface

    if (mFilter != NULL) {
        Result res = getFilterMq();
        if (res != Result::SUCCESS) {
            return -1;
        }
        return copyData(buffer, size);
    }

    return -1;
}

Result FilterClient::configure(DemuxFilterSettings configure) {
    // TODO: pending aidl interface

    if (mFilter != NULL) {
        return mFilter->configure(configure);
    }

    return Result::INVALID_STATE;
}

Result FilterClient::configureMonitorEvent(int monitorEventType) {
    // TODO: pending aidl interface

    if (mFilter_1_1 != NULL) {
        return mFilter_1_1->configureMonitorEvent(monitorEventType);
    }

    return Result::INVALID_STATE;
}

Result FilterClient::configureIpFilterContextId(int cid) {
    // TODO: pending aidl interface

    if (mFilter_1_1 != NULL) {
        return mFilter_1_1->configureIpCid(cid);
    }

    return Result::INVALID_STATE;
}

Result FilterClient::configureAvStreamType(AvStreamType avStreamType) {
    // TODO: pending aidl interface

    if (mFilter_1_1 != NULL) {
        return mFilter_1_1->configureAvStreamType(avStreamType);
    }

    return Result::INVALID_STATE;
}

Result FilterClient::start() {
    // TODO: pending aidl interface

    if (mFilter != NULL) {
        return mFilter->start();
    }

    return Result::INVALID_STATE;
}

Result FilterClient::stop() {
    // TODO: pending aidl interface

    if (mFilter != NULL) {
        return mFilter->stop();
    }

    return Result::INVALID_STATE;
}

Result FilterClient::flush() {
    // TODO: pending aidl interface

    if (mFilter != NULL) {
        return mFilter->flush();
    }

    return Result::INVALID_STATE;
}

Result FilterClient::getId(uint32_t& id) {
    // TODO: pending aidl interface

    if (mFilter != NULL) {
        Result res;
        mFilter->getId([&](Result r, uint32_t filterId) {
            res = r;
            id = filterId;
        });
        return res;
    }

    return Result::INVALID_STATE;
}

Result FilterClient::getId64Bit(uint64_t& id) {
    // TODO: pending aidl interface

    if (mFilter_1_1 != NULL) {
        Result res;
        mFilter_1_1->getId64Bit([&](Result r, uint64_t filterId) {
            res = r;
            id = filterId;
        });
        return res;
    }

    return Result::INVALID_STATE;
}

Result FilterClient::releaseAvHandle(native_handle_t* handle, uint64_t avDataId) {
    // TODO: pending aidl interface

    if (mFilter != NULL) {
        return mFilter->releaseAvHandle(hidl_handle(handle), avDataId);
    }

    return Result::INVALID_STATE;
}

Result FilterClient::setDataSource(sp<FilterClient> filterClient){
    // TODO: pending aidl interface

    if (mFilter != NULL) {
        sp<IFilter> sourceFilter = filterClient->getHalFilter();
        if (sourceFilter == NULL) {
            return Result::INVALID_ARGUMENT;
        }
        return mFilter->setDataSource(sourceFilter);
    }

    return Result::INVALID_STATE;
}

Result FilterClient::close() {
    // TODO: pending aidl interface

    if (mFilter != NULL) {
        return mFilter->close();
    }

    return Result::INVALID_STATE;
}

/////////////// FilterClient Helper Methods ///////////////////////

Result FilterClient::getFilterMq() {
    if (mFilter == NULL) {
        return Result::INVALID_STATE;
    }

    if (mFilterMQ != NULL) {
        return Result::SUCCESS;
    }

    Result getQueueDescResult = Result::UNKNOWN_ERROR;
    MQDescriptorSync<uint8_t> filterMQDesc;
    mFilter->getQueueDesc(
            [&](Result r, const MQDescriptorSync<uint8_t>& desc) {
                filterMQDesc = desc;
                getQueueDescResult = r;
            });
    if (getQueueDescResult == Result::SUCCESS) {
        mFilterMQ = std::make_unique<MQ>(filterMQDesc, true);
        EventFlag::createEventFlag(mFilterMQ->getEventFlagWord(), &mFilterMQEventFlag);
    }
    return getQueueDescResult;
}

int FilterClient::copyData(uint8_t* buffer, int size) {
    if (mFilter == NULL || mFilterMQ == NULL || mFilterMQEventFlag == NULL) {
        return -1;
    }

    int available = mFilterMQ->availableToRead();
    size = min(size, available);

    if (mFilterMQ->read(buffer, size)) {
        mFilterMQEventFlag->wake(static_cast<uint32_t>(DemuxQueueNotifyBits::DATA_CONSUMED));
    } else {
        return -1;
    }

    return size;
}
}  // namespace android
+166 −0
Original line number Original line Diff line number Diff line
/*
 * 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.
 */

#ifndef _ANDROID_MEDIA_TV_FILTER_CLIENT_H_
#define _ANDROID_MEDIA_TV_FILTER_CLIENT_H_

//#include <aidl/android/media/tv/tuner/ITunerFilter.h>
#include <android/hardware/tv/tuner/1.1/IFilter.h>
#include <android/hardware/tv/tuner/1.1/types.h>
#include <fmq/MessageQueue.h>

//#include "FilterClientCallback.h"

//using ::aidl::android::media::tv::tuner::ITunerFilter;

using ::android::hardware::EventFlag;
using ::android::hardware::MessageQueue;
using ::android::hardware::MQDescriptorSync;
using ::android::hardware::hidl_handle;
using ::android::hardware::tv::tuner::V1_0::DemuxFilterSettings;
using ::android::hardware::tv::tuner::V1_0::IFilter;
using ::android::hardware::tv::tuner::V1_0::Result;
using ::android::hardware::tv::tuner::V1_1::AvStreamType;

using namespace std;

using MQ = MessageQueue<uint8_t, kSynchronizedReadWrite>;

namespace android {

struct FilterClient : public RefBase {

public:
    // TODO: pending aidl interface
    FilterClient();
    ~FilterClient();

    // TODO: remove after migration to Tuner Service is done.
    void setHidlFilter(sp<IFilter> filter);

    /**
     * Set the filter client callback.
     */
    //Result setCallback(FilterClientCallback filterClientCallback);

    /**
     * Read size of data from filter FMQ into buffer.
     *
     * @return the actual reading size. -1 if failed to read.
     */
    int read(uint8_t* buffer, int size);

    /**
     * Configure the filter.
     */
    Result configure(DemuxFilterSettings configure);

    /**
     * Configure the monitor event of the Filter.
     */
    Result configureMonitorEvent(int monitorEventType);

    /**
     * Configure the context id of the IP Filter.
     */
    Result configureIpFilterContextId(int cid);

    /**
     * Configure the stream type of the media Filter.
     */
    Result configureAvStreamType(AvStreamType avStreamType);

    /**
     * Start the filter.
     */
    Result start();

    /**
     * Stop the filter.
     */
    Result stop();

    /**
     * Flush the filter.
     */
    Result flush();

    /**
     * Get the 32-bit filter Id.
     */
    Result getId(uint32_t& id);

    /**
     * Get the 64-bit filter Id.
     */
    Result getId64Bit(uint64_t& id);

    /**
     * Release the handle reported by the HAL for AV memory.
     */
    Result releaseAvHandle(native_handle_t* handle, uint64_t avDataId);

    /**
     * Set the filter's data source.
     */
    Result setDataSource(sp<FilterClient> filterClient);

    /**
     * Get the Hal filter to build up filter linkage.
     */
    sp<IFilter> getHalFilter() { return mFilter; }

    /**
     * Get the Aidl filter to build up filter linkage.
     */
    //shared_ptr<ITunerFilter> getAidlFilter() { return mTunerFilter; }

    /**
     * Close a new interface of ITunerFilter.
     */
    Result close();

private:
    Result getFilterMq();
    int copyData(uint8_t* buffer, int size);

    /**
     * An AIDL Tuner Filter Singleton assigned at the first time when the Tuner Client
     * opens a filter. Default null when Tuner Service does not exist.
     */
    // TODO: pending on aidl interface
    //static shared_ptr<ITunerFilter> mTunerFilter;

    /**
     * A 1.0 Filter HAL interface that is ready before migrating to the TunerFilter.
     * This is a temprary interface before Tuner Framework migrates to use TunerService.
     * Default null when the HAL service does not exist.
     */
    static sp<IFilter> mFilter;

    /**
     * A 1.1 Filter HAL interface that is ready before migrating to the TunerFilter.
     * This is a temprary interface before Tuner Framework migrates to use TunerService.
     * Default null when the HAL service does not exist.
     */
    static sp<::android::hardware::tv::tuner::V1_1::IFilter> mFilter_1_1;

    unique_ptr<MQ> mFilterMQ;
    EventFlag* mFilterMQEventFlag;
};
}  // namespace android

#endif  // _ANDROID_MEDIA_TV_FILTER_CLIENT_H_
Loading