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

Commit dd6e6a25 authored by Harish Mahendrakar's avatar Harish Mahendrakar
Browse files

SoftAVCDec: Handle interlaced streams where two fields are sent in one input

When both fields are sent in a single input buffer, only the first field was
being decoded. Fix this by not releasing input buffer when some bytes are still
left unused in the input buffer.
If both fields are sent in a separate call, decoder handles that correctly and
returns an output frame for every two fields

Bug: 32364044
Test: Manually tested by decoding clip attached in the above bug

Change-Id: Idab5acd9cbaefc5d2560a70d375f3a532d9e78eb
parent cf39459d
Loading
Loading
Loading
Loading
+24 −24
Original line number Original line Diff line number Diff line
@@ -120,7 +120,8 @@ SoftAVC::SoftAVC(
      mIvColorFormat(IV_YUV_420P),
      mIvColorFormat(IV_YUV_420P),
      mChangingResolution(false),
      mChangingResolution(false),
      mSignalledError(false),
      mSignalledError(false),
      mStride(mWidth){
      mStride(mWidth),
      mInputOffset(0){
    initPorts(
    initPorts(
            kNumBuffers, INPUT_BUF_SIZE, kNumBuffers, CODEC_MIME_TYPE);
            kNumBuffers, INPUT_BUF_SIZE, kNumBuffers, CODEC_MIME_TYPE);


@@ -214,6 +215,7 @@ status_t SoftAVC::setParams(size_t stride) {
status_t SoftAVC::resetPlugin() {
status_t SoftAVC::resetPlugin() {
    mIsInFlush = false;
    mIsInFlush = false;
    mReceivedEOS = false;
    mReceivedEOS = false;
    mInputOffset = 0;
    memset(mTimeStamps, 0, sizeof(mTimeStamps));
    memset(mTimeStamps, 0, sizeof(mTimeStamps));
    memset(mTimeStampsValid, 0, sizeof(mTimeStampsValid));
    memset(mTimeStampsValid, 0, sizeof(mTimeStampsValid));


@@ -400,8 +402,8 @@ bool SoftAVC::setDecodeArgs(
    if (inHeader) {
    if (inHeader) {
        ps_dec_ip->u4_ts = timeStampIx;
        ps_dec_ip->u4_ts = timeStampIx;
        ps_dec_ip->pv_stream_buffer =
        ps_dec_ip->pv_stream_buffer =
            inHeader->pBuffer + inHeader->nOffset;
            inHeader->pBuffer + inHeader->nOffset + mInputOffset;
        ps_dec_ip->u4_num_Bytes = inHeader->nFilledLen;
        ps_dec_ip->u4_num_Bytes = inHeader->nFilledLen - mInputOffset;
    } else {
    } else {
        ps_dec_ip->u4_ts = 0;
        ps_dec_ip->u4_ts = 0;
        ps_dec_ip->pv_stream_buffer = NULL;
        ps_dec_ip->pv_stream_buffer = NULL;
@@ -472,6 +474,8 @@ void SoftAVC::onPortFlushCompleted(OMX_U32 portIndex) {


void SoftAVC::onQueueFilled(OMX_U32 portIndex) {
void SoftAVC::onQueueFilled(OMX_U32 portIndex) {
    UNUSED(portIndex);
    UNUSED(portIndex);
    OMX_BUFFERHEADERTYPE *inHeader = NULL;
    BufferInfo *inInfo = NULL;


    if (mSignalledError) {
    if (mSignalledError) {
        return;
        return;
@@ -498,17 +502,11 @@ void SoftAVC::onQueueFilled(OMX_U32 portIndex) {
    List<BufferInfo *> &outQueue = getPortQueue(kOutputPortIndex);
    List<BufferInfo *> &outQueue = getPortQueue(kOutputPortIndex);


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

        BufferInfo *outInfo;
        BufferInfo *outInfo;
        OMX_BUFFERHEADERTYPE *outHeader;
        OMX_BUFFERHEADERTYPE *outHeader;
        size_t timeStampIx;
        size_t timeStampIx = 0;

        inInfo = NULL;
        inHeader = NULL;


        if (!mIsInFlush) {
        if (!mIsInFlush && (NULL == inHeader)) {
            if (!inQueue.empty()) {
            if (!inQueue.empty()) {
                inInfo = *inQueue.begin();
                inInfo = *inQueue.begin();
                inHeader = inInfo->mHeader;
                inHeader = inInfo->mHeader;
@@ -575,7 +573,7 @@ void SoftAVC::onQueueFilled(OMX_U32 portIndex) {
                return;
                return;
            }
            }
            // If input dump is enabled, then write to file
            // If input dump is enabled, then write to file
            DUMP_TO_FILE(mInFile, s_dec_ip.pv_stream_buffer, s_dec_ip.u4_num_Bytes);
            DUMP_TO_FILE(mInFile, s_dec_ip.pv_stream_buffer, s_dec_ip.u4_num_Bytes, mInputOffset);


            GETTIME(&mTimeStart, NULL);
            GETTIME(&mTimeStart, NULL);
            /* Compute time elapsed between end of previous decode()
            /* Compute time elapsed between end of previous decode()
@@ -683,7 +681,16 @@ void SoftAVC::onQueueFilled(OMX_U32 portIndex) {
                    resetPlugin();
                    resetPlugin();
                }
                }
            }
            }
            mInputOffset += s_dec_op.u4_num_bytes_consumed;
        }
        }
        // If more than 4 bytes are remaining in input, then do not release it
        if (inHeader != NULL && ((inHeader->nFilledLen - mInputOffset) <= 4)) {
            inInfo->mOwnedByUs = false;
            inQueue.erase(inQueue.begin());
            inInfo = NULL;
            notifyEmptyBufferDone(inHeader);
            inHeader = NULL;
            mInputOffset = 0;


            /* If input EOS is seen and decoder is not in flush mode,
            /* If input EOS is seen and decoder is not in flush mode,
             * set the decoder in flush mode.
             * set the decoder in flush mode.
@@ -694,13 +701,6 @@ void SoftAVC::onQueueFilled(OMX_U32 portIndex) {
            if (mReceivedEOS && !mIsInFlush) {
            if (mReceivedEOS && !mIsInFlush) {
                setFlushMode();
                setFlushMode();
            }
            }

        if (inHeader != NULL) {
            inInfo->mOwnedByUs = false;
            inQueue.erase(inQueue.begin());
            inInfo = NULL;
            notifyEmptyBufferDone(inHeader);
            inHeader = NULL;
        }
        }
    }
    }
}
}
+8 −5
Original line number Original line Diff line number Diff line
@@ -98,6 +98,7 @@ private:
    bool mFlushNeeded;
    bool mFlushNeeded;
    bool mSignalledError;
    bool mSignalledError;
    size_t mStride;
    size_t mStride;
    size_t mInputOffset;


    status_t initDecoder();
    status_t initDecoder();
    status_t deInitDecoder();
    status_t deInitDecoder();
@@ -140,10 +141,10 @@ private:
        ALOGD("Could not open file %s", m_filename);    \
        ALOGD("Could not open file %s", m_filename);    \
    }                                                   \
    }                                                   \
}
}
#define DUMP_TO_FILE(m_filename, m_buf, m_size)         \
#define DUMP_TO_FILE(m_filename, m_buf, m_size, m_offset)\
{                                                       \
{                                                       \
    FILE *fp = fopen(m_filename, "ab");                 \
    FILE *fp = fopen(m_filename, "ab");                 \
    if (fp != NULL && m_buf != NULL) {                  \
    if (fp != NULL && m_buf != NULL && m_offset == 0) { \
        int i;                                          \
        int i;                                          \
        i = fwrite(m_buf, 1, m_size, fp);               \
        i = fwrite(m_buf, 1, m_size, fp);               \
        ALOGD("fwrite ret %d to write %d", i, m_size);  \
        ALOGD("fwrite ret %d to write %d", i, m_size);  \
@@ -151,10 +152,12 @@ private:
            ALOGD("Error in fwrite, returned %d", i);   \
            ALOGD("Error in fwrite, returned %d", i);   \
            perror("Error in write to file");           \
            perror("Error in write to file");           \
        }                                               \
        }                                               \
        fclose(fp);                                     \
    } else if (fp == NULL) {                            \
    } else {                                            \
        ALOGD("Could not write to file %s", m_filename);\
        ALOGD("Could not write to file %s", m_filename);\
    }                                                   \
    }                                                   \
    if (fp) {                                           \
        fclose(fp);                                     \
    }                                                   \
}
}
#else /* FILE_DUMP_ENABLE */
#else /* FILE_DUMP_ENABLE */
#define INPUT_DUMP_PATH
#define INPUT_DUMP_PATH
@@ -163,7 +166,7 @@ private:
#define OUTPUT_DUMP_EXT
#define OUTPUT_DUMP_EXT
#define GENERATE_FILE_NAMES()
#define GENERATE_FILE_NAMES()
#define CREATE_DUMP_FILE(m_filename)
#define CREATE_DUMP_FILE(m_filename)
#define DUMP_TO_FILE(m_filename, m_buf, m_size)
#define DUMP_TO_FILE(m_filename, m_buf, m_size, m_offset)
#endif /* FILE_DUMP_ENABLE */
#endif /* FILE_DUMP_ENABLE */


} // namespace android
} // namespace android