summaryrefslogtreecommitdiffstats
path: root/media/libstagefright/codecs/avcenc
diff options
context:
space:
mode:
authorDoney Alex <doney.alex@ittiam.com>2015-06-01 18:14:02 +0530
committerMarco Nelissen <marcone@google.com>2015-06-25 10:36:40 -0700
commit1ad56353aec03b0255d5cd5b67f9e6df780d9b65 (patch)
treedb30f8486a228e63d364ddb72074166a8a00931b /media/libstagefright/codecs/avcenc
parentdefb2374a0e0adbd3714a2cd02be3c309cde4875 (diff)
downloadframeworks_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/libstagefright/codecs/avcenc')
-rw-r--r--media/libstagefright/codecs/avcenc/SoftAVCEnc.cpp290
-rw-r--r--media/libstagefright/codecs/avcenc/SoftAVCEnc.h33
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 */