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

Commit d977835d authored by Henry Fang's avatar Henry Fang Committed by Automerger Merge Worker
Browse files

Merge "CCodec: add support for tunneled playback." am: 41f53a9b

Original change: https://android-review.googlesource.com/c/platform/frameworks/av/+/1455053

MUST ONLY BE SUBMITTED BY AUTOMERGER

Change-Id: I4104936915e7f51ff04da96b5a8191b4e9662018
parents 2e4b1900 41f53a9b
Loading
Loading
Loading
Loading
+83 −3
Original line number Diff line number Diff line
@@ -44,6 +44,7 @@
#include <media/stagefright/BufferProducerWrapper.h>
#include <media/stagefright/MediaCodecConstants.h>
#include <media/stagefright/PersistentSurface.h>
#include <utils/NativeHandle.h>

#include "C2OMXNode.h"
#include "CCodecBufferChannel.h"
@@ -795,10 +796,30 @@ void CCodec::configure(const sp<AMessage> &msg) {
            mChannel->setMetaMode(CCodecBufferChannel::MODE_ANW);
        }

        status_t err = OK;
        sp<RefBase> obj;
        sp<Surface> surface;
        if (msg->findObject("native-window", &obj)) {
            surface = static_cast<Surface *>(obj.get());
            // setup tunneled playback
            if (surface != nullptr) {
                Mutexed<std::unique_ptr<Config>>::Locked configLocked(mConfig);
                const std::unique_ptr<Config> &config = *configLocked;
                if ((config->mDomain & Config::IS_DECODER)
                        && (config->mDomain & Config::IS_VIDEO)) {
                    int32_t tunneled;
                    if (msg->findInt32("feature-tunneled-playback", &tunneled) && tunneled != 0) {
                        ALOGI("Configuring TUNNELED video playback.");

                        err = configureTunneledVideoPlayback(comp, &config->mSidebandHandle, msg);
                        if (err != OK) {
                            ALOGE("configureTunneledVideoPlayback failed!");
                            return err;
                        }
                        config->mTunneled = true;
                    }
                }
            }
            setSurface(surface);
        }

