diff options
| author | Doney Alex <doney.alex@ittiam.com> | 2015-06-01 18:14:02 +0530 | 
|---|---|---|
| committer | Marco Nelissen <marcone@google.com> | 2015-06-25 10:36:40 -0700 | 
| commit | 1ad56353aec03b0255d5cd5b67f9e6df780d9b65 (patch) | |
| tree | db30f8486a228e63d364ddb72074166a8a00931b /media | |
| parent | defb2374a0e0adbd3714a2cd02be3c309cde4875 (diff) | |
| download | frameworks_av-1ad56353aec03b0255d5cd5b67f9e6df780d9b65.zip frameworks_av-1ad56353aec03b0255d5cd5b67f9e6df780d9b65.tar.gz frameworks_av-1ad56353aec03b0255d5cd5b67f9e6df780d9b65.tar.bz2  | |
SoftAVCEnc: Added support for Main Profile encoding.
Configured intra frame interval and deblock in setParams.
Change-Id: If501fa0ac42f2c4bf6604ea84715f7f13f707e74
Diffstat (limited to 'media')
| -rw-r--r-- | media/libstagefright/codecs/avcenc/SoftAVCEnc.cpp | 290 | ||||
| -rw-r--r-- | media/libstagefright/codecs/avcenc/SoftAVCEnc.h | 33 | 
2 files changed, 203 insertions, 120 deletions
diff --git a/media/libstagefright/codecs/avcenc/SoftAVCEnc.cpp b/media/libstagefright/codecs/avcenc/SoftAVCEnc.cpp index a00f324..9ee3518 100644 --- a/media/libstagefright/codecs/avcenc/SoftAVCEnc.cpp +++ b/media/libstagefright/codecs/avcenc/SoftAVCEnc.cpp @@ -49,10 +49,10 @@ static void InitOMXParams(T *params) {      params->nVersion.s.nStep = 0;  } -typedef struct LevelConversion { +struct LevelConversion {      OMX_VIDEO_AVCLEVELTYPE omxLevel;      WORD32 avcLevel; -} LevelConcersion; +};  static LevelConversion ConversionTable[] = {      { OMX_VIDEO_AVCLevel1,  10 }, @@ -87,8 +87,21 @@ static const CodecProfileLevel kProfileLevels[] = {      { OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel32 },      { OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel4  },      { OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel41 }, -}; +    { OMX_VIDEO_AVCProfileMain, OMX_VIDEO_AVCLevel1  }, +    { OMX_VIDEO_AVCProfileMain, OMX_VIDEO_AVCLevel1b }, +    { OMX_VIDEO_AVCProfileMain, OMX_VIDEO_AVCLevel11 }, +    { OMX_VIDEO_AVCProfileMain, OMX_VIDEO_AVCLevel12 }, +    { OMX_VIDEO_AVCProfileMain, OMX_VIDEO_AVCLevel13 }, +    { OMX_VIDEO_AVCProfileMain, OMX_VIDEO_AVCLevel2  }, +    { OMX_VIDEO_AVCProfileMain, OMX_VIDEO_AVCLevel21 }, +    { OMX_VIDEO_AVCProfileMain, OMX_VIDEO_AVCLevel22 }, +    { OMX_VIDEO_AVCProfileMain, OMX_VIDEO_AVCLevel3  }, +    { OMX_VIDEO_AVCProfileMain, OMX_VIDEO_AVCLevel31 }, +    { OMX_VIDEO_AVCProfileMain, OMX_VIDEO_AVCLevel32 }, +    { OMX_VIDEO_AVCProfileMain, OMX_VIDEO_AVCLevel4  }, +    { OMX_VIDEO_AVCProfileMain, OMX_VIDEO_AVCLevel41 }, +};  static size_t GetCPUCoreCount() {      long cpuCoreCount = 1; @@ -99,7 +112,7 @@ static size_t GetCPUCoreCount() {      cpuCoreCount = sysconf(_SC_NPROC_ONLN);  #endif      CHECK(cpuCoreCount >= 1); -    ALOGD("Number of CPU cores: %ld", cpuCoreCount); +    ALOGV("Number of CPU cores: %ld", cpuCoreCount);      return (size_t)cpuCoreCount;  } @@ -144,15 +157,15 @@ SoftAVC::SoftAVC(              kProfileLevels, NELEM(kProfileLevels),              176 /* width */, 144 /* height */,              callbacks, appData, component), +      mBitrateUpdated(false), +      mKeyFrameRequested(false),        mIvVideoColorFormat(IV_YUV_420P), -      mIDRFrameRefreshIntervalInSec(1),        mAVCEncProfile(IV_PROFILE_BASE), -      mAVCEncLevel(31), -      mPrevTimestampUs(-1), +      mAVCEncLevel(41),        mStarted(false),        mSawInputEOS(false), +      mSawOutputEOS(false),        mSignalledError(false), -      mConversionBuffer(NULL),        mCodecCtx(NULL) {      initPorts(kNumBuffers, kNumBuffers, ((mWidth * mHeight * 3) >> 1), @@ -162,6 +175,10 @@ SoftAVC::SoftAVC(      GENERATE_FILE_NAMES();      CREATE_DUMP_FILE(mInFile);      CREATE_DUMP_FILE(mOutFile); +    memset(mConversionBuffers, 0, sizeof(mConversionBuffers)); +    memset(mInputBufferInfo, 0, sizeof(mInputBufferInfo)); + +    initEncParams();  } @@ -173,7 +190,7 @@ SoftAVC::~SoftAVC() {      CHECK(inQueue.empty());  } -OMX_ERRORTYPE SoftAVC::initEncParams() { +void  SoftAVC::initEncParams() {      mCodecCtx = NULL;      mMemRecords = NULL;      mNumMemRecords = DEFAULT_MEM_REC_CNT; @@ -186,7 +203,6 @@ OMX_ERRORTYPE SoftAVC::initEncParams() {      mIInterval = DEFAULT_I_INTERVAL;      mIDRInterval = DEFAULT_IDR_INTERVAL;      mDisableDeblkLevel = DEFAULT_DISABLE_DEBLK_LEVEL; -    mFrameRate = DEFAULT_SRC_FRAME_RATE;      mEnableFastSad = DEFAULT_ENABLE_FAST_SAD;      mEnableAltRef = DEFAULT_ENABLE_ALT_REF;      mEncSpeed = DEFAULT_ENC_SPEED; @@ -195,11 +211,12 @@ OMX_ERRORTYPE SoftAVC::initEncParams() {      mAIRRefreshPeriod = DEFAULT_AIR_REFRESH_PERIOD;      mPSNREnable = DEFAULT_PSNR_ENABLE;      mReconEnable = DEFAULT_RECON_ENABLE; +    mEntropyMode = DEFAULT_ENTROPY_MODE; +    mBframes = DEFAULT_B_FRAMES;      gettimeofday(&mTimeStart, NULL);      gettimeofday(&mTimeEnd, NULL); -    return OMX_ErrorNone;  } @@ -260,8 +277,8 @@ OMX_ERRORTYPE SoftAVC::setFrameRate() {      s_frame_rate_ip.e_cmd = IVE_CMD_VIDEO_CTL;      s_frame_rate_ip.e_sub_cmd = IVE_CMD_CTL_SET_FRAMERATE; -    s_frame_rate_ip.u4_src_frame_rate = mFrameRate; -    s_frame_rate_ip.u4_tgt_frame_rate = mFrameRate; +    s_frame_rate_ip.u4_src_frame_rate = mFramerate >> 16; +    s_frame_rate_ip.u4_tgt_frame_rate = mFramerate >> 16;      s_frame_rate_ip.u4_timestamp_high = -1;      s_frame_rate_ip.u4_timestamp_low = -1; @@ -332,7 +349,6 @@ OMX_ERRORTYPE SoftAVC::setFrameType(IV_PICTURE_CODING_TYPE_T e_frame_type) {      ive_ctl_set_frame_type_ip_t s_frame_type_ip;      ive_ctl_set_frame_type_op_t s_frame_type_op;      IV_STATUS_T status; -      s_frame_type_ip.e_cmd = IVE_CMD_VIDEO_CTL;      s_frame_type_ip.e_sub_cmd = IVE_CMD_CTL_SET_FRAMETYPE; @@ -503,7 +519,6 @@ OMX_ERRORTYPE SoftAVC::setGopParams() {      s_gop_params_ip.u4_i_frm_interval = mIInterval;      s_gop_params_ip.u4_idr_frm_interval = mIDRInterval; -    s_gop_params_ip.u4_num_b_frames = DEFAULT_B_FRAMES;      s_gop_params_ip.u4_timestamp_high = -1;      s_gop_params_ip.u4_timestamp_low = -1; @@ -529,7 +544,7 @@ OMX_ERRORTYPE SoftAVC::setProfileParams() {      s_profile_params_ip.e_sub_cmd = IVE_CMD_CTL_SET_PROFILE_PARAMS;      s_profile_params_ip.e_profile = DEFAULT_EPROFILE; - +    s_profile_params_ip.u4_entropy_coding_mode = mEntropyMode;      s_profile_params_ip.u4_timestamp_high = -1;      s_profile_params_ip.u4_timestamp_low = -1; @@ -595,7 +610,6 @@ void SoftAVC::logVersion() {  OMX_ERRORTYPE SoftAVC::initEncoder() {      IV_STATUS_T status; -    size_t i;      WORD32 level;      uint32_t displaySizeY;      CHECK(!mStarted); @@ -618,31 +632,26 @@ OMX_ERRORTYPE SoftAVC::initEncoder() {      }      mAVCEncLevel = MAX(level, mAVCEncLevel); -    if (OMX_ErrorNone != (errType = initEncParams())) { -        ALOGE("Failed to initialize encoder params"); -        mSignalledError = true; -        notify(OMX_EventError, OMX_ErrorUndefined, 0, 0); -        return errType; -    } -      mStride = mWidth;      if (mInputDataIsMeta) { -        if (mConversionBuffer) { -            free(mConversionBuffer); -            mConversionBuffer = NULL; -        } +        for (size_t i = 0; i < MAX_CONVERSION_BUFFERS; i++) { +            if (mConversionBuffers[i] != NULL) { +                free(mConversionBuffers[i]); +            } -        if (mConversionBuffer == NULL) {              if (((uint64_t)mStride * mHeight) > (((uint64_t)INT32_MAX / 3) * 2)) {                  ALOGE("Buffer size is too big.");                  return OMX_ErrorUndefined;              } -            mConversionBuffer = (uint8_t *)malloc(mStride * mHeight * 3 / 2); -            if (mConversionBuffer == NULL) { +            mConversionBuffers[i] = (uint8_t *)malloc(mStride * mHeight * 3 / 2); + +            if (mConversionBuffers[i] == NULL) {                  ALOGE("Allocating conversion buffer failed.");                  return OMX_ErrorUndefined;              } + +            mConversionBuffersFree[i] = 1;          }      } @@ -658,7 +667,7 @@ OMX_ERRORTYPE SoftAVC::initEncoder() {              break;      } -    ALOGV("Params width %d height %d level %d colorFormat %d", mWidth, +    ALOGD("Params width %d height %d level %d colorFormat %d", mWidth,              mHeight, mAVCEncLevel, mIvVideoColorFormat);      /* Getting Number of MemRecords */ @@ -699,7 +708,7 @@ OMX_ERRORTYPE SoftAVC::initEncoder() {      {          iv_mem_rec_t *ps_mem_rec;          ps_mem_rec = mMemRecords; -        for (i = 0; i < mNumMemRecords; i++) { +        for (size_t i = 0; i < mNumMemRecords; i++) {              ps_mem_rec->u4_size = sizeof(iv_mem_rec_t);              ps_mem_rec->pv_base = NULL;              ps_mem_rec->u4_mem_size = 0; @@ -746,9 +755,9 @@ OMX_ERRORTYPE SoftAVC::initEncoder() {          WORD32 total_size;          iv_mem_rec_t *ps_mem_rec;          total_size = 0; -          ps_mem_rec = mMemRecords; -        for (i = 0; i < mNumMemRecords; i++) { + +        for (size_t i = 0; i < mNumMemRecords; i++) {              ps_mem_rec->pv_base = ive_aligned_malloc(                      ps_mem_rec->u4_mem_alignment, ps_mem_rec->u4_mem_size);              if (ps_mem_rec->pv_base == NULL) { @@ -763,7 +772,6 @@ OMX_ERRORTYPE SoftAVC::initEncoder() {              ps_mem_rec++;          } -        printf("\nTotal memory for codec %d\n", total_size);      }      /* Codec Instance Creation */ @@ -797,7 +805,7 @@ OMX_ERRORTYPE SoftAVC::initEncoder() {          s_init_ip.e_rc_mode = DEFAULT_RC_MODE;          s_init_ip.u4_max_framerate = DEFAULT_MAX_FRAMERATE;          s_init_ip.u4_max_bitrate = DEFAULT_MAX_BITRATE; -        s_init_ip.u4_max_num_bframes = DEFAULT_B_FRAMES; +        s_init_ip.u4_num_bframes = mBframes;          s_init_ip.e_content_type = IV_PROGRESSIVE;          s_init_ip.u4_max_srch_rng_x = DEFAULT_MAX_SRCH_RANGE_X;          s_init_ip.u4_max_srch_rng_y = DEFAULT_MAX_SRCH_RANGE_Y; @@ -872,7 +880,6 @@ OMX_ERRORTYPE SoftAVC::releaseEncoder() {      iv_retrieve_mem_rec_ip_t s_retrieve_mem_ip;      iv_retrieve_mem_rec_op_t s_retrieve_mem_op;      iv_mem_rec_t *ps_mem_rec; -    UWORD32 i;      if (!mStarted) {          return OMX_ErrorNone; @@ -893,16 +900,18 @@ OMX_ERRORTYPE SoftAVC::releaseEncoder() {      /* Free memory records */      ps_mem_rec = mMemRecords; -    for (i = 0; i < s_retrieve_mem_op.u4_num_mem_rec_filled; i++) { +    for (size_t i = 0; i < s_retrieve_mem_op.u4_num_mem_rec_filled; i++) {          ive_aligned_free(ps_mem_rec->pv_base);          ps_mem_rec++;      }      free(mMemRecords); -    if (mConversionBuffer != NULL) { -        free(mConversionBuffer); -        mConversionBuffer = NULL; +    for (size_t i = 0; i < MAX_CONVERSION_BUFFERS; i++) { +        if (mConversionBuffers[i]) { +            free(mConversionBuffers[i]); +            mConversionBuffers[i] = NULL; +        }      }      mStarted = false; @@ -934,23 +943,21 @@ OMX_ERRORTYPE SoftAVC::internalGetParameter(OMX_INDEXTYPE index, OMX_PTR params)                  return OMX_ErrorUndefined;              } -            avcParams->eProfile = OMX_VIDEO_AVCProfileBaseline; -            OMX_VIDEO_AVCLEVELTYPE omxLevel = OMX_VIDEO_AVCLevel31; +            OMX_VIDEO_AVCLEVELTYPE omxLevel = OMX_VIDEO_AVCLevel41;              if (OMX_ErrorNone                      != ConvertAvcSpecLevelToOmxAvcLevel(mAVCEncLevel, &omxLevel)) {                  return OMX_ErrorUndefined;              } +            avcParams->eProfile = OMX_VIDEO_AVCProfileBaseline;              avcParams->eLevel = omxLevel;              avcParams->nRefFrames = 1; -            avcParams->nBFrames = 0;              avcParams->bUseHadamard = OMX_TRUE;              avcParams->nAllowedPictureTypes = (OMX_VIDEO_PictureTypeI -                    | OMX_VIDEO_PictureTypeP); +                    | OMX_VIDEO_PictureTypeP | OMX_VIDEO_PictureTypeB);              avcParams->nRefIdx10ActiveMinus1 = 0;              avcParams->nRefIdx11ActiveMinus1 = 0;              avcParams->bWeightedPPrediction = OMX_FALSE; -            avcParams->bEntropyCodingCABAC = OMX_FALSE;              avcParams->bconstIpred = OMX_FALSE;              avcParams->bDirect8x8Inference = OMX_FALSE;              avcParams->bDirectSpatialTemporal = OMX_FALSE; @@ -981,14 +988,26 @@ OMX_ERRORTYPE SoftAVC::internalSetParameter(OMX_INDEXTYPE index, const OMX_PTR p                  return OMX_ErrorUndefined;              } -            if (avcType->eProfile != OMX_VIDEO_AVCProfileBaseline -                    || avcType->nRefFrames != 1 || avcType->nBFrames != 0 +            mEntropyMode = 0; + +            if (OMX_TRUE == avcType->bEntropyCodingCABAC) +                mEntropyMode = 1; + +            if ((avcType->nAllowedPictureTypes & OMX_VIDEO_PictureTypeB) && +                    avcType->nPFrames) { +                mBframes = avcType->nBFrames / avcType->nPFrames; +            } + +            mIInterval = avcType->nPFrames + avcType->nBFrames; + +            if (OMX_VIDEO_AVCLoopFilterDisable == avcType->eLoopFilterMode) +                mDisableDeblkLevel = 4; + +            if (avcType->nRefFrames != 1                      || avcType->bUseHadamard != OMX_TRUE -                    || (avcType->nAllowedPictureTypes & OMX_VIDEO_PictureTypeB) != 0                      || avcType->nRefIdx10ActiveMinus1 != 0                      || avcType->nRefIdx11ActiveMinus1 != 0                      || avcType->bWeightedPPrediction != OMX_FALSE -                    || avcType->bEntropyCodingCABAC != OMX_FALSE                      || avcType->bconstIpred != OMX_FALSE                      || avcType->bDirect8x8Inference != OMX_FALSE                      || avcType->bDirectSpatialTemporal != OMX_FALSE @@ -1083,14 +1102,27 @@ OMX_ERRORTYPE SoftAVC::setEncodeArgs(      /* Initialize color formats */      ps_inp_raw_buf->e_color_fmt = mIvVideoColorFormat; -      source = NULL; -    if (inputBufferHeader) { +    if ((inputBufferHeader != NULL) && inputBufferHeader->nFilledLen) {          source = inputBufferHeader->pBuffer + inputBufferHeader->nOffset;          if (mInputDataIsMeta) { +            uint8_t *conversionBuffer = NULL; +            for (size_t i = 0; i < MAX_CONVERSION_BUFFERS; i++) { +                if (mConversionBuffersFree[i]) { +                    mConversionBuffersFree[i] = 0; +                    conversionBuffer = mConversionBuffers[i]; +                    break; +                } +            } + +            if (NULL == conversionBuffer) { +                ALOGE("No free buffers to hold conversion data"); +                return OMX_ErrorUndefined; +            } +              source = extractGraphicBuffer( -                    mConversionBuffer, (mWidth * mHeight * 3 / 2), source, +                    conversionBuffer, (mWidth * mHeight * 3 / 2), source,                      inputBufferHeader->nFilledLen, mWidth, mHeight);              if (source == NULL) { @@ -1099,6 +1131,18 @@ OMX_ERRORTYPE SoftAVC::setEncodeArgs(                  return OMX_ErrorUndefined;              }          } +        ps_encode_ip->u4_is_last = 0; +        ps_encode_ip->u4_timestamp_high = (inputBufferHeader->nTimeStamp) >> 32; +        ps_encode_ip->u4_timestamp_low = (inputBufferHeader->nTimeStamp) & 0xFFFFFFFF; +    } +    else { +        if (mSawInputEOS){ +            ps_encode_ip->u4_is_last = 1; +        } +        memset(ps_inp_raw_buf, 0, sizeof(iv_raw_buf_t)); +        ps_inp_raw_buf->e_color_fmt = mIvVideoColorFormat; +        ps_inp_raw_buf->u4_size = sizeof(iv_raw_buf_t); +        return OMX_ErrorNone;      }      pu1_buf = (UWORD8 *)source; @@ -1153,14 +1197,6 @@ OMX_ERRORTYPE SoftAVC::setEncodeArgs(              break;          }      } - -    ps_encode_ip->u4_is_last = 0; - -    if (inputBufferHeader) { -        ps_encode_ip->u4_timestamp_high = (inputBufferHeader->nTimeStamp) >> 32; -        ps_encode_ip->u4_timestamp_low = (inputBufferHeader->nTimeStamp) & 0xFFFFFFFF; -    } -      return OMX_ErrorNone;  } @@ -1178,38 +1214,31 @@ void SoftAVC::onQueueFilled(OMX_U32 portIndex) {              return;          }      } -    if (mSignalledError || mSawInputEOS) { +    if (mSignalledError) {          return;      }      List<BufferInfo *> &inQueue = getPortQueue(0);      List<BufferInfo *> &outQueue = getPortQueue(1); -    while (!mSawInputEOS && !inQueue.empty() && !outQueue.empty()) { +    while (!mSawOutputEOS && !outQueue.empty()) { +          OMX_ERRORTYPE error;          ive_video_encode_ip_t s_encode_ip;          ive_video_encode_op_t s_encode_op; - -        BufferInfo *inputBufferInfo = *inQueue.begin(); -        OMX_BUFFERHEADERTYPE *inputBufferHeader = inputBufferInfo->mHeader; -          BufferInfo *outputBufferInfo = *outQueue.begin();          OMX_BUFFERHEADERTYPE *outputBufferHeader = outputBufferInfo->mHeader; -        if (inputBufferHeader->nFlags & OMX_BUFFERFLAG_EOS && -                inputBufferHeader->nFilledLen == 0) { -            mSawInputEOS = true; +        BufferInfo *inputBufferInfo; +        OMX_BUFFERHEADERTYPE *inputBufferHeader; -            inQueue.erase(inQueue.begin()); -            inputBufferInfo->mOwnedByUs = false; -            notifyEmptyBufferDone(inputBufferHeader); - -            outputBufferHeader->nFilledLen = 0; -            outputBufferHeader->nFlags = OMX_BUFFERFLAG_EOS; - -            outQueue.erase(outQueue.begin()); -            outputBufferInfo->mOwnedByUs = false; -            notifyFillBufferDone(outputBufferHeader); +        if (mSawInputEOS) { +            inputBufferHeader = NULL; +            inputBufferInfo = NULL; +        } else if (!inQueue.empty()) { +            inputBufferInfo = *inQueue.begin(); +            inputBufferHeader = inputBufferInfo->mHeader; +        } else {              return;          } @@ -1219,6 +1248,10 @@ void SoftAVC::onQueueFilled(OMX_U32 portIndex) {          outputBufferHeader->nFilledLen = 0;          outputBufferHeader->nOffset = 0; +        if (inputBufferHeader != NULL) { +            outputBufferHeader->nFlags = inputBufferHeader->nFlags; +        } +          uint8_t *outPtr = (uint8_t *)outputBufferHeader->pBuffer;          if (!mSpsPpsHeaderReceived) { @@ -1242,10 +1275,13 @@ void SoftAVC::onQueueFilled(OMX_U32 portIndex) {              outputBufferHeader->nFlags = OMX_BUFFERFLAG_CODECCONFIG;              outputBufferHeader->nFilledLen = s_encode_op.s_out_buf.u4_bytes; -            outputBufferHeader->nTimeStamp = inputBufferHeader->nTimeStamp; +            if (inputBufferHeader != NULL) { +                outputBufferHeader->nTimeStamp = inputBufferHeader->nTimeStamp; +            }              outQueue.erase(outQueue.begin());              outputBufferInfo->mOwnedByUs = false; +              DUMP_TO_FILE(                      mOutFile, outputBufferHeader->pBuffer,                      outputBufferHeader->nFilledLen); @@ -1263,14 +1299,24 @@ void SoftAVC::onQueueFilled(OMX_U32 portIndex) {              setFrameType(IV_IDR_FRAME);          } -        mPrevTimestampUs = inputBufferHeader->nTimeStamp; - -        if (inputBufferHeader->nFlags & OMX_BUFFERFLAG_EOS) { +        if ((inputBufferHeader != NULL) +                && (inputBufferHeader->nFlags & OMX_BUFFERFLAG_EOS)) {              mSawInputEOS = true;          } +        /* In normal mode, store inputBufferInfo and this will be returned +           when encoder consumes this input */ +        if (!mInputDataIsMeta && (inputBufferInfo != NULL)) { +            for (size_t i = 0; i < MAX_INPUT_BUFFER_HEADERS; i++) { +                if (NULL == mInputBufferInfo[i]) { +                    mInputBufferInfo[i] = inputBufferInfo; +                    break; +                } +            } +        }          error = setEncodeArgs(                  &s_encode_ip, &s_encode_op, inputBufferHeader, outputBufferHeader); +          if (error != OMX_ErrorNone) {              mSignalledError = true;              notify(OMX_EventError, OMX_ErrorUndefined, 0, 0); @@ -1280,14 +1326,11 @@ void SoftAVC::onQueueFilled(OMX_U32 portIndex) {          DUMP_TO_FILE(                  mInFile, s_encode_ip.s_inp_buf.apv_bufs[0],                  (mHeight * mStride * 3 / 2)); -        //DUMP_TO_FILE(mInFile, inputBufferHeader->pBuffer + inputBufferHeader->nOffset, -        //    inputBufferHeader->nFilledLen);          GETTIME(&mTimeStart, NULL);          /* Compute time elapsed between end of previous decode()           * to start of current decode() */          TIME_DIFF(mTimeEnd, mTimeStart, timeDelay); -          status = ive_api_function(mCodecCtx, &s_encode_ip, &s_encode_op);          if (IV_SUCCESS != status) { @@ -1305,38 +1348,77 @@ void SoftAVC::onQueueFilled(OMX_U32 portIndex) {          ALOGV("timeTaken=%6d delay=%6d numBytes=%6d", timeTaken, timeDelay,                  s_encode_op.s_out_buf.u4_bytes); +        /* In encoder frees up an input buffer, mark it as free */ +        if (s_encode_op.s_inp_buf.apv_bufs[0] != NULL) { +            if (mInputDataIsMeta) { +                for (size_t i = 0; i < MAX_CONVERSION_BUFFERS; i++) { +                    if (mConversionBuffers[i] == s_encode_op.s_inp_buf.apv_bufs[0]) { +                        mConversionBuffersFree[i] = 1; +                        break; +                    } +                } +            } else { +                /* In normal mode, call EBD on inBuffeHeader that is freed by the codec */ +                for (size_t i = 0; i < MAX_INPUT_BUFFER_HEADERS; i++) { +                    uint8_t *buf = NULL; +                    OMX_BUFFERHEADERTYPE *bufHdr = NULL; +                    if (mInputBufferInfo[i] != NULL) { +                        bufHdr = mInputBufferInfo[i]->mHeader; +                        buf = bufHdr->pBuffer + bufHdr->nOffset; +                    } +                    if (s_encode_op.s_inp_buf.apv_bufs[0] == buf) { +                        mInputBufferInfo[i]->mOwnedByUs = false; +                        notifyEmptyBufferDone(bufHdr); +                        mInputBufferInfo[i] = NULL; +                        break; +                    } +                } +            } +        } -        outputBufferHeader->nFlags = inputBufferHeader->nFlags;          outputBufferHeader->nFilledLen = s_encode_op.s_out_buf.u4_bytes; -        outputBufferHeader->nTimeStamp = inputBufferHeader->nTimeStamp; -        if (IV_IDR_FRAME -                == s_encode_op.u4_encoded_frame_type) { +        if (IV_IDR_FRAME == s_encode_op.u4_encoded_frame_type) {              outputBufferHeader->nFlags |= OMX_BUFFERFLAG_SYNCFRAME;          } -        inQueue.erase(inQueue.begin()); -        inputBufferInfo->mOwnedByUs = false; +        if (inputBufferHeader != NULL) { +            inQueue.erase(inQueue.begin()); -        notifyEmptyBufferDone(inputBufferHeader); +            /* If in meta data, call EBD on input */ +            /* In case of normal mode, EBD will be done once encoder +            releases the input buffer */ +            if (mInputDataIsMeta) { +                inputBufferInfo->mOwnedByUs = false; +                notifyEmptyBufferDone(inputBufferHeader); +            } +        } -        if (mSawInputEOS) { +        if (s_encode_op.u4_is_last) {              outputBufferHeader->nFlags |= OMX_BUFFERFLAG_EOS; +            mSawOutputEOS = true; +        } else { +            outputBufferHeader->nFlags &= ~OMX_BUFFERFLAG_EOS;          } -        outputBufferInfo->mOwnedByUs = false; -        outQueue.erase(outQueue.begin()); - -        DUMP_TO_FILE( -                mOutFile, outputBufferHeader->pBuffer, -                outputBufferHeader->nFilledLen); -        notifyFillBufferDone(outputBufferHeader); +        if (outputBufferHeader->nFilledLen || s_encode_op.u4_is_last) { +            outputBufferHeader->nTimeStamp = s_encode_op.u4_timestamp_high; +            outputBufferHeader->nTimeStamp <<= 32; +            outputBufferHeader->nTimeStamp |= s_encode_op.u4_timestamp_low; +            outputBufferInfo->mOwnedByUs = false; +            outQueue.erase(outQueue.begin()); +            DUMP_TO_FILE(mOutFile, outputBufferHeader->pBuffer, +                    outputBufferHeader->nFilledLen); +            notifyFillBufferDone(outputBufferHeader); +        } +        if (s_encode_op.u4_is_last == 1) { +            return; +        }      }      return;  } -  }  // namespace android  android::SoftOMXComponent *createSoftOMXComponent( diff --git a/media/libstagefright/codecs/avcenc/SoftAVCEnc.h b/media/libstagefright/codecs/avcenc/SoftAVCEnc.h index 2b35d45..4418a7f 100644 --- a/media/libstagefright/codecs/avcenc/SoftAVCEnc.h +++ b/media/libstagefright/codecs/avcenc/SoftAVCEnc.h @@ -17,7 +17,7 @@  #ifndef __SOFT_AVC_ENC_H__  #define __SOFT_AVC_ENC_H__ -#include <media/stagefright/MediaBuffer.h> +  #include <media/stagefright/foundation/ABase.h>  #include <utils/Vector.h> @@ -25,14 +25,14 @@  namespace android { -class MediaBuffer; - +#define MAX_INPUT_BUFFER_HEADERS 4 +#define MAX_CONVERSION_BUFFERS   4  #define CODEC_MAX_CORES          4  #define LEN_STATUS_BUFFER        (10  * 1024)  #define MAX_VBV_BUFF_SIZE        (120 * 16384)  #define MAX_NUM_IO_BUFS           3 -#define DEFAULT_MAX_REF_FRM         1 +#define DEFAULT_MAX_REF_FRM         2  #define DEFAULT_MAX_REORDER_FRM     0  #define DEFAULT_QP_MIN              10  #define DEFAULT_QP_MAX              40 @@ -57,7 +57,7 @@ class MediaBuffer;  #define DEFAULT_TGT_FRAME_RATE      30  #define DEFAULT_MAX_WD              1920  #define DEFAULT_MAX_HT              1920 -#define DEFAULT_MAX_LEVEL           40 +#define DEFAULT_MAX_LEVEL           41  #define DEFAULT_STRIDE              0  #define DEFAULT_WD                  1280  #define DEFAULT_HT                  720 @@ -88,6 +88,7 @@ class MediaBuffer;  #define DEFAULT_QPEL                1  #define DEFAULT_I4                  1  #define DEFAULT_EPROFILE            IV_PROFILE_BASE +#define DEFAULT_ENTROPY_MODE        0  #define DEFAULT_SLICE_MODE          IVE_SLICE_MODE_NONE  #define DEFAULT_SLICE_PARAM         256  #define DEFAULT_ARCH                ARCH_ARM_A9Q @@ -149,8 +150,6 @@ private:      int32_t  mStride; -    uint32_t mFrameRate; -      struct timeval mTimeStart;   // Time at the start of decode()      struct timeval mTimeEnd;     // Time at the end of decode() @@ -167,32 +166,32 @@ private:      IV_COLOR_FORMAT_T mIvVideoColorFormat; -    int32_t  mIDRFrameRefreshIntervalInSec;      IV_PROFILE_T mAVCEncProfile;      WORD32   mAVCEncLevel; -    int64_t  mNumInputFrames; -    int64_t  mPrevTimestampUs;      bool     mStarted;      bool     mSpsPpsHeaderReceived;      bool     mSawInputEOS; +    bool     mSawOutputEOS;      bool     mSignalledError;      bool     mIntra4x4;      bool     mEnableFastSad;      bool     mEnableAltRef; -    bool    mReconEnable; -    bool    mPSNREnable; +    bool     mReconEnable; +    bool     mPSNREnable; +    bool     mEntropyMode;      IVE_SPEED_CONFIG     mEncSpeed; -    uint8_t *mConversionBuffer; - +    uint8_t *mConversionBuffers[MAX_CONVERSION_BUFFERS]; +    bool     mConversionBuffersFree[MAX_CONVERSION_BUFFERS]; +    BufferInfo *mInputBufferInfo[MAX_INPUT_BUFFER_HEADERS];      iv_obj_t *mCodecCtx;         // Codec context      iv_mem_rec_t *mMemRecords;   // Memory records requested by the codec      size_t mNumMemRecords;       // Number of memory records requested by codec      size_t mNumCores;            // Number of cores used by the codec      UWORD32 mHeaderGenerated; - +    UWORD32 mBframes;      IV_ARCH_T mArch;      IVE_SLICE_MODE_T mSliceMode;      UWORD32 mSliceParam; @@ -203,7 +202,7 @@ private:      IVE_AIR_MODE_T mAIRMode;      UWORD32 mAIRRefreshPeriod; -    OMX_ERRORTYPE initEncParams(); +    void initEncParams();      OMX_ERRORTYPE initEncoder();      OMX_ERRORTYPE releaseEncoder(); @@ -292,6 +291,8 @@ private:          fclose(fp);                                     \      } else {                                            \          ALOGD("Could not write to file %s", m_filename);\ +        if (fp != NULL)                                 \ +            fclose(fp);                                 \      }                                                   \  }  #else /* FILE_DUMP_ENABLE */  | 
