]> git.vomp.tv Git - vompclient-marten.git/commitdiff
First timecode handling + Mpeg2 video hardware playback SD + HD
authorMarten Richter <marten.richter@freenet.de>
Sun, 26 Aug 2012 17:57:14 +0000 (19:57 +0200)
committerMarten Richter <marten.richter@freenet.de>
Sun, 26 Aug 2012 17:57:14 +0000 (19:57 +0200)
defines.h
player.cc [changed mode: 0755->0644]
videovpeogl.cc
videovpeogl.h

index 0e6648a9cebf6157e701b1471dbf6183f64b706d..fcb0bf9105c01adec43b5385739dbcafd5c841dc 100644 (file)
--- a/defines.h
+++ b/defines.h
@@ -105,7 +105,7 @@ long long getTimeMS();
    #define VPE_OMX_CLOCK "OMX.broadcom.clock"\r
 \r
    //#define  VPE_LIBAV_SUPPORT\r
-   #define  VPE_LIBAV_MPEG2_TRANSCODING\r
+  // #define  VPE_LIBAV_MPEG2_TRANSCODING\r
 \r
 #endif\r
 #ifdef VOMP_PLATTFORM_MVP\r
old mode 100755 (executable)
new mode 100644 (file)
index c4f9569..2c2b5b0
--- a/player.cc
+++ b/player.cc
@@ -91,7 +91,7 @@ int Player::init(bool p_isPesRecording,double framespersecond)
   if (!teletext) return 0;\r
   teletext->setRecordigMode(true);\r
   unsigned int demux_video_size=2097152;\r
