From 3f3df0b0d579fab5268437e18ba72ec581d0042b Mon Sep 17 00:00:00 2001 From: Marten Richter Date: Sat, 13 Apr 2013 14:27:30 +0200 Subject: [PATCH] Fix first frame omx handling, also only enable and disable, if the status actually changes --- videoomx.cc | 194 +++++++++++++++++++++++++++++++++++++++------------- videoomx.h | 2 +- 2 files changed, 147 insertions(+), 49 deletions(-) diff --git a/videoomx.cc b/videoomx.cc index 085441e..7a56cc0 100644 --- a/videoomx.cc +++ b/videoomx.cc @@ -1585,17 +1585,34 @@ int VideoOMX::ChangeComponentState(OMX_HANDLETYPE handle,OMX_STATETYPE type) //n int VideoOMX::EnablePort(OMX_HANDLETYPE handle,OMX_U32 port,bool wait) //needs to be called with locked mutex { OMX_ERRORTYPE error; - error=OMX_SendCommand(handle,OMX_CommandPortEnable,port,0); - if (error!=OMX_ErrorNone){ - Log::getInstance()->log("Video", Log::DEBUG, "handle %x Send Command to enable port %x %x",handle,port, error); - return 0; - } + bool skip=false; + + OMX_PARAM_PORTDEFINITIONTYPE pdt; + memset(&pdt,0,sizeof(pdt)); + pdt.nSize=sizeof(pdt); + pdt.nVersion.nVersion=OMX_VERSION; + pdt.nPortIndex=port; + error=OMX_GetParameter(handle,OMX_IndexParamPortDefinition, &pdt); + if (error==OMX_ErrorNone) { + if(pdt.bEnabled==OMX_TRUE) { + skip=true; //already disabled; + } - if (!wait) return 1; - if (!CommandFinished(handle,OMX_CommandPortEnable,port)) { - return 0; } + if (!skip) { + error=OMX_SendCommand(handle,OMX_CommandPortEnable,port,0); + if (error!=OMX_ErrorNone){ + Log::getInstance()->log("Video", Log::DEBUG, "handle %x Send Command to enable port %x %x",handle,port, error); + return 0; + } + + if (!wait) return 1; + if (!CommandFinished(handle,OMX_CommandPortEnable,port)) { + return 0; + } + + } return 1; } @@ -1603,25 +1620,43 @@ int VideoOMX::EnablePort(OMX_HANDLETYPE handle,OMX_U32 port,bool wait) //needs t int VideoOMX::DisablePort(OMX_HANDLETYPE handle,OMX_U32 port,bool wait) //needs to be called with locked mutex { OMX_ERRORTYPE error; - error=OMX_SendCommand(handle,OMX_CommandPortDisable,port,0); - if (error!=OMX_ErrorNone){ - Log::getInstance()->log("Video", Log::DEBUG, "handle %x Send Command to disable port %x %x",handle,port, error); - return 0; - } + bool skip=false; + + OMX_PARAM_PORTDEFINITIONTYPE pdt; + memset(&pdt,0,sizeof(pdt)); + pdt.nSize=sizeof(pdt); + pdt.nVersion.nVersion=OMX_VERSION; + pdt.nPortIndex=port; + error=OMX_GetParameter(handle,OMX_IndexParamPortDefinition, &pdt); + if (error==OMX_ErrorNone) { + if(pdt.bEnabled==OMX_FALSE) { + skip=true; //already disabled; + } - if (!wait) return 1; - if (!CommandFinished(handle,OMX_CommandPortDisable,port)) { - return 0; } + if (!skip) { + error=OMX_SendCommand(handle,OMX_CommandPortDisable,port,0); + if (error!=OMX_ErrorNone){ + Log::getInstance()->log("Video", Log::DEBUG, "handle %x Send Command to disable port %x %x",handle,port, error); + return 0; + } + + if (!wait) return 1; + if (!CommandFinished(handle,OMX_CommandPortDisable,port)) { + return 0; + } + } + return 1; } -int VideoOMX::WaitForEvent(OMX_HANDLETYPE handle,OMX_U32 event) //needs to be called with locked mutex +int VideoOMX::WaitForEvent(OMX_HANDLETYPE handle,OMX_U32 event, int wait) //needs to be called with locked mutex { int i=0; - while (i<1000) { + int iend=wait+1; + while (i::iterator itty=omx_events.begin(); while (itty!=omx_events.end()) { @@ -2398,33 +2433,69 @@ void VideoOMX::FirstFrameFix() pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldcancelstate); pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, &oldcanceltype); clock_mutex.Lock(); - OMX_ERRORTYPE error; - OMX_PARAM_PORTDEFINITIONTYPE port_def_type; - memset(&port_def_type,0,sizeof(port_def_type)); - port_def_type.nSize=sizeof(port_def_type); - port_def_type.nVersion.nVersion=OMX_VERSION; - port_def_type.nPortIndex=omx_codec_output_port; + if (WaitForEvent(omx_vid_dec,OMX_EventPortSettingsChanged,0)){ + WaitForEvent(omx_vid_deint,OMX_EventPortSettingsChanged,0); //clear old messages + OMX_ERRORTYPE error; + OMX_PARAM_PORTDEFINITIONTYPE port_def_type; + memset(&port_def_type,0,sizeof(port_def_type)); + port_def_type.nSize=sizeof(port_def_type); + port_def_type.nVersion.nVersion=OMX_VERSION; + port_def_type.nPortIndex=omx_codec_output_port; - error=OMX_GetParameter(omx_vid_dec,OMX_IndexParamPortDefinition, &port_def_type); - if (error != OMX_ErrorNone) { - Log::getInstance()->log("Video", Log::DEBUG, - "OMX_IndexParamPortDefinition fix failed %x", error); - clock_mutex.Unlock(); - return; - } + error=OMX_GetParameter(omx_vid_dec,OMX_IndexParamPortDefinition, &port_def_type); + if (error != OMX_ErrorNone) { + Log::getInstance()->log("Video", Log::DEBUG, + "OMX_IndexParamPortDefinition fix failed %x", error); + clock_mutex.Unlock(); + return; + } - if (port_def_type.format.video.nFrameWidth == demux->getHorizontalSize() - && port_def_type.format.video.nFrameHeight == demux->getVerticalSize()){ + + Log::getInstance()->log("Video", Log::DEBUG, + "Deinit first frame fix %d %d %d %d %d %d %d %d",port_def_type.format.video.nFrameWidth , demux->getHorizontalSize(), + port_def_type.format.video.nFrameHeight , demux->getVerticalSize(),port_def_type.format.video.nStride, + port_def_type.format.video.nSliceHeight, port_def_type.format.video.xFramerate, + port_def_type.format.video.bFlagErrorConcealment ); Log::getInstance()->log("Video", Log::DEBUG, - "Deinit first frame fix"); + "Deinit first frame fix2 %d %d", + port_def_type.format.video.eCompressionFormat , + port_def_type.format.video.eColorFormat ); first_frame=false; - WaitForEvent(omx_vid_dec,OMX_EventPortSettingsChanged); - DisablePort(omx_vid_dec,omx_codec_output_port,false); - DisablePort(omx_vid_sched,omx_shed_input_port,false); + // we cause the video_decode to determine the interlacing properties + OMX_CONFIG_INTERLACETYPE il; + memset(&il,0,sizeof(il)); + il.nSize=sizeof(il); + il.nVersion.nVersion=OMX_VERSION; + il.nPortIndex=omx_codec_output_port; + error=OMX_GetConfig(omx_vid_dec,OMX_IndexConfigCommonInterlace, &il); + if (error != OMX_ErrorNone) { + Log::getInstance()->log("Video", Log::DEBUG, + "OMX_IndexConfigCommonInterlace fix failed %x", error); + } + + + DisablePort(omx_vid_dec,omx_codec_output_port,true); + DisablePort(omx_vid_sched,omx_shed_input_port,true); if (dodeint) { - DisablePort(omx_vid_deint,omx_deint_output_port,false); - DisablePort(omx_vid_deint,omx_deint_input_port,false); + + DisablePort(omx_vid_deint,omx_deint_input_port,true); + // This is a dirty hack + DisablePort(omx_vid_deint,omx_deint_output_port,true); + + + port_def_type.nPortIndex=omx_deint_output_port; + error = OMX_SetParameter(omx_vid_deint, OMX_IndexParamPortDefinition, + &port_def_type); + if (error != OMX_ErrorNone) { + Log::getInstance()->log("Video", Log::DEBUG, + "Set OMX_IndexParamPortDefinition1 failed %x", error); + clock_mutex.Unlock(); + pthread_setcancelstate(oldcancelstate, NULL); + pthread_setcanceltype(oldcanceltype, NULL); + return; + } + // dirty hack end port_def_type.nPortIndex=omx_deint_input_port; @@ -2438,27 +2509,54 @@ void VideoOMX::FirstFrameFix() pthread_setcanceltype(oldcanceltype, NULL); return; } + // WaitForEvent(omx_vid_dec,OMX_EventPortSettingsChanged); + Log::getInstance()->log("Video", Log::DEBUG, + "Marker"); + EnablePort(omx_vid_deint,omx_deint_input_port,true); + WaitForEvent(omx_vid_deint,OMX_EventPortSettingsChanged); port_def_type.nPortIndex=omx_deint_output_port; - error = OMX_SetParameter(omx_vid_deint, OMX_IndexParamPortDefinition, + error = OMX_GetParameter(omx_vid_deint, OMX_IndexParamPortDefinition, &port_def_type); if (error != OMX_ErrorNone) { Log::getInstance()->log("Video", Log::DEBUG, - "Set OMX_IndexParamPortDefinition2 failed %x", error); + "Get OMX_IndexParamPortDefinition2 failed %x", error); clock_mutex.Unlock(); pthread_setcancelstate(oldcancelstate, NULL); pthread_setcanceltype(oldcanceltype, NULL); return; } + Log::getInstance()->log("Video", Log::DEBUG, + "Deinit first frame fix3 %d %d %d %d %d %d %d %d",port_def_type.format.video.nFrameWidth , demux->getHorizontalSize(), + port_def_type.format.video.nFrameHeight , demux->getVerticalSize(),port_def_type.format.video.nStride, + port_def_type.format.video.nSliceHeight, port_def_type.format.video.xFramerate, + port_def_type.format.video.bFlagErrorConcealment ); + Log::getInstance()->log("Video", Log::DEBUG, + "Deinit first frame fix4 %d %d", + port_def_type.format.video.eCompressionFormat , + port_def_type.format.video.eColorFormat ); + DisablePort(omx_vid_deint,omx_deint_output_port,true); + + } + port_def_type.nPortIndex=omx_shed_input_port; + error = OMX_SetParameter(omx_vid_sched, OMX_IndexParamPortDefinition, + &port_def_type); + if (error != OMX_ErrorNone) { + Log::getInstance()->log("Video", Log::DEBUG, + "Set OMX_IndexParamPortDefinition3 failed %x", error); + clock_mutex.Unlock(); + pthread_setcancelstate(oldcancelstate, NULL); + pthread_setcanceltype(oldcanceltype, NULL); + return; } + WaitForEvent(omx_vid_sched,OMX_EventPortSettingsChanged); - EnablePort(omx_vid_dec,omx_codec_output_port,false); if (dodeint) { - EnablePort(omx_vid_deint,omx_deint_input_port,false); - EnablePort(omx_vid_deint,omx_deint_output_port,false); + EnablePort(omx_vid_deint,omx_deint_output_port,true); } - EnablePort(omx_vid_sched,omx_shed_input_port,false); + EnablePort(omx_vid_dec,omx_codec_output_port,true); + EnablePort(omx_vid_sched,omx_shed_input_port,true); } clock_mutex.Unlock(); pthread_setcancelstate(oldcancelstate, NULL); @@ -2575,13 +2673,13 @@ bool VideoOMX::DrainTargetBufferFull() void VideoOMX::PrepareMediaSample(const MediaPacketList& mplist,UINT samplepos) { - + mediapackets.clear(); list::const_iterator begin=mplist.begin(); list::const_iterator itty=mplist.begin(); advance(itty,min(mplist.size(),10)); mediapackets.insert(mediapackets.begin(),begin,itty);//front - + } UINT VideoOMX::DeliverMediaSample(UCHAR* buffer, UINT *samplepos) @@ -2896,7 +2994,7 @@ bool VideoOMX::displayIFrame(const UCHAR* buffer, UINT length) { } cur_input_buf_omx->nTimeStamp = intToOMXTicks(0); - + PutBufferToPres(cur_input_buf_omx); cur_input_buf_omx = NULL; diff --git a/videoomx.h b/videoomx.h index 602bc47..400b084 100644 --- a/videoomx.h +++ b/videoomx.h @@ -202,7 +202,7 @@ class VideoOMX : public Video int ChangeComponentState(OMX_HANDLETYPE handle,OMX_STATETYPE type); int CommandFinished(OMX_HANDLETYPE handle,OMX_U32 command,OMX_U32 data2); - int WaitForEvent(OMX_HANDLETYPE handle,OMX_U32 event); + int WaitForEvent(OMX_HANDLETYPE handle,OMX_U32 event,int wait=1000); int EnablePort(OMX_HANDLETYPE handle,OMX_U32 port,bool wait); int DisablePort(OMX_HANDLETYPE handle,OMX_U32 port,bool wait=true); int clearEvents(); -- 2.39.2