Merge "Fix the 0-timestamp issue Don't return an output buffer back to the omx client if the input buffer(s) processed are only meant for setting the configuration"
diff --git a/libstagefrighthw/TIHardwareRenderer.cpp b/libstagefrighthw/TIHardwareRenderer.cpp
index c5477da..155fe85 100644
--- a/libstagefrighthw/TIHardwareRenderer.cpp
+++ b/libstagefrighthw/TIHardwareRenderer.cpp
@@ -193,7 +193,13 @@
overlay_buffer_t overlay_buffer;
if (!mIsFirstFrame) {
- CHECK_EQ(mOverlay->dequeueBuffer(&overlay_buffer), OK);
+ status_t err = mOverlay->dequeueBuffer(&overlay_buffer);
+
+ if (err == ALL_BUFFERS_FLUSHED) {
+ mIsFirstFrame = true;
+ } else {
+ return;
+ }
} else {
mIsFirstFrame = false;
}
diff --git a/omx/system/src/openmax_il/omx_core/src/OMX_Core.c b/omx/system/src/openmax_il/omx_core/src/OMX_Core.c
index 33fd603..af18744 100755
--- a/omx/system/src/openmax_il/omx_core/src/OMX_Core.c
+++ b/omx/system/src/openmax_il/omx_core/src/OMX_Core.c
@@ -88,7 +88,9 @@
{"OMX.TI.WMA.decode", "audio_decoder.wma"},
{"OMX.TI.WBAMR.decode", "audio_decoder.amrwb"},
{"OMX.TI.AMR.decode", "audio_decoder.amrnb"},
+#if 0
{"OMX.TI.AMR.encode", "audio_encoder.amrnb"},
+#endif
{"OMX.TI.WBAMR.encode", "audio_encoder.amrwb"},
#endif
/* {"OMX.TI.PCM.encode", NULL},
diff --git a/omx/video/src/openmax_il/video_encode/inc/OMX_VideoEnc_Utils.h b/omx/video/src/openmax_il/video_encode/inc/OMX_VideoEnc_Utils.h
index 5e5470f..e45bb66 100644
--- a/omx/video/src/openmax_il/video_encode/inc/OMX_VideoEnc_Utils.h
+++ b/omx/video/src/openmax_il/video_encode/inc/OMX_VideoEnc_Utils.h
@@ -105,6 +105,7 @@
#define OMX_BUFFERFLAG_SYNCFRAME 0x00000040
#endif
#define OMX_LFRAMETYPE_H264 1
+#define OMX_LFRAMETYPE_IDR_H264 4
#define OMX_CFRAMETYPE_MPEG4 1
/*Select Timeout */
#define VIDENC_TIMEOUT_SEC 120;
@@ -595,15 +596,16 @@
OMX_PTR pMarkData;
OMX_HANDLETYPE hMarkTargetComponent;
OMX_U32 nFlags;
- OMX_U32 nCounter;
/* these are duplicates */
unsigned int nIntraFrameInterval; /* should be OMX_VIDEO_CONFIG_AVCINTRAPERIOD */
unsigned int nTargetFrameRate; /* should be OMX_CONFIG_FRAMERATETYPE */
+ unsigned int nPrevTargetFrameRate;
unsigned int nQPI; /* same as OMX_VIDEO_PARAM_QUANTIZATIONTYPE */
unsigned int nAIRRate; /* same as OMX_VIDEO_PARAM_INTRAREFRESHTYPE */
unsigned int nTargetBitRate; /* should be OMX_VIDEO_CONFIG_BITRATETYPE */
OMX_U32 nMIRRate;
OMX_U8 ucUnrestrictedMV;
+ OMX_BOOL bSentFirstSpsPps;
OMX_U32 nInBufferSize;
OMX_U32 nOutBufferSize;
@@ -684,6 +686,11 @@
pthread_mutex_t mutexStateChangeRequest;
pthread_cond_t StateChangeCondition;
+ /* Variable related to variabe frame rate settings */
+ OMX_TICKS nLastUpdateTime; /* Timstamp of last framerate update */
+ OMX_U32 nFrameRateUpdateInterval; /* Unit is number of frames */
+ OMX_U32 nFrameCount; /* Number of input frames received since last framerate update */
+ OMX_TICKS nVideoTime; /* Video duration since last framerate update */
} VIDENC_COMPONENT_PRIVATE;
typedef OMX_ERRORTYPE (*fpo)(OMX_HANDLETYPE);
diff --git a/omx/video/src/openmax_il/video_encode/src/OMX_VideoEnc_Utils.c b/omx/video/src/openmax_il/video_encode/src/OMX_VideoEnc_Utils.c
index ba0482b..cf7d74d 100644
--- a/omx/video/src/openmax_il/video_encode/src/OMX_VideoEnc_Utils.c
+++ b/omx/video/src/openmax_il/video_encode/src/OMX_VideoEnc_Utils.c
@@ -86,6 +86,10 @@
// opencore to request the correct level based on resolution/bitrate/etc
#define VIDEO_ENCODER_MHZ (400 - 45 + 2)
+/* H264 Specific */
+#define SPS_CODE_PREFIX 0x07
+#define PPS_CODE_PREFIX 0x08
+
#ifdef UNDER_CE
HINSTANCE g_hLcmlDllHandle = NULL;
#endif
@@ -2872,9 +2876,23 @@
}
/* Set lFrameType*/
- if (((H264VE_GPP_SN_UALGOutputParams*)pBufferPrivate->pUalgParam)->lFrameType == OMX_LFRAMETYPE_H264)
+ if (((H264VE_GPP_SN_UALGOutputParams*)pBufferPrivate->pUalgParam)->lFrameType == OMX_LFRAMETYPE_H264 ||
+ ((H264VE_GPP_SN_UALGOutputParams*)pBufferPrivate->pUalgParam)->lFrameType == OMX_LFRAMETYPE_IDR_H264)
{
/* IDR Frame */
+ OMX_S32 nalType = pBufHead->pBuffer[0] & 0x1F;
+ if (nalType == SPS_CODE_PREFIX || nalType == PPS_CODE_PREFIX) {
+ /* Need to drop subsequent SPS or PPS NAL unit since opencore does not
+ * correctly handle storage */
+ if (!pComponentPrivate->bSentFirstSpsPps) {
+ /* we can assume here that PPS always comes second */
+ if (nalType == PPS_CODE_PREFIX)
+ pComponentPrivate->bSentFirstSpsPps = OMX_TRUE;
+ } else {
+ pBufHead->nFilledLen = 0;
+ }
+ }
+
pBufHead->nFlags |= OMX_BUFFERFLAG_SYNCFRAME;
}
@@ -3254,7 +3272,8 @@
/* set run-time frame and bit rates to create-time values */
pComponentPrivate->nTargetFrameRate = pCreatePhaseArgs->ulFrameRate;
-
+ pComponentPrivate->nPrevTargetFrameRate = 0;
+ pComponentPrivate->bSentFirstSpsPps = OMX_FALSE;
if (pPortDefIn->format.video.eColorFormat == OMX_COLOR_FormatYUV420Planar)
{
@@ -3383,7 +3402,8 @@
pCreatePhaseArgs->ucDeblockingEnable = 0;
pCreatePhaseArgs->ucLevel = 30;
}
-
+ /* Ensure frame rate update interval, which forces IDR frames, is same as I-Slice interval */
+ pComponentPrivate->nFrameRateUpdateInterval = pComponentPrivate->nIntraFrameInterval;
pCreatePhaseArgs->usNalCallback = pComponentPrivate->AVCNALFormat;
pCreatePhaseArgs->ulEncodingPreset = pComponentPrivate->nEncodingPreset;
pCreatePhaseArgs->ulRcAlgo = 0;
@@ -3616,6 +3636,7 @@
/* set run-time frame and bit rates to create-time values */
pComponentPrivate->nTargetFrameRate = pCreatePhaseArgs->ucFrameRate;
+ pComponentPrivate->nPrevTargetFrameRate = 0;
pComponentPrivate->nTargetBitRate = pCreatePhaseArgs->ulTargetBitRate;
if (pVidParamBitrate->eControlRate == OMX_Video_ControlRateConstant)
diff --git a/omx/video/src/openmax_il/video_encode/src/OMX_VideoEncoder.c b/omx/video/src/openmax_il/video_encode/src/OMX_VideoEncoder.c
index 20056f1..3cd8c79 100644
--- a/omx/video/src/openmax_il/video_encode/src/OMX_VideoEncoder.c
+++ b/omx/video/src/openmax_il/video_encode/src/OMX_VideoEncoder.c
@@ -941,6 +941,10 @@
pComponentPrivate->pCapabilityFlags->iOMXComponentSupportsPartialFrames=OMX_FALSE;
pComponentPrivate->pCapabilityFlags->iOMXComponentUsesFullAVCFrames=OMX_FALSE;
pComponentPrivate->pCapabilityFlags->iOMXComponentUsesNALStartCode=OMX_FALSE;
+ pComponentPrivate->nLastUpdateTime = 0;
+ pComponentPrivate->nFrameRateUpdateInterval = 60;
+ pComponentPrivate->nFrameCount = 0;
+ pComponentPrivate->nVideoTime = 0;
#ifndef UNDER_CE
/* Initialize Mutex for Buffer Tracking */
@@ -2831,6 +2835,37 @@
pBufferPrivate->eBufferOwner = VIDENC_BUFFER_WITH_COMPONENT;
pBufferPrivate->bReadFromPipe = OMX_FALSE;
+ /* Check if frame rate needs to be updated */
+ pComponentPrivate->nFrameCount++;
+ pComponentPrivate->nVideoTime = pBufHead->nTimeStamp - pComponentPrivate->nLastUpdateTime;
+
+ if (pComponentPrivate->nFrameCount == pComponentPrivate->nFrameRateUpdateInterval) {
+
+ if(pComponentPrivate->nVideoTime <= 0) {
+ /* Incorrect time stamps */
+ return OMX_ErrorBadParameter;
+ }
+
+ /* Timestamps are in micro seconds */
+ pComponentPrivate->nTargetFrameRate = pComponentPrivate->nFrameCount * 1000000 / pComponentPrivate->nVideoTime;
+
+ if(pComponentPrivate->pCompPort[VIDENC_OUTPUT_PORT]->pPortDef->format.video.eCompressionFormat == OMX_VIDEO_CodingAVC) {
+ /* H.264 Socket Node expects frame rate to be multiplied by 1000 */
+ pComponentPrivate->nTargetFrameRate *= 1000;
+
+ if((pComponentPrivate->nPrevTargetFrameRate) &&
+ (pComponentPrivate->nTargetFrameRate == pComponentPrivate->nPrevTargetFrameRate)) {
+ pComponentPrivate->bForceIFrame = OMX_TRUE;
+ }
+ else {
+ pComponentPrivate->nPrevTargetFrameRate = pComponentPrivate->nTargetFrameRate;
+ pComponentPrivate->bForceIFrame = OMX_FALSE;
+ }
+ }
+ pComponentPrivate->nLastUpdateTime = pBufHead->nTimeStamp;
+ pComponentPrivate->nFrameCount = 0;
+ }
+
nRet = write(pComponentPrivate->nFilled_iPipe[1],
&(pBufHead),
sizeof(pBufHead));