aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/cpluff/libcpluff/win32/dirent.c2
-rw-r--r--lib/cximage-6.0/CxImage/ximadsp.cpp28
-rw-r--r--lib/cximage-6.0/CxImage/ximatif.cpp2
-rw-r--r--xbmc/URL.cpp2
-rw-r--r--xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAE.cpp8
-rw-r--r--xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEResample.cpp3
-rw-r--r--xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEStream.cpp37
-rw-r--r--xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEStream.h2
-rw-r--r--xbmc/cores/paplayer/FLACcodec.cpp8
-rw-r--r--xbmc/interfaces/json-rpc/AudioLibrary.cpp2
-rw-r--r--xbmc/interfaces/json-rpc/ServiceDescription.h2
-rw-r--r--xbmc/settings/dialogs/GUIDialogSettings.cpp11
-rw-r--r--xbmc/video/windows/GUIWindowVideoNav.cpp18
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);