//This will be used to dynamically request the Iframe using SetConfig API
OMX_CONFIG_INTRAREFRESHVOPTYPE VideoIFrame;
+ OMX_VIDEO_CONFIG_AVCINTRAPERIOD AvcIntraPeriod;
OMX_U32 ActualNumPortFormatsSupported;
#endif //#ifndef PV_OMXCOMPONENT_H_INCLUDED
+
OMX_CONFIG_INTRAREFRESHVOPTYPE* pVideoIFrame;
OMX_CONFIG_FRAMERATETYPE* pFrameRateType;
OMX_VIDEO_CONFIG_BITRATETYPE* pConfigBitRateType;
+ OMX_VIDEO_CONFIG_AVCINTRAPERIOD* pAvcIntraPeriod;
if (NULL == pComponentConfigStructure)
{
SetHeader(pConfigBitRateType, sizeof(OMX_VIDEO_CONFIG_BITRATETYPE));
}
break;
+
+ case OMX_IndexConfigVideoAVCIntraPeriod:
+ {
+ pAvcIntraPeriod = (OMX_VIDEO_CONFIG_AVCINTRAPERIOD*) pComponentConfigStructure;
+ if (pAvcIntraPeriod->nPortIndex != iCompressedFormatPortNum)
+ {
+ PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OmxComponentBase : GetConfig error bad port index for OMX_IndexConfigVideoAVCIntraPeriod"));
+ return OMX_ErrorBadPortIndex;
+ }
+ PortIndex = pAvcIntraPeriod->nPortIndex;
+ oscl_memcpy(pAvcIntraPeriod, &ipPorts[PortIndex]->AvcIntraPeriod, sizeof(OMX_VIDEO_CONFIG_AVCINTRAPERIOD));
+ SetHeader(pAvcIntraPeriod, sizeof(OMX_VIDEO_CONFIG_AVCINTRAPERIOD));
+ }
+ break;
+
default:
{
PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OmxComponentBase : GetParameter error Unsupported Index"));
OMX_BOOL AvcUpdateFrameRate(OMX_U32 aEncodeFramerate);
OMX_BOOL GetSpsPpsHeaderFlag();
OMX_ERRORTYPE AVCOutBufferSize(OMX_U32 *aMaxVideoFrameSize);
+ OMX_BOOL AvcUpdateIDRFrameInterval(OMX_U32 aIDRInterval);
/* for avc encoder lib callback functions */
int AVC_DPBAlloc(uint frame_size_in_mbs, uint num_buffers);
}
+//Routine to update IDR frame interval dynamically when encoding is in progress
+OMX_BOOL AvcEncoder_OMX::AvcUpdateIDRFrameInterval(OMX_U32 aIDRInterval)
+{
+ /* Note -- Here, aIDRInterval defines encoding of IDR frame after every nPFrames.
+ ** aIDRInterval is different from aIDRPeriod.
+ */
+ if (AVCENC_SUCCESS != PVAVCEncUpdateIDRInterval(&iAvcHandle, (int)aIDRInterval))
+ {
+ return OMX_FALSE;
+ }
+ return OMX_TRUE;
+
+}
/* ///////////////////////////////////////////////////////////////////////// */
void AvcEncoder_OMX::AVC_FrameUnbind(int indx)
OMX_CONFIG_INTRAREFRESHVOPTYPE* pAvcIFrame;
OMX_VIDEO_CONFIG_BITRATETYPE* pBitRateType;
OMX_CONFIG_FRAMERATETYPE* pFrameRateType;
-
-
+ OMX_VIDEO_CONFIG_AVCINTRAPERIOD* pAvcIntraPeriod;
if (NULL == pComponentConfigStructure)
{
}
break;
+ case OMX_IndexConfigVideoAVCIntraPeriod:
+ {
+ pAvcIntraPeriod = (OMX_VIDEO_CONFIG_AVCINTRAPERIOD*) pComponentConfigStructure;
+ PortIndex = pAvcIntraPeriod->nPortIndex;
+
+ if (PortIndex != iCompressedFormatPortNum)
+ {
+ PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OmxComponentAvcEncAO : SetConfig error invalid port index"));
+ return OMX_ErrorBadPortIndex;
+ }
+
+ /*Check Structure Header*/
+ ErrorType = CheckHeader(pAvcIntraPeriod, sizeof(OMX_VIDEO_CONFIG_AVCINTRAPERIOD));
+ if (ErrorType != OMX_ErrorNone)
+ {
+ PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OmxComponentAvcEncAO : SetConfig error param check failed"));
+ return ErrorType;
+ }
+
+ //Call the corresponding routine of the encoder in case of setconfig call
+ if (OMX_FALSE == (ipAvcEncoderObject->AvcUpdateIDRFrameInterval(pAvcIntraPeriod->nPFrames + 1)))
+ {
+ return OMX_ErrorBadParameter;
+ }
+
+ ipPorts[PortIndex]->AvcIntraPeriod.nPFrames = pAvcIntraPeriod->nPFrames;
+ }
+ break;
+
default:
{
PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OmxComponentAvcEncAO : SetConfig error Unsupported Index"));
OMX_ERRORTYPE Mp4RequestIFrame();
OMX_BOOL Mp4UpdateBitRate(OMX_U32 aEncodedBitRate);
OMX_BOOL Mp4UpdateFrameRate(OMX_U32 aEncodeFramerate);
+ OMX_BOOL Mp4UpdateIFrameInterval(OMX_U32 aIntraPeriod);
OMX_ERRORTYPE Mp4EncDeinit();
}
-
+/* Request I frame routine */
OMX_ERRORTYPE Mpeg4Encoder_OMX::Mp4RequestIFrame()
{
if (PV_TRUE != PVIFrameRequest(&iEncoderControl))
return OMX_ErrorNone;
}
-
+/* Request Update BitRate routine */
OMX_BOOL Mpeg4Encoder_OMX::Mp4UpdateBitRate(OMX_U32 aEncodedBitRate)
{
Int BitRate[2] = {0, 0};
- OMX_BOOL Status = OMX_TRUE;
+ OMX_BOOL Status = OMX_FALSE;
//Update the bit rate only if encoder has been initialized
if (OMX_TRUE == iInitialized)
return Status;
}
-
+/* Request Update FrameRate routine */
OMX_BOOL Mpeg4Encoder_OMX::Mp4UpdateFrameRate(OMX_U32 aEncodeFramerate)
{
float EncFrameRate[2] = {0., 0.};
- OMX_BOOL Status = OMX_TRUE;
+ OMX_BOOL Status = OMX_FALSE;
//Update the frame rate only if encoder has been initialized
if (OMX_TRUE == iInitialized)
{
- EncFrameRate[0] = (float)(aEncodeFramerate >> 16);
+ EncFrameRate[0] = ((float)aEncodeFramerate / (1 << 16));
Status = (OMX_BOOL) PVUpdateEncFrameRate(&iEncoderControl, EncFrameRate);
}
return Status;
}
+/* Request Update I-FrameInterval routine */
+OMX_BOOL Mpeg4Encoder_OMX::Mp4UpdateIFrameInterval(OMX_U32 aIntraPeriod)
+{
+ OMX_BOOL Status = OMX_FALSE;
+ if (OMX_TRUE == iInitialized)
+ {
+ Status = (OMX_BOOL) PVUpdateIFrameInterval(&iEncoderControl, (Int)aIntraPeriod);
+ }
+ return Status;
+
+}
+
// This function gives the maximum output buffer requirement and
// can only be called after encoder's initialization
OMX_ERRORTYPE Mpeg4Encoder_OMX::Mp4OutBufferSize(OMX_U32 *aMaxVideoFrameSize)
OMX_CONFIG_INTRAREFRESHVOPTYPE* pVideoIFrame;
OMX_VIDEO_CONFIG_BITRATETYPE* pBitRateType;
OMX_CONFIG_FRAMERATETYPE* pFrameRateType;
-
+ OMX_VIDEO_CONFIG_AVCINTRAPERIOD* pM4vIntraPeriod;
if (NULL == pComponentConfigStructure)
}
break;
+ /* Using OMX_IndexConfigVideoAVCIntraPeriod for M4V until standard defines some struct for it*/
+ case OMX_IndexConfigVideoAVCIntraPeriod:
+ {
+ pM4vIntraPeriod = (OMX_VIDEO_CONFIG_AVCINTRAPERIOD*) pComponentConfigStructure;
+ PortIndex = pM4vIntraPeriod->nPortIndex;
+
+ if (PortIndex != iCompressedFormatPortNum)
+ {
+ PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OmxComponentAvcEncAO : SetConfig error invalid port index"));
+ return OMX_ErrorBadPortIndex;
+ }
+
+ /*Check Structure Header*/
+ ErrorType = CheckHeader(pM4vIntraPeriod, sizeof(OMX_VIDEO_CONFIG_AVCINTRAPERIOD));
+ if (ErrorType != OMX_ErrorNone)
+ {
+ PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OmxComponentAvcEncAO : SetConfig error param check failed"));
+ return ErrorType;
+ }
+
+ //Call the corresponding routine of the encoder in case of setconfig call
+ if (OMX_FALSE == (ipMpegEncoderObject->Mp4UpdateIFrameInterval(pM4vIntraPeriod->nPFrames + 1)))
+ {
+ return OMX_ErrorBadParameter;
+ }
+
+ ipPorts[PortIndex]->AvcIntraPeriod.nPFrames = pM4vIntraPeriod->nPFrames;
+ }
+ break;
+
default:
{
PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OmxComponentMpeg4EncAO : SetConfig error Unsupported Index"));
/* ------------------------------------------------------------------
- * Copyright (C) 1998-2009 PacketVideo
+ * Copyright (C) 1998-2010 PacketVideo
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
OSCL_IMPORT_REF virtual TAVCEI_RETVAL UpdateBitRate(int32* aBitRate);
OSCL_IMPORT_REF virtual TAVCEI_RETVAL UpdateFrameRate(OsclFloat* aFrameRate);
- OSCL_IMPORT_REF virtual TAVCEI_RETVAL UpdateIDRFrameInterval(int32 aIFrameInterval);
+ OSCL_IMPORT_REF virtual TAVCEI_RETVAL UpdateIDRFrameInterval(int32 aIDRFrameInterval);
OSCL_IMPORT_REF virtual TAVCEI_RETVAL IDRRequest();
OSCL_IMPORT_REF virtual int32 GetEncodeWidth(int32 aLayer);
/* ------------------------------------------------------------------
- * Copyright (C) 1998-2009 PacketVideo
+ * Copyright (C) 1998-2010 PacketVideo
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
encoding to a new value.
\parm aIFrameInterval is a new value of the IDR-frame interval in millisecond.
\return SUCCESS or FAIL (if the value is invalid). */
- virtual TAVCEI_RETVAL UpdateIDRFrameInterval(int32 aIFrameInterval) = 0;
+ virtual TAVCEI_RETVAL UpdateIDRFrameInterval(int32 aIDRFrameInterval) = 0;
/** This function forces an IDR mode to the next frame to be encoded.
\return none. */
/* assume that user will make a copy if they want to hold on */
/* to it. Otherwise, it is not guaranteed to be reserved. */
/* Most applications prefer to see original frame rather than */
-/* reconstructed frame. So, we are staying aware from complex */
+/* reconstructed frame. So, we stay away from complex */
/* buffering mechanism. If needed, can be added later. */
/* In/out : */
/* Return : AVCENC_SUCCESS for success. */
return ;
}
+/* ======================================================================== */
+/* Function : PVAVCEncUpdateBitRate() */
+/* Date : 2/20/2010 */
+/* Purpose : Update bitrate while encoding. */
+/* In/out : */
+/* Return : AVCENC_SUCCESS for success, else fail. */
+/* Modified : */
+/* ======================================================================== */
+
OSCL_EXPORT_REF AVCEnc_Status PVAVCEncUpdateBitRate(AVCHandle *avcHandle, uint32 bitrate)
{
- OSCL_UNUSED_ARG(avcHandle);
- OSCL_UNUSED_ARG(bitrate);
+ AVCEncObject *encvid = (AVCEncObject*)avcHandle->AVCObject;
+ AVCCommonObj *video = encvid->common;
+ AVCRateControl *rateCtrl = encvid->rateCtrl;
+ AVCSeqParamSet *seqParam = video->currSeqParams;
- return AVCENC_FAIL;
+ int lev_idx;
+
+ if (encvid == NULL)
+ {
+ return AVCENC_UNINITIALIZED;
+ }
+
+ // only allow changing bit rate right after encoding a frame and before a new frame is analyzed.
+ if (encvid->enc_state != AVCEnc_Analyzing_Frame)
+ {
+ return AVCENC_WRONG_STATE;
+ }
+
+ if (bitrate && rateCtrl->cpbSize && (rateCtrl->rcEnable == TRUE))
+ {
+ // verify level constraint
+ // Note we keep the same cbpsize, hence the vbv delay will be affected.
+ lev_idx = mapLev2Idx[seqParam->level_idc];
+
+ if (bitrate > (uint32)(MaxBR[lev_idx]*1000))
+ {
+ return AVCENC_FAIL;
+ }
+
+ rateCtrl->bitRate = bitrate;
+
+ // update other rate control parameters
+ RCUpdateParams(rateCtrl, encvid);
+
+ return AVCENC_SUCCESS;
+ }
+ else
+ {
+ return AVCENC_FAIL;
+ }
}
+/* ======================================================================== */
+/* Function : PVAVCEncUpdateFrameRate() */
+/* Date : 2/20/2010 */
+/* Purpose : Update frame rate while encoding. */
+/* In/out : */
+/* Return : AVCENC_SUCCESS for success, else fail. */
+/* Limitation: Changing frame rate will affect the first IDR frame coming */
+/* after this call. It may come earlier or later than expected */
+/* but after this first IDR frame, the IDR period will be back */
+/* to normal. */
+/* Modified : */
+/* ======================================================================== */
+
OSCL_EXPORT_REF AVCEnc_Status PVAVCEncUpdateFrameRate(AVCHandle *avcHandle, uint32 num, uint32 denom)
{
- OSCL_UNUSED_ARG(avcHandle);
- OSCL_UNUSED_ARG(num);
- OSCL_UNUSED_ARG(denom);
+ AVCEncObject *encvid = (AVCEncObject*)avcHandle->AVCObject;
+ AVCCommonObj *video = encvid->common;
+ AVCRateControl *rateCtrl = encvid->rateCtrl;
+ AVCSeqParamSet *seqParam = video->currSeqParams;
+
+ int mb_per_sec;
+ int lev_idx;
+
+ if (encvid == NULL)
+ {
+ return AVCENC_UNINITIALIZED;
+ }
+
+ // only allow changing frame rate right after encoding a frame and before a new frame is analyzed.
+ if (encvid->enc_state != AVCEnc_Analyzing_Frame)
+ {
+ return AVCENC_WRONG_STATE;
+ }
+
+ if (num && denom && (rateCtrl->rcEnable == TRUE))
+ {
+ mb_per_sec = ((video->PicSizeInMbs * num) + denom - 1) / denom;
+
+ // copy some code from VerifyLevel here
+ lev_idx = mapLev2Idx[seqParam->level_idc];
+
+ if (mb_per_sec > MaxMBPS[lev_idx])
+ {
+ return AVCENC_FAIL;
+ }
+
+ rateCtrl->frame_rate = (OsclFloat)num / denom;
+
+ // update other rate control parameters
+ RCUpdateParams(rateCtrl, encvid);
+
+ return AVCENC_SUCCESS;
+ }
+ else
+ {
+ return AVCENC_FAIL;
+ }
return AVCENC_FAIL;
}
+
+/* ======================================================================== */
+/* Function : PVAVCEncUpdateIDRInterval() */
+/* Date : 2/20/2010 */
+/* Purpose : Update IDR interval while encoding. */
+/* In/out : */
+/* Return : AVCENC_SUCCESS for success, else fail. */
+/* Limitation: See PVAVCEncUpdateFrameRate. */
+/* Modified : */
+/* ======================================================================== */
OSCL_EXPORT_REF AVCEnc_Status PVAVCEncUpdateIDRInterval(AVCHandle *avcHandle, int IDRInterval)
{
- OSCL_UNUSED_ARG(avcHandle);
- OSCL_UNUSED_ARG(IDRInterval);
+ AVCEncObject *encvid = (AVCEncObject*)avcHandle->AVCObject;
+ AVCCommonObj *video = encvid->common;
+ AVCRateControl *rateCtrl = encvid->rateCtrl;
- return AVCENC_FAIL;
+ if (encvid == NULL)
+ {
+ return AVCENC_UNINITIALIZED;
+ }
+
+ if (IDRInterval > (int)video->MaxFrameNum)
+ {
+ return AVCENC_FAIL;
+ }
+
+ /* Note : IDRInterval defines periodicity of IDR frames after every nPFrames.*/
+ rateCtrl->idrPeriod = IDRInterval;
+
+ /* Note, when set to 1 (all I-frame), rate control is turned off */
+
+ return AVCENC_SUCCESS;
}
+/* ======================================================================== */
+/* Function : PVAVCEncIDRRequest() */
+/* Date : 2/20/2010 */
+/* Purpose : Request next frame to be IDR. */
+/* In/out : */
+/* Return : AVCENC_SUCCESS for success, else fail. */
+/* Modified : */
+/* ======================================================================== */
OSCL_EXPORT_REF AVCEnc_Status PVAVCEncIDRRequest(AVCHandle *avcHandle)
{
- OSCL_UNUSED_ARG(avcHandle);
+ AVCEncObject *encvid = (AVCEncObject*)avcHandle->AVCObject;
+ AVCRateControl *rateCtrl = encvid->rateCtrl;
- return AVCENC_FAIL;
+ if (encvid == NULL)
+ {
+ return AVCENC_UNINITIALIZED;
+ }
+
+ // only allow changing frame rate right after encoding a frame and before a new frame is analyzed.
+ if (encvid->enc_state != AVCEnc_Analyzing_Frame)
+ {
+ return AVCENC_WRONG_STATE;
+ }
+
+ rateCtrl->first_frame = 1;
+
+ return AVCENC_SUCCESS;
}
+
+/* ======================================================================== */
+/* Function : PVAVCEncUpdateIMBRefresh() */
+/* Date : 2/20/2010 */
+/* Purpose : Update number of minimal I MBs per frame. */
+/* In/out : */
+/* Return : AVCENC_SUCCESS for success, else fail. */
+/* Modified : */
+/* ======================================================================== */
OSCL_EXPORT_REF AVCEnc_Status PVAVCEncUpdateIMBRefresh(AVCHandle *avcHandle, int numMB)
{
- OSCL_UNUSED_ARG(avcHandle);
- OSCL_UNUSED_ARG(numMB);
+ AVCEncObject *encvid = (AVCEncObject*)avcHandle->AVCObject;
+ AVCRateControl *rateCtrl = encvid->rateCtrl;
+ AVCCommonObj *video = encvid->common;
+
+ if (encvid == NULL)
+ {
+ return AVCENC_UNINITIALIZED;
+ }
+
+ if (numMB <= (int)video->PicSizeInMbs)
+ {
+ rateCtrl->intraMBRate = numMB;
+ return AVCENC_SUCCESS;
+ }
return AVCENC_FAIL;
}
/* ------------------------------------------------------------------
- * Copyright (C) 1998-2009 PacketVideo
+ * Copyright (C) 1998-2010 PacketVideo
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
*/
int AVCFindMin(int dn[]);
-
/*------------- findhalfpel.c -------------------*/
/**
*/
AVCEnc_Status RCUpdateFrame(AVCEncObject *encvid);
+ /**
+ This function is called to update the RC internal variables when bit rate/frame rate is changed.
+ \param "rateCtrl" "Pointer to the rate control structure."
+ \param "encvid" "Pointer to AVCEncObject."
+ \return "void"
+ */
+ void RCUpdateParams(AVCRateControl *rateCtrl, AVCEncObject *encvid);
+
+
/*--------- residual.c -------------------*/
/**
/* ------------------------------------------------------------------
- * Copyright (C) 1998-2009 PacketVideo
+ * Copyright (C) 1998-2010 PacketVideo
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
if (!extS && !extP)
{
- maxFrameNum = (encParam->idr_period == -1) ? (1 << 16) : encParam->idr_period;
+ maxFrameNum = (encParam->idr_period == 0) ? (1 << 16) : encParam->idr_period;
ii = 0;
while (maxFrameNum > 0)
{
/* now the rate control and performance related parameters */
rateCtrl->scdEnable = (encParam->auto_scd == AVC_ON) ? TRUE : FALSE;
- rateCtrl->idrPeriod = encParam->idr_period + 1;
+ rateCtrl->idrPeriod = encParam->idr_period;// + 1;
rateCtrl->intraMBRate = encParam->intramb_refresh;
rateCtrl->dpEnable = (encParam->data_par == AVC_ON) ? TRUE : FALSE;
/* ------------------------------------------------------------------
- * Copyright (C) 1998-2009 PacketVideo
+ * Copyright (C) 1998-2010 PacketVideo
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
offset = 0;
- if (slice_type == AVC_I_SLICE)
+ if (slice_type == AVC_I_SLICE) // need to calculate rateCtrl->totalSAD for RC to take action!!
{
/* cannot do I16 prediction here because it needs full decoding. */
- for (i = 0; i < totalMB; i++)
- {
- encvid->min_cost[i] = 0x7FFFFFFF; /* max value for int */
+ { /* no RC for I-slice */
+
+ i = totalMB - 1;
+ while (i >= 0)
+ {
+ encvid->min_cost[i--] = 0x7FFFFFFF; /* max value for int */
+ }
}
+ /* reset intra MB pattern */
oscl_memset(intraSearch, 1, sizeof(uint8)*totalMB);
encvid->firstIntraRefreshMBIndx = 0; /* reset this */
+
+
/* ------------------------------------------------------------------
- * Copyright (C) 1998-2009 PacketVideo
+ * Copyright (C) 1998-2010 PacketVideo
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
switch (aEncParam->iIFrameInterval)
{
case -1:
- aEncOption.idr_period = -1;
+ aEncOption.idr_period = 0; /* all P-frames */
break;
case 0:
- aEncOption.idr_period = 0;
+ aEncOption.idr_period = 1; /* all IDR-frames */
break;
default:
aEncOption.idr_period = (int)(aEncParam->iIFrameInterval * aVidInFormat->iFrameRate);
}
/* ///////////////////////////////////////////////////////////////////////// */
-OSCL_EXPORT_REF TAVCEI_RETVAL PVAVCEncoder::UpdateIDRFrameInterval(int32 aIFrameInterval)
+OSCL_EXPORT_REF TAVCEI_RETVAL PVAVCEncoder::UpdateIDRFrameInterval(int32 aIDRFrameInterval)
{
- if (PVAVCEncUpdateIDRInterval(&iAvcHandle, aIFrameInterval) == AVCENC_SUCCESS)
+ if (PVAVCEncUpdateIDRInterval(&iAvcHandle, aIDRFrameInterval) == AVCENC_SUCCESS)
return EAVCEI_SUCCESS;
else
return EAVCEI_FAIL;
/* ------------------------------------------------------------------
- * Copyright (C) 1998-2009 PacketVideo
+ * Copyright (C) 1998-2010 PacketVideo
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
}
modTime += encvid->wrapModTime; /* wrapModTime is non zero after wrap-around */
+ /* Calculate frame number based on frame rate starting from modTimeRef */
+ /* Note, this value is totally independent from sliceHdr->frame_num or video->CurrPicNum */
currFrameNum = (int32)(((modTime - modTimeRef) * rateCtrl->frame_rate + 200) / 1000); /* add small roundings */
if (currFrameNum <= (int32)encvid->prevProcFrameNum)
frameInc = currFrameNum - encvid->prevProcFrameNum;
+ /* Check how many frames have been skipped since the last processed frame */
if (frameInc < rateCtrl->skip_next_frame + 1)
{
return AVCENC_FAIL; /* frame skip required to maintain the target bit rate. */
RCUpdateBuffer(video, rateCtrl, frameInc - rateCtrl->skip_next_frame); /* in case more frames dropped */
- *frameNum = currFrameNum;
-
/* This part would be similar to DetermineVopType of m4venc */
- if ((*frameNum >= (uint)rateCtrl->idrPeriod && rateCtrl->idrPeriod > 0) || (*frameNum > video->MaxFrameNum)) /* first frame or IDR*/
+
+ if ((currFrameNum >= (int32)rateCtrl->idrPeriod && rateCtrl->idrPeriod > 0) /* exceed IDR period */
+ || (currFrameNum >= (int32)video->MaxFrameNum)) /* this line for all P-frames (idrPeriod=0) */
{
- /* set frame type to IDR-frame */
- if (rateCtrl->idrPeriod)
- {
- encvid->modTimeRef += (uint32)(rateCtrl->idrPeriod * 1000 / rateCtrl->frame_rate);
- *frameNum -= rateCtrl->idrPeriod;
- }
- else
- {
- encvid->modTimeRef += (uint32)(video->MaxFrameNum * 1000 / rateCtrl->frame_rate);
- *frameNum -= video->MaxFrameNum;
- }
+ /* Re-assign modTimeRef to the new IDR frame */
+ encvid->modTimeRef += (uint32)(currFrameNum * 1000 / rateCtrl->frame_rate);
+ /* Set frame type to IDR-frame */
video->nal_unit_type = AVC_NALTYPE_IDR;
sliceHdr->slice_type = AVC_I_ALL_SLICE;
video->slice_type = AVC_I_SLICE;
- encvid->prevProcFrameNum = *frameNum;
+
+ encvid->prevProcFrameNum = *frameNum = 0; // Reset frameNum to zero.
}
else
{
sliceHdr->slice_type = AVC_P_ALL_SLICE;
video->slice_type = AVC_P_SLICE;
encvid->prevProcFrameNum = currFrameNum;
+ *frameNum = currFrameNum;
}
}
}
+void RCUpdateParams(AVCRateControl *rateCtrl, AVCEncObject *encvid)
+{
+ int32 prevFrameNum, newFrameNum;
+ uint32 prevModTime;
+
+ if (rateCtrl->frame_rate != rateCtrl->pMP->framerate)
+ {
+ /* this part for frame rate change */
+
+ rateCtrl->pMP->frameRange = (int)(rateCtrl->frame_rate * 1.0); /* 1.0s time frame*/
+ rateCtrl->pMP->frameRange = AVC_MAX(rateCtrl->pMP->frameRange, 5);
+ rateCtrl->pMP->frameRange = AVC_MIN(rateCtrl->pMP->frameRange, 30);
+
+ prevFrameNum = encvid->prevProcFrameNum; // previous frame number
+
+ // convert from frame num to time based on the previous frame rate
+ prevModTime = (uint32)(prevFrameNum * 1000 / rateCtrl->pMP->framerate); // offseted by modTimeRef
+
+ // convert back from time to frame num based on new frame rate
+ newFrameNum = (int32)((prevModTime * rateCtrl->frame_rate) / 1000);
+
+ // assign the newFrameNum to prevFrameNum
+ // note, this will cause the IDR frame to come earlier and later than expected !!
+ encvid->prevProcFrameNum = newFrameNum;
+ }
+
+ // recalculate fixed values that are dependent on bitrate and framerate
+
+ rateCtrl->bitsPerFrame = (int32)(rateCtrl->bitRate / rateCtrl->frame_rate);
+
+ rateCtrl->max_BitVariance_num = (int)((OsclFloat)(rateCtrl->Bs - rateCtrl->VBV_fullness) / (rateCtrl->bitsPerFrame / 10.0)) - 5;
+ if (rateCtrl->max_BitVariance_num < 0) rateCtrl->max_BitVariance_num += 5;
+
+ /* no change to rateCtrl->cpbSize, rateCtrl->Bs, rateCtrl->low_bound, rateCtrl->VBV_fullness_offset*/
+
+ /* keep continuity to the following values */
+ /* rateCtrl->pMP->framePos, rateCtrl->TMN_TH, rateCtrl->TMN_W */
+ /* rateCtrl->VBV_fullness, rateCtrl->pMP->counter_BTsrc, */
+
+ /* reset some stats for CalculateQuantizerMultiPass and active bit resource protection */
+ rateCtrl->pMP->sum_QP /= rateCtrl->pMP->encoded_frames; // reset it to 1
+ rateCtrl->pMP->encoded_frames = 1;
+ rateCtrl->pMP->sum_mad = 0;
+ rateCtrl->T = 0;
+
+ /* Finalizing bitrate and framerate to pMP structure*/
+ rateCtrl->pMP->bitrate = rateCtrl->bitRate;
+ rateCtrl->pMP->framerate = rateCtrl->frame_rate;
+ rateCtrl->pMP->target_bits_per_frame = rateCtrl->pMP->bitrate / rateCtrl->pMP->framerate;
+
+ return ;
+}
+
encData->encParams->LayerFrameRate[i] = frameRate[i];
}
- return RC_UpdateBXRCParams((void*) encData);
-
+ RC_UpdateBXRCParams((void*) encData);
+ return PV_TRUE;
}
#endif
#ifndef LIMITED_API
encData->encParams->LayerBitRate[i] = bitRate[i];
}
- return RC_UpdateBXRCParams((void*) encData);
+ RC_UpdateBXRCParams((void*) encData);
+ return PV_TRUE;
}
#endif
/* ------------------------------------------------------------------
- * Copyright (C) 1998-2009 PacketVideo
+ * Copyright (C) 1998-2010 PacketVideo
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
OSCL_EXPORT_REF TCVEI_RETVAL CPVM4VEncoder::UpdateIFrameInterval(int32 aIFrameInterval)
{
#ifndef LIMITED_API
- if (PVUpdateIFrameInterval(&iEncoderControl, aIFrameInterval) == PV_TRUE)
+ if (PVUpdateIFrameInterval(&iEncoderControl, (Int)aIFrameInterval) == PV_TRUE)
return ECVEI_SUCCESS;
else
#endif
// This header file is automatically generated at build-time
// *** OFFICIAL RELEASE INFO -- Will not auto update
-#define PV2WAY_ENGINE_SDKINFO_LABEL "1331680"
+#define PV2WAY_ENGINE_SDKINFO_LABEL "1331852"
#define PV2WAY_ENGINE_SDKINFO_DATE 0x20100318
#endif //PV_2WAY_SDKINFO_H_INCLUDED
// This header file is automatically generated at build-time
// *** OFFICIAL RELEASE INFO -- Will not auto update
-#define PVAUTHOR_ENGINE_SDKINFO_LABEL "1331680"
+#define PVAUTHOR_ENGINE_SDKINFO_LABEL "1331852"
#define PVAUTHOR_ENGINE_SDKINFO_DATE 0x20100318
#endif //PV_AUTHOR_SDKINFO_H_INCLUDED
// This header file is automatically generated at build-time
// *** OFFICIAL RELEASE INFO -- Will not auto update
-#define PVPLAYER_ENGINE_SDKINFO_LABEL "1331680"
+#define PVPLAYER_ENGINE_SDKINFO_LABEL "1331852"
#define PVPLAYER_ENGINE_SDKINFO_DATE 0x20100318
#endif //PV_PLAYER_SDKINFO_H_INCLUDED
*/
virtual bool SetGOBHdrInterval(uint32 aGOBHdrIntrvl) = 0;
+ /**
+ * Updates Output bit rate.
+ *
+ * @param aLayer is total number of layers.
+ * @param aBitRate is updated bit rate to set.
+ * @return True if successful, else false
+ */
+ virtual bool UpdateOutputBitRate(uint32 aLayer, uint32 aBitRate) = 0;
+
+ /**
+ * Updates Output frame rate.
+ *
+ * @param aLayer is total number of layers.
+ * @param aFrameRate is updated frame rate to set.
+ * @return True if successful, else false
+ */
+ virtual bool UpdateOutputFrameRate(uint32 aLayer, OsclFloat aFrameRate) = 0;
+
+ /**
+ * Updates Intra period i.e I frame interval.
+ *
+ * @param aIFrameInterval is updated Intra period to set.
+ * @return True if successful, else false
+ */
+ virtual bool UpdateIFrameInterval(uint32 aIFrameInterval) = 0;
+
};
#endif // PV_VIDEO_ENCNODE_EXTENSION_H_INCLUDED
return true;
}
+/////////////////////////////////////////////////////////////////////////////////////////////
+OSCL_EXPORT_REF bool PVMFOMXEncNode::UpdateOutputBitRate(uint32 aLayer, uint32 aBitRate)
+{
+ OMX_ERRORTYPE Err = OMX_ErrorNone;
+ OMX_VIDEO_CONFIG_BITRATETYPE VideoConfigBitRate;
+
+ PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
+ (0, "PVMFOMXEncNode-%s::UpdateOutputBitRate", iNodeTypeId));
+
+ switch (iInterfaceState)
+ {
+ case EPVMFNodeStarted:
+ case EPVMFNodePaused:
+ break;
+ default:
+ PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR,
+ (0, "PVMFOMXEncNode-%s::UpdateOutputBitRate: Error - Wrong state", iNodeTypeId));
+ return false;
+ }
+
+ //OMX_VIDEO_CONFIG_BITRATETYPE Settings
+ CONFIG_SIZE_AND_VERSION(VideoConfigBitRate);
+ VideoConfigBitRate.nPortIndex = iOutputPortIndex;
+
+ Err = OMX_GetConfig(iOMXEncoder, OMX_IndexConfigVideoBitrate, &VideoConfigBitRate);
+ if (OMX_ErrorNone != Err)
+ {
+ PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
+ (0, "PVMFOMXEncNode-%s::UpdateOutputBitRate Parameter Invalid OMX_IndexConfigVideoBitrate from OMX_GetConfig", iNodeTypeId));
+ }
+
+ VideoConfigBitRate.nPortIndex = iOutputPortIndex;
+ VideoConfigBitRate.nEncodeBitrate = aBitRate;
+
+ Err = OMX_SetConfig(iOMXEncoder, OMX_IndexConfigVideoBitrate, &VideoConfigBitRate);
+ if (OMX_ErrorNone != Err)
+ {
+ PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
+ (0, "PVMFOMXEncNode-%s::UpdateOutputBitRate Parameter Invalid OMX_IndexConfigVideoBitrate from OMX_SetConfig", iNodeTypeId));
+ }
+
+ return true;
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////////
+OSCL_EXPORT_REF bool PVMFOMXEncNode::UpdateOutputFrameRate(uint32 aLayer, OsclFloat aFrameRate)
+{
+ OMX_ERRORTYPE Err = OMX_ErrorNone;
+ OMX_CONFIG_FRAMERATETYPE VideoConfigFrameRateType;
+
+ PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
+ (0, "PVMFOMXEncNode-%s::UpdateOutputFrameRate", iNodeTypeId));
+
+ switch (iInterfaceState)
+ {
+ case EPVMFNodeStarted:
+ case EPVMFNodePaused:
+ break;
+ default:
+ PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR,
+ (0, "PVMFOMXEncNode-%s::UpdateOutputFrameRate: Error - Wrong state", iNodeTypeId));
+ return false;
+ }
+
+ //OMX_CONFIG_FRAMERATETYPE Settings
+ CONFIG_SIZE_AND_VERSION(VideoConfigFrameRateType);
+ VideoConfigFrameRateType.nPortIndex = iOutputPortIndex;
+
+ Err = OMX_GetConfig(iOMXEncoder, OMX_IndexConfigVideoFramerate, &VideoConfigFrameRateType);
+ if (OMX_ErrorNone != Err)
+ {
+ PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
+ (0, "PVMFOMXEncNode-%s::UpdateOutputFrameRate Parameter Invalid OMX_IndexConfigVideoFramerate from OMX_GetConfig", iNodeTypeId));
+ }
+
+ VideoConfigFrameRateType.nPortIndex = iOutputPortIndex;
+ VideoConfigFrameRateType.xEncodeFramerate = (uint32)(aFrameRate * (1 << 16));
+
+ Err = OMX_SetConfig(iOMXEncoder, OMX_IndexConfigVideoFramerate, &VideoConfigFrameRateType);
+ if (OMX_ErrorNone != Err)
+ {
+ PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
+ (0, "PVMFOMXEncNode-%s::UpdateOutputFrameRate Parameter Invalid OMX_IndexConfigVideoFramerate from OMX_SetConfig", iNodeTypeId));
+ }
+
+ return true;
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////////
+OSCL_EXPORT_REF bool PVMFOMXEncNode::UpdateIFrameInterval(uint32 aIFrameInterval)
+{
+ OMX_ERRORTYPE Err = OMX_ErrorNone;
+ OMX_VIDEO_CONFIG_AVCINTRAPERIOD VideoConfigAVCIntraPeriod;
+
+ float iSrcFrameRate = 0.0;
+
+ PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
+ (0, "PVMFOMXEncNode-%s::UpdateIFrameInterval", iNodeTypeId));
+
+ switch (iInterfaceState)
+ {
+ case EPVMFNodeStarted:
+ case EPVMFNodePaused:
+ break;
+ default:
+ PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR,
+ (0, "PVMFOMXEncNode-%s::UpdateIFrameInterval: Error - Wrong state", iNodeTypeId));
+ return false;
+ }
+
+ //OMX_VIDEO_CONFIG_AVCINTRAPERIOD Settings
+ CONFIG_SIZE_AND_VERSION(VideoConfigAVCIntraPeriod);
+ VideoConfigAVCIntraPeriod.nPortIndex = iOutputPortIndex;
+
+ Err = OMX_GetConfig(iOMXEncoder, OMX_IndexConfigVideoAVCIntraPeriod, &VideoConfigAVCIntraPeriod);
+ if (OMX_ErrorNone != Err)
+ {
+ PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
+ (0, "PVMFOMXEncNode-%s::UpdateIFrameInterval Parameter Invalid OMX_IndexConfigVideoAVCIntraPeriod from OMX_GetConfig", iNodeTypeId));
+ }
+
+ /* For AVC, UpdateIFrameInterval specifies repetition of IDR frames after every nPFrames */
+ VideoConfigAVCIntraPeriod.nPortIndex = iOutputPortIndex;
+ iSrcFrameRate = (iParamPort.format.video.xFramerate / (float(1 << 16)));
+ VideoConfigAVCIntraPeriod.nPFrames = (OMX_U32)((aIFrameInterval * iSrcFrameRate) - 1);
+
+ Err = OMX_SetConfig(iOMXEncoder, OMX_IndexConfigVideoAVCIntraPeriod, &VideoConfigAVCIntraPeriod);
+ if (OMX_ErrorNone != Err)
+ {
+ PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
+ (0, "PVMFOMXEncNode-%s::UpdateIFrameInterval Parameter Invalid OMX_IndexConfigVideoAVCIntraPeriod from OMX_SetConfig", iNodeTypeId));
+ }
+
+ return true;
+}
+
////////////////////////////////////////////////////////////////////////////
//Stub GetVolHeader Function for PVVideoEncExtensionInterface
OSCL_EXPORT_REF bool PVMFOMXEncNode::GetVolHeader(OsclRefCounterMemFrag& aVolHeader)
OSCL_IMPORT_REF bool SetResyncMarker(bool aResyncMarkerFlag);
OSCL_IMPORT_REF bool SetTimeIncRes(int32 aTimeIncRes);
OSCL_IMPORT_REF bool SetGOBHdrInterval(uint32 aGOBHdrIntrvl);
+ OSCL_IMPORT_REF bool UpdateOutputBitRate(uint32 aLayer, uint32 aBitRate);
+ OSCL_IMPORT_REF bool UpdateOutputFrameRate(uint32 aLayer, OsclFloat aFrameRate);
+ OSCL_IMPORT_REF bool UpdateIFrameInterval(uint32 aIFrameInterval);
// from AudioEncExtensionInterface
OSCL_IMPORT_REF PVMFStatus SetOutputBitRate(PVMF_GSMAMR_Rate aBitRate);