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

Commit 1065b3f1 authored by Andreas Huber's avatar Andreas Huber
Browse files

Multiple changes to ACodec/codec tools:

Make sure sf2 does not coalesce input buffers, generalize ACodec's codec
instantiation based on OMXCodec's list of eligible component names.

Some changes/additions to the "sf2" commandline tool

Make surface options consistent with stagefright tool, i.e. use '-S' instead of '-s'
New option '-R' renders surface-allocated buffers.

Also fixes a longstanding bug introduced when generalizing from surfaces to native windows that never used surface-allocated buffers in sf2 even when the option was specified.

Change-Id: I59fd533f0f6ef0337ebe2806ddc81a46878eb3ae
parent 1e06f435
Loading
Loading
Loading
Loading
+24 −7
Original line number Diff line number Diff line
@@ -29,6 +29,7 @@
#include <media/stagefright/MediaExtractor.h>
#include <media/stagefright/MediaSource.h>
#include <media/stagefright/MetaData.h>
#include <media/stagefright/NativeWindowWrapper.h>
#include <media/stagefright/Utils.h>

#include <surfaceflinger/ISurfaceComposer.h>
@@ -39,10 +40,12 @@
using namespace android;

struct Controller : public AHandler {
    Controller(const char *uri, bool decodeAudio, const sp<Surface> &surface)
    Controller(const char *uri, bool decodeAudio,
               const sp<Surface> &surface, bool renderToSurface)
        : mURI(uri),
          mDecodeAudio(decodeAudio),
          mSurface(surface),
          mRenderToSurface(renderToSurface),
          mCodec(new ACodec) {
        CHECK(!mDecodeAudio || mSurface == NULL);
    }
@@ -97,7 +100,8 @@ protected:
                sp<AMessage> format = makeFormat(mSource->getFormat());

                if (mSurface != NULL) {
                    format->setObject("surface", mSurface);
                    format->setObject(
                            "native-window", new NativeWindowWrapper(mSurface));
                }

                mCodec->initiateSetup(format);
@@ -220,6 +224,7 @@ private:
    AString mURI;
    bool mDecodeAudio;
    sp<Surface> mSurface;
    bool mRenderToSurface;
    sp<ACodec> mCodec;
    sp<MediaSource> mSource;

@@ -451,7 +456,7 @@ private:
                inBuffer->release();
                inBuffer = NULL;

                // break;  // Don't coalesce
                break;  // Don't coalesce
            }

            LOGV("coalesced %d input buffers", n);
@@ -479,6 +484,10 @@ private:
        sp<AMessage> reply;
        CHECK(msg->findMessage("reply", &reply));

        if (mRenderToSurface) {
            reply->setInt32("render", 1);
        }

        reply->post();
    }

@@ -491,7 +500,8 @@ static void usage(const char *me) {
    fprintf(stderr, "       -a(udio)\n");

    fprintf(stderr,
            "       -s(surface) Allocate output buffers on a surface.\n");
            "       -S(urface) Allocate output buffers on a surface.\n"
            "       -R(ender)  Render surface-allocated buffers.\n");
}

