Fix first frame omx handling, also only enable and disable, if the status actually...
authorMarten Richter <marten.richter@freenet.de>
Sat, 13 Apr 2013 12:27:30 +0000 (14:27 +0200)
committerMarten Richter <marten.richter@freenet.de>
Sat, 13 Apr 2013 12:27:30 +0000 (14:27 +0200)
videoomx.cc
videoomx.h

index 085441e80428c5731509c4a9535f7a3a9b24b211..7a56cc06025db322e975d9d17dae17f340b93782 100644 (file)
@@ -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<iend) {
                omx_event_mutex.Lock();
                list<VPE_OMX_EVENT>::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<MediaPacket>::const_iterator begin=mplist.begin();
        list<MediaPacket>::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;
 
index 602bc47121f8b672fe161df1f255639790017a99..400b084edd40d510de3c046164438691a810ad03 100644 (file)
@@ -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();