From 64ce25e0478b0f9a3a1f55d705d2d433184a4ca6 Mon Sep 17 00:00:00 2001 From: Marten Richter Date: Sat, 13 Oct 2012 20:04:49 +0200 Subject: [PATCH] Major changes in AVSync code(Warning breaks part of recording playback) And: Fix in video switch (thanks to davep), mvp compile fix (thanks to sirwio) --- GNUmakefile | 2 +- audioomx.cc | 18 +-- audioomx.h | 2 +- vcolourtuner.cc | 2 +- videoomx.cc | 418 +++++++++++++++++++++++++++--------------------- videoomx.h | 30 ++-- wjpegcomplex.h | 2 + 7 files changed, 273 insertions(+), 201 deletions(-) diff --git a/GNUmakefile b/GNUmakefile index cc09c00..8841645 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -45,7 +45,7 @@ $(info MVP flags) LDFLAGS = -Wall -static LIBS = -lpthread -lrt -OBJECTS += wwss.o main.o threadp.o remotemvp.o ledmvp.o mtdmvp.o videomvp.o audiomvp.o osdmvp.o surfacemvp.o wjpegcomplex.o vmedialist.o vcolourtuner.o vmediaview.o vvideomedia.o mediafile.o +OBJECTS += wwss.o main.o threadp.o remotemvp.o ledmvp.o mtdmvp.o videomvp.o audiomvp.o osdmvp.o surfacemvp.o wjpegcomplex.o vmedialist.o vcolourtuner.o vmediaview.o vvideomedia.o TIOBJECT = ticonfig.o CROSSLIBS = ../jpeg/jpeg-6b/libjpeg.a INCLUDES = -I../jpeg/jpeg-6b -DVOMP_PLATTFORM_MVP diff --git a/audioomx.cc b/audioomx.cc index 6fed499..985ef93 100644 --- a/audioomx.cc +++ b/audioomx.cc @@ -1416,15 +1416,14 @@ UINT AudioOMX::DeliverMediaPacket(MediaPacket packet, const UCHAR* buffer, *samplepos += headerstrip; if (packet.synched) { if (cur_input_buf_omx) { - cur_input_buf_omx->nFlags |= OMX_BUFFERFLAG_ENDOFFRAME; + //cur_input_buf_omx->nFlags |= OMX_BUFFERFLAG_ENDOFFRAME; OMX_ERRORTYPE error = vw->ProtOMXEmptyThisBuffer(omx_aud_rend/*dec*/, cur_input_buf_omx); if (error != OMX_ErrorNone) { Log::getInstance()->log("Audio", Log::DEBUG, "OMX_EmptyThisBuffer 3 failed %x", error); } - //FrameWaitforDisplay(lastreftimeOMX); - vw->AdjustAudioPTS(correctAudioLatency(lastreftimeOMX,cur_input_buf_omx->nFilledLen/(2*2),48000)); + //vw->AdjustAudioPTS(correctAudioLatency(lastreftimeOMX,cur_input_buf_omx->nFilledLen/(2*2),48000)); cur_input_buf_omx = NULL;//write out old data } @@ -1449,7 +1448,7 @@ UINT AudioOMX::DeliverMediaPacket(MediaPacket packet, const UCHAR* buffer, cur_input_buf_omx=input_bufs_omx_free.front(); cur_input_buf_omx->nFilledLen=0; cur_input_buf_omx->nOffset=0; - cur_input_buf_omx->nTimeStamp=0; + cur_input_buf_omx->nTimeStamp=VideoOMX::intToOMXTicks(0); input_bufs_omx_free.pop_front(); input_bufs_omx_mutex.Unlock(); } @@ -1466,18 +1465,18 @@ UINT AudioOMX::DeliverMediaPacket(MediaPacket packet, const UCHAR* buffer, omx_first_frame = false; } else { cur_input_buf_omx->nFlags = 0; - cur_input_buf_omx->nFlags|=OMX_BUFFERFLAG_TIME_UNKNOWN; + //cur_input_buf_omx->nFlags|=OMX_BUFFERFLAG_TIME_UNKNOWN; } lastreftimeOMX = packet.presentation_time; // Log::getInstance()->log("Audio", Log::DEBUG, // "Time code %lld pts %lld dts %lld", lastreftimeOMX, packet.pts,packet.dts); lastreftimePTS = packet.pts; - cur_input_buf_omx->nTimeStamp =0;// lastreftimeOMX; // the clock component is faulty; + cur_input_buf_omx->nTimeStamp = VideoOMX::intToOMXTicks(lastreftimeOMX/10LL); // the clock component is faulty; } else { // Log::getInstance()->log("Audio", Log::DEBUG, // "packet NOT synched marker"); cur_input_buf_omx->nFlags = OMX_BUFFERFLAG_TIME_UNKNOWN; - cur_input_buf_omx->nTimeStamp = 0; + cur_input_buf_omx->nTimeStamp = VideoOMX::intToOMXTicks(0); } if (packet.disconti || achange) { @@ -1668,7 +1667,8 @@ UINT AudioOMX::DeliverMediaPacket(MediaPacket packet, const UCHAR* buffer, cur_input_buf_omx = input_bufs_omx_free.front(); cur_input_buf_omx->nFilledLen = 0; cur_input_buf_omx->nOffset = 0; - cur_input_buf_omx->nTimeStamp = 0; + cur_input_buf_omx->nTimeStamp = VideoOMX::intToOMXTicks(0); + cur_input_buf_omx->nFlags=OMX_BUFFERFLAG_TIME_UNKNOWN; input_bufs_omx_free.pop_front(); input_bufs_omx_mutex.Unlock(); break; @@ -1713,7 +1713,7 @@ UINT AudioOMX::DeliverMediaPacket(MediaPacket packet, const UCHAR* buffer, Log::getInstance()->log("Audio", Log::DEBUG, "OMX_EmptyThisBuffer 5 failed %x", error); } - if (packet.synched) vw->AdjustAudioPTS(correctAudioLatency(lastreftimeOMX,cur_input_buf_omx->nFilledLen/(2*2),48000)); + //if (packet.synched) vw->AdjustAudioPTS(correctAudioLatency(lastreftimeOMX,cur_input_buf_omx->nFilledLen/(2*2),48000)); cur_input_buf_omx = NULL; } diff --git a/audioomx.h b/audioomx.h index 2bd71c8..5eafae4 100644 --- a/audioomx.h +++ b/audioomx.h @@ -132,7 +132,7 @@ class AudioOMX : public Audio OMX_U32 omx_rend_clock_port; OMX_U32 omx_clock_output_port; - OMX_TICKS lastreftimeOMX; + long long lastreftimeOMX; ULLONG lastreftimePTS; diff --git a/vcolourtuner.cc b/vcolourtuner.cc index 73dfef7..1e828a4 100644 --- a/vcolourtuner.cc +++ b/vcolourtuner.cc @@ -64,7 +64,7 @@ VColourTuner::~VColourTuner() Log::getInstance()->log("VColourTuner",Log::DEBUG,"deleted %p",this); } -void VColourTuner::drawBox(int x, int y, int w, int h, Colour &c) { +void VColourTuner::drawBox(int x, int y, int w, int h, DrawStyle &c) { for (int row=y;rowdrawPixel(col,row,c); diff --git a/videoomx.cc b/videoomx.cc index b737bf3..1b26dc3 100644 --- a/videoomx.cc +++ b/videoomx.cc @@ -51,6 +51,8 @@ VideoOMX::VideoOMX() { lastreftimeOMX = 0; lastreftimePTS = 0; firstsynched = false; + cur_clock_time=0; + //cur_pts=0; mode=NORMAL; xpos=ypos=0.f; @@ -366,6 +368,8 @@ void VideoOMX::selectVideoMode(int interlaced) mymode=all_supp_modes+i; Log::getInstance()->log("Video", Log::NOTICE, "Found native mode %dx%d %d Hz i: %d", mymode->width,mymode->height,mymode->frame_rate,mymode->scan_mode); + native_width=mymode->width; + native_height=mymode->height; } } @@ -691,8 +695,8 @@ int VideoOMX::getClockAudioandInit(OMX_HANDLETYPE *p_omx_clock,OMX_U32 *p_omx_cl clock_conf.nSize=sizeof(clock_conf); clock_conf.nVersion.nVersion=OMX_VERSION; clock_conf.eState=OMX_TIME_ClockStateWaitingForStartTime; - clock_conf.nStartTime=0; - clock_conf.nOffset=0; + clock_conf.nStartTime=intToOMXTicks(0); + clock_conf.nOffset=intToOMXTicks(0); if (clock_references==1) clock_conf.nWaitMask=OMX_CLOCKPORT1; else clock_conf.nWaitMask=OMX_CLOCKPORT0|OMX_CLOCKPORT1; error=OMX_SetConfig(omx_clock,OMX_IndexConfigTimeClockState,&clock_conf); @@ -752,8 +756,8 @@ int VideoOMX::getClockVideoandInit() clock_conf.nSize=sizeof(clock_conf); clock_conf.nVersion.nVersion=OMX_VERSION; clock_conf.eState=OMX_TIME_ClockStateWaitingForStartTime; - clock_conf.nStartTime=0; - clock_conf.nOffset=0; + clock_conf.nStartTime=intToOMXTicks(0); + clock_conf.nOffset=intToOMXTicks(0); if (clock_references==1) clock_conf.nWaitMask=OMX_CLOCKPORT0; else clock_conf.nWaitMask=OMX_CLOCKPORT0|OMX_CLOCKPORT1; error=OMX_SetConfig(omx_clock,OMX_IndexConfigTimeClockState,&clock_conf); @@ -777,8 +781,8 @@ void VideoOMX::clockUnpause() clock_conf.nSize=sizeof(clock_conf); clock_conf.nVersion.nVersion=OMX_VERSION; clock_conf.eState=OMX_TIME_ClockStateRunning; - clock_conf.nStartTime=0; - clock_conf.nOffset=0; + clock_conf.nStartTime=intToOMXTicks(0); + clock_conf.nOffset=intToOMXTicks(0); clock_conf.nWaitMask=OMX_CLOCKPORT1; error=OMX_SetConfig(omx_clock,OMX_IndexConfigTimeClockState,&clock_conf); if (error!=OMX_ErrorNone) { @@ -799,8 +803,8 @@ void VideoOMX::clockPause() clock_conf.nSize=sizeof(clock_conf); clock_conf.nVersion.nVersion=OMX_VERSION; clock_conf.eState=OMX_TIME_ClockStateStopped; - clock_conf.nStartTime=0; - clock_conf.nOffset=0; + clock_conf.nStartTime=intToOMXTicks(0); + clock_conf.nOffset=intToOMXTicks(0); clock_conf.nWaitMask=OMX_CLOCKPORT1; error=OMX_SetConfig(omx_clock,OMX_IndexConfigTimeClockState,&clock_conf); if (error!=OMX_ErrorNone) { @@ -1076,7 +1080,7 @@ int VideoOMX::AllocateCodecsOMX() - ft_type.xFramerate=0;//25*(1<<16);//demux->getFrameRate()*(1<<16); + ft_type.xFramerate=0*(1<<16);//25*(1<<16);//demux->getFrameRate()*(1<<16); Log::getInstance()->log("Video", Log::DEBUG, "Framerate: %d",demux->getFrameRate()); error=OMX_SetParameter(omx_vid_dec,OMX_IndexParamVideoPortFormat,&ft_type); if (error!=OMX_ErrorNone){ @@ -1314,7 +1318,7 @@ int VideoOMX::AllocateCodecsOMX() }*/ - playbacktimeoffset=-GetCurrentSystemTime(); + //playbacktimeoffset=-GetCurrentSystemTime(); paused=false; iframemode=false; omx_running=true; @@ -1486,7 +1490,7 @@ int VideoOMX::CommandFinished(OMX_HANDLETYPE handle,OMX_U32 command,OMX_U32 data if (current.event_type==OMX_EventError) { omx_events.erase(itty); omx_event_mutex.Unlock(); - Log::getInstance()->log("Video", Log::DEBUG, "Command Finished on Error"); + Log::getInstance()->log("Video", Log::DEBUG, "Command Finished on Error %x",current.data1); return 0; } else if (current.event_type==OMX_EventCmdComplete && current.data1==command && current.data2==data2) { @@ -1604,191 +1608,196 @@ 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_time_pts.clear(); - input_is_last.clear(); + //input_time_pts.clear(); + //input_is_last.clear(); input_bufs_omx_mutex.Unlock(); } - - -int VideoOMX::DeAllocateCodecsOMX() +int VideoOMX::FlushRenderingPipe() { OMX_ERRORTYPE error; - omx_running=false; - Log::getInstance()->log("Video", Log::DEBUG, "enter deallocatecodecsomx"); - threadStop(); + 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 1 failed %x", error); - if (cur_input_buf_omx) { - cur_input_buf_omx->nFlags|=OMX_BUFFERFLAG_EOS; - OMX_ERRORTYPE error=ProtOMXEmptyThisBuffer(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 - } - clock_mutex.Lock(); - 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"); + 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 2 failed %x", error); } - clock_mutex.Unlock(); - - idleClock(); - clock_mutex.Lock(); - if (dodeint) { - if (!ChangeComponentState(omx_vid_deint, OMX_StateIdle)) { - Log::getInstance()->log("Video", Log::DEBUG, - "vid_deint ChangeComponentState"); + if (!CommandFinished(omx_vid_dec, OMX_CommandFlush, + omx_codec_output_port)) { + Log::getInstance()->log("Video", Log::DEBUG, + "flush cmd codec 3 failed"); + } - } + if (!CommandFinished(omx_vid_sched, OMX_CommandFlush, + omx_shed_input_port)) { + Log::getInstance()->log("Video", Log::DEBUG, + "flush cmd shed 4 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 5 failed %x", error); + } - if (!ChangeComponentState(omx_vid_sched,OMX_StateIdle)) { - Log::getInstance()->log("Video", Log::DEBUG, "vid_shed ChangeComponentState"); + 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 6 failed %x", error); } - if (!ChangeComponentState(omx_vid_rend,OMX_StateIdle)) { - Log::getInstance()->log("Video", Log::DEBUG, "vid_rend ChangeComponentState"); + if (!CommandFinished(omx_vid_dec, OMX_CommandFlush, + omx_codec_output_port)) { + Log::getInstance()->log("Video", Log::DEBUG, + "flush cmd codec 7 failed"); + } + if (!CommandFinished(omx_vid_deint, OMX_CommandFlush, + omx_deint_input_port)) { + Log::getInstance()->log("Video", Log::DEBUG, + "flush cmd deint 8 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 9 failed %x", error); + } - // TODO proper deinit sequence - // first flush all buffers + 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 10 failed %x", error); - 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); + if (!CommandFinished(omx_vid_deint, OMX_CommandFlush, + omx_deint_output_port)) { + Log::getInstance()->log("Video", Log::DEBUG, + "flush cmd deint 11 failed"); + } - } + if (!CommandFinished(omx_vid_sched, OMX_CommandFlush, + omx_shed_input_port)) { + Log::getInstance()->log("Video", Log::DEBUG, + "flush cmd shed 12 failed"); + } - 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); - } + 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_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"); - } + error = OMX_SendCommand(omx_vid_sched, OMX_CommandFlush, + omx_shed_output_port, NULL); + if (error != OMX_ErrorNone) { + Log::getInstance()->log("Video", Log::DEBUG, + "OMX_Flush shed out failed %x", error); - //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_rend, OMX_CommandFlush, + omx_rend_input_port)) { + Log::getInstance()->log("Video", Log::DEBUG, + "flush cmd shed rend failed"); + } - 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_output_port)) { + Log::getInstance()->log("Video", Log::DEBUG, + "flush cmd shed rend failed"); + } +} - if (!CommandFinished(omx_vid_sched, OMX_CommandFlush, - omx_shed_input_port)) { - Log::getInstance()->log("Video", Log::DEBUG, - "flush cmd shed failed"); - } +int VideoOMX::DeAllocateCodecsOMX() +{ + OMX_ERRORTYPE error; + omx_running=false; + Log::getInstance()->log("Video", Log::DEBUG, "enter deallocatecodecsomx"); + threadStop(); + if (cur_input_buf_omx) { + cur_input_buf_omx->nFlags|=OMX_BUFFERFLAG_EOS; + OMX_ERRORTYPE error=ProtOMXEmptyThisBuffer(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 + } + clock_mutex.Lock(); + 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"); + } + clock_mutex.Unlock(); + idleClock(); + clock_mutex.Lock(); - 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 (dodeint) { + if (!ChangeComponentState(omx_vid_deint, OMX_StateIdle)) { + Log::getInstance()->log("Video", Log::DEBUG, + "vid_deint ChangeComponentState"); + } } - error = OMX_SendCommand(omx_vid_sched, OMX_CommandFlush, - omx_shed_output_port, NULL); - if (error != OMX_ErrorNone) { - Log::getInstance()->log("Video", Log::DEBUG, - "OMX_Flush shed out failed %x", error); - } + if (!ChangeComponentState(omx_vid_sched,OMX_StateIdle)) { + Log::getInstance()->log("Video", Log::DEBUG, "vid_shed ChangeComponentState"); + } + if (!ChangeComponentState(omx_vid_rend,OMX_StateIdle)) { + Log::getInstance()->log("Video", Log::DEBUG, "vid_rend ChangeComponentState"); - if (!CommandFinished(omx_vid_rend, OMX_CommandFlush, - omx_rend_input_port)) { - Log::getInstance()->log("Video", Log::DEBUG, - "flush cmd shed rend failed"); } - if (!CommandFinished(omx_vid_sched, OMX_CommandFlush, - omx_shed_output_port)) { - Log::getInstance()->log("Video", Log::DEBUG, - "flush cmd shed rend failed"); - } + + + // TODO proper deinit sequence + // first flush all buffers + FlushRenderingPipe(); @@ -1999,7 +2008,7 @@ int VideoOMX::pause() if (!paused) { paused=true; //maybe also change omx clock? - pausetimecode=GetCurrentSystemTime(); + //pausetimecode=GetCurrentSystemTime(); } return 1; @@ -2011,7 +2020,7 @@ int VideoOMX::unPause() // FIXME get rid - same as play!! Not here! Log::getInstance()->log("Video", Log::DEBUG, "enter unpause"); if (paused) { - playbacktimeoffset+=GetCurrentSystemTime()-pausetimecode; + // playbacktimeoffset+=GetCurrentSystemTime()-pausetimecode; paused=false; // may be also change omx clock } @@ -2051,10 +2060,53 @@ int VideoOMX::blank(void) return 1; } -ULLONG VideoOMX::getCurrentTimestamp() -{ - if (iframemode) return 0; - return cur_pts; +ULLONG VideoOMX::getCurrentTimestamp() { + if (iframemode) + return 0; + long long ncur_clock_time = cur_clock_time; + if (omx_running) { + clock_mutex.Lock(); + OMX_ERRORTYPE error; + 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; + error= OMX_GetConfig(omx_clock, OMX_IndexConfigTimeClockState, + &clock_conf); + if (error != OMX_ErrorNone) { + Log::getInstance()->log("Video", Log::DEBUG,"getCurrentTimestamp IndexConfigTimeClockState failed %x",error); + } + + if (clock_conf.eState == OMX_TIME_ClockStateRunning) { + + OMX_TIME_CONFIG_TIMESTAMPTYPE cur_time_stamp; + memset(&cur_time_stamp, 0, sizeof(cur_time_stamp)); + cur_time_stamp.nSize = sizeof(cur_time_stamp); + cur_time_stamp.nVersion.nVersion = OMX_VERSION; + cur_time_stamp.nPortIndex = omx_clock_output_port; + error = OMX_GetConfig(omx_clock, OMX_IndexConfigTimeCurrentMediaTime, + &cur_time_stamp); + if (error != OMX_ErrorNone) { + Log::getInstance()->log("Video",Log::DEBUG,"getCurrentTimestamp OMX_IndexConfigTimeCurrentMediaTime failed %x",error); + } else { + long long temp = cur_time_stamp.nTimestamp.nLowPart + | ((long long) cur_time_stamp.nTimestamp.nHighPart << 32); + ncur_clock_time = cur_clock_time = temp * 10LL; + } + } + clock_mutex.Unlock(); + } + + //ncur_clock_time -= startoffset; + ncur_clock_time -= lastreftimeOMX; + long long result = lastreftimePTS; + result += (long long) (ncur_clock_time / 10000LL * 90LL); + if (result < 0) + result = (1LL << 33) - result; + //Log::getInstance()->log("Video", Log::DEBUG,"getCurrentTimestamp %lld %lld %lld %lld %lld %lld",ncur_clock_time,cur_clock_time,lastreftimeOMX,lastreftimePTS,result,startoffset); + + return result; + } // to be removed @@ -2154,9 +2206,9 @@ void VideoOMX::ResetTimeOffsets() { lastrefvideotime=0; lastreftimeOMX=0; lastreftimePTS=0; - cur_pts=0; + //cur_pts=0; } - +/* long long VideoOMX::GetCurrentSystemTime() { struct timespec ts; @@ -2193,7 +2245,7 @@ bool VideoOMX::FrameSkip(long long pts) /* Log::getInstance()->log("Video", Log::DEBUG, "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);*/ + target_time-current_time);* } else { skipping=false; } @@ -2203,7 +2255,7 @@ bool VideoOMX::FrameSkip(long long pts) skipping = true; /* 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);*/ + target_time-current_time);* } else { skipping = false; } @@ -2244,7 +2296,7 @@ void VideoOMX::AdjustAudioPTS(long long pts) } } - +*/ void VideoOMX::threadPostStopCleanup() { //Doing nothing @@ -2262,18 +2314,18 @@ void VideoOMX::threadMethod() OMX_BUFFERHEADERTYPE* pict=NULL; long long time; - bool islast; + //bool islast; if (!paused) { input_bufs_omx_mutex.Lock(); if (input_bufs_omx_present.size()>0) { - cur_pts=input_time_pts.front(); + //cur_pts=input_time_pts.front(); pict=input_bufs_omx_present.front(); time=input_time_present.front(); - islast=input_is_last.front(); + //islast=input_is_last.front(); input_bufs_omx_present.pop_front(); input_time_present.pop_front(); - input_time_pts.pop_front(); - input_is_last.pop_front(); + //input_time_pts.pop_front(); + //input_is_last.pop_front(); } input_bufs_omx_mutex.Unlock(); } @@ -2281,7 +2333,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)*/false && !(pict->nFlags &OMX_BUFFERFLAG_STARTTIME)) { input_bufs_omx_mutex.Lock(); input_bufs_omx_free.push_back(pict); @@ -2291,7 +2343,7 @@ void VideoOMX::threadMethod() } else { // Log::getInstance()->log("Video", Log::DEBUG, // "prot empty this buffer in"); - if (islast) FrameWaitforDisplay(time); + //if (islast) FrameWaitforDisplay(time); OMX_ERRORTYPE error = ProtOMXEmptyThisBuffer(omx_vid_dec, pict); if (error != OMX_ErrorNone) { Log::getInstance()->log("Video", Log::DEBUG, @@ -2376,13 +2428,13 @@ void VideoOMX::DeinterlaceFix() } -void VideoOMX::PutBufferToPres(OMX_BUFFERHEADERTYPE* buffer, long long time, long long pts,bool islast) +void VideoOMX::PutBufferToPres(OMX_BUFFERHEADERTYPE* buffer, long long time, /*long long pts,*/bool islast) { input_bufs_omx_mutex.Lock(); input_bufs_omx_present.push_back(buffer); input_time_present.push_back(time); - input_time_pts.push_back(pts); - input_is_last.push_back(islast); + //input_time_pts.push_back(pts); +// input_is_last.push_back(islast); input_bufs_omx_mutex.Unlock(); } @@ -2454,12 +2506,12 @@ UINT VideoOMX::DeliverMediaPacket(MediaPacket packet, if (!omx_running) return 0; // if we are not runnig do not do this if (paused) return 0; //Block if we pause - if (packet.synched && FrameSkip(packet.presentation_time)) { + /*if (packet.synched && FrameSkip(packet.presentation_time)) { *samplepos=packet.length; Log::getInstance()->log("Video", Log::DEBUG, "DeliverMediaPacketOMX Frameskip"); *samplepos=packet.length; return packet.length; - } + }*/ //long long current_media_time=GetCurrentSystemTime()+playbacktimeoffset; /* if (packet.synched && (packet.presentation_time<0 /*|| // preroll skip frames @@ -2482,7 +2534,7 @@ UINT VideoOMX::DeliverMediaPacket(MediaPacket packet, if (packet.disconti) { firstsynched=false; if (cur_input_buf_omx) { - PutBufferToPres(cur_input_buf_omx, lastreftimeOMX,lastreftimePTS, true); + PutBufferToPres(cur_input_buf_omx, lastreftimeOMX,/*lastreftimePTS,*/ true); cur_input_buf_omx=NULL; } } @@ -2500,7 +2552,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,lastreftimePTS,true); + PutBufferToPres(cur_input_buf_omx, lastreftimeOMX,/*lastreftimePTS,*/true); cur_input_buf_omx=NULL;//write out old data @@ -2525,7 +2577,7 @@ UINT VideoOMX::DeliverMediaPacket(MediaPacket packet, cur_input_buf_omx=input_bufs_omx_free.front(); cur_input_buf_omx->nFilledLen=0; cur_input_buf_omx->nOffset=0; - cur_input_buf_omx->nTimeStamp=0; + cur_input_buf_omx->nTimeStamp=intToOMXTicks(0); input_bufs_omx_free.pop_front(); input_bufs_omx_mutex.Unlock(); } @@ -2543,20 +2595,19 @@ UINT VideoOMX::DeliverMediaPacket(MediaPacket packet, Log::getInstance()->log("Video", Log::DEBUG, "Starttime"); omx_first_frame=false; } else { - //cur_input_buf_omx->nFlags=0; - cur_input_buf_omx->nFlags|=OMX_BUFFERFLAG_TIME_UNKNOWN; + 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; + cur_input_buf_omx->nTimeStamp=intToOMXTicks(lastreftimeOMX/10LL); // the clock component is faulty; } else { cur_input_buf_omx->nFlags=OMX_BUFFERFLAG_TIME_UNKNOWN; - cur_input_buf_omx->nTimeStamp=0; + cur_input_buf_omx->nTimeStamp=intToOMXTicks(0); //Log::getInstance()->log("Video", Log::DEBUG, "packet unsynched marker"); - // ms->SetSyncPoint(TRUE); } if (packet.disconti) cur_input_buf_omx->nFlags|=OMX_BUFFERFLAG_DISCONTINUITY; @@ -2574,7 +2625,7 @@ UINT VideoOMX::DeliverMediaPacket(MediaPacket packet, *samplepos+=cancopy; // push old buffer out - PutBufferToPres(cur_input_buf_omx, lastreftimeOMX,lastreftimePTS,false); + PutBufferToPres(cur_input_buf_omx, lastreftimeOMX,/*lastreftimePTS,*/false); cur_input_buf_omx=NULL; // get5 new buffer input_bufs_omx_mutex.Lock(); @@ -2586,12 +2637,11 @@ UINT VideoOMX::DeliverMediaPacket(MediaPacket packet, cur_input_buf_omx=input_bufs_omx_free.front(); cur_input_buf_omx->nFilledLen=0; cur_input_buf_omx->nOffset=0; - cur_input_buf_omx->nTimeStamp=0; + cur_input_buf_omx->nFlags=OMX_BUFFERFLAG_TIME_UNKNOWN; + cur_input_buf_omx->nTimeStamp=intToOMXTicks(0); input_bufs_omx_free.pop_front(); input_bufs_omx_mutex.Unlock(); - cur_input_buf_omx->nFlags=OMX_BUFFERFLAG_TIME_UNKNOWN; - } memcpy(cur_input_buf_omx->pBuffer+cur_input_buf_omx->nFilledLen, buffer+packet.pos_buffer+*samplepos,haveToCopy); @@ -2627,7 +2677,7 @@ bool VideoOMX::displayIFrame(const UCHAR* buffer, UINT length) { cur_input_buf_omx = input_bufs_omx_free.front(); cur_input_buf_omx->nFilledLen = 0; cur_input_buf_omx->nOffset = 0; - cur_input_buf_omx->nTimeStamp = 0; + cur_input_buf_omx->nTimeStamp = intToOMXTicks(0); input_bufs_omx_free.pop_front(); input_bufs_omx_mutex.Unlock(); } @@ -2664,8 +2714,8 @@ bool VideoOMX::displayIFrame(const UCHAR* buffer, UINT length) { |= OMX_BUFFERFLAG_TIME_UNKNOWN; } - cur_input_buf_omx->nTimeStamp = 0; - PutBufferToPres(cur_input_buf_omx, 0,0,false); + cur_input_buf_omx->nTimeStamp = intToOMXTicks(0); + PutBufferToPres(cur_input_buf_omx, 0,/*0,*/false); cur_input_buf_omx = NULL; if (!cur_input_buf_omx) { @@ -2685,7 +2735,8 @@ bool VideoOMX::displayIFrame(const UCHAR* buffer, UINT length) { cur_input_buf_omx = input_bufs_omx_free.front(); cur_input_buf_omx->nFilledLen = 0; cur_input_buf_omx->nOffset = 0; - cur_input_buf_omx->nTimeStamp = 0; + cur_input_buf_omx->nTimeStamp = intToOMXTicks(0); + cur_input_buf_omx->nFlags|= OMX_BUFFERFLAG_TIME_UNKNOWN; input_bufs_omx_free.pop_front(); input_bufs_omx_mutex.Unlock(); break; @@ -2719,9 +2770,9 @@ bool VideoOMX::displayIFrame(const UCHAR* buffer, UINT length) { cur_input_buf_omx->nFlags |= OMX_BUFFERFLAG_TIME_UNKNOWN; } - cur_input_buf_omx->nTimeStamp = 0; + cur_input_buf_omx->nTimeStamp = intToOMXTicks(0); - PutBufferToPres(cur_input_buf_omx, 0,0,false); + PutBufferToPres(cur_input_buf_omx, 0,/*0,*/false); cur_input_buf_omx = NULL; @@ -2731,8 +2782,10 @@ bool VideoOMX::displayIFrame(const UCHAR* buffer, UINT length) { int VideoOMX::EnterIframePlayback() { + Log::getInstance()->log("Video", Log::DEBUG, + "EnterIframePlayback"); if (cur_input_buf_omx) { - PutBufferToPres(cur_input_buf_omx, lastreftimeOMX, lastreftimePTS,true); + PutBufferToPres(cur_input_buf_omx, lastreftimeOMX,/* lastreftimePTS,*/true); cur_input_buf_omx = NULL; } input_bufs_omx_mutex.Lock(); @@ -2741,9 +2794,16 @@ int VideoOMX::EnterIframePlayback() input_bufs_omx_present.pop_front(); } input_time_present.clear(); - input_time_pts.clear(); - input_is_last.clear(); + /*input_time_pts.clear(); + input_is_last.clear();*/ input_bufs_omx_mutex.Unlock(); + Log::getInstance()->log("Video", Log::DEBUG, + "EnterIframePlayback 2"); + clock_mutex.Lock(); + FlushRenderingPipe(); + clock_mutex.Unlock(); + Log::getInstance()->log("Video", Log::DEBUG, + "leave IframePlayback"); iframemode=true; diff --git a/videoomx.h b/videoomx.h index cdc0c13..5effb86 100644 --- a/videoomx.h +++ b/videoomx.h @@ -40,6 +40,7 @@ #include "video.h" #include "threadsystem.h" +#define OMX_SKIP64BIT #include #include @@ -95,7 +96,7 @@ class VideoOMX : public Video, public Thread_TYPE ULLONG getCurrentTimestamp(); bool displayIFrame(const UCHAR* bulibaver, UINT length); - virtual bool dtsTimefix(){return true;} //please we need dts time values + virtual bool dtsTimefix(){return false;} //please we need dts time values virtual int getTeletextBufferFaktor(){return 5;}; // Writing Data to Videodevice @@ -128,6 +129,13 @@ class VideoOMX : public Video, public Thread_TYPE int initUsingOSDObjects(); int shutdownUsingOSDObjects() {return shutdown();}; + static inline OMX_TICKS intToOMXTicks(long long pts) { + OMX_TICKS temp; + temp.nLowPart=pts; + temp.nHighPart=pts>>32; + return temp; + } + private: @@ -147,20 +155,20 @@ class VideoOMX : public Video, public Thread_TYPE long long startoffset; long long lastrefvideotime; long long lastrefaudiotime; - long long cur_pts; - OMX_TICKS lastreftimeOMX; + // long long cur_pts; + long long lastreftimeOMX; ULLONG lastreftimePTS; - long long playbacktimeoffset; //this is the offset between the media time and system clock - long long pausetimecode; + // long long playbacktimeoffset; //this is the offset between the media time and system clock + // long long pausetimecode; bool paused; - static long long GetCurrentSystemTime(); + /* static long long GetCurrentSystemTime(); static void WaitUntil(long long time); void FrameWaitforDisplay(long long pts); bool FrameSkip(long long pts); bool skipping; - void AdjustAudioPTS(long long pts); + void AdjustAudioPTS(long long pts);*/ @@ -201,6 +209,7 @@ class VideoOMX : public Video, public Thread_TYPE void clockUnpause(); Mutex clock_mutex; //clock mutex is now responsible for all omx stuff + long long cur_clock_time; @@ -230,17 +239,18 @@ class VideoOMX : public Video, public Thread_TYPE int AllocateCodecsOMX(); int DeAllocateCodecsOMX(); + int FlushRenderingPipe(); vector input_bufs_omx_all; list input_bufs_omx_free; list input_bufs_omx_present; list input_time_present; - list input_time_pts; - list input_is_last; + //list input_time_pts; + // list input_is_last; Mutex input_bufs_omx_mutex; OMX_BUFFERHEADERTYPE* cur_input_buf_omx; - void PutBufferToPres(OMX_BUFFERHEADERTYPE* buffer, long long time,long long pts, bool is_last); + void PutBufferToPres(OMX_BUFFERHEADERTYPE* buffer, long long time,/*long long pts,*/ bool is_last); void threadMethod(); void threadPostStopCleanup(); diff --git a/wjpegcomplex.h b/wjpegcomplex.h index 008e4a5..c0956f3 100644 --- a/wjpegcomplex.h +++ b/wjpegcomplex.h @@ -27,6 +27,8 @@ #include #include +#include "wjpeg.h" + #ifdef WIN32 #include -- 2.39.2