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

Commit 1aa26f78 authored by Ronghua Wu's avatar Ronghua Wu
Browse files

stagefright: add adaptive playback support to SoftHEVC decoder.

Bug: 17326758
Change-Id: I245e2bd1490e810094ca550fdddfa87075bc2056
parent 2973994a
Loading
Loading
Loading
Loading
+117 −72
Original line number Original line Diff line number Diff line
@@ -67,22 +67,16 @@ SoftHEVC::SoftHEVC(
    : SoftVideoDecoderOMXComponent(name, componentName, codingType,
    : SoftVideoDecoderOMXComponent(name, componentName, codingType,
            kProfileLevels, ARRAY_SIZE(kProfileLevels),
            kProfileLevels, ARRAY_SIZE(kProfileLevels),
            320 /* width */, 240 /* height */, callbacks,
            320 /* width */, 240 /* height */, callbacks,
            appData, component) {
            appData, component),
      mMemRecords(NULL),
      mFlushOutBuffer(NULL),
      mOmxColorFormat(OMX_COLOR_FormatYUV420Planar),
      mIvColorFormat(IV_YUV_420P),
      mNewWidth(mWidth),
      mNewHeight(mHeight),
      mChangingResolution(false) {
    initPorts(kNumBuffers, INPUT_BUF_SIZE, kNumBuffers,
    initPorts(kNumBuffers, INPUT_BUF_SIZE, kNumBuffers,
            CODEC_MIME_TYPE);
            CODEC_MIME_TYPE);

    mOmxColorFormat = OMX_COLOR_FormatYUV420Planar;
    mStride = mWidth;

    if (OMX_COLOR_FormatYUV420Planar == mOmxColorFormat) {
        mIvColorFormat = IV_YUV_420P;
    } else if (OMX_COLOR_FormatYUV420SemiPlanar == mOmxColorFormat) {
        mIvColorFormat = IV_YUV_420SP_UV;
    }

    mInitWidth = mWidth;
    mInitHeight = mHeight;

    CHECK_EQ(initDecoder(), (status_t)OK);
    CHECK_EQ(initDecoder(), (status_t)OK);
}
}


@@ -144,7 +138,7 @@ status_t SoftHEVC::setParams(size_t stride) {
    s_ctl_ip.u4_size = sizeof(ivd_ctl_set_config_ip_t);
    s_ctl_ip.u4_size = sizeof(ivd_ctl_set_config_ip_t);
    s_ctl_op.u4_size = sizeof(ivd_ctl_set_config_op_t);
    s_ctl_op.u4_size = sizeof(ivd_ctl_set_config_op_t);


    ALOGD("Set the run-time (dynamic) parameters");
    ALOGV("Set the run-time (dynamic) parameters stride = %u", stride);
    status = ivdec_api_function(mCodecCtx, (void *)&s_ctl_ip,
    status = ivdec_api_function(mCodecCtx, (void *)&s_ctl_ip,
            (void *)&s_ctl_op);
            (void *)&s_ctl_op);


@@ -188,7 +182,7 @@ status_t SoftHEVC::resetDecoder() {
    }
    }


    /* Set the run-time (dynamic) parameters */
    /* Set the run-time (dynamic) parameters */
    setParams(0);
    setParams(outputBufferWidth());


    /* Set number of cores/threads to be used by the codec */
    /* Set number of cores/threads to be used by the codec */
    setNumCores();
    setNumCores();
@@ -250,23 +244,25 @@ status_t SoftHEVC::initDecoder() {
    WORD32 i4_level;
    WORD32 i4_level;


    mNumCores = GetCPUCoreCount();
    mNumCores = GetCPUCoreCount();
    mMemRecords = NULL;
    mFlushOutBuffer = NULL;


    /* Initialize number of ref and reorder modes (for HEVC) */
    /* Initialize number of ref and reorder modes (for HEVC) */
    u4_num_reorder_frames = 16;
    u4_num_reorder_frames = 16;
    u4_num_ref_frames = 16;
    u4_num_ref_frames = 16;
    u4_share_disp_buf = 0;
    u4_share_disp_buf = 0;


    if ((mWidth * mHeight) > (1920 * 1088)) {
    uint32_t displayStride = outputBufferWidth();
    uint32_t displayHeight = outputBufferHeight();
    uint32_t displaySizeY = displayStride * displayHeight;

    if (displaySizeY > (1920 * 1088)) {
        i4_level = 50;
        i4_level = 50;
    } else if ((mWidth * mHeight) > (1280 * 720)) {
    } else if (displaySizeY > (1280 * 720)) {
        i4_level = 40;
        i4_level = 40;
    } else if ((mWidth * mHeight) > (960 * 540)) {
    } else if (displaySizeY > (960 * 540)) {
        i4_level = 31;
        i4_level = 31;
    } else if ((mWidth * mHeight) > (640 * 360)) {
    } else if (displaySizeY > (640 * 360)) {
        i4_level = 30;
        i4_level = 30;
    } else if ((mWidth * mHeight) > (352 * 288)) {
    } else if (displaySizeY > (352 * 288)) {
        i4_level = 21;
        i4_level = 21;
    } else {
    } else {
        i4_level = 20;
        i4_level = 20;
@@ -317,8 +313,8 @@ status_t SoftHEVC::initDecoder() {


        s_fill_mem_ip.s_ivd_fill_mem_rec_ip_t.e_cmd = IV_CMD_FILL_NUM_MEM_REC;
        s_fill_mem_ip.s_ivd_fill_mem_rec_ip_t.e_cmd = IV_CMD_FILL_NUM_MEM_REC;
        s_fill_mem_ip.s_ivd_fill_mem_rec_ip_t.pv_mem_rec_location = mMemRecords;
        s_fill_mem_ip.s_ivd_fill_mem_rec_ip_t.pv_mem_rec_location = mMemRecords;
        s_fill_mem_ip.s_ivd_fill_mem_rec_ip_t.u4_max_frm_wd = mWidth;
        s_fill_mem_ip.s_ivd_fill_mem_rec_ip_t.u4_max_frm_wd = displayStride;
        s_fill_mem_ip.s_ivd_fill_mem_rec_ip_t.u4_max_frm_ht = mHeight;
        s_fill_mem_ip.s_ivd_fill_mem_rec_ip_t.u4_max_frm_ht = displayHeight;
        s_fill_mem_op.s_ivd_fill_mem_rec_op_t.u4_size =
        s_fill_mem_op.s_ivd_fill_mem_rec_op_t.u4_size =
            sizeof(ivdext_fill_mem_rec_op_t);
            sizeof(ivdext_fill_mem_rec_op_t);


@@ -363,8 +359,8 @@ status_t SoftHEVC::initDecoder() {
        s_init_ip.s_ivd_init_ip_t.u4_size = sizeof(ivdext_init_ip_t);
        s_init_ip.s_ivd_init_ip_t.u4_size = sizeof(ivdext_init_ip_t);
        s_init_ip.s_ivd_init_ip_t.e_cmd = (IVD_API_COMMAND_TYPE_T)IV_CMD_INIT;
        s_init_ip.s_ivd_init_ip_t.e_cmd = (IVD_API_COMMAND_TYPE_T)IV_CMD_INIT;
        s_init_ip.s_ivd_init_ip_t.pv_mem_rec_location = mMemRecords;
        s_init_ip.s_ivd_init_ip_t.pv_mem_rec_location = mMemRecords;
        s_init_ip.s_ivd_init_ip_t.u4_frm_max_wd = mWidth;
        s_init_ip.s_ivd_init_ip_t.u4_frm_max_wd = displayStride;
        s_init_ip.s_ivd_init_ip_t.u4_frm_max_ht = mHeight;
        s_init_ip.s_ivd_init_ip_t.u4_frm_max_ht = displayHeight;


        s_init_ip.i4_level = i4_level;
        s_init_ip.i4_level = i4_level;
        s_init_ip.u4_num_reorder_frames = u4_num_reorder_frames;
        s_init_ip.u4_num_reorder_frames = u4_num_reorder_frames;
@@ -395,7 +391,7 @@ status_t SoftHEVC::initDecoder() {
    resetPlugin();
    resetPlugin();


    /* Set the run time (dynamic) parameters */
    /* Set the run time (dynamic) parameters */
    setParams(0);
    setParams(displayStride);


    /* Set number of cores/threads to be used by the codec */
    /* Set number of cores/threads to be used by the codec */
    setNumCores();
    setNumCores();
@@ -404,12 +400,15 @@ status_t SoftHEVC::initDecoder() {
    logVersion();
    logVersion();


    /* Allocate internal picture buffer */
    /* Allocate internal picture buffer */
    mFlushOutBuffer = (uint8_t *)ivd_aligned_malloc(128, mStride * mHeight * 3 / 2);
    uint32_t bufferSize = displaySizeY * 3 / 2;
    mFlushOutBuffer = (uint8_t *)ivd_aligned_malloc(128, bufferSize);
    if (NULL == mFlushOutBuffer) {
    if (NULL == mFlushOutBuffer) {
        ALOGE("Could not allocate flushOutputBuffer of size %zu", mStride * mHeight * 3 / 2);
        ALOGE("Could not allocate flushOutputBuffer of size %zu", bufferSize);
        return NO_MEMORY;
        return NO_MEMORY;
    }
    }


    mInitNeeded = false;
    mFlushNeeded = false;
    return OK;
    return OK;
}
}


@@ -428,11 +427,17 @@ status_t SoftHEVC::deInitDecoder() {
            ps_mem_rec++;
            ps_mem_rec++;
        }
        }
        ivd_aligned_free(mMemRecords);
        ivd_aligned_free(mMemRecords);
        mMemRecords = NULL;
    }
    }


    if(mFlushOutBuffer) {
    if(mFlushOutBuffer) {
        ivd_aligned_free(mFlushOutBuffer);
        ivd_aligned_free(mFlushOutBuffer);
        mFlushOutBuffer = NULL;
    }
    }

    mInitNeeded = true;
    mChangingResolution = false;

    return OK;
    return OK;
}
}


@@ -449,6 +454,7 @@ status_t SoftHEVC::reInitDecoder() {
    }
    }
    return OK;
    return OK;
}
}

