From 1baf015a8f92024cfb65ba4d8169570290087d56 Mon Sep 17 00:00:00 2001 From: Marten Richter Date: Sun, 28 Oct 2012 19:40:47 +0100 Subject: [PATCH] Increase streaming buffers, start video only at independent frames, remove buffer skip code --- audioomx.cc | 4 +-- defines.h | 4 +++ playerlivetv.cc | 4 +-- videoomx.cc | 87 +++++++++++++++++++++++++++++++++++++++++++++++-- videoomx.h | 2 ++ 5 files changed, 95 insertions(+), 6 deletions(-) diff --git a/audioomx.cc b/audioomx.cc index 14627d9..978f9b3 100644 --- a/audioomx.cc +++ b/audioomx.cc @@ -1673,14 +1673,14 @@ UINT AudioOMX::DeliverMediaPacket(MediaPacket packet, const UCHAR* buffer, //Log::getInstance()->log("Audio", Log::DEBUG, "DeliverMediaPacketOMX time %lld",packet.presentation_time); - if (packet.synched && packet.presentation_time <= 0) { +/* if (packet.synched && packet.presentation_time <= 0) { *samplepos = packet.length; firstsynched = false; lsync=true; Log::getInstance()->log("Audio", Log::DEBUG, "DeliverMediaPacketOMX Frameskip"); return packet.length; - } + }*/ diff --git a/defines.h b/defines.h index 76f36c8..aec5c86 100644 --- a/defines.h +++ b/defines.h @@ -51,6 +51,7 @@ long long getTimeMS(); #define STRTOUL strtoul #define CLOSESOCKET closesocket #define DEFAULT_TCP_WINDOWSIZENR 1 /*=2048*/ + #define PLAYER_MAX_STREAMING_BUFFERS 120 // for video in uints of 50000 KB #define VOMP_HAS_EXIT @@ -112,6 +113,7 @@ long long getTimeMS(); // #define VPE_LIBAV_MPEG2_TRANSCODING #define DEFAULT_TCP_WINDOWSIZENR 6 /*=2048*/ + #define PLAYER_MAX_STREAMING_BUFFERS 120 // for video in uints of 50000 KB #define TV_NORM_SWITCHABLE #define HANDLE_VT_SWITCHING @@ -129,6 +131,7 @@ long long getTimeMS(); #define Video_TYPE VideoMVP #define Surface_TYPE SurfaceMVP //deprecated #define DEFAULT_TCP_WINDOWSIZENR 1 /*=2048*/ + #define PLAYER_MAX_STREAMING_BUFFERS 11 // for video in uints of 50000 KB #define PAL_WSS #define MVP_REMOTE_TYPES @@ -147,6 +150,7 @@ long long getTimeMS(); #define Video_TYPE VideoNMT #define Surface_TYPE SurfaceDirectFB //deprecated #define DEFAULT_TCP_WINDOWSIZENR 1 /*=2048*/ + #define PLAYER_MAX_STREAMING_BUFFERS 11 // for video in uints of 50000 KB #define VOMP_LINUX_CLOCK CLOCK_REALTIME diff --git a/playerlivetv.cc b/playerlivetv.cc index 7d42f72..bbd3928 100644 --- a/playerlivetv.cc +++ b/playerlivetv.cc @@ -301,7 +301,7 @@ void PlayerLiveTV::streamReceive(ULONG flag, void* data, ULONG len) messageQueue->postMessageFromOuterSpace(m); } - if (streamChunks.size() < 11) + if (streamChunks.size() < PLAYER_MAX_STREAMING_BUFFERS) { StreamChunk s; s.data = data; @@ -783,7 +783,7 @@ void PlayerLiveTV::threadMethod() if (state == S_PREBUFFERING) { - logger->log("PlayerLiveTV", Log::DEBUG, "chunk mark3"); + // logger->log("PlayerLiveTV", Log::DEBUG, "chunk mark3"); ++preBufferCount; ULONG percentDone = (ULONG)(preBufferCount / (float)preBufferAmount * 100); logger->log("PlayerLiveTV", Log::DEBUG, "Prebuffering %lu%%", percentDone); diff --git a/videoomx.cc b/videoomx.cc index 770e9c9..548c58d 100644 --- a/videoomx.cc +++ b/videoomx.cc @@ -145,6 +145,9 @@ OMX_ERRORTYPE VideoOMX::EmptyBufferDone_OMX(OMX_IN OMX_HANDLETYPE hcomp,OMX_IN O //Log::getInstance()->log("Video", Log::NOTICE, "EmptyBufferDone"); VideoOMX *video=(VideoOMX *)getInstance(); +/* long long temp =buffer->nTimeStamp.nLowPart + | ((long long) buffer->nTimeStamp.nHighPart << 32); + Log::getInstance()->log("Video", Log::NOTICE, "EBD Video %lld %x",temp,buffer->nFlags);*/ video->ReturnEmptyOMXBuffer(buffer); return OMX_ErrorNone; @@ -767,6 +770,18 @@ int VideoOMX::getClockVideoandInit() 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_ClockStateStopped; + clock_conf.nStartTime=intToOMXTicks(0); + clock_conf.nOffset=intToOMXTicks(0); + error=OMX_SetConfig(omx_clock,OMX_IndexConfigTimeClockState,&clock_conf); + if (error!=OMX_ErrorNone) { + Log::getInstance()->log("Video", Log::DEBUG, "VuI Clock IndexConfigTimeClockState failed %x", error); + } + + memset(&clock_conf,0,sizeof(clock_conf)); clock_conf.nSize=sizeof(clock_conf); clock_conf.nVersion.nVersion=OMX_VERSION; @@ -2309,10 +2324,34 @@ OMX_ERRORTYPE VideoOMX::ProtOMXEmptyThisBuffer(OMX_HANDLETYPE handle, OMX_BUFFER // protect the call to empty this buffer int oldcancelstate; int oldcanceltype; +/* long long temp =buffer->nTimeStamp.nLowPart + | ((long long) buffer->nTimeStamp.nHighPart << 32);*/ + pthread_testcancel(); pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldcancelstate); pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, &oldcanceltype); clock_mutex.Lock(); +// Diagnosis code +/* OMX_ERRORTYPE error; + OMX_TIME_CONFIG_TIMESTAMPTYPE timestamp; + memset(×tamp, 0, sizeof(timestamp)); + timestamp.nSize = sizeof(timestamp); + timestamp.nVersion.nVersion = OMX_VERSION; + timestamp.nPortIndex =omx_clock_output_port; + + error = OMX_GetConfig(omx_clock, OMX_IndexConfigTimeCurrentMediaTime, + ×tamp); + + if (error != OMX_ErrorNone) { + Log::getInstance()->log("Audio", Log::DEBUG, + "Init OMX_IndexConfigAudioRenderingLatencyfailed %x %d", error, + omx_rend_input_port); + } + long long temp2 =timestamp.nTimestamp.nLowPart + | ((long long) timestamp.nTimestamp.nHighPart << 32); + + + Log::getInstance()->log("Video", Log::NOTICE, "OMXETB %x %lld %lld %x",handle,temp,temp2,buffer->nFlags);*/ OMX_ERRORTYPE ret_val; ret_val=OMX_EmptyThisBuffer(handle,buffer); clock_mutex.Unlock(); @@ -2322,6 +2361,43 @@ OMX_ERRORTYPE VideoOMX::ProtOMXEmptyThisBuffer(OMX_HANDLETYPE handle, OMX_BUFFER return ret_val; } +bool VideoOMX::detectIFrame(const UCHAR *buffer,unsigned int length) +{ + const UCHAR* curbuf=buffer; + const UCHAR* curbufend=buffer+length; + unsigned int detector=0xFFFFFFFF; + bool gotaud=false; // have seen access unit delimiter + + while (curbuf!=curbufend) { + detector<<=8; + detector|=*curbuf; + if (h264) { + if (detector==0x00000109) { + gotaud=true; + detector=0xFFFFFFFF; + } else if (gotaud &&detector==0x00000001) { + curbuf++; + if (curbuf!=curbufend) { + unsigned char picttype=(*curbuf)& 0x1F; + return picttype==0x07; + } + } + } else { + if (detector==0x00000100) { + curbuf++; + if (curbuf==curbufend) return false; + curbuf++; + if (curbuf==curbufend) return false; + unsigned char picttype=((*curbuf) >> 3) & 0x07; + return picttype==1; + } + } + curbuf++; + } + + return false; // no frame found +} + void VideoOMX::PrepareMediaSample(const MediaPacketList& mplist,UINT samplepos) { @@ -2372,13 +2448,13 @@ UINT VideoOMX::DeliverMediaPacket(MediaPacket packet, if (paused) return 0; //Block if we pause //Log::getInstance()->log("Video", Log::DEBUG, "DeliverMediaPacketOMX time %lld",packet.presentation_time); - if (packet.synched && packet.presentation_time <= 2000000) { +/* if (packet.synched && packet.presentation_time <= 0) { *samplepos = packet.length; firstsynched = false; Log::getInstance()->log("Video", Log::DEBUG, "DeliverMediaPacketOMX Frameskip"); return packet.length; - } + }*/ /*if (packet.synched && FrameSkip(packet.presentation_time)) { *samplepos=packet.length; @@ -2424,6 +2500,13 @@ UINT VideoOMX::DeliverMediaPacket(MediaPacket packet, // buffer[packet.pos_buffer+0],buffer[packet.pos_buffer+1],buffer[packet.pos_buffer+2],buffer[packet.pos_buffer+3]); *samplepos+=headerstrip; if ( packet.synched ) { + if (!firstsynched) { + // check if this is an I frame, the decoder does not like non I frames at startup! + if (!detectIFrame(buffer,packet.length)) { + *samplepos=packet.length;//if we have not processed at least one + return packet.length;//synched packet ignore it! + } + } if (cur_input_buf_omx) { cur_input_buf_omx->nFlags|=OMX_BUFFERFLAG_ENDOFFRAME; PutBufferToPres(cur_input_buf_omx); diff --git a/videoomx.h b/videoomx.h index fe931d8..332c38c 100644 --- a/videoomx.h +++ b/videoomx.h @@ -182,6 +182,8 @@ class VideoOMX : public Video const UCHAR* bulibaver, UINT *samplepos); + bool detectIFrame(const UCHAR *buffer,unsigned int length); + int PrepareInputBufsOMX(); int DestroyInputBufsOMX(); -- 2.39.2