]> git.vomp.tv Git - vompclient-marten.git/commitdiff
Add deinterlacing for SD + enhance performance of consuming media packets
authorMarten Richter <marten.richter@freenet.de>
Sun, 9 Sep 2012 20:41:46 +0000 (22:41 +0200)
committerMarten Richter <marten.richter@freenet.de>
Sun, 9 Sep 2012 20:41:46 +0000 (22:41 +0200)
boxx.cc
video.h
videoomx.cc
videoomx.h
videowin.h

diff --git a/boxx.cc b/boxx.cc
index 1e31c139a97beccfbfeb687cb222c28aa22d5d9f..e10d2ad9c21424c559feab8a1bd27687045b3f2a 100644 (file)
--- a/boxx.cc
+++ b/boxx.cc
@@ -144,15 +144,15 @@ void Boxx::blt(Region& r)
   destination x on screen\r
   destination y on screen\r
   */\r
-         Log::getInstance()->log("Boxx", Log::DEBUG, "blt mark 1");\r
+\r
   if (parent) abort(); // if (parent) then this is a child boxx. It can not blt.\r
-  Log::getInstance()->log("Boxx", Log::DEBUG, "blt mark 2");\r
+\r
   // this shouldn't be here\r
   r.x -= area.x;\r
   r.y -= area.y;\r
-  Log::getInstance()->log("Boxx", Log::DEBUG, "blt mark 3");\r
+\r
   surface->updateToScreen(r.x, r.y, r.w, r.h, area.x + r.x, area.y + r.y);\r
-  Log::getInstance()->log("Boxx", Log::DEBUG, "blt mark 4");\r
+\r
 }\r
 \r
 int Boxx::getScreenX()\r
diff --git a/video.h b/video.h
index e09d0176debed9b50e73ae863a471ddff2cde238..2980d2c346fef178cdc9aa445161aec4c1b603a1 100644 (file)
--- a/video.h
+++ b/video.h
@@ -45,6 +45,7 @@ class Video: public DrainTarget, public AbstractOption
     virtual int init(UCHAR format)=0;\r
     virtual int shutdown()=0;\r
     virtual int setFormat(UCHAR format)=0;\r
+    virtual UCHAR getSupportedFormats() { return COMPOSITERGB | SVIDEO;}; // if it returns zero there are no different formats\r
     virtual int setConnection(UCHAR connection)=0;\r
     virtual int setAspectRatio(UCHAR aspectRatio)=0;   // This one does the pin 8 scart widescreen switching\r
     virtual int setMode(UCHAR mode)=0;\r
@@ -112,6 +113,8 @@ class Video: public DrainTarget, public AbstractOption
     // Video connections - AV_SET_VID_OUTPUT\r
     const static UCHAR COMPOSITERGB = 1;\r
     const static UCHAR SVIDEO = 2;\r
+    const static UCHAR HDMI = 4;\r
+    const static UCHAR HDMI3D = 16; //For future use\r
 \r
     // Video aspect ratios - AV_SET_VID_RATIO\r
     const static UCHAR ASPECT4X3 = 0;\r
index 56e35e3e40dfb0890bd25798d9dfcd1a331e8972..7bda5c7a42506e7bf4c40ac2150d89d20848af23 100644 (file)
@@ -23,6 +23,8 @@
 #include "mtdraspberry.h"
 #include "demuxer.h"
 #include "osdopengl.h"
+#include "vdr.h"
+#include "woptionpane.h"
 
 // temp
 #include "log.h"
@@ -50,6 +52,7 @@ VideoOMX::VideoOMX() {
 
        mode=NORMAL;
        xpos=ypos=0.f;
+       deinterlace=2; //advanced
 
 }
 