int main(int argc, char **argv) {
@@ -499,18 +509,23 @@ int main(int argc, char **argv) {

    bool decodeAudio = false;
    bool useSurface = false;
    bool renderToSurface = false;

    int res;
    while ((res = getopt(argc, argv, "has")) >= 0) {
    while ((res = getopt(argc, argv, "haSR")) >= 0) {
        switch (res) {
            case 'a':
                decodeAudio = true;
                break;

            case 's':
            case 'S':
                useSurface = true;
                break;

            case 'R':
                renderToSurface = true;
                break;

            case '?':
            case 'h':
            default:
@@ -562,7 +577,9 @@ int main(int argc, char **argv) {
        CHECK(surface != NULL);
    }

    sp<Controller> controller = new Controller(argv[0], decodeAudio, surface);
    sp<Controller> controller =
        new Controller(argv[0], decodeAudio, surface, renderToSurface);

    looper->registerHandler(controller);

    controller->startAsync();
+7 −6
Original line number Diff line number Diff line
@@ -79,6 +79,13 @@ struct OMXCodec : public MediaSource,
    // from MediaBufferObserver
    virtual void signalBufferReturned(MediaBuffer *buffer);

    // for use by ACodec
    static void findMatchingCodecs(
            const char *mime,
            bool createEncoder, const char *matchComponentName,
            uint32_t flags,
            Vector<String8> *matchingCodecs);

protected:
    virtual ~OMXCodec();

@@ -311,12 +318,6 @@ private:
    static uint32_t getComponentQuirks(
            const char *componentName, bool isEncoder);

    static void findMatchingCodecs(
            const char *mime,
            bool createEncoder, const char *matchComponentName,
            uint32_t flags,
            Vector<String8> *matchingCodecs);

    void restorePatchedDataPointer(BufferInfo *info);

    status_t applyRotation();
+41 −22
Original line number Diff line number Diff line
@@ -29,6 +29,7 @@
#include <media/stagefright/MediaDefs.h>
#include <media/stagefright/NativeWindowWrapper.h>
#include <media/stagefright/OMXClient.h>
#include <media/stagefright/OMXCodec.h>

#include <surfaceflinger/Surface.h>
#include <gui/SurfaceTextureClient.h>
@@ -401,11 +402,22 @@ status_t ACodec::allocateBuffersOnPort(OMX_U32 portIndex) {
        CHECK(mem.get() != NULL);

        IOMX::buffer_id buffer;
#if 0
        err = mOMX->allocateBufferWithBackup(mNode, portIndex, mem, &buffer);
#else

        if (!strcasecmp(
                    mComponentName.c_str(), "OMX.TI.DUCATI1.VIDEO.DECODER")) {
            if (portIndex == kPortIndexInput && i == 0) {
                // Only log this warning once per allocation round.

                LOGW("OMX.TI.DUCATI1.VIDEO.DECODER requires the use of "
                     "OMX_AllocateBuffer instead of the preferred "
                     "OMX_UseBuffer. Vendor must fix this.");
            }

            err = mOMX->allocateBufferWithBackup(
                    mNode, portIndex, mem, &buffer);
        } else {
            err = mOMX->useBuffer(mNode, portIndex, mem, &buffer);
#endif
        }

        if (err != OK) {
            return err;
@@ -891,6 +903,7 @@ status_t ACodec::setSupportedOutputFormat() {
    CHECK(format.eColorFormat == OMX_COLOR_FormatYUV420Planar
           || format.eColorFormat == OMX_COLOR_FormatYUV420SemiPlanar
           || format.eColorFormat == OMX_COLOR_FormatCbYCrY
           || format.eColorFormat == OMX_TI_COLOR_FormatYUV420PackedSemiPlanar
           || format.eColorFormat == OMX_QCOM_COLOR_FormatYVU420SemiPlanar);

    return mOMX->setParameter(
@@ -1639,27 +1652,33 @@ void ACodec::UninitializedState::onSetup(
    AString mime;
    CHECK(msg->findString("mime", &mime));

    Vector<String8> matchingCodecs;
    OMXCodec::findMatchingCodecs(
            mime.c_str(),
            false, // createEncoder
            NULL,  // matchComponentName
            0,     // flags
            &matchingCodecs);

    sp<CodecObserver> observer = new CodecObserver;
    IOMX::node_id node = NULL;

    AString componentName;

    if (!strcasecmp(mime.c_str(), MEDIA_MIMETYPE_VIDEO_AVC)) {
        componentName = "OMX.Nvidia.h264.decode";
    } else if (!strcasecmp(mime.c_str(), MEDIA_MIMETYPE_AUDIO_AAC)) {
        componentName = "OMX.google.aac.decoder";
    } else if (!strcasecmp(mime.c_str(), MEDIA_MIMETYPE_AUDIO_MPEG)) {
        componentName = "OMX.Nvidia.mp3.decoder";
    } else if (!strcasecmp(mime.c_str(), MEDIA_MIMETYPE_VIDEO_MPEG2)) {
        componentName = "OMX.Nvidia.mpeg2v.decode";
    } else if (!strcasecmp(mime.c_str(), MEDIA_MIMETYPE_VIDEO_MPEG4)) {
        componentName = "OMX.google.mpeg4.decoder";
    } else {
        TRESPASS();
    for (size_t matchIndex = 0; matchIndex < matchingCodecs.size();
            ++matchIndex) {
        componentName = matchingCodecs.itemAt(matchIndex).string();

        status_t err = omx->allocateNode(componentName.c_str(), observer, &node);

        if (err == OK) {
            break;
        }

    sp<CodecObserver> observer = new CodecObserver;
        node = NULL;
    }

    IOMX::node_id node;
    CHECK_EQ(omx->allocateNode(componentName.c_str(), observer, &node),
             (status_t)OK);
    CHECK(node != NULL);

    sp<AMessage> notify = new AMessage(kWhatOMXMessage, mCodec->id());
    observer->setNotificationMessage(notify);