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

Commit 098446ae authored by Lajos Molnar's avatar Lajos Molnar
Browse files

stagefright: reconnect to ANW on setup in non-output-meta mode

BufferQueue now needs reconnect to allow dequeuing all buffers from
a BufferQueue.
Use getConsumerName instead of connect failure to detect that we
are connecting to the same surface.

Bug: 29422927
Change-Id: I4fc4d1ec9fd452ec027cab60b06e4af88d53d830
parent 6e706147
Loading
Loading
Loading
Loading
+3 −2
Original line number Original line Diff line number Diff line
@@ -314,11 +314,12 @@ private:


    status_t handleSetSurface(const sp<Surface> &surface);
    status_t handleSetSurface(const sp<Surface> &surface);
    status_t setupNativeWindowSizeFormatAndUsage(
    status_t setupNativeWindowSizeFormatAndUsage(
            ANativeWindow *nativeWindow /* nonnull */, int *finalUsage /* nonnull */);
            ANativeWindow *nativeWindow /* nonnull */, int *finalUsage /* nonnull */,
            bool reconnect);


    status_t configureOutputBuffersFromNativeWindow(
    status_t configureOutputBuffersFromNativeWindow(
            OMX_U32 *nBufferCount, OMX_U32 *nBufferSize,
            OMX_U32 *nBufferCount, OMX_U32 *nBufferSize,
            OMX_U32 *nMinUndequeuedBuffers);
            OMX_U32 *nMinUndequeuedBuffers, bool preregister);
    status_t allocateOutputMetadataBuffers();
    status_t allocateOutputMetadataBuffers();
    status_t submitOutputMetadataBuffer();
    status_t submitOutputMetadataBuffer();
    void signalSubmitOutputMetadataBufferIfEOS_workaround();
    void signalSubmitOutputMetadataBufferIfEOS_workaround();
+6 −1
Original line number Original line Diff line number Diff line
@@ -24,9 +24,14 @@ struct ANativeWindow;


namespace android {
namespace android {


/**
 * Configures |nativeWindow| for given |width|x|height|, pixel |format|, |rotation| and |usage|.
 * If |reconnect| is true, reconnects to the native window before hand.
 * @return first error encountered, or NO_ERROR on success.
 */
status_t setNativeWindowSizeFormatAndUsage(
status_t setNativeWindowSizeFormatAndUsage(
        ANativeWindow *nativeWindow /* nonnull */,
        ANativeWindow *nativeWindow /* nonnull */,
        int width, int height, int format, int rotation, int usage);
        int width, int height, int format, int rotation, int usage, bool reconnect);
status_t pushBlankBuffersToNativeWindow(ANativeWindow *nativeWindow /* nonnull */);
status_t pushBlankBuffersToNativeWindow(ANativeWindow *nativeWindow /* nonnull */);


} // namespace android
} // namespace android
+15 −7
Original line number Original line Diff line number Diff line
@@ -674,7 +674,10 @@ status_t ACodec::handleSetSurface(const sp<Surface> &surface) {
    }
    }


    int usageBits = 0;
    int usageBits = 0;
    status_t err = setupNativeWindowSizeFormatAndUsage(nativeWindow, &usageBits);
    // no need to reconnect as we will not dequeue all buffers
    status_t err = setupNativeWindowSizeFormatAndUsage(
            nativeWindow, &usageBits,
            !storingMetadataInDecodedBuffers() || mLegacyAdaptiveExperiment /* reconnect */);
    if (err != OK) {
    if (err != OK) {
        return err;
        return err;
    }
    }
@@ -948,7 +951,8 @@ status_t ACodec::allocateBuffersOnPort(OMX_U32 portIndex) {
}
}


status_t ACodec::setupNativeWindowSizeFormatAndUsage(
status_t ACodec::setupNativeWindowSizeFormatAndUsage(
        ANativeWindow *nativeWindow /* nonnull */, int *finalUsage /* nonnull */) {
        ANativeWindow *nativeWindow /* nonnull */, int *finalUsage /* nonnull */,
        bool reconnect) {
    OMX_PARAM_PORTDEFINITIONTYPE def;
    OMX_PARAM_PORTDEFINITIONTYPE def;
    InitOMXParams(&def);
    InitOMXParams(&def);
    def.nPortIndex = kPortIndexOutput;
    def.nPortIndex = kPortIndexOutput;
@@ -986,12 +990,14 @@ status_t ACodec::setupNativeWindowSizeFormatAndUsage(
            def.format.video.nFrameHeight,
            def.format.video.nFrameHeight,
            def.format.video.eColorFormat,
            def.format.video.eColorFormat,
            mRotationDegrees,
            mRotationDegrees,
            usage);
            usage,
            reconnect);
}
}


