#define H264_CTRL_NUM 91
#define MPEG4_CTRL_NUM 26
#define H263_CTRL_NUM 18
+#define MAX_INPUTBUFFER_COUNT 32
/*
* [Common] __CodingType_To_V4L2PixelFormat
}
if (nBufferCount == 0) {
- ALOGE("%s: Buffer count must be greater than 0", __func__);
- ret = VIDEO_ERROR_BADPARAM;
- goto EXIT;
+ nBufferCount = MAX_INPUTBUFFER_COUNT;
+ ALOGV("%s: Change buffer count %d", __func__, nBufferCount);
}
memset(&req, 0, sizeof(req));
return ret;
}
+
+/*
+ * [Encoder Buffer OPS] FindIndex (Input)
+ */
+static int MFC_Encoder_FindEmpty_Inbuf(void *pHandle)
+{
+ ExynosVideoEncContext *pCtx = (ExynosVideoEncContext *)pHandle;
+ int nIndex = -1;
+
+ if (pCtx == NULL) {
+ ALOGE("%s: Video context info must be supplied", __func__);
+ goto EXIT;
+ }
+
+ for (nIndex = 0; nIndex < pCtx->nInbufs; nIndex++) {
+ if (pCtx->pInbuf[nIndex].bQueued == VIDEO_FALSE) {
+ break;
+ }
+ }
+
+ if (nIndex == pCtx->nInbufs)
+ nIndex = -1;
+
+EXIT:
+ return nIndex;
+}
+
+/*
+ * [Encoder Buffer OPS] ExtensionEnqueue (Input)
+ */
+static ExynosVideoErrorType MFC_Encoder_ExtensionEnqueue_Inbuf(
+ void *pHandle,
+ unsigned char *pBuffer[],
+ unsigned int *pFd[],
+ unsigned int allocLen[],
+ unsigned int dataSize[],
+ int nPlanes,
+ void *pPrivate)
+{
+ ExynosVideoEncContext *pCtx = (ExynosVideoEncContext *)pHandle;
+ ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
+ pthread_mutex_t *pMutex = NULL;
+
+ struct v4l2_plane planes[VIDEO_ENCODER_INBUF_PLANES];
+ struct v4l2_buffer buf;
+ int index, i;
+
+ if (pCtx == NULL) {
+ ALOGE("%s: Video context info must be supplied", __func__);
+ ret = VIDEO_ERROR_BADPARAM;
+ goto EXIT;
+ }
+
+ if (VIDEO_ENCODER_INBUF_PLANES < nPlanes) {
+ ALOGE("%s: Number of max planes : %d, nPlanes : %d", __func__,
+ VIDEO_ENCODER_INBUF_PLANES, nPlanes);
+ ret = VIDEO_ERROR_BADPARAM;
+ goto EXIT;
+ }
+
+ memset(&buf, 0, sizeof(buf));
+
+ buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
+ buf.m.planes = planes;
+ buf.length = VIDEO_ENCODER_INBUF_PLANES;
+
+ pMutex = (pthread_mutex_t*)pCtx->pInMutex;
+ pthread_mutex_lock(pMutex);
+ index = MFC_Encoder_FindEmpty_Inbuf(pCtx);
+ if (index == -1) {
+ pthread_mutex_unlock(pMutex);
+ ALOGE("%s: Failed to get index", __func__);
+ ret = VIDEO_ERROR_NOBUFFERS;
+ goto EXIT;
+ }
+
+ buf.index = index;
+
+ pCtx->pInbuf[buf.index].bQueued = VIDEO_TRUE;
+ pthread_mutex_unlock(pMutex);
+
+ buf.memory = pCtx->nMemoryType;
+ for (i = 0; i < nPlanes; i++) {
+ /* V4L2_MEMORY_DMABUF */
+ buf.m.planes[i].m.fd = (unsigned int)pFd[i];
+ buf.m.planes[i].length = allocLen[i];
+ buf.m.planes[i].bytesused = dataSize[i];
+
+ /* Temporary storage for Dequeue */
+ pCtx->pInbuf[buf.index].planes[i].addr = (unsigned long)pBuffer[i];
+ pCtx->pInbuf[buf.index].planes[i].fd = (unsigned int)pFd[i];
+ pCtx->pInbuf[buf.index].planes[i].allocSize = allocLen[i];
+ }
+
+ if (exynos_v4l2_qbuf(pCtx->hEnc, &buf) != 0) {
+ ALOGE("%s: Failed to enqueue input buffer", __func__);
+ pthread_mutex_lock(pMutex);
+ pCtx->pInbuf[buf.index].bQueued = VIDEO_FALSE;
+ pthread_mutex_unlock(pMutex);
+ ret = VIDEO_ERROR_APIFAIL;
+ goto EXIT;
+ }
+
+ pCtx->pInbuf[buf.index].pPrivate = pPrivate;
+
+EXIT:
+ return ret;
+}
+
+/*
+ * [Encoder Buffer OPS] ExtensionDequeue (Input)
+ */
+static ExynosVideoErrorType MFC_Encoder_ExtensionDequeue_Inbuf(void *pHandle, ExynosVideoBuffer *pVideoBuffer)
+{
+ ExynosVideoEncContext *pCtx = (ExynosVideoEncContext *)pHandle;
+ ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
+ pthread_mutex_t *pMutex = NULL;
+
+ struct v4l2_buffer buf;
+
+ if (pCtx == NULL) {
+ ALOGE("%s: Video context info must be supplied", __func__);
+ ret = VIDEO_ERROR_BADPARAM;
+ goto EXIT;
+ }
+
+ if (pCtx->bStreamonInbuf == VIDEO_FALSE) {
+ ret = VIDEO_ERROR_APIFAIL;
+ goto EXIT;
+ }
+
+ memset(&buf, 0, sizeof(buf));
+ buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
+ buf.memory = pCtx->nMemoryType;
+ if (exynos_v4l2_dqbuf(pCtx->hEnc, &buf) != 0) {
+ ALOGE("%s: Failed to dequeue input buffer", __func__);
+ ret = VIDEO_ERROR_APIFAIL;
+ goto EXIT;
+ }
+
+ memcpy(pVideoBuffer, &pCtx->pInbuf[buf.index], sizeof(ExynosVideoBuffer));
+ pMutex = (pthread_mutex_t*)pCtx->pInMutex;
+ pthread_mutex_lock(pMutex);
+ pCtx->pInbuf[buf.index].bQueued = VIDEO_FALSE;
+ pthread_mutex_unlock(pMutex);
+
+EXIT:
+ return ret;
+}
+
+
/*
* [Encoder OPS] Common
*/
.Register = MFC_Encoder_Register_Inbuf,
.Clear_RegisteredBuffer = MFC_Encoder_Clear_RegisteredBuffer_Inbuf,
.Clear_Queue = MFC_Encoder_Clear_Queued_Inbuf,
+ .ExtensionEnqueue = MFC_Encoder_ExtensionEnqueue_Inbuf,
+ .ExtensionDequeue = MFC_Encoder_ExtensionDequeue_Inbuf,
};
/*
ExynosVideoErrorType (*Register)(void *pHandle, ExynosVideoPlane *planes, int nPlanes);
ExynosVideoErrorType (*Clear_RegisteredBuffer)(void *pHandle);
ExynosVideoErrorType (*Clear_Queue)(void *pHandle);
+ ExynosVideoErrorType (*ExtensionEnqueue)(void *pHandle, unsigned char *pBuffer[], unsigned int *pFd[], unsigned int allocLen[], unsigned int dataSize[], int nPlanes, void *pPrivate);
+ ExynosVideoErrorType (*ExtensionDequeue)(void *pHandle, ExynosVideoBuffer *pVideoBuffer);
} ExynosVideoEncBufferOps;
int Exynos_Video_Register_Decoder(
#define MFC_INPUT_BUFFER_PLANE 2
#define MFC_OUTPUT_BUFFER_PLANE 1
-#define MAX_CAMERA_INPUTBUFFER_NUM 12 /* number of metadata buffer */
+#define MAX_INPUTBUFFER_NUM_DYNAMIC 0 /* Dynamic number of metadata buffer */
// The largest metadata buffer size advertised
// when metadata buffer mode is used for video encoding
bufferConf.nFrameHeight = pExynosInputPort->portDefinition.format.video.nFrameHeight;
pInbufOps->Set_Shareable(hMFCHandle);
if (pExynosInputPort->bufferProcessType == BUFFER_SHARE) {
- inputBufferNumber = MAX_CAMERA_INPUTBUFFER_NUM; /* Need change to number of camera buffer */
+ inputBufferNumber = MAX_INPUTBUFFER_NUM_DYNAMIC;
} else if ((pExynosInputPort->bufferProcessType & BUFFER_COPY) == BUFFER_COPY) {
inputBufferNumber = MFC_INPUT_BUFFER_NUM_MAX;
}
SetupBufferNumber = MFC_OUTPUT_BUFFER_NUM_MAX;
else
SetupBufferNumber = pExynosOutputPort->portDefinition.nBufferCountActual;
- Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "SetupBufferNumber:%d", SetupBufferNumber);
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "SetupBufferNumber:%d", SetupBufferNumber);
if (pOutbufOps->Setup(pH264Enc->hMFCH264Handle.hMFCHandle, SetupBufferNumber) != VIDEO_ERROR_NONE) {
Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to setup output buffer");
if ((pSrcInputData->dataLen >= 0) ||
((pSrcInputData->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS)) {
+ OMX_U32 nAllocLen[MFC_INPUT_BUFFER_PLANE] = {0, 0};
OMX_U32 pMFCYUVDataSize[MFC_INPUT_BUFFER_PLANE] = {NULL, NULL};
ExynosVideoPlane planes[MFC_INPUT_BUFFER_PLANE];
int plane;
pMFCYUVDataSize[0] = pExynosInputPort->portDefinition.format.video.nFrameWidth * pExynosInputPort->portDefinition.format.video.nFrameHeight;
pMFCYUVDataSize[1] = pMFCYUVDataSize[0] / 2;
- codecReturn = pInbufOps->Enqueue(hMFCHandle, (unsigned char **)pSrcInputData->buffer.multiPlaneBuffer.dataBuffer,
- (unsigned int *)pMFCYUVDataSize, MFC_INPUT_BUFFER_PLANE, pSrcInputData->bufferHeader);
#ifdef USE_METADATABUFFERTYPE
- if ((codecReturn == VIDEO_ERROR_NOBUFFERS) &&
- (pExynosInputPort->bStoreMetaData == OMX_TRUE) &&
- (pExynosInputPort->bufferProcessType == BUFFER_SHARE)) {
- OMX_U32 nAllocLen[MFC_INPUT_BUFFER_PLANE] = {0, 0};
- nAllocLen[0] = ALIGN_TO_16B(pExynosInputPort->portDefinition.format.video.nFrameWidth) *
- ALIGN_TO_16B(pExynosInputPort->portDefinition.format.video.nFrameHeight);
- nAllocLen[1] = ALIGN(nAllocLen[0]/2,256);
- for (plane = 0; plane < MFC_INPUT_BUFFER_PLANE; plane++) {
- planes[plane].addr = pSrcInputData->buffer.multiPlaneBuffer.dataBuffer[plane];
- planes[plane].allocSize = nAllocLen[plane];
- planes[plane].fd = pSrcInputData->buffer.multiPlaneBuffer.fd[plane];
- }
+ nAllocLen[0] = ALIGN_TO_16B(pExynosInputPort->portDefinition.format.video.nFrameWidth) *
+ ALIGN_TO_16B(pExynosInputPort->portDefinition.format.video.nFrameHeight);
+ nAllocLen[1] = ALIGN(nAllocLen[0]/2,256);
- /* Register input buffer */
- if (pInbufOps->Register(pH264Enc->hMFCH264Handle.hMFCHandle,
- planes, MFC_INPUT_BUFFER_PLANE) != VIDEO_ERROR_NONE) {
- Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to Register input buffer");
- ret = OMX_ErrorInsufficientResources;
- goto EXIT;
- }
+ if ((pExynosInputPort->bStoreMetaData == OMX_TRUE) &&
+ (pExynosInputPort->bufferProcessType == BUFFER_SHARE)) {
+ codecReturn = pInbufOps->ExtensionEnqueue(hMFCHandle,
+ (unsigned char **)pSrcInputData->buffer.multiPlaneBuffer.dataBuffer,
+ (unsigned char **)pSrcInputData->buffer.multiPlaneBuffer.fd,
+ (unsigned int *)nAllocLen, (unsigned int *)pMFCYUVDataSize,
+ MFC_INPUT_BUFFER_PLANE, pSrcInputData->bufferHeader);
+ } else {
codecReturn = pInbufOps->Enqueue(hMFCHandle, (unsigned char **)pSrcInputData->buffer.multiPlaneBuffer.dataBuffer,
(unsigned int *)pMFCYUVDataSize, MFC_INPUT_BUFFER_PLANE, pSrcInputData->bufferHeader);
-
}
+#else
+ codecReturn = pInbufOps->Enqueue(hMFCHandle, (unsigned char **)pSrcInputData->buffer.multiPlaneBuffer.dataBuffer,
+ (unsigned int *)pMFCYUVDataSize, MFC_INPUT_BUFFER_PLANE, pSrcInputData->bufferHeader);
#endif
if (codecReturn != VIDEO_ERROR_NONE) {
Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: %d: Failed - pInbufOps->Enqueue", __FUNCTION__, __LINE__);
ExynosVideoEncOps *pEncOps = pH264Enc->hMFCH264Handle.pEncOps;
ExynosVideoEncBufferOps *pInbufOps = pH264Enc->hMFCH264Handle.pInbufOps;
ExynosVideoBuffer *pVideoBuffer;
+ ExynosVideoBuffer videoBuffer;
FunctionIn();
- pVideoBuffer = pInbufOps->Dequeue(hMFCHandle);
+ if ((pExynosInputPort->bStoreMetaData == OMX_TRUE) &&
+ (pExynosInputPort->bufferProcessType == BUFFER_SHARE)) {
+ if (pInbufOps->ExtensionDequeue(hMFCHandle, &videoBuffer) == VIDEO_ERROR_NONE)
+ pVideoBuffer = &videoBuffer;
+ else
+ pVideoBuffer = NULL;
+ } else {
+ pVideoBuffer = pInbufOps->Dequeue(hMFCHandle);
+ }
pSrcOutputData->dataLen = 0;
pSrcOutputData->usedDataLen = 0;
bufferConf.nFrameHeight = pExynosInputPort->portDefinition.format.video.nFrameHeight;
pInbufOps->Set_Shareable(hMFCHandle);
if (pExynosInputPort->bufferProcessType == BUFFER_SHARE) {
- inputBufferNumber = MAX_CAMERA_INPUTBUFFER_NUM; /* Need change to number of camera buffer */
+ inputBufferNumber = MAX_INPUTBUFFER_NUM_DYNAMIC;
} else if ((pExynosInputPort->bufferProcessType & BUFFER_COPY) == BUFFER_COPY) {
inputBufferNumber = MFC_INPUT_BUFFER_NUM_MAX;
}
SetupBufferNumber = MFC_OUTPUT_BUFFER_NUM_MAX;
else
SetupBufferNumber = pExynosOutputPort->portDefinition.nBufferCountActual;
- Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "SetupBufferNumber:%d", SetupBufferNumber);
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "SetupBufferNumber:%d", SetupBufferNumber);
if (pOutbufOps->Setup(pMpeg4Enc->hMFCMpeg4Handle.hMFCHandle, SetupBufferNumber) != VIDEO_ERROR_NONE) {
Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to setup output buffer");
if ((pSrcInputData->dataLen >= 0) ||
((pSrcInputData->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS)) {
+ OMX_U32 nAllocLen[MFC_INPUT_BUFFER_PLANE] = {0, 0};
OMX_U32 pMFCYUVDataSize[MFC_INPUT_BUFFER_PLANE] = {NULL, NULL};
ExynosVideoPlane planes[MFC_INPUT_BUFFER_PLANE];
int plane;
pMFCYUVDataSize[0] = pExynosInputPort->portDefinition.format.video.nFrameWidth * pExynosInputPort->portDefinition.format.video.nFrameHeight;
pMFCYUVDataSize[1] = pMFCYUVDataSize[0] / 2;
- codecReturn = pInbufOps->Enqueue(hMFCHandle, (unsigned char **)pSrcInputData->buffer.multiPlaneBuffer.dataBuffer,
- (unsigned int *)pMFCYUVDataSize, MFC_INPUT_BUFFER_PLANE, pSrcInputData->bufferHeader);
#ifdef USE_METADATABUFFERTYPE
- if ((codecReturn == VIDEO_ERROR_NOBUFFERS) &&
- (pExynosInputPort->bStoreMetaData == OMX_TRUE) &&
- (pExynosInputPort->bufferProcessType == BUFFER_SHARE)) {
- OMX_U32 nAllocLen[MFC_INPUT_BUFFER_PLANE] = {0, 0};
- nAllocLen[0] = ALIGN_TO_16B(pExynosInputPort->portDefinition.format.video.nFrameWidth) *
- ALIGN_TO_16B(pExynosInputPort->portDefinition.format.video.nFrameHeight);
- nAllocLen[1] = ALIGN(nAllocLen[0]/2,256);
- for (plane = 0; plane < MFC_INPUT_BUFFER_PLANE; plane++) {
- planes[plane].addr = pSrcInputData->buffer.multiPlaneBuffer.dataBuffer[plane];
- planes[plane].allocSize = nAllocLen[plane];
- planes[plane].fd = pSrcInputData->buffer.multiPlaneBuffer.fd[plane];
- }
+ nAllocLen[0] = ALIGN_TO_16B(pExynosInputPort->portDefinition.format.video.nFrameWidth) *
+ ALIGN_TO_16B(pExynosInputPort->portDefinition.format.video.nFrameHeight);
+ nAllocLen[1] = ALIGN(nAllocLen[0]/2,256);
- /* Register input buffer */
- if (pInbufOps->Register(pMpeg4Enc->hMFCMpeg4Handle.hMFCHandle,
- planes, MFC_INPUT_BUFFER_PLANE) != VIDEO_ERROR_NONE) {
- Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to Register input buffer");
- ret = OMX_ErrorInsufficientResources;
- goto EXIT;
- }
+ if ((pExynosInputPort->bStoreMetaData == OMX_TRUE) &&
+ (pExynosInputPort->bufferProcessType == BUFFER_SHARE)) {
+ codecReturn = pInbufOps->ExtensionEnqueue(hMFCHandle,
+ (unsigned char **)pSrcInputData->buffer.multiPlaneBuffer.dataBuffer,
+ (unsigned char **)pSrcInputData->buffer.multiPlaneBuffer.fd,
+ (unsigned int *)nAllocLen, (unsigned int *)pMFCYUVDataSize,
+ MFC_INPUT_BUFFER_PLANE, pSrcInputData->bufferHeader);
+ } else {
codecReturn = pInbufOps->Enqueue(hMFCHandle, (unsigned char **)pSrcInputData->buffer.multiPlaneBuffer.dataBuffer,
(unsigned int *)pMFCYUVDataSize, MFC_INPUT_BUFFER_PLANE, pSrcInputData->bufferHeader);
-
}
+#else
+ codecReturn = pInbufOps->Enqueue(hMFCHandle, (unsigned char **)pSrcInputData->buffer.multiPlaneBuffer.dataBuffer,
+ (unsigned int *)pMFCYUVDataSize, MFC_INPUT_BUFFER_PLANE, pSrcInputData->bufferHeader);
#endif
if (codecReturn != VIDEO_ERROR_NONE) {
Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: %d: Failed - pInbufOps->Enqueue", __FUNCTION__, __LINE__);
ExynosVideoEncOps *pEncOps = pMpeg4Enc->hMFCMpeg4Handle.pEncOps;
ExynosVideoEncBufferOps *pInbufOps = pMpeg4Enc->hMFCMpeg4Handle.pInbufOps;
ExynosVideoBuffer *pVideoBuffer;
+ ExynosVideoBuffer videoBuffer;
FunctionIn();
- pVideoBuffer = pInbufOps->Dequeue(hMFCHandle);
+ if ((pExynosInputPort->bStoreMetaData == OMX_TRUE) &&
+ (pExynosInputPort->bufferProcessType == BUFFER_SHARE)) {
+ if (pInbufOps->ExtensionDequeue(hMFCHandle, &videoBuffer) == VIDEO_ERROR_NONE)
+ pVideoBuffer = &videoBuffer;
+ else
+ pVideoBuffer = NULL;
+ } else {
+ pVideoBuffer = pInbufOps->Dequeue(hMFCHandle);
+ }
pSrcOutputData->dataLen = 0;
pSrcOutputData->usedDataLen = 0;
pFindElement = pCurrentElement->pNextMemory;
} else {
Exynos_OSAL_MutexUnlock(pHandle->hSMMutex);
- Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Can not find SharedMemory");
+ Exynos_OSAL_Log(EXYNOS_LOG_WARNING, "Can not find SharedMemory");
goto EXIT;
}
}
pFindElement = pCurrentElement->pNextMemory;
} else {
Exynos_OSAL_MutexUnlock(pHandle->hSMMutex);
- Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Can not find SharedMemory");
+ Exynos_OSAL_Log(EXYNOS_LOG_WARNING, "Can not find SharedMemory");
goto EXIT;
}
}