-   if (video->supportsh264()) demux_video_size*=5;\r
+  if (video->supportsh264()) demux_video_size*=5;\r
  \r
   if (!demuxer->init(this, audio, video,teletext, demux_video_size,524288,65536, framespersecond, subtitles))\r
   {\r
index d4346ea2d07b5159982d30677afcacbddf0c0dee..b56526619855d5d2f82df8aab7cfe2c307cd544a 100644 (file)
@@ -64,6 +64,16 @@ VideoVPEOGL::VideoVPEOGL()
         transcodecodec_context_libav=NULL;
 #endif
 
+        offsetnotset=true;
+        offsetvideonotset=true;
+        offsetaudionotset=true;
+        startoffset=0;
+        lastrefaudiotime=0;
+        lastrefvideotime=0;
+        lastreftimeOMX=0;
+        lastreftimePTS=0;
+        firstsynched=false;
+
 
 #ifdef BENCHMARK_FPS
        time_in_decoder=0;
@@ -1021,6 +1031,7 @@ int VideoVPEOGL::play()
   decoding_backend=0;
 #ifdef VPE_OMX_SUPPORT
   bool doomx=true;
+  Log::getInstance()->log("Video", Log::DEBUG, "enter play");
   if (h264) {
          if (!omx_h264) doomx=false;
   } else {
@@ -1129,6 +1140,7 @@ int VideoVPEOGL::AllocateCodecsOMX()
 
 
 
+       /* TODO Clock config to separate method */
        OMX_PORT_PARAM_TYPE p_param;
        memset(&p_param,0,sizeof(p_param));
        p_param.nSize=sizeof(p_param);
@@ -1142,7 +1154,7 @@ int VideoVPEOGL::AllocateCodecsOMX()
        omx_clock_output_port=p_param.nStartPortNumber;
 
        for (unsigned int i=0;i<p_param.nPorts;i++) {
-               if (!DisablePort(omx_clock,p_param.nStartPortNumber+i) ) {
+               if (!DisablePort(omx_clock,p_param.nStartPortNumber+i,true) ) {
                        Log::getInstance()->log("Video", Log::DEBUG, "Disable Ports OMX clock failed %d",i);
                        DeAllocateCodecsOMX();
                        return 0;
@@ -1150,6 +1162,8 @@ int VideoVPEOGL::AllocateCodecsOMX()
        }
 
 
+
+
        OMX_TIME_CONFIG_CLOCKSTATETYPE clock_conf;
        memset(&clock_conf,0,sizeof(clock_conf));
        clock_conf.nSize=sizeof(clock_conf);
@@ -1158,7 +1172,7 @@ int VideoVPEOGL::AllocateCodecsOMX()
        clock_conf.nStartTime=0;
        clock_conf.nOffset=0;
        clock_conf.nWaitMask=OMX_CLOCKPORT0;
-       error=OMX_SetParameter(omx_clock,OMX_IndexConfigTimeClockState,&clock_conf);
+       error=OMX_SetConfig(omx_clock,OMX_IndexConfigTimeClockState,&clock_conf);
        if (error!=OMX_ErrorNone){
                Log::getInstance()->log("Video", Log::DEBUG, "Clock IndexConfigTimeClockState failed %x", error);
                DeAllocateCodecsOMX();
@@ -1166,6 +1180,36 @@ int VideoVPEOGL::AllocateCodecsOMX()
        }
 
 
+       OMX_TIME_CONFIG_ACTIVEREFCLOCKTYPE refclock;
+       memset(&refclock,0,sizeof(refclock));
+       refclock.nSize=sizeof(refclock);
+       refclock.nVersion.nVersion=OMX_VERSION;
+
+       if (/*AUDIO*/ false) {
+               refclock.eClock=OMX_TIME_RefClockAudio;
+       } else {
+               refclock.eClock=OMX_TIME_RefClockVideo;
+       }
+       error=OMX_SetConfig(omx_clock,OMX_IndexConfigTimeActiveRefClock,&refclock);
+       if (error!=OMX_ErrorNone){
+               Log::getInstance()->log("Video", Log::DEBUG, "Clock OMX_IndexConfigTimeActiveRefClock failed %x", error);
+               DeAllocateCodecsOMX();
+               return 0;
+       }
+
+       if (!ChangeComponentState(omx_clock,OMX_StateIdle)) {
+               Log::getInstance()->log("Video", Log::DEBUG, "omx_clock ChangeComponentState Idle");
+               DeAllocateCodecsOMX();
+               return 0;
+       }
+
+
+
+
+       /* TODO end */
+
+
+
 
        if (h264) {
                error=OMX_GetHandle(&omx_vid_dec,VPE_OMX_H264_DECODER,NULL,&callbacks);
@@ -1240,10 +1284,11 @@ int VideoVPEOGL::AllocateCodecsOMX()
                return 0;
        }
        omx_shed_clock_port=p_param.nStartPortNumber;
+       Log::getInstance()->log("Video", Log::DEBUG, "scheduler ports %d %d %d ",omx_shed_input_port,omx_shed_output_port,omx_shed_clock_port);
 
 
-       if (!DisablePort(omx_vid_sched,omx_shed_input_port) || !DisablePort(omx_vid_sched,omx_shed_output_port)
-                       || !DisablePort(omx_vid_sched,omx_shed_clock_port)) {
+       if (!DisablePort(omx_vid_sched,omx_shed_input_port,true) || !DisablePort(omx_vid_sched,omx_shed_output_port,true)
+                       || !DisablePort(omx_vid_sched,omx_shed_clock_port,true)) {
                Log::getInstance()->log("Video", Log::DEBUG, "Disable Ports OMX video shed failed");
                DeAllocateCodecsOMX();
                return 0;
@@ -1267,7 +1312,7 @@ int VideoVPEOGL::AllocateCodecsOMX()
        //omx_rend_output_port=p_param.nStartPortNumber+1;
 
 
-       if (!DisablePort(omx_vid_rend,omx_rend_input_port) /*|| !DisablePort(omx_vid_rend,omx_rend_output_port)*/
+       if (!DisablePort(omx_vid_rend,omx_rend_input_port,true) /*|| !DisablePort(omx_vid_rend,omx_rend_output_port)*/
                                ) {
                Log::getInstance()->log("Video", Log::DEBUG, "Disable Ports OMX video rend failed");
                DeAllocateCodecsOMX();
@@ -1279,19 +1324,54 @@ int VideoVPEOGL::AllocateCodecsOMX()
 
 
 
+       error=OMX_SetupTunnel(omx_clock,omx_clock_output_port,omx_vid_sched,omx_shed_clock_port);
+       if (error!=OMX_ErrorNone){
+               Log::getInstance()->log("Video", Log::DEBUG, "OMX_Setup tunnel clock to sched failed %x %d %d", error,omx_clock_output_port,omx_shed_clock_port);
+               DeAllocateCodecsOMX();
+               return 0;
+       }
 
+       if (!EnablePort(omx_clock,omx_clock_output_port,false) || !EnablePort(omx_vid_sched,omx_shed_clock_port,false)
+                                       ) {
+               Log::getInstance()->log("Video", Log::DEBUG, "Enable Ports OMX clock shed failed");
+               DeAllocateCodecsOMX();
+               return 0;
+       }
+
+       Log::getInstance()->log("Video", Log::DEBUG, "mark2 ");
+       if (!ChangeComponentState(omx_vid_sched,OMX_StateIdle)) {
+               Log::getInstance()->log("Video", Log::DEBUG, "vid_sched idle ChangeComponentState");
+               DeAllocateCodecsOMX();
+               return 0;
+       }
+
+
+
+       Log::getInstance()->log("Video", Log::DEBUG, "mark1 ");
+       if ( !CommandFinished(omx_vid_sched,OMX_CommandPortEnable,omx_shed_clock_port)) {
+               DeAllocateCodecsOMX();
+               return 0;
+       }
 
 
 
+
+       Log::getInstance()->log("Video", Log::DEBUG, "mark1 special ");
+       if ( !CommandFinished(omx_clock,OMX_CommandPortEnable,omx_clock_output_port)) {
+               DeAllocateCodecsOMX();
+               return 0;
+       }
+
+
+       Log::getInstance()->log("Video", Log::DEBUG, "mark1b ");
+
+
 /*     error=OMX_SendCommand(omx_vid_dec,OMX_CommandStateSet,OMX_StateIdle,0);
        if (error!=OMX_ErrorNone){
                Log::getInstance()->log("Video", Log::DEBUG, "vid_dec Send Command to OMX State Idle %x", error);
                return 0;
        }*/
 
-
-
-
        OMX_VIDEO_PARAM_PORTFORMATTYPE ft_type;
        memset(&ft_type,0,sizeof(ft_type));
        ft_type.nSize=sizeof(ft_type);
@@ -1301,10 +1381,13 @@ int VideoVPEOGL::AllocateCodecsOMX()
        if (h264) {
                ft_type.eCompressionFormat=OMX_VIDEO_CodingAVC;
        } else {
-               //ft_type.eCompressionFormat=OMX_VIDEO_CodingMPEG2;
+#ifndef VPE_LIBAV_MPEG2_TRANSCODING
+               ft_type.eCompressionFormat=OMX_VIDEO_CodingMPEG2;
+#else
                ft_type.eCompressionFormat=OMX_VIDEO_CodingMPEG4;
                decoding_backend=VPE_DECODER_OMX_libav_TRANSCODE;
                InitTranscoderLibAV();
+#endif
        }
 
        Demuxer* demux=Demuxer::getInstance();
@@ -1332,31 +1415,6 @@ int VideoVPEOGL::AllocateCodecsOMX()
        }
 
 
-       if (!ChangeComponentState(omx_clock,OMX_StateIdle)) {
-               Log::getInstance()->log("Video", Log::DEBUG, "omx_clock ChangeComponentState Idle");
-               DeAllocateCodecsOMX();
-               return 0;
-       }
-
-       error=OMX_SetupTunnel(omx_clock,omx_clock_output_port,omx_vid_sched,omx_shed_clock_port);
-       if (error!=OMX_ErrorNone){
-               Log::getInstance()->log("Video", Log::DEBUG, "OMX_Setup tunnel clock to sched failed %x %d %d", error,omx_clock_output_port,omx_shed_clock_port);
-               DeAllocateCodecsOMX();
-               return 0;
-       }
-
-       if (!EnablePort(omx_clock,omx_clock_output_port,false) || !EnablePort(omx_vid_sched,omx_shed_clock_port,false)
-                                       ) {
-               Log::getInstance()->log("Video", Log::DEBUG, "Enable Ports OMX clock shed failed");
-               DeAllocateCodecsOMX();
-               return 0;
-       }
-
-       if ( !CommandFinished(omx_vid_sched,OMX_CommandPortEnable,omx_shed_clock_port)) {
-               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);
@@ -1373,16 +1431,7 @@ int VideoVPEOGL::AllocateCodecsOMX()
                return 0;
        }
 
-       if ( !CommandFinished(omx_vid_sched,OMX_CommandPortEnable,omx_shed_input_port)) {
-               return 0;
-       }
-       if (!ChangeComponentState(omx_vid_sched,OMX_StateIdle)) {
-               Log::getInstance()->log("Video", Log::DEBUG, "vid_sched idle ChangeComponentState");
-               DeAllocateCodecsOMX();
-               return 0;
-       }
-       if (!CommandFinished(omx_clock,OMX_CommandPortEnable,omx_clock_output_port)
-                       ||!CommandFinished(omx_vid_dec,OMX_CommandPortEnable,omx_codec_output_port)){
+       if ( !CommandFinished(omx_vid_dec,OMX_CommandPortEnable,omx_codec_output_port) || !CommandFinished(omx_vid_sched,OMX_CommandPortEnable,omx_shed_input_port)) {
                DeAllocateCodecsOMX();
                return 0;
        }
@@ -1442,7 +1491,7 @@ int VideoVPEOGL::AllocateCodecsOMX()
 
        dispconf.set=OMX_DISPLAY_SET_LAYER ;
        dispconf.layer=1;
-       error=OMX_SetParameter(omx_vid_rend,OMX_IndexConfigDisplayRegion,&dispconf);
+       error=OMX_SetConfig(omx_vid_rend,OMX_IndexConfigDisplayRegion,&dispconf);
        if (error!=OMX_ErrorNone){
                Log::getInstance()->log("Video", Log::DEBUG, "Init OMX_IndexConfigDisplayRegion failed %x", error);
                DeAllocateCodecsOMX();
@@ -1470,17 +1519,34 @@ int VideoVPEOGL::AllocateCodecsOMX()
                return 0;
        }*/
 
+       if (decoding_backend!=VPE_DECODER_OMX_libav_TRANSCODE) decoding_backend=VPE_DECODER_OMX;
 
-
+       playbacktimeoffset=-GetCurrentSystemTime();
+       paused=false;
+       omx_running=true;
 
        if (!ChangeComponentState(omx_clock,OMX_StateExecuting)) {
-                       Log::getInstance()->log("Video", Log::DEBUG, "omx_clock ChangeComponentState Exccute");
-                       DeAllocateCodecsOMX();
-                       return 0;
+               Log::getInstance()->log("Video", Log::DEBUG, "omx_clock ChangeComponentState Execute failed");
+               DeAllocateCodecsOMX();
+               return 0;
+       }
+
+
+       //OMX_TIME_CONFIG_CLOCKSTATETYPE clock_conf;
+       memset(&clock_conf,0,sizeof(clock_conf));
+       clock_conf.nSize=sizeof(clock_conf);
+       clock_conf.nVersion.nVersion=OMX_VERSION;
+       clock_conf.eState=OMX_TIME_ClockStateRunning;
+       error=OMX_SetConfig(omx_clock,OMX_IndexConfigTimeClockState,&clock_conf);
+       if (error!=OMX_ErrorNone){
+               Log::getInstance()->log("Video", Log::DEBUG, "Clock IndexConfigTimeClockState failed %x", error);
+               DeAllocateCodecsOMX();
+               return 0;
        }
 
-       if (decoding_backend!=VPE_DECODER_OMX_libav_TRANSCODE) decoding_backend=VPE_DECODER_OMX;
-       omx_running=true;
+
+
+
 
        return 1;
 }
@@ -1555,11 +1621,13 @@ int VideoVPEOGL::CommandFinished(OMX_HANDLETYPE handle,OMX_U32 command,OMX_U32 d
                                if (current.event_type==OMX_EventError) {
                                        omx_events.erase(itty);
                                        omx_event_mutex.Unlock();
+                                       Log::getInstance()->log("Video", Log::DEBUG, "Command Finished on Error");
                                        return 0;
 
                                } else if (current.event_type==OMX_EventCmdComplete && current.data1==command && current.data2==data2) {
                                        omx_events.erase(itty);
                                        omx_event_mutex.Unlock();
+                                       //Log::getInstance()->log("Video", Log::DEBUG, "Command Finished Completed");
                                        return 1;
                                }
                        }
@@ -1598,7 +1666,7 @@ int VideoVPEOGL::PrepareInputBufsOMX()
                        port_def_type.nBufferCountMin,port_def_type.nBufferSize,port_def_type.bEnabled,port_def_type.bPopulated,
                        port_def_type.bBuffersContiguous,port_def_type.nBufferAlignment);*/
 
-       port_def_type.nBufferCountActual=60;
+       port_def_type.nBufferCountActual=10;
        port_def_type.nBufferSize=max(port_def_type.nBufferSize,200000); // for transcoder important
 
        error=OMX_SetParameter(omx_vid_dec,OMX_IndexParamPortDefinition, &port_def_type);
@@ -1694,20 +1762,83 @@ int VideoVPEOGL::DeAllocateCodecsOMX()
 {
        OMX_ERRORTYPE error;
        omx_running=false;
+         Log::getInstance()->log("Video", Log::DEBUG, "enter deallocatecodecsomx");
 #ifdef VPE_LIBAV_MPEG2_TRANSCODING
    if (decoding_backend==VPE_DECODER_OMX_libav_TRANSCODE)
            DeInitTranscoderLibAV();
 #endif
 
+   if (cur_input_buf_omx) {
+               cur_input_buf_omx->nFlags|=OMX_BUFFERFLAG_EOS;
+               OMX_ERRORTYPE error=OMX_EmptyThisBuffer(omx_vid_dec,cur_input_buf_omx);
+               if (error!=OMX_ErrorNone) {
+                       Log::getInstance()->log("Video", Log::DEBUG, "OMX_EmptyThisBuffer failed %x", error);
+               }
+
+               cur_input_buf_omx=NULL;//write out old data
+       }
+
        if (omx_vid_dec) {
+               // first stop the omx elements
+               if (!ChangeComponentState(omx_vid_dec,OMX_StateIdle)) {
+                       Log::getInstance()->log("Video", Log::DEBUG, "vid_dec ChangeComponentState");
+                       DeAllocateCodecsOMX();
+                       return 0;
+               }
+
+               if (!ChangeComponentState(omx_clock,OMX_StateIdle)) {
+                       Log::getInstance()->log("Video", Log::DEBUG, "vid_clock ChangeComponentState");
+                       DeAllocateCodecsOMX();
+                       return 0;
+               }
+
+               if (!ChangeComponentState(omx_vid_sched,OMX_StateIdle)) {
+                       Log::getInstance()->log("Video", Log::DEBUG, "vid_shed ChangeComponentState");
+                       DeAllocateCodecsOMX();
+                       return 0;
+               }
+
+               if (!ChangeComponentState(omx_vid_rend,OMX_StateIdle)) {
+                       Log::getInstance()->log("Video", Log::DEBUG, "vid_rend ChangeComponentState");
+                       DeAllocateCodecsOMX();
+                       return 0;
+               }
+
+
+
+        // TODO proper deinit sequence
                // first flush all buffers
 
+               error=OMX_SendCommand(omx_vid_rend,OMX_CommandFlush, omx_rend_input_port, NULL);
+               if (error!=OMX_ErrorNone) {
+                       Log::getInstance()->log("Video", Log::DEBUG, "OMX_Flush rend in failed %x", error);
+
+               }
+
+               if (!CommandFinished(omx_vid_rend,OMX_CommandFlush,omx_rend_input_port)) {
+                       Log::getInstance()->log("Video", Log::DEBUG, "flush cmd shed rend failed");
+               }
+
+               error=OMX_SendCommand(omx_vid_dec,OMX_CommandFlush, omx_codec_input_port, NULL);
+               if (error!=OMX_ErrorNone){
+                       Log::getInstance()->log("Video", Log::DEBUG, "OMX_Flush codec out failed %x", error);
+
+               }
+
+
+               if (!CommandFinished(omx_vid_dec,OMX_CommandFlush,omx_codec_input_port)) {
+                       Log::getInstance()->log("Video", Log::DEBUG, "flush cmd codec input failed");
+               }
+
                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);
@@ -1742,53 +1873,43 @@ int VideoVPEOGL::DeAllocateCodecsOMX()
 
                }
 
-               error=OMX_SendCommand(omx_vid_rend,OMX_CommandFlush, omx_rend_input_port, NULL);
-               if (error!=OMX_ErrorNone) {
-                       Log::getInstance()->log("Video", Log::DEBUG, "OMX_Flush rend in failed %x", error);
 
-               }
 
-               if (!CommandFinished(omx_vid_sched,OMX_CommandFlush,omx_shed_output_port) ||
-                               !CommandFinished(omx_vid_rend,OMX_CommandFlush,omx_rend_input_port)) {
+               if (!CommandFinished(omx_vid_sched,OMX_CommandFlush,omx_shed_output_port) ) {
                        Log::getInstance()->log("Video", Log::DEBUG, "flush cmd shed rend failed");
                }
 
 
 
 
-               error=OMX_SendCommand(omx_vid_dec,OMX_CommandFlush, omx_codec_input_port, NULL);
-               if (error!=OMX_ErrorNone){
-                       Log::getInstance()->log("Video", Log::DEBUG, "OMX_Flush codec out failed %x", error);
-
-               }
-
 
-               if (!CommandFinished(omx_vid_dec,OMX_CommandFlush,omx_codec_input_port)) {
-                       Log::getInstance()->log("Video", Log::DEBUG, "flush cmd codec input failed");
-               }
 
                DestroyInputBufsOMX();
 
                //todo flushing
-               if (!DisablePort(omx_vid_rend,omx_rend_input_port,true)) {
-                       Log::getInstance()->log("Video", Log::DEBUG, "Disable Tunnel Port failed 1");
-               }
                if (!DisablePort(omx_vid_sched,omx_shed_output_port,true)) {
                        Log::getInstance()->log("Video", Log::DEBUG, "Disable Tunnel Port failed 2 ");
                }
+               if (!DisablePort(omx_vid_rend,omx_rend_input_port,true)) {
+                       Log::getInstance()->log("Video", Log::DEBUG, "Disable Tunnel Port failed 1");
+               }
+
+
 
-               error=OMX_SetupTunnel(omx_vid_rend,omx_rend_input_port,NULL,NULL);
-               if (error!=OMX_ErrorNone){
-                       Log::getInstance()->log("Video", Log::DEBUG, "OMX_Setup tunnel teardown failed %x", error);
 
+               if (!DisablePort(omx_vid_dec,omx_codec_output_port,true)) {
+                       Log::getInstance()->log("Video", Log::DEBUG, "Disable Tunnel Port failed 6");
                }
 
-               error=OMX_SetupTunnel(omx_vid_sched,omx_shed_output_port,NULL,NULL);
-               if (error!=OMX_ErrorNone){
-                       Log::getInstance()->log("Video", Log::DEBUG, "OMX_Setup tunnel teardown failed %x", error);
 
+
+               if (!DisablePort(omx_vid_dec,omx_codec_input_port,true)) {
+                       Log::getInstance()->log("Video", Log::DEBUG, "Disable Tunnel Port failed 7");
                }
 
+
+
+
                if (!DisablePort(omx_vid_sched,omx_shed_input_port,true)) {
                        Log::getInstance()->log("Video", Log::DEBUG, "Disable Tunnel Port failed 3");
                }
@@ -1800,36 +1921,42 @@ int VideoVPEOGL::DeAllocateCodecsOMX()
                if (!DisablePort(omx_clock,omx_clock_output_port,true)) {
                        Log::getInstance()->log("Video", Log::DEBUG, "Disable Tunnel Port failed 5");
                }
-               if (!DisablePort(omx_vid_dec,omx_codec_output_port,true)) {
-                       Log::getInstance()->log("Video", Log::DEBUG, "Disable Tunnel Port failed 6");
-               }
 
 
 
-               if (!DisablePort(omx_vid_dec,omx_codec_input_port,true)) {
-                       Log::getInstance()->log("Video", Log::DEBUG, "Disable Tunnel Port failed 7");
-               }
+               error=OMX_SetupTunnel(omx_vid_dec,omx_codec_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){
+               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_clock_port,NULL,NULL);
-               if (error!=OMX_ErrorNone){
+
+
+               error=OMX_SetupTunnel(omx_vid_sched,omx_shed_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_rend,omx_rend_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_clock,omx_clock_output_port,NULL,NULL);
-               if (error!=OMX_ErrorNone){
+               if (error!=OMX_ErrorNone) {
                        Log::getInstance()->log("Video", Log::DEBUG, "OMX_Setup tunnel teardown failed %x", error);
 
                }
 
-               error=OMX_SetupTunnel(omx_vid_dec,omx_codec_output_port,NULL,NULL);
-               if (error!=OMX_ErrorNone){
+               error=OMX_SetupTunnel(omx_vid_sched,omx_shed_clock_port,NULL,NULL);
+               if (error!=OMX_ErrorNone) {
                        Log::getInstance()->log("Video", Log::DEBUG, "OMX_Setup tunnel teardown failed %x", error);
 
                }
@@ -1838,6 +1965,13 @@ int VideoVPEOGL::DeAllocateCodecsOMX()
 
 
 
+
+
+
+
+
+
+
                error=OMX_FreeHandle(omx_vid_dec);
                error=OMX_FreeHandle(omx_vid_sched);
                error=OMX_FreeHandle(omx_vid_rend);
@@ -1847,6 +1981,7 @@ int VideoVPEOGL::DeAllocateCodecsOMX()
                        Log::getInstance()->log("Video", Log::DEBUG, "FreeHandle failed %d", error);
                }
        }
+         Log::getInstance()->log("Video", Log::DEBUG, "leave deallocate codecs OMX");
 
        return 1;
 }
@@ -2361,15 +2496,26 @@ int VideoVPEOGL::reset()
 int VideoVPEOGL::pause()
 {
   if (!initted) return 0;
+  Log::getInstance()->log("Video", Log::DEBUG, "enter pause");
+  if (!paused) {
+         paused=true;
+         //maybe also change omx clock?
+         pausetimecode=GetCurrentSystemTime();
 
-//  if (ioctl(fdVideo, AV_SET_VID_PAUSE, 0) != 0) return 0;
+  }
   return 1;
 }
 
-int VideoVPEOGL::unPause() // FIXME get rid - same as play!!
+int VideoVPEOGL::unPause() // FIXME get rid - same as play!! Not here!
 {
   if (!initted) return 0;
-//  if (ioctl(fdVideo, AV_SET_VID_PLAY, 0) != 0) return 0;
+  Log::getInstance()->log("Video", Log::DEBUG, "enter unpause");
+
+  if (paused) {
+         playbacktimeoffset+=GetCurrentSystemTime()-pausetimecode;
+         paused=false; // may be also change omx clock
+  }
+
   return 1;
 }
 
@@ -2408,29 +2554,19 @@ int VideoVPEOGL::blank(void)
 
 ULLONG VideoVPEOGL::getCurrentTimestamp()
 {
-/*  sync_data_t timestamps;
-  if (ioctl(fdVideo, AV_GET_VID_TIMESTAMPS, &timestamps) == 0)
-  {
-    // FIXME are these the right way around?
-
-    timestamps.stc = (timestamps.stc >> 31 ) | (timestamps.stc & 1);
-    timestamps.pts = (timestamps.pts >> 31 ) | (timestamps.pts & 1);
 
-    return timestamps.stc;
-  }
-  else
-  {
-    return 0;
-  }*/
-  return 0;
+  return lastreftimePTS;
 }
 
+// to be removed
+/*
 ULONG VideoVPEOGL::timecodeToFrameNumber(ULLONG timecode)
 {
   if (format == PAL) return (ULONG)(((double)timecode / (double)90000) * (double)25);
   else               return (ULONG)(((double)timecode / (double)90000) * (double)30);
 }
 
+*/
 #ifdef DEV
 int VideoVPEOGL::test()
 {
@@ -2450,6 +2586,111 @@ int VideoVPEOGL::test2()
 }
 #endif
 
+
+
+long long VideoVPEOGL::SetStartOffset(long long curreftime, bool *rsync)
+{
+  *rsync=false;
+  if (offsetnotset) {
+    startoffset=curreftime;//offset is set for audio
+    offsetnotset=false;
+    offsetvideonotset=false;
+  } else {
+    if (offsetvideonotset) {
+      offsetvideonotset=false;
+      *rsync=true;
+    } else {
+      if ( (curreftime-lastrefvideotime)>10000000LL
+        || (curreftime-lastrefvideotime)<-10000000LL) {//if pts jumps to big resync
+        startoffset+=curreftime-lastrefvideotime;
+        lastrefaudiotime+=curreftime-lastrefvideotime;
+        //*rsync=true;
+        offsetaudionotset=true;
+
+      }
+    }
+
+  }
+
+  lastrefvideotime=curreftime;
+
+  return startoffset;
+
+}
+
+long long VideoVPEOGL::SetStartAudioOffset(long long curreftime, bool *rsync)
+{
+  *rsync=false;
+  if (offsetnotset) {
+    startoffset=curreftime;
+    offsetnotset=false;
+    offsetaudionotset=false;
+  }else {
+    if (offsetaudionotset) {
+      offsetaudionotset=false;
+      *rsync=true;
+    } else {
+      if ( (curreftime-lastrefaudiotime)>10000000LL
+        || (curreftime-lastrefaudiotime)<-10000000LL) {//if pts jumps to big resync
+        startoffset+=curreftime-lastrefaudiotime;
+        lastrefvideotime+=curreftime-lastrefaudiotime;
+        //*rsync=true;
+        offsetvideonotset=true;
+
+      }
+    }
+
+  }
+  lastrefaudiotime=curreftime;
+  return startoffset;
+
+}
+
+void VideoVPEOGL::ResetTimeOffsets() {
+  offsetnotset=true; //called from demuxer
+  offsetvideonotset=true;
+  offsetaudionotset=true;
+  startoffset=0;
+  lastrefaudiotime=0;
+  lastrefvideotime=0;
+  lastreftimeOMX=0;
+  lastreftimePTS=0;
+}
+
+long long VideoVPEOGL::GetCurrentSystemTime()
+{
+       struct timespec ts;
+       clock_gettime(CLOCK_MONOTONIC, &ts);
+       return ts.tv_sec*10000000LL+ts.tv_nsec/100LL;
+}
+
+void VideoVPEOGL::WaitUntil(long long time)
+{
+       struct timespec interval;
+       interval.tv_sec=time/10000000LL;
+       interval.tv_nsec=(time %10000000LL)*100LL;
+       while (clock_nanosleep(CLOCK_MONOTONIC,TIMER_ABSTIME,&interval,NULL)==EINTR) {};
+}
+
+void VideoVPEOGL::FrameWaitforDisplay(long long pts)
+{
+       //ok first calculate the absolute time
+       long long target_time=pts-playbacktimeoffset;
+       // we have to wait untile the next frame
+       long long offset=Demuxer::getInstance()->getFrameRate();
+       long long current_time=GetCurrentSystemTime();
+       if ((target_time-current_time)>5000000LL) target_time=current_time+5000000LL; // something is wrong do not wait too long
+       if (offset==0) offset=25;
+       offset=10000000LL/offset;
+       target_time+=offset;
+       Log::getInstance()->log("Video", Log::DEBUG, "Wait for display pts: %lld target: %lld sys: %lld off: %lld diff %lld",pts,target_time,current_time,offset,
+                       target_time-current_time);
+
+       WaitUntil(target_time);
+       Log::getInstance()->log("Video", Log::DEBUG, "Wait for display out");
+}
+
+
 void VideoVPEOGL::PrepareMediaSample(const MediaPacketList& mplist,UINT samplepos)
 {
   mediapacket = mplist.front();
@@ -2499,7 +2740,7 @@ UINT VideoVPEOGL::DeliverMediaPacketOMX(MediaPacket packet,
 
 
        //Later add fail back code for libav
-       /*if (!videoon) {
+/*     if (!videoon) {
                *samplepos+=packet.length;
                return packet.length;
        }*/
@@ -2507,6 +2748,11 @@ UINT VideoVPEOGL::DeliverMediaPacketOMX(MediaPacket packet,
 
        if (!omx_running) return 0; // if we are not runnig do not do this
 
+       if (packet.synched && packet.presentation_time<0) {
+               Log::getInstance()->log("Video", Log::DEBUG, "DeliverMediaPacketOMX Preroll %lld", packet.presentation_time);
+               *samplepos=packet.length;
+               return packet.length;
+       }
 
        OMX_ERRORTYPE error;
 
@@ -2551,10 +2797,12 @@ UINT VideoVPEOGL::DeliverMediaPacketOMX(MediaPacket packet,
                if ( packet.synched ) {
 
                        if (cur_input_buf_omx) {
+                               cur_input_buf_omx->nFlags|=OMX_BUFFERFLAG_ENDOFFRAME;
                                OMX_ERRORTYPE error=OMX_EmptyThisBuffer(omx_vid_dec,cur_input_buf_omx);
                                if (error!=OMX_ErrorNone){
                                        Log::getInstance()->log("Video", Log::DEBUG, "OMX_EmptyThisBuffer failed %x", error);
                                }
+                               FrameWaitforDisplay(lastreftimeOMX);
 
                                cur_input_buf_omx=NULL;//write out old data
                        }
@@ -2594,22 +2842,34 @@ UINT VideoVPEOGL::DeliverMediaPacketOMX(MediaPacket packet,
                } else {
                        ms->SetDiscontinuity(FALSE);
                }*/
-               //if (packet.synched) {
+               if (packet.synched) {
+                       Log::getInstance()->log("Video", Log::DEBUG, "packet synched marker");
 
                        //lastreftimePTS=packet.pts;
                   if (omx_first_frame) { // TODO time
                           cur_input_buf_omx->nFlags=OMX_BUFFERFLAG_STARTTIME;
+                          Log::getInstance()->log("Video", Log::DEBUG, "Starttime");
                           omx_first_frame=false;
-                  } else
-
-               //}
-               //else
-               //{
+                  } else {
+                          //cur_input_buf_omx->nFlags=0;
+                          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);
+                  lastreftimePTS=packet.pts;
+                  cur_input_buf_omx->nTimeStamp=0;//lastreftimeOMX; // the clock component is faulty;
+               }
+               else
+               {
                        cur_input_buf_omx->nFlags=OMX_BUFFERFLAG_TIME_UNKNOWN;
+                       cur_input_buf_omx->nTimeStamp=0;
 
 
                        //  ms->SetSyncPoint(TRUE);
-               //}
+               }
+               if (packet.disconti) cur_input_buf_omx->nFlags|=OMX_BUFFERFLAG_DISCONTINUITY;
+
+
 
        }
        unsigned int haveToCopy=packet.length-*samplepos;
@@ -3004,14 +3264,6 @@ UINT VideoVPEOGL::DeliverMediaPacketlibav(MediaPacket packet,
 #endif
 
 
-
-
-
-
-void VideoVPEOGL::ResetTimeOffsets()
-{
-}
-
 bool VideoVPEOGL::displayIFrame(const UCHAR* buffer, UINT length)
 {
   //write(fdVideo, buffer, length);
index e4ee1389f3001bce574aaad0828f157133709c20..97a589c46d98eae49cc88d20ed342e5ba898cfe8 100644 (file)
@@ -158,12 +158,12 @@ class VideoVPEOGL : public Video, public Thread_TYPE
     ULLONG getCurrentTimestamp();\r
     bool displayIFrame(const UCHAR* bulibaver, UINT length);\r
 \r
+    virtual bool dtsTimefix(){return true;} //please we need dts time values\r
+\r
     // Writing Data to Videodevice\r
     virtual void PrepareMediaSample(const MediaPacketList&, UINT samplepos);\r
     virtual UINT DeliverMediaSample(UCHAR* bulibaver, UINT* samplepos);\r
-    virtual long long SetStartOffset(long long curreftime, bool *rsync)\r
-    { *rsync=false; return 0; };\r
-    virtual void ResetTimeOffsets();\r
+\r
 \r
        virtual bool supportsh264(){return true;};\r
 \r
@@ -175,6 +175,14 @@ class VideoVPEOGL : public Video, public Thread_TYPE
        void returnOGLFrame(VPEOGLFrame *frame);\r
        void recycleOGLRefFrames();\r
 \r
+       virtual long long SetStartOffset(long long curreftime, bool *rsync);\r
+       long long SetStartAudioOffset(long long curreftime, bool *rsync);\r
+       virtual void ResetTimeOffsets();\r
+\r
+       static long long GetCurrentSystemTime();\r
+       static void WaitUntil(long long time);\r
+       void FrameWaitforDisplay(long long pts);\r
+\r
 \r
 \r
 \r
@@ -197,14 +205,30 @@ class VideoVPEOGL : public Video, public Thread_TYPE
           int EnterIframePlayback();\r
           bool iframemode;\r
 \r
-          UINT DeliverMediaPacket(MediaPacket packet,\r
-                                            const UCHAR* bulibaver,\r
-                                            UINT *samplepos);\r
+          UINT DeliverMediaPacket(MediaPacket packet,const UCHAR* bulibaver,UINT *samplepos);\r
+\r
           int decoding_backend; //1 omx, 2 libav, 3 omx through lib av transcoder\r
 #define VPE_DECODER_OMX 1\r
 #define VPE_DECODER_libav 2\r
 #define VPE_DECODER_OMX_libav_TRANSCODE 3\r
 \r
+\r
+          bool offsetnotset;\r
+          bool offsetvideonotset;\r
+          bool offsetaudionotset;\r
+          long long startoffset;\r
+          long long lastrefvideotime;\r
+          long long lastrefaudiotime;\r
+          OMX_TICKS lastreftimeOMX;\r
+          ULLONG lastreftimePTS;\r
+\r
+          long long playbacktimeoffset; //this is the offset between the media time and system clock\r
+          long long pausetimecode;\r
+          bool paused;\r
+\r
+\r
+\r
+\r
 #ifdef VPE_OMX_SUPPORT\r
           static OMX_ERRORTYPE EventHandler_OMX(OMX_IN OMX_HANDLETYPE handle,OMX_IN OMX_PTR appdata,\r
           OMX_IN OMX_EVENTTYPE event_type,OMX_IN OMX_U32 data1,\r