status_t ACodec::configureOutputBuffersFromNativeWindow(
status_t ACodec::configureOutputBuffersFromNativeWindow(
        OMX_U32 *bufferCount, OMX_U32 *bufferSize,
        OMX_U32 *bufferCount, OMX_U32 *bufferSize,
        OMX_U32 *minUndequeuedBuffers) {
        OMX_U32 *minUndequeuedBuffers, bool preregister) {

    OMX_PARAM_PORTDEFINITIONTYPE def;
    OMX_PARAM_PORTDEFINITIONTYPE def;
    InitOMXParams(&def);
    InitOMXParams(&def);
    def.nPortIndex = kPortIndexOutput;
    def.nPortIndex = kPortIndexOutput;
@@ -1000,7 +1006,8 @@ status_t ACodec::configureOutputBuffersFromNativeWindow(
            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));


    if (err == OK) {
    if (err == OK) {
        err = setupNativeWindowSizeFormatAndUsage(mNativeWindow.get(), &mNativeWindowUsageBits);
        err = setupNativeWindowSizeFormatAndUsage(
                mNativeWindow.get(), &mNativeWindowUsageBits, preregister /* reconnect */);
    }
    }
    if (err != OK) {
    if (err != OK) {
        mNativeWindowUsageBits = 0;
        mNativeWindowUsageBits = 0;
@@ -1082,7 +1089,7 @@ status_t ACodec::configureOutputBuffersFromNativeWindow(
status_t ACodec::allocateOutputBuffersFromNativeWindow() {
status_t ACodec::allocateOutputBuffersFromNativeWindow() {
    OMX_U32 bufferCount, bufferSize, minUndequeuedBuffers;
    OMX_U32 bufferCount, bufferSize, minUndequeuedBuffers;
    status_t err = configureOutputBuffersFromNativeWindow(
    status_t err = configureOutputBuffersFromNativeWindow(
            &bufferCount, &bufferSize, &minUndequeuedBuffers);
            &bufferCount, &bufferSize, &minUndequeuedBuffers, true /* preregister */);
    if (err != 0)
    if (err != 0)
        return err;
        return err;
    mNumUndequeuedBuffers = minUndequeuedBuffers;
    mNumUndequeuedBuffers = minUndequeuedBuffers;
@@ -1168,7 +1175,8 @@ status_t ACodec::allocateOutputBuffersFromNativeWindow() {
status_t ACodec::allocateOutputMetadataBuffers() {
status_t ACodec::allocateOutputMetadataBuffers() {
    OMX_U32 bufferCount, bufferSize, minUndequeuedBuffers;
    OMX_U32 bufferCount, bufferSize, minUndequeuedBuffers;
    status_t err = configureOutputBuffersFromNativeWindow(
    status_t err = configureOutputBuffersFromNativeWindow(
            &bufferCount, &bufferSize, &minUndequeuedBuffers);
            &bufferCount, &bufferSize, &minUndequeuedBuffers,
            mLegacyAdaptiveExperiment /* preregister */);
    if (err != 0)
    if (err != 0)
        return err;
        return err;
    mNumUndequeuedBuffers = minUndequeuedBuffers;
    mNumUndequeuedBuffers = minUndequeuedBuffers;
+11 −8
Original line number Original line Diff line number Diff line
@@ -1791,9 +1791,8 @@ void MediaCodec::onMessageReceived(const sp<AMessage> &msg) {
                        err = BAD_VALUE;
                        err = BAD_VALUE;
                    } else {
                    } else {
                        err = connectToSurface(surface);
                        err = connectToSurface(surface);
                        if (err == BAD_VALUE) {
                        if (err == ALREADY_EXISTS) {
                            // assuming reconnecting to same surface
                            // reconnecting to same surface
                            // TODO: check if it is the same surface
                            err = OK;
                            err = OK;
                        } else {
                        } else {
                            if (err == OK) {
                            if (err == OK) {
@@ -2683,11 +2682,14 @@ ssize_t MediaCodec::dequeuePortBuffer(int32_t portIndex) {
status_t MediaCodec::connectToSurface(const sp<Surface> &surface) {
status_t MediaCodec::connectToSurface(const sp<Surface> &surface) {
    status_t err = OK;
    status_t err = OK;
    if (surface != NULL) {
    if (surface != NULL) {
        if (mSurface != NULL
                && surface->getConsumerName() == mSurface->getConsumerName()) {
            ALOGI("connecting to native window with same name. Assuming no change of surface");
            return ALREADY_EXISTS;
        }

        err = native_window_api_connect(surface.get(), NATIVE_WINDOW_API_MEDIA);
        err = native_window_api_connect(surface.get(), NATIVE_WINDOW_API_MEDIA);
        if (err == BAD_VALUE) {
        if (err == OK) {
            ALOGI("native window already connected. Assuming no change of surface");
            return err;
        } else if (err == OK) {
            // Require a fresh set of buffers after each connect by using a unique generation
            // Require a fresh set of buffers after each connect by using a unique generation
            // number. Rely on the fact that max supported process id by Linux is 2^22.
            // number. Rely on the fact that max supported process id by Linux is 2^22.
            // PID is never 0 so we don't have to worry that we use the default generation of 0.
            // PID is never 0 so we don't have to worry that we use the default generation of 0.
@@ -2709,7 +2711,8 @@ status_t MediaCodec::connectToSurface(const sp<Surface> &surface) {
            ALOGE("native_window_api_connect returned an error: %s (%d)", strerror(-err), err);
            ALOGE("native_window_api_connect returned an error: %s (%d)", strerror(-err), err);
        }
        }
    }
    }
    return err;
    // do not return ALREADY_EXISTS unless surfaces are the same
    return err == ALREADY_EXISTS ? BAD_VALUE : err;
}
}


status_t MediaCodec::disconnectFromSurface() {
status_t MediaCodec::disconnectFromSurface() {
+21 −3
Original line number Original line Diff line number Diff line
@@ -26,8 +26,25 @@ namespace android {


status_t setNativeWindowSizeFormatAndUsage(
status_t setNativeWindowSizeFormatAndUsage(
        ANativeWindow *nativeWindow /* nonnull */,
        ANativeWindow *nativeWindow /* nonnull */,
        int width, int height, int format, int rotation, int usage) {
        int width, int height, int format, int rotation, int usage, bool reconnect) {
    status_t err = native_window_set_buffers_dimensions(nativeWindow, width, height);
    status_t err = NO_ERROR;

    // In some cases we need to reconnect so that we can dequeue all buffers
    if (reconnect) {
        err = native_window_api_disconnect(nativeWindow, NATIVE_WINDOW_API_MEDIA);
        if (err != NO_ERROR) {
            ALOGE("native_window_api_disconnect failed: %s (%d)", strerror(-err), -err);
            return err;
        }

        err = native_window_api_connect(nativeWindow, NATIVE_WINDOW_API_MEDIA);
        if (err != NO_ERROR) {
            ALOGE("native_window_api_connect failed: %s (%d)", strerror(-err), -err);
            return err;
        }
    }

    err = native_window_set_buffers_dimensions(nativeWindow, width, height);
    if (err != NO_ERROR) {
    if (err != NO_ERROR) {
        ALOGE("native_window_set_buffers_dimensions failed: %s (%d)", strerror(-err), -err);
        ALOGE("native_window_set_buffers_dimensions failed: %s (%d)", strerror(-err), -err);
        return err;
        return err;
@@ -124,7 +141,8 @@ status_t pushBlankBuffersToNativeWindow(ANativeWindow *nativeWindow /* nonnull *
    }
    }


    err = setNativeWindowSizeFormatAndUsage(
    err = setNativeWindowSizeFormatAndUsage(
            nativeWindow, 1, 1, HAL_PIXEL_FORMAT_RGBX_8888, 0, GRALLOC_USAGE_SW_WRITE_OFTEN);
            nativeWindow, 1, 1, HAL_PIXEL_FORMAT_RGBX_8888, 0, GRALLOC_USAGE_SW_WRITE_OFTEN,
            false /* reconnect */);
    if (err != NO_ERROR) {
    if (err != NO_ERROR) {
        goto error;
        goto error;
    }
    }