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

Commit 28fb53f4 authored by Amy Zhang's avatar Amy Zhang Committed by Android (Google) Code Review
Browse files

Merge "Add an initial Demxu client and Filter Client interface"

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