@@ -1023,7 +1044,7 @@ void CCodec::configure(const sp<AMessage> &msg) {
            sdkParams = msg->dup();
            sdkParams->removeEntryAt(sdkParams->findEntryByName(PARAMETER_KEY_VIDEO_BITRATE));
        }
        status_t err = config->getConfigUpdateFromSdkParams(
        err = config->getConfigUpdateFromSdkParams(
                comp, sdkParams, Config::IS_CONFIG, C2_DONT_BLOCK, &configUpdate);
        if (err != OK) {
            ALOGW("failed to convert configuration to c2 params");
@@ -1703,6 +1724,19 @@ void CCodec::release(bool sendCallback) {
}

status_t CCodec::setSurface(const sp<Surface> &surface) {
    Mutexed<std::unique_ptr<Config>>::Locked configLocked(mConfig);
    const std::unique_ptr<Config> &config = *configLocked;
    if (config->mTunneled && config->mSidebandHandle != nullptr) {
        sp<ANativeWindow> nativeWindow = static_cast<ANativeWindow *>(surface.get());
        status_t err = native_window_set_sideband_stream(
                nativeWindow.get(),
                const_cast<native_handle_t *>(config->mSidebandHandle->handle()));
        if (err != OK) {
            ALOGE("NativeWindow(%p) native_window_set_sideband_stream(%p) failed! (err %d).",
                    nativeWindow.get(), config->mSidebandHandle->handle(), err);
            return err;
        }
    }
    return mChannel->setSurface(surface);
}

@@ -2099,6 +2133,51 @@ void CCodec::setDeadline(
    deadline->set(now + (timeout * mult), name);
}

status_t CCodec::configureTunneledVideoPlayback(
        std::shared_ptr<Codec2Client::Component> comp,
        sp<NativeHandle> *sidebandHandle,
        const sp<AMessage> &msg) {
    std::vector<std::unique_ptr<C2SettingResult>> failures;

    std::unique_ptr<C2PortTunneledModeTuning::output> tunneledPlayback =
        C2PortTunneledModeTuning::output::AllocUnique(
            1,
            C2PortTunneledModeTuning::Struct::SIDEBAND,
            C2PortTunneledModeTuning::Struct::REALTIME,
            0);
    // TODO: use KEY_AUDIO_HW_SYNC, KEY_HARDWARE_AV_SYNC_ID when they are in MediaCodecConstants.h
    if (msg->findInt32("audio-hw-sync", &tunneledPlayback->m.syncId[0])) {
        tunneledPlayback->m.syncType = C2PortTunneledModeTuning::Struct::sync_type_t::AUDIO_HW_SYNC;
    } else if (msg->findInt32("hw-av-sync-id", &tunneledPlayback->m.syncId[0])) {
        tunneledPlayback->m.syncType = C2PortTunneledModeTuning::Struct::sync_type_t::HW_AV_SYNC;
    } else {
        tunneledPlayback->m.syncType = C2PortTunneledModeTuning::Struct::sync_type_t::REALTIME;
        tunneledPlayback->setFlexCount(0);
    }
    c2_status_t c2err = comp->config({ tunneledPlayback.get() }, C2_MAY_BLOCK, &failures);
    if (c2err != C2_OK) {
        return UNKNOWN_ERROR;
    }

    std::vector<std::unique_ptr<C2Param>> params;
    c2err = comp->query({}, {C2PortTunnelHandleTuning::output::PARAM_TYPE}, C2_DONT_BLOCK, &params);
    if (c2err == C2_OK && params.size() == 1u) {
        C2PortTunnelHandleTuning::output *videoTunnelSideband =
            C2PortTunnelHandleTuning::output::From(params[0].get());
        // Currently, Codec2 only supports non-fd case for sideband native_handle.
        native_handle_t *handle = native_handle_create(0, videoTunnelSideband->flexCount());
        *sidebandHandle = NativeHandle::create(handle, true /* ownsHandle */);
        if (handle != nullptr && videoTunnelSideband->flexCount()) {
            memcpy(handle->data, videoTunnelSideband->m.values,
                    sizeof(int32_t) * videoTunnelSideband->flexCount());
            return OK;
        } else {
            return NO_MEMORY;
        }
    }
    return UNKNOWN_ERROR;
}

void CCodec::initiateReleaseIfStuck() {
    std::string name;
    bool pendingDeadline = false;
@@ -2111,7 +2190,9 @@ void CCodec::initiateReleaseIfStuck() {
            pendingDeadline = true;
        }
    }
    if (name.empty()) {
    Mutexed<std::unique_ptr<Config>>::Locked configLocked(mConfig);
    const std::unique_ptr<Config> &config = *configLocked;
    if (config->mTunneled == false && name.empty()) {
        constexpr std::chrono::steady_clock::duration kWorkDurationThreshold = 3s;
        std::chrono::steady_clock::duration elapsed = mChannel->elapsed();
        if (elapsed >= kWorkDurationThreshold) {
@@ -2500,4 +2581,3 @@ std::shared_ptr<C2GraphicBlock> CCodec::FetchGraphicBlock(
}

}  // namespace android
+3 −1
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@
#define LOG_TAG "CCodecConfig"
#include <cutils/properties.h>
#include <log/log.h>
#include <utils/NativeHandle.h>

#include <C2Component.h>
#include <C2Param.h>
@@ -321,7 +322,8 @@ const std::vector<ConfigMapper> StandardParams::NO_MAPPERS;
CCodecConfig::CCodecConfig()
    : mInputFormat(new AMessage),
      mOutputFormat(new AMessage),
      mUsingSurface(false) { }
      mUsingSurface(false),
      mTunneled(false) { }

void CCodecConfig::initializeStandardParams() {
    typedef Domain D;
+5 −0
Original line number Diff line number Diff line
@@ -35,6 +35,7 @@
namespace android {

struct AMessage;
class NativeHandle;
struct StandardParams;

/**
@@ -141,6 +142,10 @@ struct CCodecConfig {

    std::set<std::string> mLastConfig;

    /// Tunneled codecs
    bool mTunneled;
    sp<NativeHandle> mSidebandHandle;

    CCodecConfig();

    /// initializes the members required to manage the format: descriptors, reflector,
+5 −0
Original line number Diff line number Diff line
@@ -126,6 +126,11 @@ private:
            const std::chrono::milliseconds &timeout,
            const char *name);

    status_t configureTunneledVideoPlayback(
            const std::shared_ptr<Codec2Client::Component> comp,
            sp<NativeHandle> *sidebandHandle,
            const sp<AMessage> &msg);

    enum {
        kWhatAllocate,
        kWhatConfigure,