diff options
-rw-r--r-- | lib/cpluff/libcpluff/win32/dirent.c | 2 | ||||
-rw-r--r-- | lib/cximage-6.0/CxImage/ximadsp.cpp | 28 | ||||
-rw-r--r-- | lib/cximage-6.0/CxImage/ximatif.cpp | 2 | ||||
-rw-r--r-- | xbmc/URL.cpp | 2 | ||||
-rw-r--r-- | xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAE.cpp | 8 | ||||
-rw-r--r-- | xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEResample.cpp | 3 | ||||
-rw-r--r-- | xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEStream.cpp | 37 | ||||
-rw-r--r-- | xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEStream.h | 2 | ||||
-rw-r--r-- | xbmc/cores/paplayer/FLACcodec.cpp | 8 | ||||
-rw-r--r-- | xbmc/interfaces/json-rpc/AudioLibrary.cpp | 2 | ||||
-rw-r--r-- | xbmc/interfaces/json-rpc/ServiceDescription.h | 2 | ||||
-rw-r--r-- | xbmc/settings/dialogs/GUIDialogSettings.cpp | 11 | ||||
-rw-r--r-- | xbmc/video/windows/GUIWindowVideoNav.cpp | 18 |
13 files changed, 102 insertions, 23 deletions
diff --git a/lib/cpluff/libcpluff/win32/dirent.c b/lib/cpluff/libcpluff/win32/dirent.c index db72f39d37..3254b22729 100644 --- a/lib/cpluff/libcpluff/win32/dirent.c +++ b/lib/cpluff/libcpluff/win32/dirent.c @@ -199,6 +199,8 @@ int scandir( ++entries; } + closedir(d); + // sort if (*namelist && compar) qsort(*namelist, entries, sizeof((*namelist)[0]), compar); diff --git a/lib/cximage-6.0/CxImage/ximadsp.cpp b/lib/cximage-6.0/CxImage/ximadsp.cpp index feff6ab867..f54ffd615a 100644 --- a/lib/cximage-6.0/CxImage/ximadsp.cpp +++ b/lib/cximage-6.0/CxImage/ximadsp.cpp @@ -1374,6 +1374,7 @@ bool CxImage::Median(long Ksize) CxImage tmp(*this); if (!tmp.IsValid()){ + free(kernel); strcpy(info.szLastError,tmp.GetLastError()); return false; } @@ -2424,11 +2425,15 @@ bool CxImage::TextBlur(BYTE threshold, BYTE decay, BYTE max_depth, bool bBlurHor pPalette = new RGBQUAD[head.biClrUsed]; memcpy(pPalette, GetPalette(),GetPaletteSize()); if (!IncreaseBpp(24)) + { + delete [] pPalette; return false; + } } CxImage tmp(*this); if (!tmp.IsValid()){ + delete [] pPalette; strcpy(info.szLastError,tmp.GetLastError()); return false; } @@ -2484,12 +2489,16 @@ bool CxImage::GaussianBlur(float radius /*= 1.0f*/, CxImage* iDst /*= 0*/) pPalette = new RGBQUAD[head.biClrUsed]; memcpy(pPalette, GetPalette(),GetPaletteSize()); if (!IncreaseBpp(24)) + { + delete [] pPalette; return false; + } } CxImage tmp_x(*this, false, true, true); if (!tmp_x.IsValid()){ strcpy(info.szLastError,tmp_x.GetLastError()); + delete [] pPalette; return false; } @@ -2508,7 +2517,7 @@ bool CxImage::GaussianBlur(float radius /*= 1.0f*/, CxImage* iDst /*= 0*/) double dbScaler = 50.0f/head.biHeight; // blur the rows - for (y=0;y<head.biHeight;y++) + for (y=0;y<head.biHeight;y++) { if (info.nEscape) break; info.nProgress = (long)(y*dbScaler); @@ -2518,6 +2527,7 @@ bool CxImage::GaussianBlur(float radius /*= 1.0f*/, CxImage* iDst /*= 0*/) CxImage tmp_y(tmp_x, false, true, true); if (!tmp_y.IsValid()){ + delete [] pPalette; strcpy(info.szLastError,tmp_y.GetLastError()); return false; } @@ -2525,8 +2535,8 @@ bool CxImage::GaussianBlur(float radius /*= 1.0f*/, CxImage* iDst /*= 0*/) CImageIterator itDst(&tmp_y); // blur the cols - BYTE* cur_col = (BYTE*)malloc(bypp*head.biHeight); - BYTE* dest_col = (BYTE*)malloc(bypp*head.biHeight); + BYTE* cur_col = (BYTE*)malloc(bypp*head.biHeight); + BYTE* dest_col = (BYTE*)malloc(bypp*head.biHeight); dbScaler = 50.0f/head.biWidth; @@ -2594,11 +2604,15 @@ bool CxImage::SelectiveBlur(float radius, BYTE threshold, CxImage* iDst) pPalette = new RGBQUAD[head.biClrUsed]; memcpy(pPalette, GetPalette(),GetPaletteSize()); if (!Tmp.IncreaseBpp(24)) + { + delete [] pPalette; return false; + } } CxImage Dst(Tmp, true, true, true); if (!Dst.IsValid()){ + delete [] pPalette; strcpy(info.szLastError,Dst.GetLastError()); return false; } @@ -2608,6 +2622,7 @@ bool CxImage::SelectiveBlur(float radius, BYTE threshold, CxImage* iDst) BYTE thresh_up = (BYTE)min(255,(int)(128 + threshold)); long kernel[]={-100,-100,-100,-100,801,-100,-100,-100,-100}; if (!Tmp.Filter(kernel,3,800,128)){ + delete [] pPalette; strcpy(info.szLastError,Tmp.GetLastError()); return false; } @@ -2644,6 +2659,7 @@ bool CxImage::SelectiveBlur(float radius, BYTE threshold, CxImage* iDst) //blur the image (only in the selected pixels) Dst.SelectionCopy(Tmp); if (!Dst.GaussianBlur(radius)){ + delete [] pPalette; strcpy(info.szLastError,Dst.GetLastError()); return false; } @@ -3493,12 +3509,18 @@ bool CxImage::FloodFill(const long xStart, const long yStart, const RGBQUAD cFil pPalette = new RGBQUAD[head.biClrUsed]; memcpy(pPalette, GetPalette(),GetPaletteSize()); if (!IncreaseBpp(24)) + { + delete [] pPalette; return false; + } } BYTE* pFillMask = (BYTE*)calloc(head.biWidth * head.biHeight,1); if (!pFillMask) + { + delete [] pPalette; return false; + } //------------------------------------- Begin of Flood Fill POINT offset[4] = {{-1,0},{0,-1},{1,0},{0,1}}; diff --git a/lib/cximage-6.0/CxImage/ximatif.cpp b/lib/cximage-6.0/CxImage/ximatif.cpp index 0018fa98f2..658392a824 100644 --- a/lib/cximage-6.0/CxImage/ximatif.cpp +++ b/lib/cximage-6.0/CxImage/ximatif.cpp @@ -316,6 +316,7 @@ bool CxImageTIF::Decode(CxFile * hFile) if (info.nEscape){ // <vho> - cancel decoding free(bits); + free(row_shifts); cx_throw("Cancelled"); } @@ -332,6 +333,7 @@ bool CxImageTIF::Decode(CxFile * hFile) if (TIFFReadTile(m_tif, tilebuf, col, ys, 0, 0) < 0){ free(tilebuf); free(bits); + free(row_shifts); cx_throw("Corrupted tiled TIFF file!"); } diff --git a/xbmc/URL.cpp b/xbmc/URL.cpp index 884263eea2..65057d50e5 100644 --- a/xbmc/URL.cpp +++ b/xbmc/URL.cpp @@ -861,6 +861,6 @@ void CURL::SetProtocolOption(const CStdString &key, const CStdString &value) void CURL::RemoveProtocolOption(const CStdString &key) { - m_options.RemoveOption(key); + m_protocolOptions.RemoveOption(key); m_strProtocolOptions = m_protocolOptions.GetOptionsString(false); } diff --git a/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAE.cpp b/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAE.cpp index 3eb213e6da..2fad7ee148 100644 --- a/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAE.cpp +++ b/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAE.cpp @@ -1242,9 +1242,15 @@ void CActiveAE::ApplySettingsToFormat(AEAudioFormat &format, AudioSettings &sett else { format.m_dataFormat = AE_FMT_FLOAT; + // consider user channel layout for those cases + // 1. input stream is multichannel + // 2. stereo upmix is selected + // 3. already playing > 2 channels and "audiophile" is not set + // this is the case if e.g. a stream changes config from 5.1 to 2.0 + // which would cause a short audio drop-out if we changed the sink if ((format.m_channelLayout.Count() > 2) || settings.stereoupmix || - !g_advancedSettings.m_audioAudiophile) + (m_stats.GetWaterLevel() > 0 && m_internalFormat.m_channelLayout.Count() > 2 && !g_advancedSettings.m_audioAudiophile)) { CAEChannelInfo stdLayout; switch (settings.channels) diff --git a/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEResample.cpp b/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEResample.cpp index 2182289740..7649b7ab2c 100644 --- a/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEResample.cpp +++ b/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEResample.cpp @@ -93,8 +93,10 @@ bool CActiveAEResample::Init(uint64_t dst_chan_layout, int dst_channels, int dst // remapLayout is the layout of the sink, if the channel is in our src layout // the channel is mapped by setting coef 1.0 memset(m_rematrix, 0, sizeof(m_rematrix)); + m_dst_chan_layout = 0; for (unsigned int out=0; out<remapLayout->Count(); out++) { + m_dst_chan_layout += (1 << out); int idx = GetAVChannelIndex((*remapLayout)[out], m_src_chan_layout); if (idx >= 0) { @@ -102,7 +104,6 @@ bool CActiveAEResample::Init(uint64_t dst_chan_layout, int dst_channels, int dst } } - m_dst_chan_layout = m_dllAvUtil.av_get_default_channel_layout(m_dst_channels); m_dllAvUtil.av_opt_set_int(m_pContext, "out_channel_count", m_dst_channels, 0); m_dllAvUtil.av_opt_set_int(m_pContext, "out_channel_layout", m_dst_chan_layout, 0); diff --git a/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEStream.cpp b/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEStream.cpp index 9472449bf0..cfa4eb59bf 100644 --- a/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEStream.cpp +++ b/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEStream.cpp @@ -53,10 +53,13 @@ CActiveAEStream::CActiveAEStream(AEAudioFormat *format) m_streamIsBuffering = true; m_streamSlave = NULL; m_convertFn = NULL; + m_leftoverBuffer = new uint8_t[m_format.m_frameSize]; + m_leftoverBytes = 0; } CActiveAEStream::~CActiveAEStream() { + delete [] m_leftoverBuffer; } void CActiveAEStream::IncFreeBuffers() @@ -88,10 +91,28 @@ unsigned int CActiveAEStream::AddData(void *data, unsigned int size) Message *msg; unsigned int copied = 0; int bytesToCopy = size; + uint8_t *buf = (uint8_t*)data; + while(copied < size) { + buf = (uint8_t*)data; + bytesToCopy = size - copied; + if (m_currentBuffer) { + // fill leftover buffer and copy it first + if (m_leftoverBytes && bytesToCopy >= (m_format.m_frameSize - m_leftoverBytes)) + { + int fillbytes = m_format.m_frameSize - m_leftoverBytes; + memcpy(m_leftoverBuffer+m_leftoverBytes, (uint8_t*)data, fillbytes); + data = (uint8_t*)data + fillbytes; + size -= fillbytes; + // leftover buffer will be copied on next cycle + buf = m_leftoverBuffer; + bytesToCopy = m_format.m_frameSize; + m_leftoverBytes = 0; + } + int start = m_currentBuffer->pkt->nb_samples * m_currentBuffer->pkt->bytes_per_sample * m_currentBuffer->pkt->config.channels / @@ -99,20 +120,29 @@ unsigned int CActiveAEStream::AddData(void *data, unsigned int size) int freeSamples = m_currentBuffer->pkt->max_nb_samples - m_currentBuffer->pkt->nb_samples; int availableSamples = bytesToCopy / m_format.m_frameSize; + + // if we don't have a full frame, copy to leftover buffer + if (!availableSamples && bytesToCopy) + { + memcpy(m_leftoverBuffer+m_leftoverBytes, buf+copied, bytesToCopy); + m_leftoverBytes = bytesToCopy; + copied += bytesToCopy; + } + int samples = std::min(freeSamples, availableSamples); int bytes = samples * m_format.m_frameSize; + //TODO: handle planar formats if (m_convertFn) - m_convertFn((uint8_t*)data+copied, samples*m_currentBuffer->pkt->config.channels, (float*)(m_currentBuffer->pkt->data[0] + start)); + m_convertFn(buf+copied, samples*m_currentBuffer->pkt->config.channels, (float*)(m_currentBuffer->pkt->data[0] + start)); else - memcpy(m_currentBuffer->pkt->data[0] + start, (uint8_t*)data+copied, bytes); + memcpy(m_currentBuffer->pkt->data[0] + start, buf+copied, bytes); { CSingleLock lock(*m_statsLock); m_currentBuffer->pkt->nb_samples += samples; m_bufferedTime += (double)samples / m_currentBuffer->pkt->config.sample_rate; } copied += bytes; - bytesToCopy -= bytes; if (m_currentBuffer->pkt->nb_samples == m_currentBuffer->pkt->max_nb_samples) { MsgStreamSample msgData; @@ -249,6 +279,7 @@ bool CActiveAEStream::IsDrained() void CActiveAEStream::Flush() { m_currentBuffer = NULL; + m_leftoverBytes = 0; AE.FlushStream(this); ResetFreeBuffers(); } diff --git a/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEStream.h b/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEStream.h index 2c0de2e30a..4cf252fcbf 100644 --- a/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEStream.h +++ b/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEStream.h @@ -92,6 +92,8 @@ protected: IAEStream *m_streamSlave; CAEConvert::AEConvertToFn m_convertFn; CCriticalSection m_streamLock; + uint8_t *m_leftoverBuffer; + int m_leftoverBytes; // only accessed by engine CActiveAEBufferPool *m_inputBuffers; diff --git a/xbmc/cores/paplayer/FLACcodec.cpp b/xbmc/cores/paplayer/FLACcodec.cpp index bb6c2f1ca4..cea984493b 100644 --- a/xbmc/cores/paplayer/FLACcodec.cpp +++ b/xbmc/cores/paplayer/FLACcodec.cpp @@ -311,17 +311,19 @@ void FLACCodec::DecoderMetadataCallback(const FLAC__StreamDecoder *decoder, cons if (metadata->type==FLAC__METADATA_TYPE_STREAMINFO) { - static enum AEChannel map[6][7] = { + static enum AEChannel map[8][9] = { {AE_CH_FC, AE_CH_NULL}, {AE_CH_FL, AE_CH_FR, AE_CH_NULL}, {AE_CH_FL, AE_CH_FR, AE_CH_FC, AE_CH_NULL}, {AE_CH_FL, AE_CH_FR, AE_CH_BL, AE_CH_BR, AE_CH_NULL}, {AE_CH_FL, AE_CH_FR, AE_CH_FC, AE_CH_BL, AE_CH_BR, AE_CH_NULL}, - {AE_CH_FL, AE_CH_FR, AE_CH_FC, AE_CH_LFE, AE_CH_BL, AE_CH_BR, AE_CH_NULL} + {AE_CH_FL, AE_CH_FR, AE_CH_FC, AE_CH_LFE, AE_CH_BL, AE_CH_BR, AE_CH_NULL}, // 6 channels + {AE_CH_FL, AE_CH_FR, AE_CH_FC, AE_CH_LFE, AE_CH_BC, AE_CH_BL, AE_CH_BR, AE_CH_NULL}, // 7 channels + {AE_CH_FL, AE_CH_FR, AE_CH_FC, AE_CH_LFE, AE_CH_BL, AE_CH_BR, AE_CH_SL, AE_CH_SR, AE_CH_NULL} // 8 channels }; /* channel counts greater then 6 are undefined */ - if (metadata->data.stream_info.channels > 6) + if (metadata->data.stream_info.channels > 8) pThis->m_ChannelInfo = CAEUtil::GuessChLayout(metadata->data.stream_info.channels); else pThis->m_ChannelInfo = CAEChannelInfo(map[metadata->data.stream_info.channels - 1]); diff --git a/xbmc/interfaces/json-rpc/AudioLibrary.cpp b/xbmc/interfaces/json-rpc/AudioLibrary.cpp index 716e91aabc..5f92236614 100644 --- a/xbmc/interfaces/json-rpc/AudioLibrary.cpp +++ b/xbmc/interfaces/json-rpc/AudioLibrary.cpp @@ -270,7 +270,7 @@ JSONRPC_STATUS CAudioLibrary::GetSongDetails(const CStdString &method, ITranspor if (ret != OK) return ret; - HandleFileItem("songid", false, "songdetails", items[0], parameterObject, parameterObject["properties"], result, false); + HandleFileItem("songid", true, "songdetails", items[0], parameterObject, parameterObject["properties"], result, false); return OK; } diff --git a/xbmc/interfaces/json-rpc/ServiceDescription.h b/xbmc/interfaces/json-rpc/ServiceDescription.h index 7d18cf428f..b4afd3accf 100644 --- a/xbmc/interfaces/json-rpc/ServiceDescription.h +++ b/xbmc/interfaces/json-rpc/ServiceDescription.h @@ -22,7 +22,7 @@ namespace JSONRPC { const char* const JSONRPC_SERVICE_ID = "http://xbmc.org/jsonrpc/ServiceDescription.json"; - const char* const JSONRPC_SERVICE_VERSION = "6.6.1"; + const char* const JSONRPC_SERVICE_VERSION = "6.6.2"; const char* const JSONRPC_SERVICE_DESCRIPTION = "JSON-RPC API of XBMC"; const char* const JSONRPC_SERVICE_TYPES[] = { diff --git a/xbmc/settings/dialogs/GUIDialogSettings.cpp b/xbmc/settings/dialogs/GUIDialogSettings.cpp index 009a16298b..240dad544a 100644 --- a/xbmc/settings/dialogs/GUIDialogSettings.cpp +++ b/xbmc/settings/dialogs/GUIDialogSettings.cpp @@ -599,6 +599,8 @@ void CGUIDialogSettings::AddSpin(unsigned int id, int label, int *current, vecto setting.type = SettingInfo::SPIN; setting.data = current; setting.entry = values; + if (values.size() <= 1) + setting.enabled = false; m_settings.push_back(setting); } @@ -664,6 +666,15 @@ void CGUIDialogSettings::OnInitWindow() SetupPage(); // set the default focus control m_lastControlID = CONTROL_START; + + for (unsigned int i = 0; i < m_settings.size(); i++) + { + if (m_settings.at(i).enabled) + { + m_lastControlID = CONTROL_START + i; + break; + } + } CGUIDialog::OnInitWindow(); } diff --git a/xbmc/video/windows/GUIWindowVideoNav.cpp b/xbmc/video/windows/GUIWindowVideoNav.cpp index d58f77b97c..b888ea7f1c 100644 --- a/xbmc/video/windows/GUIWindowVideoNav.cpp +++ b/xbmc/video/windows/GUIWindowVideoNav.cpp @@ -939,15 +939,10 @@ void CGUIWindowVideoNav::GetContextButtons(int itemNumber, CContextButtons &butt else buttons.Add(CONTEXT_BUTTON_SCAN, 13349); } - if (!g_application.IsVideoScanning() && item->IsVideoDb() && item->HasVideoInfoTag() && - (!item->m_bIsFolder || m_vecItems->GetContent().Equals("movies") || m_vecItems->GetContent().Equals("tvshows"))) - { - buttons.Add(CONTEXT_BUTTON_EDIT, 16106); - } - else if (!item->IsPlugin() && !item->IsScript() && !item->IsLiveTV() && !item->IsAddonsPath() && - item->GetPath() != "sources://video/" && item->GetPath() != "special://videoplaylists/" && - item->GetPath().Left(19) != "newsmartplaylist://" && item->GetPath().Left(14) != "newplaylist://" && - item->GetPath().Left(9) != "newtag://") + if (!item->IsPlugin() && !item->IsScript() && !item->IsLiveTV() && !item->IsAddonsPath() && + item->GetPath() != "sources://video/" && item->GetPath() != "special://videoplaylists/" && + item->GetPath().Left(19) != "newsmartplaylist://" && item->GetPath().Left(14) != "newplaylist://" && + item->GetPath().Left(9) != "newtag://") { if (item->m_bIsFolder) { @@ -963,6 +958,11 @@ void CGUIWindowVideoNav::GetContextButtons(int itemNumber, CContextButtons &butt buttons.Add(CONTEXT_BUTTON_MARK_WATCHED, 16103); //Mark as Watched } } + if (!g_application.IsVideoScanning() && item->IsVideoDb() && item->HasVideoInfoTag() && + (!item->m_bIsFolder || m_vecItems->GetContent().Equals("movies") || m_vecItems->GetContent().Equals("tvshows"))) + { + buttons.Add(CONTEXT_BUTTON_EDIT, 16106); + } if (node == NODE_TYPE_SEASONS && item->m_bIsFolder) buttons.Add(CONTEXT_BUTTON_SET_SEASON_ART, 13511); |