diff --git a/packages/mediacenter/xbmc/patches/xbmc-990.20-PR2286.patch b/packages/mediacenter/xbmc/patches/xbmc-990.20-PR2286.patch new file mode 100644 index 0000000000..373c7963de --- /dev/null +++ b/packages/mediacenter/xbmc/patches/xbmc-990.20-PR2286.patch @@ -0,0 +1,520 @@ +From dac7871e3440b9d4235fcd91af1c2d41a931d69d Mon Sep 17 00:00:00 2001 +From: popcornmix +Date: Mon, 18 Feb 2013 23:04:28 +0000 +Subject: [PATCH] [rbp] Handle resolution changes during video stream. + +When the resolution changes, GPU sends a port settings changed message. Host has to acknowledge it by disabling and enabling the affected ports. +--- + xbmc/cores/omxplayer/OMXPlayerVideo.cpp | 229 ++++++++++++------------------- + xbmc/cores/omxplayer/OMXPlayerVideo.h | 7 +- + xbmc/cores/omxplayer/OMXVideo.cpp | 95 ++++++++----- + xbmc/cores/omxplayer/OMXVideo.h | 7 +- + 4 files changed, 151 insertions(+), 187 deletions(-) + +diff --git a/xbmc/cores/omxplayer/OMXPlayerVideo.cpp b/xbmc/cores/omxplayer/OMXPlayerVideo.cpp +index 5a6e31e..a033c78 100644 +--- a/xbmc/cores/omxplayer/OMXPlayerVideo.cpp ++++ b/xbmc/cores/omxplayer/OMXPlayerVideo.cpp +@@ -83,9 +83,6 @@ class COMXMsgVideoCodecChange : public CDVDMsg + m_iSubtitleDelay = 0; + m_FlipTimeStamp = 0.0; + m_bRenderSubs = false; +- m_width = 0; +- m_height = 0; +- m_fps = 0.0f; + m_flags = 0; + m_bAllowFullscreen = false; + m_iCurrentPts = DVD_NOPTS_VALUE; +@@ -98,12 +95,7 @@ class COMXMsgVideoCodecChange : public CDVDMsg + m_messageQueue.SetMaxDataSize(10 * 1024 * 1024); + m_messageQueue.SetMaxTimeSize(8.0); + +- RESOLUTION res = g_graphicsContext.GetVideoResolution(); +- m_video_width = g_settings.m_ResInfo[res].iScreenWidth; +- m_video_height = g_settings.m_ResInfo[res].iScreenHeight; +- + m_dst_rect.SetRect(0, 0, 0, 0); +- + } + + OMXPlayerVideo::~OMXPlayerVideo() +@@ -125,6 +117,8 @@ bool OMXPlayerVideo::OpenStream(CDVDStreamInfo &hints) + m_stalled = m_messageQueue.GetPacketCount(CDVDMsg::DEMUXER_PACKET) == 0; + m_autosync = 1; + m_iSleepEndTime = DVD_NOPTS_VALUE; ++ // force SetVideoRect to be called initially ++ m_dst_rect.SetRect(0, 0, 0, 0); + + m_audio_count = m_av_clock->HasAudio(); + +@@ -220,154 +214,45 @@ void OMXPlayerVideo::ProcessOverlays(int iGroupId, double pts) + if (m_started) + m_pOverlayContainer->CleanUp(pts - m_iSubtitleDelay); + +- enum EOverlay +- { OVERLAY_AUTO // select mode auto +- , OVERLAY_GPU // render osd using gpu +- , OVERLAY_BUF // render osd on buffer +- } render = OVERLAY_AUTO; +- +- /* +- if(m_pOverlayContainer->ContainsOverlayType(DVDOVERLAY_TYPE_SPU) +- || m_pOverlayContainer->ContainsOverlayType(DVDOVERLAY_TYPE_IMAGE) +- || m_pOverlayContainer->ContainsOverlayType(DVDOVERLAY_TYPE_SSA) ) +- render = OVERLAY_BUF; +- */ +- +- if(render == OVERLAY_BUF) +- { +- // rendering spu overlay types directly on video memory costs a lot of processing power. +- // thus we allocate a temp picture, copy the original to it (needed because the same picture can be used more than once). +- // then do all the rendering on that temp picture and finaly copy it to video memory. +- // In almost all cases this is 5 or more times faster!. +- +- if(m_pTempOverlayPicture && ( m_pTempOverlayPicture->iWidth != m_width +- || m_pTempOverlayPicture->iHeight != m_height)) +- { +- CDVDCodecUtils::FreePicture(m_pTempOverlayPicture); +- m_pTempOverlayPicture = NULL; +- } +- +- if(!m_pTempOverlayPicture) +- m_pTempOverlayPicture = CDVDCodecUtils::AllocatePicture(m_width, m_height); +- if(!m_pTempOverlayPicture) +- return; +- m_pTempOverlayPicture->format = RENDER_FMT_YUV420P; +- } +- +- if(render == OVERLAY_AUTO) +- render = OVERLAY_GPU; +- + VecOverlays overlays; + +- { +- CSingleLock lock(*m_pOverlayContainer); ++ CSingleLock lock(*m_pOverlayContainer); + +- VecOverlays* pVecOverlays = m_pOverlayContainer->GetOverlays(); +- VecOverlaysIter it = pVecOverlays->begin(); +- +- //Check all overlays and render those that should be rendered, based on time and forced +- //Both forced and subs should check timeing, pts == 0 in the stillframe case +- while (it != pVecOverlays->end()) +- { +- CDVDOverlay* pOverlay = *it++; +- if(!pOverlay->bForced && !m_bRenderSubs) +- continue; +- +- if(pOverlay->iGroupId != iGroupId) +- continue; ++ VecOverlays* pVecOverlays = m_pOverlayContainer->GetOverlays(); ++ VecOverlaysIter it = pVecOverlays->begin(); + +- double pts2 = pOverlay->bForced ? pts : pts - m_iSubtitleDelay; ++ //Check all overlays and render those that should be rendered, based on time and forced ++ //Both forced and subs should check timeing, pts == 0 in the stillframe case ++ while (it != pVecOverlays->end()) ++ { ++ CDVDOverlay* pOverlay = *it++; ++ if(!pOverlay->bForced && !m_bRenderSubs) ++ continue; + +- if((pOverlay->iPTSStartTime <= pts2 && (pOverlay->iPTSStopTime > pts2 || pOverlay->iPTSStopTime == 0LL)) || pts == 0) +- { +- if(pOverlay->IsOverlayType(DVDOVERLAY_TYPE_GROUP)) +- overlays.insert(overlays.end(), static_cast(pOverlay)->m_overlays.begin() +- , static_cast(pOverlay)->m_overlays.end()); +- else +- overlays.push_back(pOverlay); ++ if(pOverlay->iGroupId != iGroupId) ++ continue; + +- } +- } ++ double pts2 = pOverlay->bForced ? pts : pts - m_iSubtitleDelay; + +- for(it = overlays.begin(); it != overlays.end(); ++it) ++ if((pOverlay->iPTSStartTime <= pts2 && (pOverlay->iPTSStopTime > pts2 || pOverlay->iPTSStopTime == 0LL)) || pts == 0) + { +- double pts2 = (*it)->bForced ? pts : pts - m_iSubtitleDelay; +- +- if (render == OVERLAY_GPU) +- g_renderManager.AddOverlay(*it, pts2); +- +- /* +- printf("subtitle : DVDOVERLAY_TYPE_SPU %d DVDOVERLAY_TYPE_IMAGE %d DVDOVERLAY_TYPE_SSA %d\n", +- m_pOverlayContainer->ContainsOverlayType(DVDOVERLAY_TYPE_SPU), +- m_pOverlayContainer->ContainsOverlayType(DVDOVERLAY_TYPE_IMAGE), +- m_pOverlayContainer->ContainsOverlayType(DVDOVERLAY_TYPE_SSA) ); +- */ +- +- if (render == OVERLAY_BUF) +- CDVDOverlayRenderer::Render(m_pTempOverlayPicture, *it, pts2); ++ if(pOverlay->IsOverlayType(DVDOVERLAY_TYPE_GROUP)) ++ overlays.insert(overlays.end(), static_cast(pOverlay)->m_overlays.begin() ++ , static_cast(pOverlay)->m_overlays.end()); ++ else ++ overlays.push_back(pOverlay); + } + } +-} +- +-void OMXPlayerVideo::Output(int iGroupId, double pts, bool bDropPacket) +-{ + +- if (!g_renderManager.IsConfigured() +- || m_video_width != m_width +- || m_video_height != m_height +- || m_fps != m_fFrameRate) ++ for(it = overlays.begin(); it != overlays.end(); ++it) + { +- m_width = m_video_width; +- m_height = m_video_height; +- m_fps = m_fFrameRate; +- +- unsigned flags = 0; +- ERenderFormat format = RENDER_FMT_BYPASS; +- +- if(m_bAllowFullscreen) +- { +- flags |= CONF_FLAGS_FULLSCREEN; +- m_bAllowFullscreen = false; // only allow on first configure +- } +- +- if(m_flags & CONF_FLAGS_FORMAT_SBS) +- { +- if(g_Windowing.Support3D(m_video_width, m_video_height, D3DPRESENTFLAG_MODE3DSBS)) +- { +- CLog::Log(LOGNOTICE, "3DSBS movie found"); +- flags |= CONF_FLAGS_FORMAT_SBS; +- } +- } +- else if(m_flags & CONF_FLAGS_FORMAT_TB) +- { +- if(g_Windowing.Support3D(m_video_width, m_video_height, D3DPRESENTFLAG_MODE3DTB)) +- { +- CLog::Log(LOGNOTICE, "3DTB movie found"); +- flags |= CONF_FLAGS_FORMAT_TB; +- } +- } +- +- unsigned int iDisplayWidth = m_hints.width; +- unsigned int iDisplayHeight = m_hints.height; +- +- /* use forced aspect if any */ +- if( m_fForcedAspectRatio != 0.0f ) +- iDisplayWidth = (int) (iDisplayHeight * m_fForcedAspectRatio); +- +- CLog::Log(LOGDEBUG,"%s - change configuration. %dx%d. framerate: %4.2f. %dx%x format: BYPASS", +- __FUNCTION__, m_width, m_height, m_fps, iDisplayWidth, iDisplayHeight); +- +- if(!g_renderManager.Configure(m_hints.width, m_hints.height, +- iDisplayWidth, iDisplayHeight, m_fps, flags, format, 0, +- m_hints.orientation)) +- { +- CLog::Log(LOGERROR, "%s - failed to configure renderer", __FUNCTION__); +- return; +- } +- +- g_renderManager.RegisterRenderUpdateCallBack((const void*)this, RenderUpdateCallBack); ++ double pts2 = (*it)->bForced ? pts : pts - m_iSubtitleDelay; ++ g_renderManager.AddOverlay(*it, pts2); + } ++} + ++void OMXPlayerVideo::Output(int iGroupId, double pts, bool bDropPacket) ++{ + if (!g_renderManager.IsStarted()) { + CLog::Log(LOGERROR, "%s - renderer not started", __FUNCTION__); + return; +@@ -724,6 +609,7 @@ bool OMXPlayerVideo::OpenDecoder() + m_av_clock->OMXStop(false); + + bool bVideoDecoderOpen = m_omxVideo.Open(m_hints, m_av_clock, m_Deinterlace, m_hdmi_clock_sync); ++ m_omxVideo.RegisterResolutionUpdateCallBack((void *)this, ResolutionUpdateCallBack); + + if(!bVideoDecoderOpen) + { +@@ -859,3 +745,62 @@ void OMXPlayerVideo::RenderUpdateCallBack(const void *ctx, const CRect &SrcRect, + player->SetVideoRect(SrcRect, DestRect); + } + ++void OMXPlayerVideo::ResolutionUpdateCallBack(uint32_t width, uint32_t height) ++{ ++ RESOLUTION res = g_graphicsContext.GetVideoResolution(); ++ uint32_t video_width = g_settings.m_ResInfo[res].iScreenWidth; ++ uint32_t video_height = g_settings.m_ResInfo[res].iScreenHeight; ++ ++ unsigned flags = 0; ++ ERenderFormat format = RENDER_FMT_BYPASS; ++ ++ if(m_bAllowFullscreen) ++ { ++ flags |= CONF_FLAGS_FULLSCREEN; ++ m_bAllowFullscreen = false; // only allow on first configure ++ } ++ ++ if(m_flags & CONF_FLAGS_FORMAT_SBS) ++ { ++ if(g_Windowing.Support3D(video_width, video_height, D3DPRESENTFLAG_MODE3DSBS)) ++ { ++ CLog::Log(LOGNOTICE, "3DSBS movie found"); ++ flags |= CONF_FLAGS_FORMAT_SBS; ++ } ++ } ++ else if(m_flags & CONF_FLAGS_FORMAT_TB) ++ { ++ if(g_Windowing.Support3D(video_width, video_height, D3DPRESENTFLAG_MODE3DTB)) ++ { ++ CLog::Log(LOGNOTICE, "3DTB movie found"); ++ flags |= CONF_FLAGS_FORMAT_TB; ++ } ++ } ++ ++ unsigned int iDisplayWidth = width; ++ unsigned int iDisplayHeight = height; ++ ++ /* use forced aspect if any */ ++ if( m_fForcedAspectRatio != 0.0f ) ++ iDisplayWidth = (int) (iDisplayHeight * m_fForcedAspectRatio); ++ ++ CLog::Log(LOGDEBUG,"%s - change configuration. video:%dx%d. framerate: %4.2f. %dx%d format: BYPASS", ++ __FUNCTION__, video_width, video_height, m_fFrameRate, iDisplayWidth, iDisplayHeight); ++ ++ if(!g_renderManager.Configure(width, height, ++ iDisplayWidth, iDisplayHeight, m_fFrameRate, flags, format, 0, ++ m_hints.orientation)) ++ { ++ CLog::Log(LOGERROR, "%s - failed to configure renderer", __FUNCTION__); ++ return; ++ } ++ ++ g_renderManager.RegisterRenderUpdateCallBack((const void*)this, RenderUpdateCallBack); ++} ++ ++void OMXPlayerVideo::ResolutionUpdateCallBack(void *ctx, uint32_t width, uint32_t height) ++{ ++ OMXPlayerVideo *player = static_cast(ctx); ++ player->ResolutionUpdateCallBack(width, height); ++} ++ +diff --git a/xbmc/cores/omxplayer/OMXPlayerVideo.h b/xbmc/cores/omxplayer/OMXPlayerVideo.h +index cf05c1f..95a691b 100644 +--- a/xbmc/cores/omxplayer/OMXPlayerVideo.h ++++ b/xbmc/cores/omxplayer/OMXPlayerVideo.h +@@ -70,12 +70,7 @@ class OMXPlayerVideo : public CThread + bool m_bAllowFullscreen; + + float m_fForcedAspectRatio; +- unsigned int m_width; +- unsigned int m_height; +- unsigned int m_video_width; +- unsigned int m_video_height; + unsigned m_flags; +- float m_fps; + + CRect m_dst_rect; + int m_view_mode; +@@ -133,5 +128,7 @@ class OMXPlayerVideo : public CThread + int GetFreeSpace(); + void SetVideoRect(const CRect &SrcRect, const CRect &DestRect); + static void RenderUpdateCallBack(const void *ctx, const CRect &SrcRect, const CRect &DestRect); ++ void ResolutionUpdateCallBack(uint32_t width, uint32_t height); ++ static void ResolutionUpdateCallBack(void *ctx, uint32_t width, uint32_t height); + }; + #endif +diff --git a/xbmc/cores/omxplayer/OMXVideo.cpp b/xbmc/cores/omxplayer/OMXVideo.cpp +index 3417286..b6b42e7 100644 +--- a/xbmc/cores/omxplayer/OMXVideo.cpp ++++ b/xbmc/cores/omxplayer/OMXVideo.cpp +@@ -86,7 +86,6 @@ + m_video_codec_name = ""; + m_deinterlace = false; + m_hdmi_clock_sync = false; +- m_first_frame = true; + } + + COMXVideo::~COMXVideo() +@@ -154,6 +153,9 @@ bool COMXVideo::Open(CDVDStreamInfo &hints, OMXClock *clock, bool deinterlace, b + OMX_ERRORTYPE omx_err = OMX_ErrorNone; + std::string decoder_name; + ++ m_res_ctx = NULL; ++ m_res_callback = NULL; ++ + m_video_codec_name = ""; + m_codingType = OMX_VIDEO_CodingUnused; + +@@ -697,7 +699,6 @@ bool COMXVideo::Open(CDVDStreamInfo &hints, OMXClock *clock, bool deinterlace, b + CLASSNAME, __func__, m_omx_decoder.GetComponent(), m_omx_decoder.GetInputPort(), m_omx_decoder.GetOutputPort(), + m_deinterlace, m_hdmi_clock_sync); + +- m_first_frame = true; + // start from assuming all recent frames had valid pts + m_history_valid_pts = ~0; + +@@ -736,8 +737,10 @@ void COMXVideo::Close() + m_video_convert = false; + m_video_codec_name = ""; + m_deinterlace = false; +- m_first_frame = true; + m_av_clock = NULL; ++ ++ m_res_ctx = NULL; ++ m_res_callback = NULL; + } + + void COMXVideo::SetDropState(bool bDrop) +@@ -851,57 +854,74 @@ int COMXVideo::Decode(uint8_t *pData, int iSize, double dts, double pts) + } + } + +- if(m_first_frame && m_deinterlace) ++ omx_err = m_omx_decoder.WaitForEvent(OMX_EventPortSettingsChanged, 0); ++ if (omx_err == OMX_ErrorNone) + { + OMX_PARAM_PORTDEFINITIONTYPE port_image; + OMX_INIT_STRUCTURE(port_image); + port_image.nPortIndex = m_omx_decoder.GetOutputPort(); +- + omx_err = m_omx_decoder.GetParameter(OMX_IndexParamPortDefinition, &port_image); + if(omx_err != OMX_ErrorNone) +- CLog::Log(LOGERROR, "%s::%s - error OMX_IndexParamPortDefinition 1 omx_err(0x%08x)\n", CLASSNAME, __func__, omx_err); ++ { ++ CLog::Log(LOGERROR, "%s::%s - error m_omx_decoder.GetParameter(OMX_IndexParamPortDefinition) omx_err(0x%08x)\n", CLASSNAME, __func__, omx_err); ++ } ++ // let OMXPlayerVideo know about resolution so it can inform RenderManager ++ if (m_res_callback) ++ m_res_callback(m_res_ctx, port_image.format.video.nFrameWidth, port_image.format.video.nFrameHeight); ++ ++ m_omx_decoder.DisablePort(m_omx_decoder.GetOutputPort(), true); ++ m_omx_sched.DisablePort(m_omx_sched.GetInputPort(), true); + +- /* we assume when the sizes equal we have the first decoded frame */ +- if(port_image.format.video.nFrameWidth == m_decoded_width && port_image.format.video.nFrameHeight == m_decoded_height) ++ OMX_CONFIG_INTERLACETYPE interlace; ++ OMX_INIT_STRUCTURE(interlace); ++ interlace.nPortIndex = m_omx_decoder.GetOutputPort(); ++ omx_err = m_omx_decoder.GetConfig(OMX_IndexConfigCommonInterlace, &interlace); ++ if(omx_err != OMX_ErrorNone) + { +- m_first_frame = false; ++ CLog::Log(LOGERROR, "%s::%s - error m_omx_decoder.GetConfig(OMX_IndexConfigCommonInterlace) omx_err(0x%08x)\n", CLASSNAME, __func__, omx_err); ++ } + +- omx_err = m_omx_decoder.WaitForEvent(OMX_EventPortSettingsChanged); +- if(omx_err == OMX_ErrorStreamCorrupt) ++ if (m_deinterlace) ++ { ++ m_omx_image_fx.DisablePort(m_omx_image_fx.GetInputPort(), true); ++ port_image.nPortIndex = m_omx_image_fx.GetInputPort(); ++ omx_err = m_omx_image_fx.SetParameter(OMX_IndexParamPortDefinition, &port_image); ++ if(omx_err != OMX_ErrorNone) + { +- CLog::Log(LOGERROR, "%s::%s - image not unsupported\n", CLASSNAME, __func__); +- return false; ++ CLog::Log(LOGERROR, "%s::%s - error m_omx_image_fx.SetParameter(OMX_IndexParamPortDefinition) omx_err(0x%08x)\n", CLASSNAME, __func__, omx_err); + } +- +- m_omx_decoder.DisablePort(m_omx_decoder.GetOutputPort(), false); +- m_omx_sched.DisablePort(m_omx_sched.GetInputPort(), false); +- +- if(m_deinterlace) ++ omx_err = m_omx_decoder.WaitForEvent(OMX_EventPortSettingsChanged); ++ if(omx_err != OMX_ErrorNone) + { +- m_omx_image_fx.DisablePort(m_omx_image_fx.GetOutputPort(), false); +- m_omx_image_fx.DisablePort(m_omx_image_fx.GetInputPort(), false); +- +- port_image.nPortIndex = m_omx_image_fx.GetInputPort(); +- omx_err = m_omx_image_fx.SetParameter(OMX_IndexParamPortDefinition, &port_image); +- if(omx_err != OMX_ErrorNone) +- CLog::Log(LOGERROR, "%s::%s - error OMX_IndexParamPortDefinition 2 omx_err(0x%08x)\n", CLASSNAME, __func__, omx_err); +- +- port_image.nPortIndex = m_omx_image_fx.GetOutputPort(); +- omx_err = m_omx_image_fx.SetParameter(OMX_IndexParamPortDefinition, &port_image); +- if(omx_err != OMX_ErrorNone) +- CLog::Log(LOGERROR, "%s::%s - error OMX_IndexParamPortDefinition 3 omx_err(0x%08x)\n", CLASSNAME, __func__, omx_err); ++ CLog::Log(LOGERROR, "%s::%s - error m_omx_decoder.WaitForEvent(OMX_EventPortSettingsChanged) omx_err(0x%08x)\n", CLASSNAME, __func__, omx_err); + } +- +- m_omx_decoder.EnablePort(m_omx_decoder.GetOutputPort(), false); +- +- if(m_deinterlace) ++ port_image.nPortIndex = m_omx_image_fx.GetOutputPort(); ++ omx_err = m_omx_image_fx.GetParameter(OMX_IndexParamPortDefinition, &port_image); ++ if(omx_err != OMX_ErrorNone) + { +- m_omx_image_fx.EnablePort(m_omx_image_fx.GetOutputPort(), false); +- m_omx_image_fx.EnablePort(m_omx_image_fx.GetInputPort(), false); ++ CLog::Log(LOGERROR, "%s::%s - error m_omx_image_fx.GetParameter(OMX_IndexParamPortDefinition) omx_err(0x%08x)\n", CLASSNAME, __func__, omx_err); + } ++ m_omx_image_fx.EnablePort(m_omx_image_fx.GetInputPort(), true); + +- m_omx_sched.EnablePort(m_omx_sched.GetInputPort(), false); ++ m_omx_image_fx.DisablePort(m_omx_image_fx.GetOutputPort(), true); ++ } ++ port_image.nPortIndex = m_omx_sched.GetInputPort(); ++ omx_err = m_omx_sched.SetParameter(OMX_IndexParamPortDefinition, &port_image); ++ if(omx_err != OMX_ErrorNone) ++ { ++ CLog::Log(LOGERROR, "%s::%s - error m_omx_sched.SetParameter(OMX_IndexParamPortDefinition) omx_err(0x%08x)\n", CLASSNAME, __func__, omx_err); ++ } ++ omx_err = m_omx_sched.WaitForEvent(OMX_EventPortSettingsChanged); ++ if(omx_err != OMX_ErrorNone) ++ { ++ CLog::Log(LOGERROR, "%s::%s - error m_omx_sched.WaitForEvent(OMX_EventPortSettingsChanged) omx_err(0x%08x)\n", CLASSNAME, __func__, omx_err); ++ } ++ if (m_deinterlace) ++ { ++ m_omx_image_fx.EnablePort(m_omx_image_fx.GetOutputPort(), true); + } ++ m_omx_decoder.EnablePort(m_omx_decoder.GetOutputPort(), true); ++ m_omx_sched.EnablePort(m_omx_sched.GetInputPort(), true); + } + } + +@@ -932,7 +952,6 @@ void COMXVideo::Reset(void) + + SendDecoderConfig(); + +- m_first_frame = true; + */ + } + +diff --git a/xbmc/cores/omxplayer/OMXVideo.h b/xbmc/cores/omxplayer/OMXVideo.h +index 0afa56d..037f155 100644 +--- a/xbmc/cores/omxplayer/OMXVideo.h ++++ b/xbmc/cores/omxplayer/OMXVideo.h +@@ -36,6 +36,8 @@ + + #define CLASSNAME "COMXVideo" + ++typedef void (*ResolutionUpdateCallBackFn)(void *ctx, uint32_t width, uint32_t height); ++ + class COMXVideo + { + public: +@@ -45,6 +47,7 @@ class COMXVideo + // Required overrides + bool SendDecoderConfig(); + bool Open(CDVDStreamInfo &hints, OMXClock *clock, bool deinterlace = false, bool hdmi_clock_sync = false); ++ void RegisterResolutionUpdateCallBack(void *ctx, ResolutionUpdateCallBackFn callback) { m_res_ctx = ctx; m_res_callback = callback; } + void Close(void); + unsigned int GetFreeSpace(); + unsigned int GetSize(); +@@ -89,9 +92,9 @@ class COMXVideo + + bool m_deinterlace; + bool m_hdmi_clock_sync; +- bool m_first_frame; + uint32_t m_history_valid_pts; +- ++ ResolutionUpdateCallBackFn m_res_callback; ++ void *m_res_ctx; + bool NaluFormatStartCodes(enum CodecID codec, uint8_t *in_extradata, int in_extrasize); + }; + +-- +1.7.10 + diff --git a/packages/mediacenter/xbmc/patches/xbmc-990.23-PR2363.patch b/packages/mediacenter/xbmc/patches/xbmc-990.23-PR2363.patch new file mode 100644 index 0000000000..11ccd5224c --- /dev/null +++ b/packages/mediacenter/xbmc/patches/xbmc-990.23-PR2363.patch @@ -0,0 +1,202 @@ +From 3d1005fdd34e72f81aff9034f8d30a0d33a780a8 Mon Sep 17 00:00:00 2001 +From: xbmc +Date: Mon, 4 Mar 2013 08:30:47 +0100 +Subject: [PATCH] Always copy overlays from file parser - Fixes stuck hw + resources on render + +--- + .../cores/dvdplayer/DVDCodecs/Overlay/DVDOverlay.h | 6 +++ + .../dvdplayer/DVDCodecs/Overlay/DVDOverlayImage.h | 6 +++ + .../dvdplayer/DVDCodecs/Overlay/DVDOverlaySSA.h | 11 ++++++ + .../dvdplayer/DVDCodecs/Overlay/DVDOverlayText.h | 41 ++++++++++++++++++++ + xbmc/cores/dvdplayer/DVDPlayerSubtitle.cpp | 1 + + .../dvdplayer/DVDSubtitles/DVDSubtitleParser.h | 8 +++- + 6 files changed, 72 insertions(+), 1 deletion(-) + +diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Overlay/DVDOverlay.h b/xbmc/cores/dvdplayer/DVDCodecs/Overlay/DVDOverlay.h +index 8c87bc4..da8de1f 100644 +--- a/xbmc/cores/dvdplayer/DVDCodecs/Overlay/DVDOverlay.h ++++ b/xbmc/cores/dvdplayer/DVDCodecs/Overlay/DVDOverlay.h +@@ -103,6 +103,12 @@ class CDVDOverlay + + bool IsOverlayType(DVDOverlayType type) { return (m_type == type); } + ++ /** ++ * return a copy to DVDPlayerSubtitle in order to have hw resources cleared ++ * after rendering ++ */ ++ virtual CDVDOverlay* Clone() { return Acquire(); } ++ + double iPTSStartTime; + double iPTSStopTime; + bool bForced; // display, no matter what +diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Overlay/DVDOverlayImage.h b/xbmc/cores/dvdplayer/DVDCodecs/Overlay/DVDOverlayImage.h +index bc90d68..e1cdf59 100644 +--- a/xbmc/cores/dvdplayer/DVDCodecs/Overlay/DVDOverlayImage.h ++++ b/xbmc/cores/dvdplayer/DVDCodecs/Overlay/DVDOverlayImage.h +@@ -20,6 +20,7 @@ + * + */ + ++#include "PlatformDefs.h" + #include "DVDOverlay.h" + #include + #include +@@ -117,6 +118,11 @@ class CDVDOverlayImage : public CDVDOverlay + if(palette) free(palette); + } + ++ virtual CDVDOverlayImage* Clone() ++ { ++ return new CDVDOverlayImage(*this); ++ } ++ + BYTE* data_at(int sub_x, int sub_y) const + { + int bpp; +diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Overlay/DVDOverlaySSA.h b/xbmc/cores/dvdplayer/DVDCodecs/Overlay/DVDOverlaySSA.h +index 31deba1..f42c571 100644 +--- a/xbmc/cores/dvdplayer/DVDCodecs/Overlay/DVDOverlaySSA.h ++++ b/xbmc/cores/dvdplayer/DVDCodecs/Overlay/DVDOverlaySSA.h +@@ -37,10 +37,21 @@ class CDVDOverlaySSA : public CDVDOverlay + libass->Acquire(); + } + ++ CDVDOverlaySSA(CDVDOverlaySSA& src) ++ : CDVDOverlay(src) ++ , m_libass(src.m_libass) ++ { ++ m_libass->Acquire(); ++ } ++ + ~CDVDOverlaySSA() + { + if(m_libass) + SAFE_RELEASE(m_libass); + } + ++ virtual CDVDOverlaySSA* Clone() ++ { ++ return new CDVDOverlaySSA(*this); ++ } + }; +diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Overlay/DVDOverlayText.h b/xbmc/cores/dvdplayer/DVDCodecs/Overlay/DVDOverlayText.h +index 849a6e3..54e3bfa 100644 +--- a/xbmc/cores/dvdplayer/DVDCodecs/Overlay/DVDOverlayText.h ++++ b/xbmc/cores/dvdplayer/DVDCodecs/Overlay/DVDOverlayText.h +@@ -46,6 +46,12 @@ class CDVDOverlayText : public CDVDOverlay + m_type = type; + } + ++ CElement(CElement& src) ++ { ++ pNext = NULL; ++ m_type = src.m_type; ++ } ++ + virtual ~CElement() + { + } +@@ -71,6 +77,12 @@ class CDVDOverlayText : public CDVDOverlay + } + } + ++ CElementText(CElementText& src) ++ : CElement(src) ++ { ++ m_text = strdup(src.m_text); ++ } ++ + virtual ~CElementText() + { + if (m_text) free(m_text); +@@ -81,12 +93,20 @@ class CDVDOverlayText : public CDVDOverlay + + class CElementProperty : public CElement + { ++ public: + CElementProperty() : CElement(ELEMENT_TYPE_PROPERTY) + { + bItalic = false; + bBold = false; + } + ++ CElementProperty(CElementProperty& src) ++ : CElement(src) ++ { ++ bItalic = src.bItalic; ++ bBold = src.bBold; ++ } ++ + public: + bool bItalic; + bool bBold; +@@ -99,6 +119,22 @@ class CDVDOverlayText : public CDVDOverlay + m_pEnd = NULL; + } + ++ CDVDOverlayText(CDVDOverlayText& src) ++ : CDVDOverlay(src) ++ { ++ m_pHead = NULL; ++ m_pEnd = NULL; ++ for(CElement* e = src.m_pHead; e; e = e->pNext) ++ { ++ if(e->IsElementType(ELEMENT_TYPE_TEXT)) ++ AddElement(new CElementText(*static_cast(e))); ++ else if(e->IsElementType(ELEMENT_TYPE_PROPERTY)) ++ AddElement(new CElementProperty(*static_cast(e))); ++ else ++ AddElement(new CElement(*static_cast(e))); ++ } ++ } ++ + virtual ~CDVDOverlayText() + { + CElement* pTemp; +@@ -110,6 +146,11 @@ class CDVDOverlayText : public CDVDOverlay + } + } + ++ virtual CDVDOverlayText* Clone() ++ { ++ return new CDVDOverlayText(*this); ++ } ++ + void AddElement(CDVDOverlayText::CElement* pElement) + { + pElement->pNext = NULL; +diff --git a/xbmc/cores/dvdplayer/DVDPlayerSubtitle.cpp b/xbmc/cores/dvdplayer/DVDPlayerSubtitle.cpp +index 29c8d57..540d890 100644 +--- a/xbmc/cores/dvdplayer/DVDPlayerSubtitle.cpp ++++ b/xbmc/cores/dvdplayer/DVDPlayerSubtitle.cpp +@@ -222,6 +222,7 @@ void CDVDPlayerSubtitle::Process(double pts) + while(pOverlay) + { + m_pOverlayContainer->Add(pOverlay); ++ pOverlay->Release(); + pOverlay = m_pSubtitleFileParser->Parse(pts); + } + +diff --git a/xbmc/cores/dvdplayer/DVDSubtitles/DVDSubtitleParser.h b/xbmc/cores/dvdplayer/DVDSubtitles/DVDSubtitleParser.h +index 944bf06..3cd1e95 100644 +--- a/xbmc/cores/dvdplayer/DVDSubtitles/DVDSubtitleParser.h ++++ b/xbmc/cores/dvdplayer/DVDSubtitles/DVDSubtitleParser.h +@@ -47,7 +47,13 @@ class CDVDSubtitleParserCollection + m_filename = strFile; + } + virtual ~CDVDSubtitleParserCollection() { } +- virtual CDVDOverlay* Parse(double iPts) { return m_collection.Get(iPts); } ++ virtual CDVDOverlay* Parse(double iPts) ++ { ++ CDVDOverlay* o = m_collection.Get(iPts); ++ if(o == NULL) ++ return o; ++ return o->Clone(); ++ } + virtual void Reset() { m_collection.Reset(); } + virtual void Dispose() { m_collection.Clear(); } + +-- +1.7.10 + diff --git a/packages/mediacenter/xbmc/patches/xbmc-990.24-PR2375.patch b/packages/mediacenter/xbmc/patches/xbmc-990.24-PR2375.patch new file mode 100644 index 0000000000..ddf3dd7e81 --- /dev/null +++ b/packages/mediacenter/xbmc/patches/xbmc-990.24-PR2375.patch @@ -0,0 +1,31 @@ +From 8717c162b8c5092d77672351ce3bfa2d4e7e32d8 Mon Sep 17 00:00:00 2001 +From: fritsch +Date: Tue, 5 Mar 2013 22:17:15 +0100 +Subject: [PATCH] AE: Fix resample of e.g. 192 khz to 48 khz audio by scaling + the usual suspects with the src sampleRate + +--- + xbmc/cores/AudioEngine/Engines/SoftAE/SoftAEStream.cpp | 7 +++++++ + 1 file changed, 7 insertions(+) + +diff --git a/xbmc/cores/AudioEngine/Engines/SoftAE/SoftAEStream.cpp b/xbmc/cores/AudioEngine/Engines/SoftAE/SoftAEStream.cpp +index 258dcac..a64beb1 100644 +--- a/xbmc/cores/AudioEngine/Engines/SoftAE/SoftAEStream.cpp ++++ b/xbmc/cores/AudioEngine/Engines/SoftAE/SoftAEStream.cpp +@@ -196,6 +196,13 @@ void CSoftAEStream::Initialize() + m_ssrcData.data_out = (float*)_aligned_malloc(m_format.m_frameSamples * (int)std::ceil(m_ssrcData.src_ratio) * sizeof(float), 16); + m_ssrcData.output_frames = m_format.m_frames * (long)std::ceil(m_ssrcData.src_ratio); + m_ssrcData.end_of_input = 0; ++ // we must buffer the same amount as before but taking the source sample rate into account ++ // there is no reason to decrease the buffer for upsampling ++ if (m_internalRatio < 1) ++ { ++ m_waterLevel *= (1.0 / m_internalRatio); ++ m_refillBuffer = m_waterLevel; ++ } + } + + m_limiter.SetSamplerate(AE.GetSampleRate()); +-- +1.7.10 + diff --git a/packages/mediacenter/xbmc/patches/xbmc-990.26-PR2378.patch b/packages/mediacenter/xbmc/patches/xbmc-990.26-PR2378.patch new file mode 100644 index 0000000000..838c7a6198 --- /dev/null +++ b/packages/mediacenter/xbmc/patches/xbmc-990.26-PR2378.patch @@ -0,0 +1,53 @@ +From 907f5086e76b0b6d0211c9bbd9da6c6fb54e891b Mon Sep 17 00:00:00 2001 +From: Juan Font +Date: Wed, 6 Mar 2013 09:50:15 +0100 +Subject: [PATCH 1/2] Avoid fps detection when probing the format if we will + trust codec fps during playback. + +--- + xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.cpp | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.cpp b/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.cpp +index 7d4e35b..4b62d75 100644 +--- a/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.cpp ++++ b/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.cpp +@@ -425,6 +425,9 @@ bool CDVDDemuxFFmpeg::Open(CDVDInputStream* pInput) + + // set the interrupt callback, appeared in libavformat 53.15.0 + m_pFormatContext->interrupt_callback = int_cb; ++ ++ // Avoid detecting framerate if advancedsettings.xml says so ++ m_pFormatContext->fps_probe_size = (!g_advancedSettings.m_videoFpsDetect) ? 0 : -1; + + // analyse very short to speed up mjpeg playback start + if (iformat && (strcmp(iformat->name, "mjpeg") == 0) && m_ioContext->seekable == 0) +-- +1.7.10 + + +From e2966a346140fcd7a9742f17bfd7710bffbe1066 Mon Sep 17 00:00:00 2001 +From: Juan Font +Date: Wed, 6 Mar 2013 10:33:32 +0100 +Subject: [PATCH 2/2] Improved code legibility. + +--- + xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.cpp | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.cpp b/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.cpp +index 4b62d75..e84290d 100644 +--- a/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.cpp ++++ b/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.cpp +@@ -427,7 +427,7 @@ bool CDVDDemuxFFmpeg::Open(CDVDInputStream* pInput) + m_pFormatContext->interrupt_callback = int_cb; + + // Avoid detecting framerate if advancedsettings.xml says so +- m_pFormatContext->fps_probe_size = (!g_advancedSettings.m_videoFpsDetect) ? 0 : -1; ++ m_pFormatContext->fps_probe_size = (g_advancedSettings.m_videoFpsDetect == 0) ? 0 : -1; + + // analyse very short to speed up mjpeg playback start + if (iformat && (strcmp(iformat->name, "mjpeg") == 0) && m_ioContext->seekable == 0) +-- +1.7.10 + diff --git a/packages/mediacenter/xbmc/patches/xbmc-990.27-PR2388.patch b/packages/mediacenter/xbmc/patches/xbmc-990.27-PR2388.patch new file mode 100644 index 0000000000..2b158d1f20 --- /dev/null +++ b/packages/mediacenter/xbmc/patches/xbmc-990.27-PR2388.patch @@ -0,0 +1,25 @@ +From 249cccc2da097917995571b123ac22e30ed3f686 Mon Sep 17 00:00:00 2001 +From: popcornmix +Date: Thu, 7 Mar 2013 12:50:57 +0000 +Subject: [PATCH] [rbp] Enable Vsync as a default + +--- + xbmc/settings/Settings.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/xbmc/settings/Settings.h b/xbmc/settings/Settings.h +index fd44a0f..5ba1d36 100644 +--- a/xbmc/settings/Settings.h ++++ b/xbmc/settings/Settings.h +@@ -36,7 +36,7 @@ + #ifdef MID + #define DEFAULT_VSYNC VSYNC_DISABLED + #else // MID +-#if defined(TARGET_DARWIN) || defined(_WIN32) ++#if defined(TARGET_DARWIN) || defined(_WIN32) || defined(TARGET_RASPBERRY_PI) + #define DEFAULT_VSYNC VSYNC_ALWAYS + #else + #define DEFAULT_VSYNC VSYNC_DRIVER +-- +1.7.10 +