OMX_ERRORTYPE OMXVideoDecoderBase::ProcessorStop(void) { // There is no need to return all retained buffers as we don't accumulate buffer //this->ports[INPORT_INDEX]->ReturnAllRetainedBuffers(); // TODO: this is new code ProcessorFlush(OMX_ALL); if (mWorkingMode == GRAPHICBUFFER_MODE) { // for GRAPHICBUFFER_MODE mode, va_destroySurface need to lock the graphicbuffer, // Make sure va_destroySurface is called(ExecutingToIdle) before graphicbuffer is freed(IdleToLoaded). if (mVideoDecoder == NULL) { LOGE("ProcessorStop: Video decoder is not created."); return OMX_ErrorDynamicResourcesUnavailable; } mVideoDecoder->stop(); } return OMXComponentCodecBase::ProcessorStop(); }
OMX_ERRORTYPE OMXVideoDecoderBase::HandleFormatChange(void) { LOGW("Video format is changed."); //pthread_mutex_lock(&mSerializationLock); const VideoFormatInfo *formatInfo = mVideoDecoder->getFormatInfo(); //pthread_mutex_unlock(&mSerializationLock); // Sync port definition as it may change. OMX_PARAM_PORTDEFINITIONTYPE paramPortDefinitionInput, paramPortDefinitionOutput; memcpy(¶mPortDefinitionInput, this->ports[INPORT_INDEX]->GetPortDefinition(), sizeof(paramPortDefinitionInput)); memcpy(¶mPortDefinitionOutput, this->ports[OUTPORT_INDEX]->GetPortDefinition(), sizeof(paramPortDefinitionOutput)); uint32_t width = formatInfo->width; uint32_t height = formatInfo->height; uint32_t stride = formatInfo->width; uint32_t sliceHeight = formatInfo->height; uint32_t widthCropped = formatInfo->width - formatInfo->cropLeft - formatInfo->cropRight; uint32_t heightCropped = formatInfo->height - formatInfo->cropTop - formatInfo->cropBottom; uint32_t strideCropped = widthCropped; uint32_t sliceHeightCropped = heightCropped; int force_realloc = 0; bool isVP8 = false; #ifdef TARGET_HAS_ISV LOGI("============== mVppBufferNum = %d\n", mVppBufferNum); if (paramPortDefinitionOutput.nBufferCountActual - mVppBufferNum < formatInfo->actualBufferNeeded) { #else if (paramPortDefinitionOutput.nBufferCountActual < formatInfo->actualBufferNeeded) { #endif if (mWorkingMode == GRAPHICBUFFER_MODE) { LOGV("output port buffer number is not enough: %d to %d", paramPortDefinitionOutput.nBufferCountActual, formatInfo->actualBufferNeeded); paramPortDefinitionOutput.nBufferCountActual = mNativeBufferCount = formatInfo->actualBufferNeeded; paramPortDefinitionOutput.nBufferCountMin = mNativeBufferCount; force_realloc = 1; } } LOGV("Original size = %u x %u, new size = %d x %d, cropped size = %d x %d", paramPortDefinitionInput.format.video.nFrameWidth, paramPortDefinitionInput.format.video.nFrameHeight, width, height, widthCropped, heightCropped); if (paramPortDefinitionInput.format.video.eCompressionFormat == OMX_VIDEO_CodingVP8) { isVP8 = true; } if (!force_realloc && widthCropped == paramPortDefinitionOutput.format.video.nFrameWidth && heightCropped == paramPortDefinitionOutput.format.video.nFrameHeight) { if (mWorkingMode == RAWDATA_MODE) { LOGW("Change of portsetting is not reported as size is not changed."); return OMX_ErrorNone; } } paramPortDefinitionInput.format.video.nFrameWidth = width; paramPortDefinitionInput.format.video.nFrameHeight = height; paramPortDefinitionInput.format.video.nStride = stride; paramPortDefinitionInput.format.video.nSliceHeight = sliceHeight; if (mWorkingMode == RAWDATA_MODE) { paramPortDefinitionOutput.format.video.nFrameWidth = widthCropped; paramPortDefinitionOutput.format.video.nFrameHeight = heightCropped; paramPortDefinitionOutput.format.video.nStride = strideCropped; paramPortDefinitionOutput.format.video.nSliceHeight = sliceHeightCropped; } else if (mWorkingMode == GRAPHICBUFFER_MODE) { // when the width and height ES parse are not larger than allocated graphic buffer in outport, // there is no need to reallocate graphic buffer,just report the crop info to omx client if (!force_realloc && width <= formatInfo->surfaceWidth && height <= formatInfo->surfaceHeight) { this->ports[INPORT_INDEX]->SetPortDefinition(¶mPortDefinitionInput, true); this->ports[OUTPORT_INDEX]->ReportOutputCrop(); return OMX_ErrorNone; } if (isVP8 || width > formatInfo->surfaceWidth || height > formatInfo->surfaceHeight) { // update the real decoded resolution to outport instead of display resolution for graphic buffer reallocation // when the width and height parsed from ES are larger than allocated graphic buffer in outport, paramPortDefinitionOutput.format.video.nFrameWidth = width; paramPortDefinitionOutput.format.video.nFrameHeight = height; paramPortDefinitionOutput.format.video.eColorFormat = GetOutputColorFormat( paramPortDefinitionOutput.format.video.nFrameWidth); paramPortDefinitionOutput.format.video.nStride = stride; paramPortDefinitionOutput.format.video.nSliceHeight = sliceHeight; } } paramPortDefinitionOutput.bEnabled = (OMX_BOOL)false; mOMXBufferHeaderTypePtrNum = 0; memset(&mGraphicBufferParam, 0, sizeof(mGraphicBufferParam)); this->ports[INPORT_INDEX]->SetPortDefinition(¶mPortDefinitionInput, true); this->ports[OUTPORT_INDEX]->SetPortDefinition(¶mPortDefinitionOutput, true); if (mWorkingMode == GRAPHICBUFFER_MODE) { // Make sure va_destroySurface is called before graphicbuffer is freed in case of port setting changed mVideoDecoder->freeSurfaceBuffers(); // Also make sure all the reference frames are flushed ProcessorFlush(INPORT_INDEX); } this->ports[OUTPORT_INDEX]->ReportPortSettingsChanged(); return OMX_ErrorNone; } OMX_ERRORTYPE OMXVideoDecoderBase::TranslateDecodeStatus(Decode_Status status) { switch (status) { case DECODE_NEED_RESTART: LOGE("Decoder returned DECODE_NEED_RESTART"); return (OMX_ERRORTYPE)OMX_ErrorIntelVideoNotPermitted; case DECODE_NO_CONFIG: LOGE("Decoder returned DECODE_NO_CONFIG"); return (OMX_ERRORTYPE)OMX_ErrorIntelMissingConfig; case DECODE_NO_SURFACE: LOGE("Decoder returned DECODE_NO_SURFACE"); return OMX_ErrorDynamicResourcesUnavailable; case DECODE_NO_REFERENCE: LOGE("Decoder returned DECODE_NO_REFERENCE"); return OMX_ErrorDynamicResourcesUnavailable; // TO DO case DECODE_NO_PARSER: LOGE("Decoder returned DECODE_NO_PARSER"); return OMX_ErrorDynamicResourcesUnavailable; case DECODE_INVALID_DATA: LOGE("Decoder returned DECODE_INVALID_DATA"); return OMX_ErrorBadParameter; case DECODE_DRIVER_FAIL: LOGE("Decoder returned DECODE_DRIVER_FAIL"); return OMX_ErrorHardware; case DECODE_PARSER_FAIL: LOGE("Decoder returned DECODE_PARSER_FAIL"); return (OMX_ERRORTYPE)OMX_ErrorIntelProcessStream; // OMX_ErrorStreamCorrupt case DECODE_MEMORY_FAIL: LOGE("Decoder returned DECODE_MEMORY_FAIL"); return OMX_ErrorInsufficientResources; case DECODE_FAIL: LOGE("Decoder returned DECODE_FAIL"); return OMX_ErrorUndefined; case DECODE_SUCCESS: return OMX_ErrorNone; case DECODE_FORMAT_CHANGE: LOGW("Decoder returned DECODE_FORMAT_CHANGE"); return OMX_ErrorNone; case DECODE_FRAME_DROPPED: LOGI("Decoder returned DECODE_FRAME_DROPPED"); return OMX_ErrorNone; default: LOGW("Decoder returned unknown error"); return OMX_ErrorUndefined; } } OMX_ERRORTYPE OMXVideoDecoderBase::BuildHandlerList(void) { OMXComponentCodecBase::BuildHandlerList(); AddHandler(OMX_IndexParamVideoPortFormat, GetParamVideoPortFormat, SetParamVideoPortFormat); AddHandler(static_cast<OMX_INDEXTYPE>(OMX_IndexExtGetNativeBufferUsage), GetNativeBufferUsage, SetNativeBufferUsage); AddHandler(static_cast<OMX_INDEXTYPE>(OMX_IndexExtUseNativeBuffer), GetNativeBuffer, SetNativeBuffer); AddHandler(static_cast<OMX_INDEXTYPE>(OMX_IndexExtEnableNativeBuffer), GetNativeBufferMode, SetNativeBufferMode); AddHandler(static_cast<OMX_INDEXTYPE>(OMX_IndexExtRotationDegrees), GetDecoderRotation, SetDecoderRotation); #ifdef TARGET_HAS_ISV AddHandler(static_cast<OMX_INDEXTYPE>(OMX_IndexExtVppBufferNum), GetDecoderVppBufferNum, SetDecoderVppBufferNum); #endif AddHandler(OMX_IndexConfigCommonOutputCrop, GetDecoderOutputCrop, SetDecoderOutputCrop); AddHandler(static_cast<OMX_INDEXTYPE>(OMX_IndexExtEnableErrorReport), GetErrorReportMode, SetErrorReportMode); return OMX_ErrorNone; }