@@ -144,7 +147,7 @@ OMX_ERRORTYPE VideoOMX::EmptyBufferDone_OMX(OMX_IN OMX_HANDLETYPE hcomp,OMX_IN O
 
 void VideoOMX::ReturnEmptyOMXBuffer(OMX_BUFFERHEADERTYPE* buffer){
        input_bufs_omx_mutex.Lock();
-//     Log::getInstance()->log("Video", Log::NOTICE, "ReturnEmptyOMXBuffer %d %d %d",input_bufs_omx_free.size(),input_bufs_omx_present.size(),input_bufs_omx_all.size());
+       //Log::getInstance()->log("Video", Log::NOTICE, "ReturnEmptyOMXBuffer %d %d %d",input_bufs_omx_free.size(),input_bufs_omx_present.size(),input_bufs_omx_all.size());
        input_bufs_omx_free.push_back(buffer);
        //Log::getInstance()->log("Video", Log::NOTICE, "ReturnEmptyOMXBuffer %d",input_bufs_omx_free.size());
        input_bufs_omx_mutex.Unlock();
@@ -168,6 +171,100 @@ int VideoOMX::shutdown()
 }
 
 
+
+bool VideoOMX::loadOptionsfromServer(VDR* vdr)
+{
+       Log::getInstance()->log("Video", Log::DEBUG, "VideoOMX config load");
+    char *name=vdr->configLoad("VideoOMX","SDDeinterlacing");
+
+    if (name != NULL) {
+               if (STRCASECMP(name, "None") == 0) {
+                       deinterlace = 0;
+               }/* else if (STRCASECMP(name, "LineDouble") == 0) {
+                       deinterlace = 1;
+               }*/ else if (STRCASECMP(name, "Advanced") == 0) {
+                       deinterlace = 2;
+               } /*else if (STRCASECMP(name, "Crazy") == 0) {
+                       deinterlace = 3; // this does not activate deinterlacing but a image filter, just for fun
+               }*/
+               Log::getInstance()->log("Video", Log::DEBUG, "Set deinterlacing to %s %d",name,deinterlace);
+       }
+
+   return true;
+
+}
+
+bool VideoOMX::handleOptionChanges(Option* option)
+{
+    if (Video::handleOptionChanges(option))
+               return true;
+       switch (option->id) {
+       case 1: {
+               if (STRCASECMP(option->options[option->userSetChoice], "None") == 0) {
+                       deinterlace = 0;
+               } /*else if (STRCASECMP(option->options[option->userSetChoice], "LineDouble")
+                               == 0) {
+                       deinterlace = 1;
+               }*/ else if (STRCASECMP(option->options[option->userSetChoice], "Advanced")
+                               == 0) {
+                       deinterlace = 2;
+               } /*else if (STRCASECMP(option->options[option->userSetChoice], "Crazy")
+                               == 0) {
+                       deinterlace = 3;
+               }*/
+               Log::getInstance()->log("Video", Log::DEBUG, "Set deinterlacing to %s %d",option->options[option->userSetChoice],deinterlace);
+               return true;
+       }
+       break;
+       };
+       return false;
+
+}
+
+bool VideoOMX::saveOptionstoServer()
+{
+
+    switch (deinterlace) {
+       case 0:
+               VDR::getInstance()->configSave("VideoOMX","SDDeinterlacing", "None");
+               break;
+       /*case 1:
+               VDR::getInstance()->configSave("VideoOMX","SDDeinterlacing", "LineDouble");
+               break;*/
+       case 2:
+               VDR::getInstance()->configSave("VideoOMX","SDDeinterlacing", "Advanced");
+               break;
+       /*case 3:
+               VDR::getInstance()->configSave("VideoOMX","SDDeinterlacing", "Crazy");
+               break;*/
+       };
+
+    return true;
+}
+
+/*Option(UINT id, const char* displayText, const char* configSection, const char* configKey, UINT optionType,
+           UINT numChoices, UINT defaultChoice, UINT startInt,
+           const char * const * options, const char * const * optionkeys = NULL, AbstractOption* handler=NULL);*/
+
+bool VideoOMX::addOptionsToPanes(int panenumber,Options *options,WOptionPane* pane)
+{
+    if (!Video::addOptionsToPanes(panenumber,options,pane)) return false;
+
+
+    Option* option;
+    if (panenumber == 2)
+    {
+       static const char* deinterlaceopts[]={"None",/*"LineDouble",*/"Advanced"/*,"Crazy"*/};
+       option = new Option(1,tr("SD Deinterlacing"), "VideoOMX","SDDeinterlacing",Option::TYPE_TEXT,/*4,2*/2,1,0,deinterlaceopts,NULL,false,this);
+       options->push_back(option);
+       pane->addOptionLine(option);
+    }
+
+    return true;
+}
+
+
+
 int VideoOMX::setTVsize(UCHAR ttvsize)
 {
 /*  tvsize = ttvsize;
@@ -623,14 +720,26 @@ int VideoOMX::AllocateCodecsOMX()
        OMX_ERRORTYPE error;
        static OMX_CALLBACKTYPE callbacks= {&EventHandler_OMX,&EmptyBufferDone_OMX,&FillBufferDone_OMX};
 
+       Demuxer* demux=Demuxer::getInstance();
+
+       dodeint=false;
+
        Log::getInstance()->log("Video", Log::NOTICE, "Allocate Codecs OMX");
        //Clock, move later to audio including events
 
-       Log::getInstance()->log("Video", Log::DEBUG, "Nmark1 ");
+       if (deinterlace!=0 && demux->getHorizontalSize()<=720) { //only deinterlace SD material
+               dodeint=true;
+               deint_first_frame=true;
+
+               Log::getInstance()->log("Video", Log::NOTICE, "Deinterlacing activated %d",deinterlace);
+
+       }
+
+
        if (!getClockVideoandInit()){
                return 0;// get the clock and init it if necessary
        }
-       Log::getInstance()->log("Video", Log::DEBUG, "Nmark2 ");
+
 
        if (!idleClock()) {
                Log::getInstance()->log("Video", Log::DEBUG, "idleClock failed");
@@ -692,6 +801,41 @@ int VideoOMX::AllocateCodecsOMX()
                return 0;
        }
 
+       if (dodeint) {
+               error = OMX_GetHandle(&omx_vid_deint, VPE_OMX_VIDEO_DEINTERLACE, NULL,
+                               &callbacks);
+               if (error != OMX_ErrorNone) {
+                       Log::getInstance()->log("Video", Log::DEBUG,
+                                       "Init OMX video deinterlacer failed %x", error);
+                       clock_mutex.Unlock();
+                       DeAllocateCodecsOMX();
+                       return 0;
+               }
+
+               error = OMX_GetParameter(omx_vid_deint, OMX_IndexParamImageInit,
+                               &p_param);
+               if (error != OMX_ErrorNone) {
+                       Log::getInstance()->log("Video", Log::DEBUG,
+                                       "Init OMX video deinterlacer OMX_GetParameter failed %x",
+                                       error);
+                       clock_mutex.Unlock();
+                       DeAllocateCodecsOMX();
+                       return 0;
+               }
+               omx_deint_input_port = p_param.nStartPortNumber;
+               omx_deint_output_port = p_param.nStartPortNumber + 1;
+
+               if (!DisablePort(omx_vid_deint, omx_deint_input_port, true)
+                               || !DisablePort(omx_vid_deint, omx_deint_output_port, true)) {
+                       Log::getInstance()->log("Video", Log::DEBUG,
+                                       "Disable Ports OMX video deint failed");
+                       clock_mutex.Unlock();
+                       DeAllocateCodecsOMX();
+                       return 0;
+               }
+
+       }
+
 
        error=OMX_GetHandle(&omx_vid_sched,VPE_OMX_VIDEO_SCHED,NULL,&callbacks);
        if (error!=OMX_ErrorNone){
@@ -832,7 +976,7 @@ int VideoOMX::AllocateCodecsOMX()
                ft_type.eCompressionFormat=OMX_VIDEO_CodingMPEG2;
        }
 
-       Demuxer* demux=Demuxer::getInstance();
+
 
     ft_type.xFramerate=0;//25*(1<<16);//demux->getFrameRate()*(1<<16);
     Log::getInstance()->log("Video", Log::DEBUG, "Framerate: %d",demux->getFrameRate());
@@ -859,29 +1003,113 @@ int VideoOMX::AllocateCodecsOMX()
                return 0;
        }
 
+       if (!dodeint) {
+               error=OMX_SetupTunnel(omx_vid_dec,omx_codec_output_port,omx_vid_sched,omx_shed_input_port);
+               if (error!=OMX_ErrorNone){
+                       Log::getInstance()->log("Video", Log::DEBUG, "OMX_Setup tunnel dec to sched failed %x", error);
+                       clock_mutex.Unlock();
+                       DeAllocateCodecsOMX();
+                       return 0;
+               }
 
-       error=OMX_SetupTunnel(omx_vid_dec,omx_codec_output_port,omx_vid_sched,omx_shed_input_port);
-       if (error!=OMX_ErrorNone){
-               Log::getInstance()->log("Video", Log::DEBUG, "OMX_Setup tunnel dec to sched failed %x", error);
-               clock_mutex.Unlock();
-               DeAllocateCodecsOMX();
-               return 0;
-       }
 
 
+               if (!EnablePort(omx_vid_dec,omx_codec_output_port,false) || !EnablePort(omx_vid_sched,omx_shed_input_port,false)
+               ) {
+                       Log::getInstance()->log("Video", Log::DEBUG, "Enable Ports OMX codec shed failed");
+                       clock_mutex.Unlock();
+                       DeAllocateCodecsOMX();
+                       return 0;
+               }
 
-       if (!EnablePort(omx_vid_dec,omx_codec_output_port,false) || !EnablePort(omx_vid_sched,omx_shed_input_port,false)
-                                               ) {
-               Log::getInstance()->log("Video", Log::DEBUG, "Enable Ports OMX codec shed failed");
-               clock_mutex.Unlock();
-               DeAllocateCodecsOMX();
-               return 0;
-       }
+               if ( !CommandFinished(omx_vid_dec,OMX_CommandPortEnable,omx_codec_output_port) || !CommandFinished(omx_vid_sched,OMX_CommandPortEnable,omx_shed_input_port)) {
+                       clock_mutex.Unlock();
+                       DeAllocateCodecsOMX();
+                       return 0;
+               }
+
+       } else {
+
+               error=OMX_SetupTunnel(omx_vid_dec,omx_codec_output_port,omx_vid_deint,omx_deint_input_port);
+               if (error!=OMX_ErrorNone){
+                       Log::getInstance()->log("Video", Log::DEBUG, "OMX_Setup tunnel dec to deint failed %x", error);
+                       clock_mutex.Unlock();
+                       DeAllocateCodecsOMX();
+                       return 0;
+               }
+
+
+
+               if (!EnablePort(omx_vid_dec,omx_codec_output_port,false) || !EnablePort(omx_vid_deint,omx_deint_input_port,false)
+               ) {
+                       Log::getInstance()->log("Video", Log::DEBUG, "Enable Ports OMX codec deint failed");
+                       clock_mutex.Unlock();
+                       DeAllocateCodecsOMX();
+                       return 0;
+               }
+
+               if ( !CommandFinished(omx_vid_dec,OMX_CommandPortEnable,omx_codec_output_port) || !CommandFinished(omx_vid_deint,OMX_CommandPortEnable,omx_deint_input_port)) {
+                       clock_mutex.Unlock();
+                       DeAllocateCodecsOMX();
+                       return 0;
+               }
+
+               if (!ChangeComponentState(omx_vid_deint,OMX_StateIdle)) {
+                       Log::getInstance()->log("Video", Log::DEBUG, "vid_deint ChangeComponentState");
+                       clock_mutex.Unlock();
+                       DeAllocateCodecsOMX();
+                       return 0;
+               }
+
+               OMX_CONFIG_IMAGEFILTERPARAMSTYPE imagefilter;
+               memset(&imagefilter,0,sizeof(imagefilter));
+               imagefilter.nSize=sizeof(imagefilter);
+               imagefilter.nVersion.nVersion=OMX_VERSION;
+
+               imagefilter.nPortIndex=omx_deint_output_port;
+               imagefilter.nNumParams=1;
+               imagefilter.nParams[0]=3;//???
+               switch (deinterlace) {
+               case 1:
+                       imagefilter.eImageFilter=OMX_ImageFilterDeInterlaceLineDouble; break;
+               case 2:
+                       imagefilter.eImageFilter=OMX_ImageFilterDeInterlaceAdvanced; break;
+               case 3:
+                       imagefilter.eImageFilter=OMX_ImageFilterFilm; break;
+               }
+
+
+               error=OMX_SetConfig(omx_vid_deint,OMX_IndexConfigCommonImageFilterParameters,&imagefilter);
+               if (error!=OMX_ErrorNone){
+                       Log::getInstance()->log("Video", Log::DEBUG, "Init OMX_IndexConfigCommonImageFilterParameters failed %x", error);
+                       clock_mutex.Unlock();
+                       DeAllocateCodecsOMX();
+                       return 0;
+               }
+
+
+               error=OMX_SetupTunnel(omx_vid_deint,omx_deint_output_port,omx_vid_sched,omx_shed_input_port);
+               if (error!=OMX_ErrorNone){
+                       Log::getInstance()->log("Video", Log::DEBUG, "OMX_Setup tunnel deint to sched failed %x", error);
+                       clock_mutex.Unlock();
+                       DeAllocateCodecsOMX();
+                       return 0;
+               }
+
+               if (!EnablePort(omx_vid_deint,omx_deint_output_port,false) || !EnablePort(omx_vid_sched,omx_shed_input_port,false)
+               ) {
+                       Log::getInstance()->log("Video", Log::DEBUG, "Enable Ports OMX deint shed failed");
+                       clock_mutex.Unlock();
+                       DeAllocateCodecsOMX();
+                       return 0;
+               }
+
+               if ( !CommandFinished(omx_vid_deint,OMX_CommandPortEnable,omx_deint_output_port) || !CommandFinished(omx_vid_sched,OMX_CommandPortEnable,omx_shed_input_port)) {
+                       clock_mutex.Unlock();
+                       DeAllocateCodecsOMX();
+                       return 0;
+               }
 
-       if ( !CommandFinished(omx_vid_dec,OMX_CommandPortEnable,omx_codec_output_port) || !CommandFinished(omx_vid_sched,OMX_CommandPortEnable,omx_shed_input_port)) {
-               clock_mutex.Unlock();
-               DeAllocateCodecsOMX();
-               return 0;
        }
 
        if (!ChangeComponentState(omx_vid_dec,OMX_StateExecuting)) {
@@ -921,6 +1149,16 @@ int VideoOMX::AllocateCodecsOMX()
                return 0;
        }
 
+       if (dodeint) {
+               if (!ChangeComponentState(omx_vid_deint,OMX_StateExecuting)) {
+                       Log::getInstance()->log("Video", Log::DEBUG, "vid_vid_deint ChangeComponentState");
+                       clock_mutex.Unlock();
+                       DeAllocateCodecsOMX();
+                       return 0;
+               }
+               DisablePort(omx_vid_deint,omx_deint_output_port,false);
+               DisablePort(omx_vid_deint,omx_deint_input_port,false);
+       }
 
        if (!ChangeComponentState(omx_vid_sched,OMX_StateExecuting)) {
                Log::getInstance()->log("Video", Log::DEBUG, "omx_vid_sched ChangeComponentState Execute");
@@ -1100,7 +1338,41 @@ int VideoOMX::DisablePort(OMX_HANDLETYPE handle,OMX_U32 port,bool wait) //needs
        return 1;
 }
 
+int VideoOMX::WaitForEvent(OMX_HANDLETYPE handle,OMX_U32 event) //needs to be called with locked mutex
+{
+       int i=0;
+       while (i<1000) {
+               omx_event_mutex.Lock();
+               list<VPE_OMX_EVENT>::iterator itty=omx_events.begin();
+               while (itty!=omx_events.end()) {
+
+                       VPE_OMX_EVENT current=*itty;
+                       if (current.handle==handle) { //this is ours
+                               if (current.event_type==OMX_EventError) {
+                                       omx_events.erase(itty);
+                                       omx_event_mutex.Unlock();
+                                       Log::getInstance()->log("Video", Log::DEBUG, "WaitForEvent Finished on Error");
+                                       return 0;
 
+                               } else if (current.event_type==event) {
+                                       omx_events.erase(itty);
+                                       omx_event_mutex.Unlock();
+                                       Log::getInstance()->log("Video", Log::DEBUG, "WaitForEvent Finished Completed");
+                                       return 1;
+                               }
+                       }
+                       itty++;
+
+               }
+               omx_event_mutex.Unlock();
+               MILLISLEEP(2);
+               i++;
+
+       }
+       Log::getInstance()->log("Video", Log::DEBUG, "WaitForEvent waited too long %x %x",handle,event);
+       return 0;
+
+}
 
 
 int VideoOMX::CommandFinished(OMX_HANDLETYPE handle,OMX_U32 command,OMX_U32 data2) //needs to be called with locked mutex
@@ -1234,6 +1506,7 @@ int VideoOMX::DestroyInputBufsOMX() //need s to be called with locked mutex
        input_bufs_omx_free.clear();
        input_bufs_omx_present.clear();
        input_time_present.clear();
+       input_is_last.clear();
        input_bufs_omx_mutex.Unlock();
 
 }
@@ -1270,6 +1543,14 @@ int VideoOMX::DeAllocateCodecsOMX()
                idleClock();
                clock_mutex.Lock();
 
+               if (dodeint) {
+                       if (!ChangeComponentState(omx_vid_deint, OMX_StateIdle)) {
+                               Log::getInstance()->log("Video", Log::DEBUG,
+                                               "vid_deint ChangeComponentState");
+
+                       }
+               }
+
 
                if (!ChangeComponentState(omx_vid_sched,OMX_StateIdle)) {
                        Log::getInstance()->log("Video", Log::DEBUG, "vid_shed ChangeComponentState");
@@ -1286,33 +1567,95 @@ int VideoOMX::DeAllocateCodecsOMX()
         // TODO proper deinit sequence
                // first flush all buffers
 
+               if (!dodeint) {
 
-               error = OMX_SendCommand(omx_vid_dec, OMX_CommandFlush,
-                               omx_codec_output_port, NULL);
-               if (error != OMX_ErrorNone) {
-                       Log::getInstance()->log("Video", Log::DEBUG,
-                                       "OMX_Flush codec out failed %x", error);
+                       error = OMX_SendCommand(omx_vid_dec, OMX_CommandFlush,
+                                       omx_codec_output_port, NULL);
+                       if (error != OMX_ErrorNone) {
+                               Log::getInstance()->log("Video", Log::DEBUG,
+                                               "OMX_Flush codec out failed %x", error);
 
-               }
+                       }
 
-               error = OMX_SendCommand(omx_vid_sched, OMX_CommandFlush,
-                               omx_shed_input_port, NULL);
-               if (error != OMX_ErrorNone) {
-                       Log::getInstance()->log("Video", Log::DEBUG,
-                                       "OMX_Flush shed in failed %x", error);
+                       error = OMX_SendCommand(omx_vid_sched, OMX_CommandFlush,
+                                       omx_shed_input_port, NULL);
+                       if (error != OMX_ErrorNone) {
+                               Log::getInstance()->log("Video", Log::DEBUG,
+                                               "OMX_Flush shed in failed %x", error);
+
+                       }
+
+                       if (!CommandFinished(omx_vid_dec, OMX_CommandFlush,
+                                       omx_codec_output_port)) {
+                               Log::getInstance()->log("Video", Log::DEBUG,
+                                               "flush cmd codec  failed");
+                       }
+
+                       if (!CommandFinished(omx_vid_sched, OMX_CommandFlush,
+                                       omx_shed_input_port)) {
+                               Log::getInstance()->log("Video", Log::DEBUG,
+                                               "flush cmd  shed failed");
+                       }
+               } else {
+                       error = OMX_SendCommand(omx_vid_dec, OMX_CommandFlush,
+                                       omx_codec_output_port, NULL);
+                       if (error != OMX_ErrorNone) {
+                               Log::getInstance()->log("Video", Log::DEBUG,
+                                               "OMX_Flush codec out failed %x", error);
+
+                       }
+
+                       error = OMX_SendCommand(omx_vid_deint, OMX_CommandFlush,
+                                       omx_deint_input_port, NULL);
+                       if (error != OMX_ErrorNone) {
+                               Log::getInstance()->log("Video", Log::DEBUG,
+                                               "OMX_Flush deint in failed %x", error);
+
+                       }
+
+                       if (!CommandFinished(omx_vid_dec, OMX_CommandFlush,
+                                       omx_codec_output_port)) {
+                               Log::getInstance()->log("Video", Log::DEBUG,
+                                               "flush cmd codec  failed");
+                       }
+
+                       if (!CommandFinished(omx_vid_deint, OMX_CommandFlush,
+                                       omx_deint_input_port)) {
+                               Log::getInstance()->log("Video", Log::DEBUG,
+                                               "flush cmd  deint failed");
+                       }
+
+                       //m
+                       error = OMX_SendCommand(omx_vid_deint, OMX_CommandFlush,
+                                       omx_deint_output_port, NULL);
+                       if (error != OMX_ErrorNone) {
+                               Log::getInstance()->log("Video", Log::DEBUG,
+                                               "OMX_Flush deint out failed %x", error);
+
+                       }
+
+                       error = OMX_SendCommand(omx_vid_sched, OMX_CommandFlush,
+                                       omx_shed_input_port, NULL);
+                       if (error != OMX_ErrorNone) {
+                               Log::getInstance()->log("Video", Log::DEBUG,
+                                               "OMX_Flush shed in failed %x", error);
+
+                       }
+
+                       if (!CommandFinished(omx_vid_deint, OMX_CommandFlush,
+                                       omx_deint_output_port)) {
+                               Log::getInstance()->log("Video", Log::DEBUG,
+                                               "flush cmd deint  failed");
+                       }
+
+                       if (!CommandFinished(omx_vid_sched, OMX_CommandFlush,
+                                       omx_shed_input_port)) {
+                               Log::getInstance()->log("Video", Log::DEBUG,
+                                               "flush cmd  shed failed");
+                       }
 
-               }
 
-               if (!CommandFinished(omx_vid_dec, OMX_CommandFlush,
-                               omx_codec_output_port)) {
-                       Log::getInstance()->log("Video", Log::DEBUG,
-                                       "flush cmd codec  failed");
-               }
 
-               if (!CommandFinished(omx_vid_sched, OMX_CommandFlush,
-                               omx_shed_input_port)) {
-                       Log::getInstance()->log("Video", Log::DEBUG,
-                                       "flush cmd  shed failed");
                }
 
 
@@ -1406,6 +1749,17 @@ int VideoOMX::DeAllocateCodecsOMX()
                        Log::getInstance()->log("Video", Log::DEBUG, "Disable Tunnel Port failed 7");
                }
 
+               if (dodeint) {
+                       if (!DisablePort(omx_vid_deint,omx_deint_output_port,true)) {
+                               Log::getInstance()->log("Video", Log::DEBUG, "Disable Tunnel Port failed 6a");
+                       }
+
+
+
+                       if (!DisablePort(omx_vid_deint,omx_deint_input_port,true)) {
+                               Log::getInstance()->log("Video", Log::DEBUG, "Disable Tunnel Port failed 7a");
+                       }
+               }
 
 
 
@@ -1430,6 +1784,19 @@ int VideoOMX::DeAllocateCodecsOMX()
 
                }
 
+               if (dodeint) {
+                       error=OMX_SetupTunnel(omx_vid_deint,omx_deint_input_port,NULL,NULL);
+                       if (error!=OMX_ErrorNone) {
+                               Log::getInstance()->log("Video", Log::DEBUG, "OMX_Setup tunnel teardown failed %x", error);
+                       }
+
+
+                       error=OMX_SetupTunnel(omx_vid_deint,omx_deint_output_port,NULL,NULL);
+                       if (error!=OMX_ErrorNone) {
+                               Log::getInstance()->log("Video", Log::DEBUG, "OMX_Setup tunnel teardown failed %x", error);
+                       }
+               }
+
                error=OMX_SetupTunnel(omx_vid_sched,omx_shed_input_port,NULL,NULL);
                if (error!=OMX_ErrorNone) {
                        Log::getInstance()->log("Video", Log::DEBUG, "OMX_Setup tunnel teardown failed %x", error);
@@ -1468,6 +1835,7 @@ int VideoOMX::DeAllocateCodecsOMX()
                error=OMX_FreeHandle(omx_vid_dec);
                error=OMX_FreeHandle(omx_vid_sched);
                error=OMX_FreeHandle(omx_vid_rend);
+               if (dodeint) error=OMX_FreeHandle(omx_vid_deint);
                omx_vid_dec=NULL;
                clock_mutex.Unlock();
                destroyClock();
@@ -1723,7 +2091,7 @@ bool VideoOMX::FrameSkip(long long pts)
                        skip=true; // we are too slow
                        skipping=true;
                /*      Log::getInstance()->log("Video", Log::DEBUG,
-                                                                                                               "Skipping frames1 %lld %lld",target_time-current_time,pts);
+                                                                                                               "Skipping frames1 %lld %lld %d",target_time-current_time,pts,Demuxer::getInstance()->getFrameRate());
                        Log::getInstance()->log("Video", Log::DEBUG, "skip detail pts: %lld target: %lld sys: %lld off: %lld diff %lld",pts,target_time,current_time,offset,
                                                target_time-current_time);*/
                }  else {
@@ -1733,7 +2101,7 @@ bool VideoOMX::FrameSkip(long long pts)
                if ((target_time - current_time) < 0000LL) { //skip a bit more
                        skip = true; // we are too slow
                        skipping = true;
-               /*      Log::getInstance()->log("Video", Log::DEBUG,"Skipping frames2 %lld %lld",target_time-current_time,pts);
+               /*      Log::getInstance()->log("Video", Log::DEBUG,"Skipping frames2 %lld %lld %d",target_time-current_time,pts,Demuxer::getInstance()->getFrameRate());
                        Log::getInstance()->log("Video", Log::DEBUG, "skip detail pts: %lld target: %lld sys: %lld off: %lld diff %lld",pts,target_time,current_time,offset,
                                                                        target_time-current_time);*/
                } else {
@@ -1792,14 +2160,17 @@ void VideoOMX::threadMethod()
 
                OMX_BUFFERHEADERTYPE* pict=NULL;
                long long time;
+               bool islast;
                if (!paused) {
                        input_bufs_omx_mutex.Lock();
                        if (input_bufs_omx_present.size()>0) {
 
                                pict=input_bufs_omx_present.front();
                                time=input_time_present.front();
+                               islast=input_is_last.front();
                                input_bufs_omx_present.pop_front();
                                input_time_present.pop_front();
+                               input_is_last.pop_front();
                        }
                        input_bufs_omx_mutex.Unlock();
                }
@@ -1807,7 +2178,7 @@ void VideoOMX::threadMethod()
                if ( pict) {
                        //Log::getInstance()->log("Video", Log::DEBUG,
                        //                                                                                      "Got pict");
-                       if (time!=0 &&FrameSkip(time) && !(pict->nFlags &OMX_BUFFERFLAG_STARTTIME)) {
+                       if (time!=0 && FrameSkip(time) && !(pict->nFlags &OMX_BUFFERFLAG_STARTTIME)) {
 
                                input_bufs_omx_mutex.Lock();
                                input_bufs_omx_free.push_back(pict);
@@ -1819,7 +2190,8 @@ void VideoOMX::threadMethod()
                                        Log::getInstance()->log("Video", Log::DEBUG,
                                                        "OMX_EmptyThisBuffer failed %x", error);
                                }
-                               if (time!=0) FrameWaitforDisplay(time);
+                               if (deint_first_frame && dodeint) DeinterlaceFix();
+                               if (islast) FrameWaitforDisplay(time);
                        }
                } else {
                        MILLISLEEP(5);
@@ -1831,11 +2203,76 @@ void VideoOMX::threadMethod()
                                                                                        "end thread");
 }
 
-void VideoOMX::PutBufferToPres(OMX_BUFFERHEADERTYPE* buffer, long long time)
+void VideoOMX::DeinterlaceFix()
+{
+
+       Demuxer* demux=Demuxer::getInstance();
+       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;
+
+       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");
+               deint_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);
+               DisablePort(omx_vid_deint,omx_deint_output_port,false);
+               DisablePort(omx_vid_deint,omx_deint_input_port,false);
+
+               port_def_type.nPortIndex=omx_deint_input_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();
+                       return;
+               }
+
+               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_IndexParamPortDefinition2 failed %x", error);
+                       clock_mutex.Unlock();
+                       return;
+               }
+
+
+               EnablePort(omx_vid_dec,omx_codec_output_port,false);
+               EnablePort(omx_vid_deint,omx_deint_input_port,false);
+               EnablePort(omx_vid_deint,omx_deint_output_port,false);
+               EnablePort(omx_vid_sched,omx_shed_input_port,false);
+       }
+       clock_mutex.Unlock();
+
+
+}
+
+
+void VideoOMX::PutBufferToPres(OMX_BUFFERHEADERTYPE* buffer, long long time,bool islast)
 {
        input_bufs_omx_mutex.Lock();
        input_bufs_omx_present.push_back(buffer);
        input_time_present.push_back(time);
+       input_is_last.push_back(islast);
        input_bufs_omx_mutex.Unlock();
 
 }
