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

Commit 17c160c2 authored by Steve Kondik's avatar Steve Kondik
Browse files

stagefright: Support hardware codecs with FFMPEG extractor

 * Quite often we'll be using our custom extractor to handle
   container formats which aren't supported by any other means,
   but the codecs used inside the container are hardware supported.
 * For QC specifically we need to send a few magical incantations,
   so add support for this. Software codecs will be used if
   hardware support is unavailable.

Change-Id: I917b674142fdab0b009e066e9511648c2695ec4b
parent 92d5d486
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -62,7 +62,8 @@ struct FFMPEGSoftCodec {
    static status_t setVideoFormat(
            const sp<AMessage> &msg, const char* mime,
            sp<IOMX> OMXhandle,IOMX::node_id nodeID,
            bool isEncoder, OMX_VIDEO_CODINGTYPE *compressionFormat);
            bool isEncoder, OMX_VIDEO_CODINGTYPE *compressionFormat,
            const char* componentName);

    static status_t getAudioPortFormat(
            OMX_U32 portIndex, int coding,
+7 −13
Original line number Diff line number Diff line
@@ -1603,11 +1603,7 @@ status_t ACodec::setComponentRole(
    }

    if (i == kNumMimeToRole) {
        status_t err = ERROR_UNSUPPORTED;
        if (!strncmp(mComponentName.c_str(), "OMX.ffmpeg.", 11)) {
            err = FFMPEGSoftCodec::setSupportedRole(mOMX, mNode, isEncoder, mime);
        }
        return err;
        return FFMPEGSoftCodec::setSupportedRole(mOMX, mNode, isEncoder, mime);
    }

    const char *role =
@@ -2930,10 +2926,9 @@ status_t ACodec::setupVideoDecoder(
    status_t err = GetVideoCodingTypeFromMime(mime, &compressionFormat);

    if (err != OK) {
        if (!strncmp(mComponentName.c_str(), "OMX.ffmpeg.", 11)) {
        err = FFMPEGSoftCodec::setVideoFormat(
                    msg, mime, mOMX, mNode, mIsEncoder, &compressionFormat);
        }
                    msg, mime, mOMX, mNode, mIsEncoder, &compressionFormat,
                    mComponentName.c_str());
        if (err != OK) {
            return err;
        }
@@ -3086,10 +3081,9 @@ status_t ACodec::setupVideoEncoder(const char *mime, const sp<AMessage> &msg) {
    err = GetVideoCodingTypeFromMime(mime, &compressionFormat);

    if (err != OK) {
        if (!strncmp(mComponentName.c_str(), "OMX.ffmpeg.", 11)) {
        err = FFMPEGSoftCodec::setVideoFormat(
                    msg, mime, mOMX, mNode, mIsEncoder, &compressionFormat);
        }
                msg, mime, mOMX, mNode, mIsEncoder, &compressionFormat,
                mComponentName.c_str());
        if (err != OK) {
            ALOGE("Not a supported video mime type: %s", mime);
            return err;
+3 −0
Original line number Diff line number Diff line
@@ -161,6 +161,8 @@ ifeq ($(TARGET_USES_QCOM_BSP), true)
    LOCAL_CFLAGS += -DQTI_BSP
endif

LOCAL_C_INCLUDES += $(call project-path-for,qcom-media)/mm-core/inc

# enable experiments only in userdebug and eng builds
ifneq (,$(filter userdebug eng,$(TARGET_BUILD_VARIANT)))
LOCAL_CFLAGS += -DENABLE_STAGEFRIGHT_EXPERIMENTS
@@ -189,6 +191,7 @@ endif
# FFMPEG plugin
LOCAL_C_INCLUDES += $(TOP)/external/stagefright-plugins/include

#LOCAL_CFLAGS += -DLOG_NDEBUG=0
LOCAL_MODULE:= libstagefright

LOCAL_MODULE_TAGS := optional
+86 −7
Original line number Diff line number Diff line
@@ -37,6 +37,10 @@

#include <OMX_FFMPEG_Extn.h>

#ifdef QCOM_HARDWARE
#include <OMX_QCOMExtns.h>
#endif

namespace android {

enum MetaKeyType{
@@ -217,7 +221,8 @@ void FFMPEGSoftCodec::overrideComponentName(
status_t FFMPEGSoftCodec::setVideoFormat(
        const sp<AMessage> &msg, const char* mime, sp<IOMX> OMXhandle,
        IOMX::node_id nodeID, bool isEncoder,
        OMX_VIDEO_CODINGTYPE *compressionFormat) {
        OMX_VIDEO_CODINGTYPE *compressionFormat,
        const char* componentName) {
    status_t err = OK;

    if (isEncoder) {
@@ -225,12 +230,13 @@ status_t FFMPEGSoftCodec::setVideoFormat(
        err = BAD_VALUE;
    
    } else if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_WMV, mime)) {
        if (strncmp(componentName, "OMX.ffmpeg.", 11) == 0) {
            err = setWMVFormat(msg, OMXhandle, nodeID);
            if (err != OK) {
                ALOGE("setWMVFormat() failed (err = %d)", err);
        } else {
            *compressionFormat = OMX_VIDEO_CodingWMV;
            }
        }
        *compressionFormat = OMX_VIDEO_CodingWMV;
    } else if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_RV, mime)) {
        err = setRVFormat(msg, OMXhandle, nodeID);
        if (err != OK) {
@@ -258,6 +264,79 @@ status_t FFMPEGSoftCodec::setVideoFormat(
        err = BAD_TYPE;
    }

#ifdef QCOM_HARDWARE
    // We need to do a few extra steps if FFMPEGExtractor is in control
    // and we want to talk to the hardware codecs. This logic is taken
    // from the CAF L release. It was unfortunately moved to a proprietary
    // blob and an architecture which is hellish for OEMs who wish to
    // customize the platform.
    if (err != BAD_TYPE && (strncmp(componentName, "OMX.qcom.", 9) == 0)) {
        status_t xerr = OK;

        int32_t mode = 0;
        OMX_QCOM_PARAM_PORTDEFINITIONTYPE portFmt;
        portFmt.nPortIndex = kPortIndexInput;

        if (msg->findInt32("use-arbitrary-mode", &mode) && mode) {
            ALOGI("Decoder will be in arbitrary mode");
            portFmt.nFramePackingFormat = OMX_QCOM_FramePacking_Arbitrary;
        } else {
            ALOGI("Decoder will be in frame by frame mode");
            portFmt.nFramePackingFormat = OMX_QCOM_FramePacking_OnlyOneCompleteFrame;
        }
        xerr = OMXhandle->setParameter(
                nodeID, (OMX_INDEXTYPE)OMX_QcomIndexPortDefn,
                (void *)&portFmt, sizeof(portFmt));
        if (xerr != OK) {
            ALOGW("Failed to set frame packing format on component");
        }

        // Enable timestamp reordering for mpeg4 and vc1 codec types, the AVI file
        // type, and hevc content in the ts container
        bool tsReorder = false;
        const char* roleVC1 = "OMX.qcom.video.decoder.vc1";
        const char* roleMPEG4 = "OMX.qcom.video.decoder.mpeg4";
        if (!strncmp(componentName, roleVC1, strlen(roleVC1)) ||
                !strncmp(componentName, roleMPEG4, strlen(roleMPEG4))) {
            // The codec requires timestamp reordering
            tsReorder = true;
        }

        if (tsReorder) {
            ALOGI("Enabling timestamp reordering");
            QOMX_INDEXTIMESTAMPREORDER reorder;
            InitOMXParams(&reorder);
            reorder.nPortIndex = kPortIndexOutput;
            reorder.bEnable = OMX_TRUE;
            xerr = OMXhandle->setParameter(nodeID,
                           (OMX_INDEXTYPE)OMX_QcomIndexParamEnableTimeStampReorder,
                           (void *)&reorder, sizeof(reorder));

            if (xerr != OK) {
                ALOGW("Failed to enable timestamp reordering");
            }
        }

        // MediaCodec clients can request decoder extradata by setting
        // "enable-extradata-<type>" in MediaFormat.
        // Following <type>s are supported:
        //    "user" => user-extradata
        int extraDataRequested = 0;
        if (msg->findInt32("enable-extradata-user", &extraDataRequested) &&
                extraDataRequested == 1) {
            ALOGI("[%s] User-extradata requested", componentName);
            QOMX_ENABLETYPE enableType;
            enableType.bEnable = OMX_TRUE;

            xerr = OMXhandle->setParameter(
                    nodeID, (OMX_INDEXTYPE)OMX_QcomIndexEnableExtnUserData,
                    (OMX_PTR)&enableType, sizeof(enableType));
            if (xerr != OK) {
                ALOGW("[%s] Failed to enable user-extradata", componentName);
            }
        }
    }
#endif
    return err;
}

@@ -582,7 +661,7 @@ status_t FFMPEGSoftCodec::setSupportedRole(
        { MEDIA_MIMETYPE_VIDEO_DIVX311,
          "video_decoder.divx", NULL },
        { MEDIA_MIMETYPE_VIDEO_WMV,
          "video_decoder.wmv",  NULL },
          "video_decoder.vc1",  NULL }, // so we can still talk to hardware codec
        { MEDIA_MIMETYPE_VIDEO_VC1,
          "video_decoder.vc1", NULL },
        { MEDIA_MIMETYPE_VIDEO_RV,