void SoftHEVC::onReset() {
void SoftHEVC::onReset() {
    ALOGD("onReset called");
    ALOGD("onReset called");
    SoftVideoDecoderOMXComponent::onReset();
    SoftVideoDecoderOMXComponent::onReset();
@@ -457,12 +463,22 @@ void SoftHEVC::onReset() {
    resetPlugin();
    resetPlugin();
}
}


OMX_ERRORTYPE SoftHEVC::internalSetParameter(OMX_INDEXTYPE index, const OMX_PTR params) {
    const uint32_t oldWidth = mWidth;
    const uint32_t oldHeight = mHeight;
    OMX_ERRORTYPE ret = SoftVideoDecoderOMXComponent::internalSetParameter(index, params);
    if (mWidth != oldWidth || mHeight != oldHeight) {
        reInitDecoder();
    }
    return ret;
}

void SoftHEVC::setDecodeArgs(ivd_video_decode_ip_t *ps_dec_ip,
void SoftHEVC::setDecodeArgs(ivd_video_decode_ip_t *ps_dec_ip,
        ivd_video_decode_op_t *ps_dec_op,
        ivd_video_decode_op_t *ps_dec_op,
        OMX_BUFFERHEADERTYPE *inHeader,
        OMX_BUFFERHEADERTYPE *inHeader,
        OMX_BUFFERHEADERTYPE *outHeader,
        OMX_BUFFERHEADERTYPE *outHeader,
        size_t sizeY,
        size_t timeStampIx) {
        size_t timeStampIx) {
    size_t sizeY = outputBufferWidth() * outputBufferHeight();
    size_t sizeUV;
    size_t sizeUV;
    uint8_t *pBuf;
    uint8_t *pBuf;


@@ -502,8 +518,6 @@ void SoftHEVC::setDecodeArgs(ivd_video_decode_ip_t *ps_dec_ip,
    return;
    return;
}
}
void SoftHEVC::onPortFlushCompleted(OMX_U32 portIndex) {
void SoftHEVC::onPortFlushCompleted(OMX_U32 portIndex) {
    ALOGD("onPortFlushCompleted on port %d", portIndex);

    /* Once the output buffers are flushed, ignore any buffers that are held in decoder */
    /* Once the output buffers are flushed, ignore any buffers that are held in decoder */
    if (kOutputPortIndex == portIndex) {
    if (kOutputPortIndex == portIndex) {
        setFlushMode();
        setFlushMode();
@@ -514,7 +528,7 @@ void SoftHEVC::onPortFlushCompleted(OMX_U32 portIndex) {
            IV_API_CALL_STATUS_T status;
            IV_API_CALL_STATUS_T status;
            size_t sizeY, sizeUV;
            size_t sizeY, sizeUV;


            setDecodeArgs(&s_dec_ip, &s_dec_op, NULL, NULL, mStride * mHeight, 0);
            setDecodeArgs(&s_dec_ip, &s_dec_op, NULL, NULL, 0);


            status = ivdec_api_function(mCodecCtx, (void *)&s_dec_ip,
            status = ivdec_api_function(mCodecCtx, (void *)&s_dec_ip,
                    (void *)&s_dec_op);
                    (void *)&s_dec_op);
@@ -527,8 +541,6 @@ void SoftHEVC::onPortFlushCompleted(OMX_U32 portIndex) {
}
}


void SoftHEVC::onQueueFilled(OMX_U32 portIndex) {
void SoftHEVC::onQueueFilled(OMX_U32 portIndex) {
    IV_API_CALL_STATUS_T status;

    UNUSED(portIndex);
    UNUSED(portIndex);


    if (mOutputPortSettingsChange != NONE) {
    if (mOutputPortSettingsChange != NONE) {
@@ -548,7 +560,7 @@ void SoftHEVC::onQueueFilled(OMX_U32 portIndex) {
        setFlushMode();
        setFlushMode();
    }
    }


    while (outQueue.size() == kNumBuffers) {
    while (!outQueue.empty()) {
        BufferInfo *inInfo;
        BufferInfo *inInfo;
        OMX_BUFFERHEADERTYPE *inHeader;
        OMX_BUFFERHEADERTYPE *inHeader;


@@ -586,6 +598,16 @@ void SoftHEVC::onQueueFilled(OMX_U32 portIndex) {
            }
            }
        }
        }


        // When there is an init required and the decoder is not in flush mode,
        // update output port's definition and reinitialize decoder.
        if (mInitNeeded && !mIsInFlush) {
            bool portWillReset = false;
            handlePortSettingsChange(&portWillReset, mNewWidth, mNewHeight);

            CHECK_EQ(reInitDecoder(), (status_t)OK);
            return;
        }

        /* Get a free slot in timestamp array to hold input timestamp */
        /* Get a free slot in timestamp array to hold input timestamp */
        {
        {
            size_t i;
            size_t i;
@@ -608,68 +630,91 @@ void SoftHEVC::onQueueFilled(OMX_U32 portIndex) {
            WORD32 timeDelay, timeTaken;
            WORD32 timeDelay, timeTaken;
            size_t sizeY, sizeUV;
            size_t sizeY, sizeUV;


            setDecodeArgs(&s_dec_ip, &s_dec_op, inHeader, outHeader,
            setDecodeArgs(&s_dec_ip, &s_dec_op, inHeader, outHeader, timeStampIx);
                          mStride * mHeight, timeStampIx);


            GETTIME(&mTimeStart, NULL);
            GETTIME(&mTimeStart, NULL);
            /* Compute time elapsed between end of previous decode()
            /* Compute time elapsed between end of previous decode()
             * to start of current decode() */
             * to start of current decode() */
            TIME_DIFF(mTimeEnd, mTimeStart, timeDelay);
            TIME_DIFF(mTimeEnd, mTimeStart, timeDelay);


            status = ivdec_api_function(mCodecCtx, (void *)&s_dec_ip,
            IV_API_CALL_STATUS_T status;
                    (void *)&s_dec_op);
            status = ivdec_api_function(mCodecCtx, (void *)&s_dec_ip, (void *)&s_dec_op);
            // FIXME: Compare |status| to IHEVCD_UNSUPPORTED_DIMENSIONS, which is not one of the
            // IV_API_CALL_STATUS_T, seems be wrong. But this is what the decoder returns right now.
            // The decoder should be fixed so that |u4_error_code| instead of |status| returns
            // IHEVCD_UNSUPPORTED_DIMENSIONS.
            bool unsupportedDimensions =
                ((IHEVCD_UNSUPPORTED_DIMENSIONS == status)
                    || (IHEVCD_UNSUPPORTED_DIMENSIONS == s_dec_op.u4_error_code));
            bool resChanged = (IVD_RES_CHANGED == (s_dec_op.u4_error_code & 0xFF));


            GETTIME(&mTimeEnd, NULL);
            GETTIME(&mTimeEnd, NULL);
            /* Compute time taken for decode() */
            /* Compute time taken for decode() */
            TIME_DIFF(mTimeStart, mTimeEnd, timeTaken);
            TIME_DIFF(mTimeStart, mTimeEnd, timeTaken);


            ALOGD("timeTaken=%6d delay=%6d numBytes=%6d", timeTaken, timeDelay,
            ALOGV("timeTaken=%6d delay=%6d numBytes=%6d", timeTaken, timeDelay,
                   s_dec_op.u4_num_bytes_consumed);
                   s_dec_op.u4_num_bytes_consumed);
            if (s_dec_op.u4_frame_decoded_flag && !mFlushNeeded) {
                mFlushNeeded = true;
            }

            if ((inHeader != NULL) && (1 != s_dec_op.u4_frame_decoded_flag)) {
                /* If the input did not contain picture data, then ignore
                 * the associated timestamp */
                mTimeStampsValid[timeStampIx] = false;
            }


            /* If width and height are greater than the
            // This is needed to handle CTS DecoderTest testCodecResetsHEVCWithoutSurface,
             * the dimensions used during codec create, then
            // which is not sending SPS/PPS after port reconfiguration and flush to the codec.
             * delete the current instance and recreate an instance with
            if (unsupportedDimensions && !mFlushNeeded) {
             * new dimensions */
                bool portWillReset = false;
                handlePortSettingsChange(&portWillReset, s_dec_op.u4_pic_wd, s_dec_op.u4_pic_ht);


            if(IHEVCD_UNSUPPORTED_DIMENSIONS == s_dec_op.u4_error_code) {
                mInitWidth = s_dec_op.u4_pic_wd;
                mInitHeight = s_dec_op.u4_pic_ht;
                mStride = mInitWidth;
                CHECK_EQ(reInitDecoder(), (status_t)OK);
                CHECK_EQ(reInitDecoder(), (status_t)OK);


                setDecodeArgs(&s_dec_ip, &s_dec_op, inHeader, outHeader,
                setDecodeArgs(&s_dec_ip, &s_dec_op, inHeader, outHeader, timeStampIx);
                              mStride * mHeight, timeStampIx);


                status = ivdec_api_function(mCodecCtx, (void *)&s_dec_ip,
                ivdec_api_function(mCodecCtx, (void *)&s_dec_ip, (void *)&s_dec_op);
                        (void *)&s_dec_op);
                return;
            }
            }
            if ((inHeader != NULL) && (1 != s_dec_op.u4_frame_decoded_flag)) {

                /* If the input did not contain picture data, then ignore
            // If the decoder is in the changing resolution mode and there is no output present,
                 * the associated timestamp */
            // that means the switching is done and it's ready to reset the decoder and the plugin.
                mTimeStampsValid[timeStampIx] = false;
            if (mChangingResolution && !s_dec_op.u4_output_present) {
                mChangingResolution = false;
                resetDecoder();
                resetPlugin();
                continue;
            }

            if (unsupportedDimensions || resChanged) {
                mChangingResolution = true;
                if (mFlushNeeded) {
                    setFlushMode();
                }

                if (unsupportedDimensions) {
                    mNewWidth = s_dec_op.u4_pic_wd;
                    mNewHeight = s_dec_op.u4_pic_ht;
                    mInitNeeded = true;
                }
                continue;
            }
            }


            /* If valid height and width are decoded,
             * then look at change in resolution */
            if ((0 < s_dec_op.u4_pic_wd) && (0 < s_dec_op.u4_pic_ht)) {
            if ((0 < s_dec_op.u4_pic_wd) && (0 < s_dec_op.u4_pic_ht)) {
                uint32_t width = s_dec_op.u4_pic_wd;
                uint32_t width = s_dec_op.u4_pic_wd;
                uint32_t height = s_dec_op.u4_pic_ht;
                uint32_t height = s_dec_op.u4_pic_ht;
                bool portWillReset = false;
                handlePortSettingsChange(&portWillReset, width, height);


                if ((width != mWidth) || (height != mHeight)) {
                if (portWillReset) {
                    mWidth = width;
                    resetDecoder();
                    mHeight = height;
                    mStride = mWidth;

                    updatePortDefinitions();

                    notify(OMX_EventPortSettingsChanged, 1, 0, NULL);
                    mOutputPortSettingsChange = AWAITING_DISABLED;
                    return;
                    return;
                }
                }
            }
            }


            if (s_dec_op.u4_output_present) {
            if (s_dec_op.u4_output_present) {
                outHeader->nFilledLen = (mStride * mHeight * 3) / 2;
                outHeader->nFilledLen = (mWidth * mHeight * 3) / 2;


                outHeader->nTimeStamp = mTimeStamps[s_dec_op.u4_ts];
                outHeader->nTimeStamp = mTimeStamps[s_dec_op.u4_ts];
                mTimeStampsValid[s_dec_op.u4_ts] = false;
                mTimeStampsValid[s_dec_op.u4_ts] = false;
+8 −8
Original line number Original line Diff line number Diff line
@@ -62,6 +62,7 @@ protected:
    virtual void onQueueFilled(OMX_U32 portIndex);
    virtual void onQueueFilled(OMX_U32 portIndex);
    virtual void onPortFlushCompleted(OMX_U32 portIndex);
    virtual void onPortFlushCompleted(OMX_U32 portIndex);
    virtual void onReset();
    virtual void onReset();
    virtual OMX_ERRORTYPE internalSetParameter(OMX_INDEXTYPE index, const OMX_PTR params);
private:
private:
    // Number of input and output buffers
    // Number of input and output buffers
    enum {
    enum {
@@ -72,12 +73,6 @@ private:
    iv_mem_rec_t *mMemRecords;   // Memory records requested by the codec
    iv_mem_rec_t *mMemRecords;   // Memory records requested by the codec
    size_t mNumMemRecords;       // Number of memory records requested by the codec
    size_t mNumMemRecords;       // Number of memory records requested by the codec


    uint32_t mNewWidth;          // New width after change in resolution
    uint32_t mNewHeight;         // New height after change in resolution
    uint32_t mInitWidth;         // Width used during codec creation
    uint32_t mInitHeight;        // Height used during codec creation
    size_t mStride;              // Stride to be used for display buffers

    size_t mNumCores;            // Number of cores to be uesd by the codec
    size_t mNumCores;            // Number of cores to be uesd by the codec


    struct timeval mTimeStart;   // Time at the start of decode()
    struct timeval mTimeStart;   // Time at the start of decode()
@@ -98,7 +93,13 @@ private:


    bool mIsInFlush;        // codec is flush mode
    bool mIsInFlush;        // codec is flush mode
    bool mReceivedEOS;      // EOS is receieved on input port
    bool mReceivedEOS;      // EOS is receieved on input port
    bool mIsAdapting;       // plugin in middle of change in resolution
    bool mInitNeeded;
    uint32_t mNewWidth;
    uint32_t mNewHeight;
    // The input stream has changed to a different resolution, which is still supported by the
    // codec. So the codec is switching to decode the new resolution.
    bool mChangingResolution;
    bool mFlushNeeded;


    status_t initDecoder();
    status_t initDecoder();
    status_t deInitDecoder();
    status_t deInitDecoder();
@@ -114,7 +115,6 @@ private:
        ivd_video_decode_op_t *ps_dec_op,
        ivd_video_decode_op_t *ps_dec_op,
        OMX_BUFFERHEADERTYPE *inHeader,
        OMX_BUFFERHEADERTYPE *inHeader,
        OMX_BUFFERHEADERTYPE *outHeader,
        OMX_BUFFERHEADERTYPE *outHeader,
        size_t sizeY,
        size_t timeStampIx);
        size_t timeStampIx);


    DISALLOW_EVIL_CONSTRUCTORS (SoftHEVC);
    DISALLOW_EVIL_CONSTRUCTORS (SoftHEVC);
+3 −0
Original line number Original line Diff line number Diff line
@@ -65,6 +65,9 @@ protected:


    virtual void updatePortDefinitions(bool updateCrop = true);
    virtual void updatePortDefinitions(bool updateCrop = true);


    uint32_t outputBufferWidth();
    uint32_t outputBufferHeight();

    void handlePortSettingsChange(
    void handlePortSettingsChange(
            bool *portWillReset, uint32_t width, uint32_t height,
            bool *portWillReset, uint32_t width, uint32_t height,
            bool cropChanged = false, bool fakeStride = false);
            bool cropChanged = false, bool fakeStride = false);
+13 −4
Original line number Original line Diff line number Diff line
@@ -133,8 +133,8 @@ void SoftVideoDecoderOMXComponent::updatePortDefinitions(bool updateCrop) {
    def->nBufferSize = def->format.video.nFrameWidth * def->format.video.nFrameHeight * 3 / 2;
    def->nBufferSize = def->format.video.nFrameWidth * def->format.video.nFrameHeight * 3 / 2;


    def = &editPortInfo(kOutputPortIndex)->mDef;
    def = &editPortInfo(kOutputPortIndex)->mDef;
    def->format.video.nFrameWidth = mIsAdaptive ? mAdaptiveMaxWidth : mWidth;
    def->format.video.nFrameWidth = outputBufferWidth();
    def->format.video.nFrameHeight = mIsAdaptive ? mAdaptiveMaxHeight : mHeight;
    def->format.video.nFrameHeight = outputBufferHeight();
    def->format.video.nStride = def->format.video.nFrameWidth;
    def->format.video.nStride = def->format.video.nFrameWidth;
    def->format.video.nSliceHeight = def->format.video.nFrameHeight;
    def->format.video.nSliceHeight = def->format.video.nFrameHeight;


@@ -150,6 +150,15 @@ void SoftVideoDecoderOMXComponent::updatePortDefinitions(bool updateCrop) {
    }
    }
}
}



uint32_t SoftVideoDecoderOMXComponent::outputBufferWidth() {
    return mIsAdaptive ? mAdaptiveMaxWidth : mWidth;
}

uint32_t SoftVideoDecoderOMXComponent::outputBufferHeight() {
    return mIsAdaptive ? mAdaptiveMaxHeight : mHeight;
}

void SoftVideoDecoderOMXComponent::handlePortSettingsChange(
void SoftVideoDecoderOMXComponent::handlePortSettingsChange(
        bool *portWillReset, uint32_t width, uint32_t height, bool cropChanged, bool fakeStride) {
        bool *portWillReset, uint32_t width, uint32_t height, bool cropChanged, bool fakeStride) {
    *portWillReset = false;
    *portWillReset = false;
@@ -199,9 +208,9 @@ void SoftVideoDecoderOMXComponent::handlePortSettingsChange(
void SoftVideoDecoderOMXComponent::copyYV12FrameToOutputBuffer(
void SoftVideoDecoderOMXComponent::copyYV12FrameToOutputBuffer(
        uint8_t *dst, const uint8_t *srcY, const uint8_t *srcU, const uint8_t *srcV,
        uint8_t *dst, const uint8_t *srcY, const uint8_t *srcU, const uint8_t *srcV,
        size_t srcYStride, size_t srcUStride, size_t srcVStride) {
        size_t srcYStride, size_t srcUStride, size_t srcVStride) {
    size_t dstYStride = mIsAdaptive ? mAdaptiveMaxWidth : mWidth;
    size_t dstYStride = outputBufferWidth();
    size_t dstUVStride = dstYStride / 2;
    size_t dstUVStride = dstYStride / 2;
    size_t dstHeight = mIsAdaptive ? mAdaptiveMaxHeight : mHeight;
    size_t dstHeight = outputBufferHeight();
    uint8_t *dstStart = dst;
    uint8_t *dstStart = dst;


    for (size_t i = 0; i < mHeight; ++i) {
    for (size_t i = 0; i < mHeight; ++i) {