@@ -1860,17 +2297,27 @@ OMX_ERRORTYPE VideoOMX::ProtOMXEmptyThisBuffer(OMX_HANDLETYPE handle, OMX_BUFFER
 
 void VideoOMX::PrepareMediaSample(const MediaPacketList& mplist,UINT samplepos)
 {
-  mediapacket = mplist.front();
+  mediapackets.clear();
+  list<MediaPacket>::const_iterator begin=mplist.begin();
+  list<MediaPacket>::const_iterator itty=mplist.begin();
+  advance(itty,min(mplist.size(),50));
+  mediapackets.insert(mediapackets.begin(),begin,itty);//front
 }
 
 UINT VideoOMX::DeliverMediaSample(UCHAR* buffer, UINT *samplepos)
 {
-  DeliverMediaPacket(mediapacket, buffer, samplepos);
-  if (*samplepos == mediapacket.length) {
-    *samplepos = 0;
-    return 1;
-  }
-  else return 0;
+       int consumed=0;
+       while (mediapackets.size()) {
+               MediaPacket mediapacket=mediapackets.front();
+           DeliverMediaPacket(mediapacket, buffer, samplepos);
+           if (*samplepos == mediapacket.length) {
+               *samplepos = 0;
+               mediapackets.pop_front();
+               consumed++;
+               //return 1;
+           } else return consumed;
+       }
+       return consumed;
 }
 
 UINT VideoOMX::DeliverMediaPacket(MediaPacket packet,
@@ -1919,7 +2366,7 @@ UINT VideoOMX::DeliverMediaPacket(MediaPacket packet,
        if (packet.disconti) {
                firstsynched=false;
                if (cur_input_buf_omx) {
-                       PutBufferToPres(cur_input_buf_omx, lastreftimeOMX);
+                       PutBufferToPres(cur_input_buf_omx, lastreftimeOMX,true);
                        cur_input_buf_omx=NULL;
                }
        }
@@ -1937,7 +2384,7 @@ UINT VideoOMX::DeliverMediaPacket(MediaPacket packet,
                if ( packet.synched ) {
                        if (cur_input_buf_omx) {
                                cur_input_buf_omx->nFlags|=OMX_BUFFERFLAG_ENDOFFRAME;
-                               PutBufferToPres(cur_input_buf_omx, lastreftimeOMX);
+                               PutBufferToPres(cur_input_buf_omx, lastreftimeOMX,true);
                                cur_input_buf_omx=NULL;//write out old data
 
 
@@ -1984,7 +2431,7 @@ UINT VideoOMX::DeliverMediaPacket(MediaPacket packet,
                           cur_input_buf_omx->nFlags|=OMX_BUFFERFLAG_TIME_UNKNOWN;
                   }
                   lastreftimeOMX=packet.presentation_time;
-                //  Log::getInstance()->log("Video", Log::DEBUG, "Time code %lld pts %lld", lastreftimeOMX,packet.pts);
+                 // Log::getInstance()->log("Video", Log::DEBUG, "Time code %lld pts %lld", lastreftimeOMX,packet.pts);
                   lastreftimePTS=packet.pts;
                   cur_input_buf_omx->nTimeStamp=0;//lastreftimeOMX; // the clock component is faulty;
                }
@@ -1992,8 +2439,7 @@ UINT VideoOMX::DeliverMediaPacket(MediaPacket packet,
                {
                        cur_input_buf_omx->nFlags=OMX_BUFFERFLAG_TIME_UNKNOWN;
                        cur_input_buf_omx->nTimeStamp=0;
-
-
+                       //Log::getInstance()->log("Video", Log::DEBUG, "packet unsynched marker");
                        //  ms->SetSyncPoint(TRUE);
                }
                if (packet.disconti) cur_input_buf_omx->nFlags|=OMX_BUFFERFLAG_DISCONTINUITY;
@@ -2011,12 +2457,12 @@ UINT VideoOMX::DeliverMediaPacket(MediaPacket packet,
                *samplepos+=cancopy;
                // push old buffer out
 
-               PutBufferToPres(cur_input_buf_omx, 0LL);
+               PutBufferToPres(cur_input_buf_omx, lastreftimeOMX,false);
                // get5 new buffer
                input_bufs_omx_mutex.Lock();
                if (input_bufs_omx_free.size()==0) {
                        input_bufs_omx_mutex.Unlock();
-                       //Log::getInstance()->log("Video", Log::DEBUG, "Deliver MediaPacket no free sample");
+               //      Log::getInstance()->log("Video", Log::DEBUG, "Deliver MediaPacket no free sample2");
                        return *samplepos; // we do not have a free media sample
                }
                cur_input_buf_omx=input_bufs_omx_free.front();
@@ -2101,7 +2547,7 @@ bool VideoOMX::displayIFrame(const UCHAR* buffer, UINT length) {
 
                                        }
                                        cur_input_buf_omx->nTimeStamp = 0;
-                                       PutBufferToPres(cur_input_buf_omx, 0);
+                                       PutBufferToPres(cur_input_buf_omx, 0,false);
                                        cur_input_buf_omx = NULL;
 
                                        if (!cur_input_buf_omx) {
@@ -2156,7 +2602,7 @@ bool VideoOMX::displayIFrame(const UCHAR* buffer, UINT length) {
 
        }
        cur_input_buf_omx->nTimeStamp = 0;
-       PutBufferToPres(cur_input_buf_omx, 0);
+       PutBufferToPres(cur_input_buf_omx, 0,false);
        cur_input_buf_omx = NULL;
 
 
@@ -2168,7 +2614,7 @@ int VideoOMX::EnterIframePlayback()
 {
        clock_mutex.Lock();
        if (cur_input_buf_omx) {
-               PutBufferToPres(cur_input_buf_omx, lastreftimeOMX);
+               PutBufferToPres(cur_input_buf_omx, lastreftimeOMX,true);
 
                cur_input_buf_omx = NULL;
        }
index 260774a5449caf460212c930fd15559ec09927e9..b4f8a42dd6924bfc52c24d3674dfbcdb87a82c93 100644 (file)
@@ -114,6 +114,11 @@ class VideoOMX : public Video, public Thread_TYPE
        long long SetStartAudioOffset(long long curreftime, bool *rsync);\r
        virtual void ResetTimeOffsets();\r
 \r
+       bool loadOptionsfromServer(VDR* vdr);\r
+       bool saveOptionstoServer();\r
+       bool addOptionsToPanes(int panenumber,Options *options,WOptionPane* pane);\r
+       bool handleOptionChanges(Option* option);\r
+\r
 \r
 #ifdef DEV\r
     int test();\r
@@ -177,6 +182,7 @@ class VideoOMX : public Video, public Thread_TYPE
 \r
           int ChangeComponentState(OMX_HANDLETYPE handle,OMX_STATETYPE type);\r
           int CommandFinished(OMX_HANDLETYPE handle,OMX_U32 command,OMX_U32 data2);\r
+          int WaitForEvent(OMX_HANDLETYPE handle,OMX_U32 event);\r
           int EnablePort(OMX_HANDLETYPE handle,OMX_U32 port,bool wait);\r
           int DisablePort(OMX_HANDLETYPE handle,OMX_U32 port,bool wait=true);\r
 \r
@@ -199,13 +205,19 @@ class VideoOMX : public Video, public Thread_TYPE
 \r
           OMX_HANDLETYPE omx_vid_dec;\r
           OMX_HANDLETYPE omx_vid_sched;\r
+          OMX_HANDLETYPE omx_vid_deint;\r
           OMX_HANDLETYPE omx_vid_rend;\r
           OMX_HANDLETYPE omx_clock;\r
           int clock_references;\r
+          bool dodeint; //deinterlacer was activated in omx filtergraph\r
+          bool deint_first_frame; //handle frame change\r
+          void DeinterlaceFix();\r
 \r
 \r
           OMX_U32 omx_codec_input_port;\r
           OMX_U32 omx_codec_output_port;\r
+          OMX_U32 omx_deint_input_port;\r
+          OMX_U32 omx_deint_output_port;\r
           OMX_U32 omx_rend_input_port;\r
           OMX_U32 omx_shed_input_port;\r
           OMX_U32 omx_shed_output_port;\r
@@ -222,10 +234,11 @@ class VideoOMX : public Video, public Thread_TYPE
           list<OMX_BUFFERHEADERTYPE*> input_bufs_omx_free;\r
           list<OMX_BUFFERHEADERTYPE*> input_bufs_omx_present;\r
           list<long long> input_time_present;\r
+          list<bool> input_is_last;\r
           Mutex input_bufs_omx_mutex;\r
           OMX_BUFFERHEADERTYPE* cur_input_buf_omx;\r
 \r
-          void PutBufferToPres(OMX_BUFFERHEADERTYPE* buffer, long long time);\r
+          void PutBufferToPres(OMX_BUFFERHEADERTYPE* buffer, long long time,bool is_last);\r
           void threadMethod();\r
           void threadPostStopCleanup();\r
 \r
@@ -239,8 +252,8 @@ class VideoOMX : public Video, public Thread_TYPE
 \r
           bool omx_mpeg2;\r
           bool omx_h264;\r
-          UCHAR mode;\r
           float xpos,ypos;\r
+          int deinterlace;\r
           void updateMode();//called internally to adjust for different parameters\r
 \r
 \r
@@ -248,7 +261,7 @@ class VideoOMX : public Video, public Thread_TYPE
    bool firstsynched;\r
 \r
     \r
-       MediaPacket mediapacket;\r
+   MediaPacketList mediapackets;\r
 };\r
 \r
 #endif\r
index 48682cf3823c1cae20dbdd6b82328f0b4c08d873..dc9fa77e34899fd758ecb6ff9d66902b804bae50 100644 (file)
@@ -59,6 +59,7 @@ public:
        int shutdown();\r
 \r
        int setFormat(UCHAR format);\r
+       virtual UCHAR getSupportedFormats() { return 0;};\r
        int setConnection(UCHAR connection);\r
        int setAspectRatio(UCHAR aspectRatio);   // This one does the pin 8 scart widescreen switching\r
        UCHAR getAspectRatio(){return aspectRatio;};\r