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

Commit a0940a56 authored by Lajos Molnar's avatar Lajos Molnar
Browse files

stagefright: misc fixes to software video encoders (and decoders)

- move logic to set encoder parameters to common encoder class
  (similarly to what was done for decoders)
- set compressed buffer size based on frame size and compression ratio,
  and codec-specific minimum size
- set raw buffer size based on frame size and metadata mode
- do not set stride and slice height on compressed ports
- advertise only QCIF support for google H263 encoder
- set large-enough input size for video decoders to support adaptive
  playback
- do not change input buffer size on output port reconfiguration, as
  no input buffer reallocation takes place
- do not return empty buffers with EOS after EOS has been signaled

Bug: 18513091
Bug: 18639027
Change-Id: Ib13492ef66adf331aa4572c67d2b283ea020cb41
parent 94a92c69
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -40,6 +40,12 @@ inline static const T divUp(const T &nom, const T &den) {
    }
}

/* == ceil(nom / den) * den. T must be integer type, alignment must be positive power of 2 */
template<class T, class U>
inline static const T align(const T &nom, const U &den) {
    return (nom + (T)(den - 1)) & (T)~(den - 1);
}

template<class T>
inline static T abs(const T &a) {
    return a < 0 ? -a : a;
+2 −1
Original line number Diff line number Diff line
@@ -4240,7 +4240,8 @@ bool ACodec::BaseState::onOMXFillBufferDone(

        case RESUBMIT_BUFFERS:
        {
            if (rangeLength == 0 && !(flags & OMX_BUFFERFLAG_EOS)) {
            if (rangeLength == 0 && (!(flags & OMX_BUFFERFLAG_EOS)
                    || mCodec->mPortEOS[kPortIndexOutput])) {
                ALOGV("[%s] calling fillBuffer %u",
                     mCodec->mComponentName.c_str(), info->mBufferID);

+59 −292
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@
//#define LOG_NDEBUG 0
#define LOG_TAG "SoftAVCEncoder"
#include <utils/Log.h>
#include <utils/misc.h>

#include "avcenc_api.h"
#include "avcenc_int.h"
@@ -25,6 +26,7 @@
#include <HardwareAPI.h>
#include <MetadataBufferType.h>
#include <media/stagefright/foundation/ADebug.h>
#include <media/stagefright/foundation/AUtils.h>
#include <media/stagefright/MediaDefs.h>
#include <media/stagefright/MediaErrors.h>
#include <media/stagefright/MetaData.h>
@@ -51,31 +53,36 @@ static void InitOMXParams(T *params) {
    params->nVersion.s.nStep = 0;
}

static const CodecProfileLevel kProfileLevels[] = {
    { OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel2  },
};

typedef struct LevelConversion {
    OMX_U32 omxLevel;
    AVCLevel avcLevel;
    uint32_t maxMacroBlocks;
} LevelConcersion;

static LevelConversion ConversionTable[] = {
    { OMX_VIDEO_AVCLevel1,  AVC_LEVEL1_B },
    { OMX_VIDEO_AVCLevel1b, AVC_LEVEL1   },
    { OMX_VIDEO_AVCLevel11, AVC_LEVEL1_1 },
    { OMX_VIDEO_AVCLevel12, AVC_LEVEL1_2 },
    { OMX_VIDEO_AVCLevel13, AVC_LEVEL1_3 },
    { OMX_VIDEO_AVCLevel2,  AVC_LEVEL2 },
    { OMX_VIDEO_AVCLevel1,  AVC_LEVEL1_B, 99 },
    { OMX_VIDEO_AVCLevel1b, AVC_LEVEL1,   99 },
    { OMX_VIDEO_AVCLevel11, AVC_LEVEL1_1, 396 },
    { OMX_VIDEO_AVCLevel12, AVC_LEVEL1_2, 396 },
    { OMX_VIDEO_AVCLevel13, AVC_LEVEL1_3, 396 },
    { OMX_VIDEO_AVCLevel2,  AVC_LEVEL2,   396 },
#if 0
    // encoding speed is very poor if video
    // resolution is higher than CIF
    { OMX_VIDEO_AVCLevel21, AVC_LEVEL2_1 },
    { OMX_VIDEO_AVCLevel22, AVC_LEVEL2_2 },
    { OMX_VIDEO_AVCLevel3,  AVC_LEVEL3   },
    { OMX_VIDEO_AVCLevel31, AVC_LEVEL3_1 },
    { OMX_VIDEO_AVCLevel32, AVC_LEVEL3_2 },
    { OMX_VIDEO_AVCLevel4,  AVC_LEVEL4   },
    { OMX_VIDEO_AVCLevel41, AVC_LEVEL4_1 },
    { OMX_VIDEO_AVCLevel42, AVC_LEVEL4_2 },
    { OMX_VIDEO_AVCLevel5,  AVC_LEVEL5   },
    { OMX_VIDEO_AVCLevel51, AVC_LEVEL5_1 },
    // encoding speed is very poor if video resolution
    // is higher than CIF or if level is higher than 2
    { OMX_VIDEO_AVCLevel21, AVC_LEVEL2_1, 792 },
    { OMX_VIDEO_AVCLevel22, AVC_LEVEL2_2, 1620 },
    { OMX_VIDEO_AVCLevel3,  AVC_LEVEL3,   1620 },
    { OMX_VIDEO_AVCLevel31, AVC_LEVEL3_1, 3600 },
    { OMX_VIDEO_AVCLevel32, AVC_LEVEL3_2, 5120 },
    { OMX_VIDEO_AVCLevel4,  AVC_LEVEL4,   8192 },
    { OMX_VIDEO_AVCLevel41, AVC_LEVEL4_1, 8192 },
    { OMX_VIDEO_AVCLevel42, AVC_LEVEL4_2, 8704 },
    { OMX_VIDEO_AVCLevel5,  AVC_LEVEL5,   22080 },
    { OMX_VIDEO_AVCLevel51, AVC_LEVEL5_1, 36864 },
#endif
};

@@ -148,13 +155,11 @@ SoftAVCEncoder::SoftAVCEncoder(
            const OMX_CALLBACKTYPE *callbacks,
            OMX_PTR appData,
            OMX_COMPONENTTYPE **component)
    : SoftVideoEncoderOMXComponent(name, callbacks, appData, component),
      mVideoWidth(176),
      mVideoHeight(144),
      mVideoFrameRate(30),
      mVideoBitRate(192000),
      mVideoColorFormat(OMX_COLOR_FormatYUV420Planar),
      mStoreMetaDataInBuffers(false),
    : SoftVideoEncoderOMXComponent(
            name, "video_encoder.avc", OMX_VIDEO_CodingAVC,
            kProfileLevels, NELEM(kProfileLevels),
            176 /* width */, 144 /* height */,
            callbacks, appData, component),
      mIDRFrameRefreshIntervalInSec(1),
      mAVCEncProfile(AVC_BASELINE),
      mAVCEncLevel(AVC_LEVEL2),
@@ -168,7 +173,13 @@ SoftAVCEncoder::SoftAVCEncoder(
      mInputFrameData(NULL),
      mSliceGroup(NULL) {

    initPorts();
    const size_t kOutputBufferSize =
        320 * ConversionTable[NELEM(ConversionTable) - 1].maxMacroBlocks;

    initPorts(
            kNumBuffers, kNumBuffers, kOutputBufferSize,
            MEDIA_MIMETYPE_VIDEO_AVC, 2 /* minCompressionRatio */);

    ALOGI("Construct SoftAVCEncoder");
}

@@ -230,30 +241,28 @@ OMX_ERRORTYPE SoftAVCEncoder::initEncParams() {

    mEncParams->use_overrun_buffer = AVC_OFF;

    if (mVideoColorFormat != OMX_COLOR_FormatYUV420Planar
            || mStoreMetaDataInBuffers) {
    if (mColorFormat != OMX_COLOR_FormatYUV420Planar || mInputDataIsMeta) {
        // Color conversion is needed.
        free(mInputFrameData);
        mInputFrameData =
            (uint8_t *) malloc((mVideoWidth * mVideoHeight * 3 ) >> 1);
            (uint8_t *) malloc((mWidth * mHeight * 3 ) >> 1);
        CHECK(mInputFrameData != NULL);
    }

    // PV's AVC encoder requires the video dimension of multiple
    if (mVideoWidth % 16 != 0 || mVideoHeight % 16 != 0) {
    if (mWidth % 16 != 0 || mHeight % 16 != 0) {
        ALOGE("Video frame size %dx%d must be a multiple of 16",
            mVideoWidth, mVideoHeight);
            mWidth, mHeight);
        return OMX_ErrorBadParameter;
    }

    mEncParams->width = mVideoWidth;
    mEncParams->height = mVideoHeight;
    mEncParams->bitrate = mVideoBitRate;
    mEncParams->frame_rate = 1000 * mVideoFrameRate;  // In frames/ms!
    mEncParams->CPB_size = (uint32_t) (mVideoBitRate >> 1);
    mEncParams->width = mWidth;
    mEncParams->height = mHeight;
    mEncParams->bitrate = mBitrate;
    mEncParams->frame_rate = (1000 * mFramerate) >> 16;  // In frames/ms!, mFramerate is in Q16
    mEncParams->CPB_size = (uint32_t) (mBitrate >> 1);

    int32_t nMacroBlocks = ((((mVideoWidth + 15) >> 4) << 4) *
            (((mVideoHeight + 15) >> 4) << 4)) >> 8;
    int32_t nMacroBlocks = divUp(mWidth, 16) * divUp(mHeight, 16);
    CHECK(mSliceGroup == NULL);
    mSliceGroup = (uint32_t *) malloc(sizeof(uint32_t) * nMacroBlocks);
    CHECK(mSliceGroup != NULL);
@@ -272,7 +281,7 @@ OMX_ERRORTYPE SoftAVCEncoder::initEncParams() {
        mEncParams->idr_period = 1;  // All I frames
    } else {
        mEncParams->idr_period =
            (mIDRFrameRefreshIntervalInSec * mVideoFrameRate);
            (mIDRFrameRefreshIntervalInSec * mFramerate) >> 16; // mFramerate is in Q16
    }

    // Set profile and level
@@ -345,71 +354,9 @@ void SoftAVCEncoder::releaseOutputBuffers() {
    mOutputBuffers.clear();
}

void SoftAVCEncoder::initPorts() {
    OMX_PARAM_PORTDEFINITIONTYPE def;
    InitOMXParams(&def);

    const size_t kInputBufferSize = (mVideoWidth * mVideoHeight * 3) >> 1;

    // 31584 is PV's magic number.  Not sure why.
    const size_t kOutputBufferSize =
            (kInputBufferSize > 31584) ? kInputBufferSize: 31584;

    def.nPortIndex = 0;
    def.eDir = OMX_DirInput;
    def.nBufferCountMin = kNumBuffers;
    def.nBufferCountActual = def.nBufferCountMin;
    def.nBufferSize = kInputBufferSize;
    def.bEnabled = OMX_TRUE;
    def.bPopulated = OMX_FALSE;
    def.eDomain = OMX_PortDomainVideo;
    def.bBuffersContiguous = OMX_FALSE;
    def.nBufferAlignment = 1;

    def.format.video.cMIMEType = const_cast<char *>("video/raw");
    def.format.video.eCompressionFormat = OMX_VIDEO_CodingUnused;
    def.format.video.eColorFormat = OMX_COLOR_FormatYUV420Planar;
    def.format.video.xFramerate = (mVideoFrameRate << 16);  // Q16 format
    def.format.video.nBitrate = mVideoBitRate;
    def.format.video.nFrameWidth = mVideoWidth;
    def.format.video.nFrameHeight = mVideoHeight;
    def.format.video.nStride = mVideoWidth;
    def.format.video.nSliceHeight = mVideoHeight;

    addPort(def);

    def.nPortIndex = 1;
    def.eDir = OMX_DirOutput;
    def.nBufferCountMin = kNumBuffers;
    def.nBufferCountActual = def.nBufferCountMin;
    def.nBufferSize = kOutputBufferSize;
    def.bEnabled = OMX_TRUE;
    def.bPopulated = OMX_FALSE;
    def.eDomain = OMX_PortDomainVideo;
    def.bBuffersContiguous = OMX_FALSE;
    def.nBufferAlignment = 2;

    def.format.video.cMIMEType = const_cast<char *>("video/avc");
    def.format.video.eCompressionFormat = OMX_VIDEO_CodingAVC;
    def.format.video.eColorFormat = OMX_COLOR_FormatUnused;
    def.format.video.xFramerate = (0 << 16);  // Q16 format
    def.format.video.nBitrate = mVideoBitRate;
    def.format.video.nFrameWidth = mVideoWidth;
    def.format.video.nFrameHeight = mVideoHeight;
    def.format.video.nStride = mVideoWidth;
    def.format.video.nSliceHeight = mVideoHeight;

    addPort(def);
}

OMX_ERRORTYPE SoftAVCEncoder::internalGetParameter(
        OMX_INDEXTYPE index, OMX_PTR params) {
    switch (index) {
        case OMX_IndexParamVideoErrorCorrection:
        {
            return OMX_ErrorNotImplemented;
        }

        case OMX_IndexParamVideoBitrate:
        {
            OMX_VIDEO_PARAM_BITRATETYPE *bitRate =
@@ -420,37 +367,7 @@ OMX_ERRORTYPE SoftAVCEncoder::internalGetParameter(
            }

            bitRate->eControlRate = OMX_Video_ControlRateVariable;
            bitRate->nTargetBitrate = mVideoBitRate;
            return OMX_ErrorNone;
        }

        case OMX_IndexParamVideoPortFormat:
        {
            OMX_VIDEO_PARAM_PORTFORMATTYPE *formatParams =
                (OMX_VIDEO_PARAM_PORTFORMATTYPE *)params;

            if (formatParams->nPortIndex > 1) {
                return OMX_ErrorUndefined;
            }

            if (formatParams->nIndex > 2) {
                return OMX_ErrorNoMore;
            }

            if (formatParams->nPortIndex == 0) {
                formatParams->eCompressionFormat = OMX_VIDEO_CodingUnused;
                if (formatParams->nIndex == 0) {
                    formatParams->eColorFormat = OMX_COLOR_FormatYUV420Planar;
                } else if (formatParams->nIndex == 1) {
                    formatParams->eColorFormat = OMX_COLOR_FormatYUV420SemiPlanar;
                } else {
                    formatParams->eColorFormat = OMX_COLOR_FormatAndroidOpaque;
                }
            } else {
                formatParams->eCompressionFormat = OMX_VIDEO_CodingAVC;
                formatParams->eColorFormat = OMX_COLOR_FormatUnused;
            }

            bitRate->nTargetBitrate = mBitrate;
            return OMX_ErrorNone;
        }

@@ -487,30 +404,8 @@ OMX_ERRORTYPE SoftAVCEncoder::internalGetParameter(
            return OMX_ErrorNone;
        }

        case OMX_IndexParamVideoProfileLevelQuerySupported:
        {
            OMX_VIDEO_PARAM_PROFILELEVELTYPE *profileLevel =
                (OMX_VIDEO_PARAM_PROFILELEVELTYPE *)params;

            if (profileLevel->nPortIndex != 1) {
                return OMX_ErrorUndefined;
            }

            const size_t size =
                    sizeof(ConversionTable) / sizeof(ConversionTable[0]);

            if (profileLevel->nProfileIndex >= size) {
                return OMX_ErrorNoMore;
            }

            profileLevel->eProfile = OMX_VIDEO_AVCProfileBaseline;
            profileLevel->eLevel = ConversionTable[profileLevel->nProfileIndex].omxLevel;

            return OMX_ErrorNone;
        }

        default:
            return SimpleSoftOMXComponent::internalGetParameter(index, params);
            return SoftVideoEncoderOMXComponent::internalGetParameter(index, params);
    }
}

@@ -519,11 +414,6 @@ OMX_ERRORTYPE SoftAVCEncoder::internalSetParameter(
    int32_t indexFull = index;

    switch (indexFull) {
        case OMX_IndexParamVideoErrorCorrection:
        {
            return OMX_ErrorNotImplemented;
        }

        case OMX_IndexParamVideoBitrate:
        {
            OMX_VIDEO_PARAM_BITRATETYPE *bitRate =
@@ -534,109 +424,7 @@ OMX_ERRORTYPE SoftAVCEncoder::internalSetParameter(
                return OMX_ErrorUndefined;
            }

            mVideoBitRate = bitRate->nTargetBitrate;
            return OMX_ErrorNone;
        }

        case OMX_IndexParamPortDefinition:
        {
            OMX_PARAM_PORTDEFINITIONTYPE *def =
                (OMX_PARAM_PORTDEFINITIONTYPE *)params;
            if (def->nPortIndex > 1) {
                return OMX_ErrorUndefined;
            }

            if (def->nPortIndex == 0) {
                if (def->format.video.eCompressionFormat != OMX_VIDEO_CodingUnused ||
                    (def->format.video.eColorFormat != OMX_COLOR_FormatYUV420Planar &&
                     def->format.video.eColorFormat != OMX_COLOR_FormatYUV420SemiPlanar &&
                     def->format.video.eColorFormat != OMX_COLOR_FormatAndroidOpaque)) {
                    return OMX_ErrorUndefined;
                }
            } else {
                if (def->format.video.eCompressionFormat != OMX_VIDEO_CodingAVC ||
                    (def->format.video.eColorFormat != OMX_COLOR_FormatUnused)) {
                    return OMX_ErrorUndefined;
                }
            }

            OMX_ERRORTYPE err = SimpleSoftOMXComponent::internalSetParameter(index, params);
            if (OMX_ErrorNone != err) {
                return err;
            }

            if (def->nPortIndex == 0) {
                mVideoWidth = def->format.video.nFrameWidth;
                mVideoHeight = def->format.video.nFrameHeight;
                mVideoFrameRate = def->format.video.xFramerate >> 16;
                mVideoColorFormat = def->format.video.eColorFormat;

                OMX_PARAM_PORTDEFINITIONTYPE *portDef =
                    &editPortInfo(0)->mDef;
                portDef->format.video.nFrameWidth = mVideoWidth;
                portDef->format.video.nFrameHeight = mVideoHeight;
                portDef->format.video.nStride = portDef->format.video.nFrameWidth;
                portDef->format.video.nSliceHeight = portDef->format.video.nFrameHeight;
                portDef->format.video.xFramerate = def->format.video.xFramerate;
                portDef->format.video.eColorFormat =
                    (OMX_COLOR_FORMATTYPE) mVideoColorFormat;
                portDef->nBufferSize =
                    (portDef->format.video.nStride * portDef->format.video.nSliceHeight * 3) / 2;
                portDef = &editPortInfo(1)->mDef;
                portDef->format.video.nFrameWidth = mVideoWidth;
                portDef->format.video.nFrameHeight = mVideoHeight;
            } else {
                mVideoBitRate = def->format.video.nBitrate;
            }

            return OMX_ErrorNone;
        }

        case OMX_IndexParamStandardComponentRole:
        {
            const OMX_PARAM_COMPONENTROLETYPE *roleParams =
                (const OMX_PARAM_COMPONENTROLETYPE *)params;

            if (strncmp((const char *)roleParams->cRole,
                        "video_encoder.avc",
                        OMX_MAX_STRINGNAME_SIZE - 1)) {
                return OMX_ErrorUndefined;
            }

            return OMX_ErrorNone;
        }

        case OMX_IndexParamVideoPortFormat:
        {
            const OMX_VIDEO_PARAM_PORTFORMATTYPE *formatParams =
                (const OMX_VIDEO_PARAM_PORTFORMATTYPE *)params;

            if (formatParams->nPortIndex > 1) {
                return OMX_ErrorUndefined;
            }

            if (formatParams->nIndex > 2) {
                return OMX_ErrorNoMore;
            }

            if (formatParams->nPortIndex == 0) {
                if (formatParams->eCompressionFormat != OMX_VIDEO_CodingUnused ||
                    ((formatParams->nIndex == 0 &&
                      formatParams->eColorFormat != OMX_COLOR_FormatYUV420Planar) ||
                    (formatParams->nIndex == 1 &&
                     formatParams->eColorFormat != OMX_COLOR_FormatYUV420SemiPlanar) ||
                    (formatParams->nIndex == 2 &&
                     formatParams->eColorFormat != OMX_COLOR_FormatAndroidOpaque) )) {
                    return OMX_ErrorUndefined;
                }
                mVideoColorFormat = formatParams->eColorFormat;
            } else {
                if (formatParams->eCompressionFormat != OMX_VIDEO_CodingAVC ||
                    formatParams->eColorFormat != OMX_COLOR_FormatUnused) {
                    return OMX_ErrorUndefined;
                }
            }

            mBitrate = bitRate->nTargetBitrate;
            return OMX_ErrorNone;
        }

@@ -673,29 +461,8 @@ OMX_ERRORTYPE SoftAVCEncoder::internalSetParameter(
            return OMX_ErrorNone;
        }

        case kStoreMetaDataExtensionIndex:
        {
            StoreMetaDataInBuffersParams *storeParams =
                    (StoreMetaDataInBuffersParams*)params;
            if (storeParams->nPortIndex != 0) {
                ALOGE("%s: StoreMetadataInBuffersParams.nPortIndex not zero!",
                        __FUNCTION__);
                return OMX_ErrorUndefined;
            }

            mStoreMetaDataInBuffers = storeParams->bStoreMetaData;
            ALOGV("StoreMetaDataInBuffers set to: %s",
                    mStoreMetaDataInBuffers ? " true" : "false");

            if (mStoreMetaDataInBuffers) {
                mVideoColorFormat = OMX_COLOR_FormatAndroidOpaque;
            }

            return OMX_ErrorNone;
        }

        default:
            return SimpleSoftOMXComponent::internalSetParameter(index, params);
            return SoftVideoEncoderOMXComponent::internalSetParameter(index, params);
    }
}

@@ -789,11 +556,11 @@ void SoftAVCEncoder::onQueueFilled(OMX_U32 /* portIndex */) {
            if (inHeader->nFilledLen > 0) {
                AVCFrameIO videoInput;
                memset(&videoInput, 0, sizeof(videoInput));
                videoInput.height = ((mVideoHeight  + 15) >> 4) << 4;
                videoInput.pitch = ((mVideoWidth + 15) >> 4) << 4;
                videoInput.height = align(mHeight, 16);
                videoInput.pitch = align(mWidth, 16);
                videoInput.coding_timestamp = (inHeader->nTimeStamp + 500) / 1000;  // in ms
                const uint8_t *inputData = NULL;
                if (mStoreMetaDataInBuffers) {
                if (mInputDataIsMeta) {
                    if (inHeader->nFilledLen != 8) {
                        ALOGE("MetaData buffer is wrong size! "
                                "(got %u bytes, expected 8)", inHeader->nFilledLen);
@@ -803,9 +570,9 @@ void SoftAVCEncoder::onQueueFilled(OMX_U32 /* portIndex */) {
                    }
                    inputData =
                        extractGraphicBuffer(
                                mInputFrameData, (mVideoWidth * mVideoHeight * 3) >> 1,
                                mInputFrameData, (mWidth * mHeight * 3) >> 1,
                                inHeader->pBuffer + inHeader->nOffset, inHeader->nFilledLen,
                                mVideoWidth, mVideoHeight);
                                mWidth, mHeight);
                    if (inputData == NULL) {
                        ALOGE("Unable to extract gralloc buffer in metadata mode");
                        mSignalledError = true;
@@ -815,9 +582,9 @@ void SoftAVCEncoder::onQueueFilled(OMX_U32 /* portIndex */) {
                    // TODO: Verify/convert pixel format enum
                } else {
                    inputData = (const uint8_t *)inHeader->pBuffer + inHeader->nOffset;
                    if (mVideoColorFormat != OMX_COLOR_FormatYUV420Planar) {
                    if (mColorFormat != OMX_COLOR_FormatYUV420Planar) {
                        ConvertYUV420SemiPlanarToYUV420Planar(
                            inputData, mInputFrameData, mVideoWidth, mVideoHeight);
                            inputData, mInputFrameData, mWidth, mHeight);
                        inputData = mInputFrameData;
                    }
                }
+0 −7
Original line number Diff line number Diff line
@@ -68,12 +68,6 @@ private:
        int32_t mFlags;
    } InputBufferInfo;

    int32_t  mVideoWidth;
    int32_t  mVideoHeight;
    int32_t  mVideoFrameRate;
    int32_t  mVideoBitRate;
    int32_t  mVideoColorFormat;
    bool     mStoreMetaDataInBuffers;
    int32_t  mIDRFrameRefreshIntervalInSec;
    AVCProfile mAVCEncProfile;
    AVCLevel   mAVCEncLevel;
@@ -94,7 +88,6 @@ private:
    Vector<MediaBuffer *> mOutputBuffers;
    Vector<InputBufferInfo> mInputBufferInfoVec;

    void initPorts();
    OMX_ERRORTYPE initEncParams();
    OMX_ERRORTYPE initEncoder();
    OMX_ERRORTYPE releaseEncoder();
+8 −3
Original line number Diff line number Diff line
@@ -26,6 +26,7 @@
#include "SoftHEVC.h"

#include <media/stagefright/foundation/ADebug.h>
#include <media/stagefright/foundation/AUtils.h>
#include <media/stagefright/MediaDefs.h>
#include <OMX_VideoExt.h>

@@ -75,8 +76,12 @@ SoftHEVC::SoftHEVC(
      mNewWidth(mWidth),
      mNewHeight(mHeight),
      mChangingResolution(false) {
    initPorts(kNumBuffers, INPUT_BUF_SIZE, kNumBuffers,
            CODEC_MIME_TYPE);
    const size_t kMinCompressionRatio = 4 /* compressionRatio (for Level 4+) */;
    const size_t kMaxOutputBufferSize = 2048 * 2048 * 3 / 2;
    // INPUT_BUF_SIZE is given by HEVC codec as minimum input size
    initPorts(
            kNumBuffers, max(kMaxOutputBufferSize / kMinCompressionRatio, (size_t)INPUT_BUF_SIZE),
            kNumBuffers, CODEC_MIME_TYPE, kMinCompressionRatio);
    CHECK_EQ(initDecoder(), (status_t)OK);
}

@@ -644,7 +649,7 @@ void SoftHEVC::onQueueFilled(OMX_U32 portIndex) {
            // 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 == (IHEVCD_CXA_ERROR_CODES_T)status)
                    || (IHEVCD_UNSUPPORTED_DIMENSIONS == s_dec_op.u4_error_code));
            bool resChanged = (IVD_RES_CHANGED == (s_dec_op.u4_error_code & 0xFF));

Loading