summaryrefslogtreecommitdiff
path: root/src/multimedia
diff options
context:
space:
mode:
authorOlivier Goffart <olivier.goffart@nokia.com>2010-07-28 11:43:13 +0200
committerOlivier Goffart <olivier.goffart@nokia.com>2010-07-28 11:43:13 +0200
commit84294f47e55073914bcbcdbaf85df1a0e2e2d845 (patch)
tree1166be97fcfcc6a71b9603443ef6360d33aef276 /src/multimedia
parent80e13f5bd418395bd64396e359a288b748ae1dfb (diff)
parent7b10151cb6550fe8060217fad8549950eadd5fca (diff)
downloadqt4-tools-84294f47e55073914bcbcdbaf85df1a0e2e2d845.tar.gz
Merge remote branch 'origin/4.7' into qt-master-from-4.7
Conflicts: src/gui/kernel/qapplication.cpp tests/auto/qfileinfo/tst_qfileinfo.cpp tools/qdoc3/test/assistant.qdocconf tools/qdoc3/test/designer.qdocconf tools/qdoc3/test/linguist.qdocconf tools/qdoc3/test/qmake.qdocconf tools/qdoc3/test/qt-build-docs.qdocconf tools/qdoc3/test/qt.qdocconf
Diffstat (limited to 'src/multimedia')
-rw-r--r--src/multimedia/audio/qaudiodevicefactory.cpp22
-rw-r--r--src/multimedia/audio/qaudiodeviceinfo_alsa_p.cpp46
-rw-r--r--src/multimedia/audio/qaudiodeviceinfo_alsa_p.h5
-rw-r--r--src/multimedia/audio/qaudiodeviceinfo_win32_p.cpp5
-rw-r--r--src/multimedia/audio/qaudioinput_alsa_p.cpp54
-rw-r--r--src/multimedia/audio/qaudioinput_alsa_p.h1
-rw-r--r--src/multimedia/audio/qaudioinput_win32_p.cpp2
-rw-r--r--src/multimedia/audio/qaudiooutput_win32_p.cpp101
-rw-r--r--src/multimedia/video/qabstractvideobuffer.cpp1
-rw-r--r--src/multimedia/video/qabstractvideobuffer.h1
10 files changed, 198 insertions, 40 deletions
diff --git a/src/multimedia/audio/qaudiodevicefactory.cpp b/src/multimedia/audio/qaudiodevicefactory.cpp
index 96545b4043..736630ed8c 100644
--- a/src/multimedia/audio/qaudiodevicefactory.cpp
+++ b/src/multimedia/audio/qaudiodevicefactory.cpp
@@ -67,7 +67,8 @@
QT_BEGIN_NAMESPACE
-#ifndef QT_NO_LIBRARY
+
+#if !defined(QT_NO_LIBRARY) && !defined(QT_NO_SETTINGS)
Q_GLOBAL_STATIC_WITH_ARGS(QFactoryLoader, loader,
(QAudioEngineFactoryInterface_iid, QLatin1String("/audio"), Qt::CaseInsensitive))
#endif
@@ -138,8 +139,7 @@ QList<QAudioDeviceInfo> QAudioDeviceFactory::availableDevices(QAudio::Mode mode)
devices << QAudioDeviceInfo(QLatin1String("builtin"), handle, mode);
#endif
#endif
-
-#ifndef QT_NO_LIBRARY
+#if !defined(QT_NO_LIBRARY) && !defined(QT_NO_SETTINGS)
QFactoryLoader* l = loader();
foreach (QString const& key, l->keys()) {
@@ -152,13 +152,12 @@ QList<QAudioDeviceInfo> QAudioDeviceFactory::availableDevices(QAudio::Mode mode)
delete plugin;
}
#endif
-
return devices;
}
QAudioDeviceInfo QAudioDeviceFactory::defaultInputDevice()
{
-#ifndef QT_NO_LIBRARY
+#if !defined(QT_NO_LIBRARY) && !defined(QT_NO_SETTINGS)
QAudioEngineFactoryInterface* plugin = qobject_cast<QAudioEngineFactoryInterface*>(loader()->instance(QLatin1String("default")));
if (plugin) {
@@ -178,7 +177,7 @@ QAudioDeviceInfo QAudioDeviceFactory::defaultInputDevice()
QAudioDeviceInfo QAudioDeviceFactory::defaultOutputDevice()
{
-#ifndef QT_NO_LIBRARY
+#if !defined(QT_NO_LIBRARY) && !defined(QT_NO_SETTINGS)
QAudioEngineFactoryInterface* plugin = qobject_cast<QAudioEngineFactoryInterface*>(loader()->instance(QLatin1String("default")));
if (plugin) {
@@ -206,15 +205,13 @@ QAbstractAudioDeviceInfo* QAudioDeviceFactory::audioDeviceInfo(const QString &re
return new QAudioDeviceInfoInternal(handle, mode);
#endif
#endif
-
-#ifndef QT_NO_LIBRARY
+#if !defined(QT_NO_LIBRARY) && !defined(QT_NO_SETTINGS)
QAudioEngineFactoryInterface* plugin =
qobject_cast<QAudioEngineFactoryInterface*>(loader()->instance(realm));
if (plugin)
rc = plugin->createDeviceInfo(handle, mode);
#endif
-
return rc == 0 ? new QNullDeviceInfo() : rc;
}
@@ -238,14 +235,13 @@ QAbstractAudioInput* QAudioDeviceFactory::createInputDevice(QAudioDeviceInfo con
return new QAudioInputPrivate(deviceInfo.handle(), format);
#endif
#endif
-#ifndef QT_NO_LIBRARY
+#if !defined(QT_NO_LIBRARY) && !defined(QT_NO_SETTINGS)
QAudioEngineFactoryInterface* plugin =
qobject_cast<QAudioEngineFactoryInterface*>(loader()->instance(deviceInfo.realm()));
if (plugin)
return plugin->createInput(deviceInfo.handle(), format);
#endif
-
return new QNullInputDevice();
}
@@ -259,15 +255,13 @@ QAbstractAudioOutput* QAudioDeviceFactory::createOutputDevice(QAudioDeviceInfo c
return new QAudioOutputPrivate(deviceInfo.handle(), format);
#endif
#endif
-
-#ifndef QT_NO_LIBRARY
+#if !defined(QT_NO_LIBRARY) && !defined(QT_NO_SETTINGS)
QAudioEngineFactoryInterface* plugin =
qobject_cast<QAudioEngineFactoryInterface*>(loader()->instance(deviceInfo.realm()));
if (plugin)
return plugin->createOutput(deviceInfo.handle(), format);
#endif
-
return new QNullOutputDevice();
}
diff --git a/src/multimedia/audio/qaudiodeviceinfo_alsa_p.cpp b/src/multimedia/audio/qaudiodeviceinfo_alsa_p.cpp
index 36270a7a25..f663dd2667 100644
--- a/src/multimedia/audio/qaudiodeviceinfo_alsa_p.cpp
+++ b/src/multimedia/audio/qaudiodeviceinfo_alsa_p.cpp
@@ -62,6 +62,8 @@ QAudioDeviceInfoInternal::QAudioDeviceInfoInternal(QByteArray dev, QAudio::Mode
device = QLatin1String(dev);
this->mode = mode;
+
+ checkSurround();
}
QAudioDeviceInfoInternal::~QAudioDeviceInfoInternal()
@@ -389,6 +391,9 @@ void QAudioDeviceInfoInternal::updateLists()
}
channelz.append(1);
channelz.append(2);
+ if (surround40) channelz.append(4);
+ if (surround51) channelz.append(6);
+ if (surround71) channelz.append(8);
sizez.append(8);
sizez.append(16);
sizez.append(32);
@@ -483,4 +488,45 @@ QByteArray QAudioDeviceInfoInternal::defaultOutputDevice()
return devices.first();
}
+void QAudioDeviceInfoInternal::checkSurround()
+{
+ QList<QByteArray> devices;
+ surround40 = false;
+ surround51 = false;
+ surround71 = false;
+
+ void **hints, **n;
+ char *name, *descr, *io;
+
+ if(snd_device_name_hint(-1, "pcm", &hints) < 0)
+ return;
+
+ n = hints;
+
+ while (*n != NULL) {
+ name = snd_device_name_get_hint(*n, "NAME");
+ descr = snd_device_name_get_hint(*n, "DESC");
+ io = snd_device_name_get_hint(*n, "IOID");
+ if((name != NULL) && (descr != NULL)) {
+ QString deviceName = QLatin1String(name);
+ if (mode == QAudio::AudioOutput) {
+ if(deviceName.contains(QLatin1String("surround40")))
+ surround40 = true;
+ if(deviceName.contains(QLatin1String("surround51")))
+ surround51 = true;
+ if(deviceName.contains(QLatin1String("surround71")))
+ surround71 = true;
+ }
+ }
+ if(name != NULL)
+ free(name);
+ if(descr != NULL)
+ free(descr);
+ if(io != NULL)
+ free(io);
+ ++n;
+ }
+ snd_device_name_free_hint(hints);
+}
+
QT_END_NAMESPACE
diff --git a/src/multimedia/audio/qaudiodeviceinfo_alsa_p.h b/src/multimedia/audio/qaudiodeviceinfo_alsa_p.h
index 6f9a459366..8525980e05 100644
--- a/src/multimedia/audio/qaudiodeviceinfo_alsa_p.h
+++ b/src/multimedia/audio/qaudiodeviceinfo_alsa_p.h
@@ -98,6 +98,11 @@ private:
bool open();
void close();
+ void checkSurround();
+ bool surround40;
+ bool surround51;
+ bool surround71;
+
QString device;
QAudio::Mode mode;
QAudioFormat nearest;
diff --git a/src/multimedia/audio/qaudiodeviceinfo_win32_p.cpp b/src/multimedia/audio/qaudiodeviceinfo_win32_p.cpp
index aee0807463..9e8b1bfdf8 100644
--- a/src/multimedia/audio/qaudiodeviceinfo_win32_p.cpp
+++ b/src/multimedia/audio/qaudiodeviceinfo_win32_p.cpp
@@ -374,6 +374,11 @@ void QAudioDeviceInfoInternal::updateLists()
#endif
channelz.append(1);
channelz.append(2);
+ if (mode == QAudio::AudioOutput) {
+ channelz.append(4);
+ channelz.append(6);
+ channelz.append(8);
+ }
byteOrderz.append(QAudioFormat::LittleEndian);
diff --git a/src/multimedia/audio/qaudioinput_alsa_p.cpp b/src/multimedia/audio/qaudioinput_alsa_p.cpp
index c9a8b713f8..58669b3532 100644
--- a/src/multimedia/audio/qaudioinput_alsa_p.cpp
+++ b/src/multimedia/audio/qaudioinput_alsa_p.cpp
@@ -120,7 +120,7 @@ int QAudioInputPrivate::xrun_recovery(int err)
if(err < 0)
reset = true;
else {
- bytesAvailable = bytesReady();
+ bytesAvailable = checkBytesReady();
if (bytesAvailable <= 0)
reset = true;
}
@@ -408,7 +408,7 @@ bool QAudioInputPrivate::open()
snd_pcm_start(handle);
// Step 5: Setup timer
- bytesAvailable = bytesReady();
+ bytesAvailable = checkBytesReady();
if(pullMode)
connect(audioSource,SIGNAL(readyRead()),this,SLOT(userFeed()));
@@ -437,19 +437,29 @@ void QAudioInputPrivate::close()
}
}
-int QAudioInputPrivate::bytesReady() const
+int QAudioInputPrivate::checkBytesReady()
{
if(resuming)
- return period_size;
-
- if(deviceState != QAudio::ActiveState && deviceState != QAudio::IdleState)
- return 0;
- int frames = snd_pcm_avail_update(handle);
- if (frames < 0) return frames;
- if((int)frames > (int)buffer_frames)
- frames = buffer_frames;
+ bytesAvailable = period_size;
+ else if(deviceState != QAudio::ActiveState
+ && deviceState != QAudio::IdleState)
+ bytesAvailable = 0;
+ else {
+ int frames = snd_pcm_avail_update(handle);
+ if (frames < 0) {
+ bytesAvailable = frames;
+ } else {
+ if((int)frames > (int)buffer_frames)
+ frames = buffer_frames;
+ bytesAvailable = snd_pcm_frames_to_bytes(handle, frames);
+ }
+ }
+ return bytesAvailable;
+}
- return snd_pcm_frames_to_bytes(handle, frames);
+int QAudioInputPrivate::bytesReady() const
+{
+ return qMax(bytesAvailable, 0);
}
qint64 QAudioInputPrivate::read(char* data, qint64 len)
@@ -460,12 +470,12 @@ qint64 QAudioInputPrivate::read(char* data, qint64 len)
if ( !handle )
return 0;
- bytesAvailable = bytesReady();
+ bytesAvailable = checkBytesReady();
if (bytesAvailable < 0) {
// bytesAvailable as negative is error code, try to recover from it.
xrun_recovery(bytesAvailable);
- bytesAvailable = bytesReady();
+ bytesAvailable = checkBytesReady();
if (bytesAvailable < 0) {
// recovery failed must stop and set error.
close();
@@ -639,11 +649,25 @@ bool QAudioInputPrivate::deviceReady()
InputPrivate* a = qobject_cast<InputPrivate*>(audioSource);
a->trigger();
}
- bytesAvailable = bytesReady();
+ bytesAvailable = checkBytesReady();
if(deviceState != QAudio::ActiveState)
return true;
+ if (bytesAvailable < 0) {
+ // bytesAvailable as negative is error code, try to recover from it.
+ xrun_recovery(bytesAvailable);
+ bytesAvailable = checkBytesReady();
+ if (bytesAvailable < 0) {
+ // recovery failed must stop and set error.
+ close();
+ errorState = QAudio::IOError;
+ deviceState = QAudio::StoppedState;
+ emit stateChanged(deviceState);
+ return 0;
+ }
+ }
+
if(intervalTime && (timeStamp.elapsed() + elapsedTimeOffset) > intervalTime) {
emit notify();
elapsedTimeOffset = timeStamp.elapsed() + elapsedTimeOffset - intervalTime;
diff --git a/src/multimedia/audio/qaudioinput_alsa_p.h b/src/multimedia/audio/qaudioinput_alsa_p.h
index c907019318..52975a647b 100644
--- a/src/multimedia/audio/qaudioinput_alsa_p.h
+++ b/src/multimedia/audio/qaudioinput_alsa_p.h
@@ -110,6 +110,7 @@ private slots:
bool deviceReady();
private:
+ int checkBytesReady();
int xrun_recovery(int err);
int setFormat();
bool open();
diff --git a/src/multimedia/audio/qaudioinput_win32_p.cpp b/src/multimedia/audio/qaudioinput_win32_p.cpp
index 14a1cf337d..ece1c26c3e 100644
--- a/src/multimedia/audio/qaudioinput_win32_p.cpp
+++ b/src/multimedia/audio/qaudioinput_win32_p.cpp
@@ -148,7 +148,7 @@ void QAudioInputPrivate::freeBlocks(WAVEHDR* blockArray)
for(int i = 0; i < count; i++) {
waveInUnprepareHeader(hWaveIn,blocks, sizeof(WAVEHDR));
- blocks+=sizeof(WAVEHDR);
+ blocks++;
}
HeapFree(GetProcessHeap(), 0, blockArray);
}
diff --git a/src/multimedia/audio/qaudiooutput_win32_p.cpp b/src/multimedia/audio/qaudiooutput_win32_p.cpp
index a8aeb4193d..99bada2a5c 100644
--- a/src/multimedia/audio/qaudiooutput_win32_p.cpp
+++ b/src/multimedia/audio/qaudiooutput_win32_p.cpp
@@ -52,6 +52,53 @@
#include "qaudiooutput_win32_p.h"
+#ifndef SPEAKER_FRONT_LEFT
+ #define SPEAKER_FRONT_LEFT 0x00000001
+ #define SPEAKER_FRONT_RIGHT 0x00000002
+ #define SPEAKER_FRONT_CENTER 0x00000004
+ #define SPEAKER_LOW_FREQUENCY 0x00000008
+ #define SPEAKER_BACK_LEFT 0x00000010
+ #define SPEAKER_BACK_RIGHT 0x00000020
+ #define SPEAKER_FRONT_LEFT_OF_CENTER 0x00000040
+ #define SPEAKER_FRONT_RIGHT_OF_CENTER 0x00000080
+ #define SPEAKER_BACK_CENTER 0x00000100
+ #define SPEAKER_SIDE_LEFT 0x00000200
+ #define SPEAKER_SIDE_RIGHT 0x00000400
+ #define SPEAKER_TOP_CENTER 0x00000800
+ #define SPEAKER_TOP_FRONT_LEFT 0x00001000
+ #define SPEAKER_TOP_FRONT_CENTER 0x00002000
+ #define SPEAKER_TOP_FRONT_RIGHT 0x00004000
+ #define SPEAKER_TOP_BACK_LEFT 0x00008000
+ #define SPEAKER_TOP_BACK_CENTER 0x00010000
+ #define SPEAKER_TOP_BACK_RIGHT 0x00020000
+ #define SPEAKER_RESERVED 0x7FFC0000
+ #define SPEAKER_ALL 0x80000000
+#endif
+
+#ifndef _WAVEFORMATEXTENSIBLE_
+
+ #define _WAVEFORMATEXTENSIBLE_
+ typedef struct
+ {
+ WAVEFORMATEX Format; // Base WAVEFORMATEX data
+ union
+ {
+ WORD wValidBitsPerSample; // Valid bits in each sample container
+ WORD wSamplesPerBlock; // Samples per block of audio data; valid
+ // if wBitsPerSample=0 (but rarely used).
+ WORD wReserved; // Zero if neither case above applies.
+ } Samples;
+ DWORD dwChannelMask; // Positions of the audio channels
+ GUID SubFormat; // Format identifier GUID
+ } WAVEFORMATEXTENSIBLE, *PWAVEFORMATEXTENSIBLE, *LPPWAVEFORMATEXTENSIBLE;
+ typedef const WAVEFORMATEXTENSIBLE* LPCWAVEFORMATEXTENSIBLE;
+
+#endif
+
+#if !defined(WAVE_FORMAT_EXTENSIBLE)
+#define WAVE_FORMAT_EXTENSIBLE 0xFFFE
+#endif
+
//#define DEBUG_AUDIO 1
QT_BEGIN_NAMESPACE
@@ -146,7 +193,7 @@ void QAudioOutputPrivate::freeBlocks(WAVEHDR* blockArray)
for(int i = 0; i < count; i++) {
waveOutUnprepareHeader(hWaveOut,blocks, sizeof(WAVEHDR));
- blocks+=sizeof(WAVEHDR);
+ blocks++;
}
HeapFree(GetProcessHeap(), 0, blockArray);
}
@@ -258,15 +305,49 @@ bool QAudioOutputPrivate::open()
}
}
- if(waveOutOpen(&hWaveOut, devId, &wfx,
- (DWORD_PTR)&waveOutProc,
- (DWORD_PTR) this,
- CALLBACK_FUNCTION) != MMSYSERR_NOERROR) {
- errorState = QAudio::OpenError;
- deviceState = QAudio::StoppedState;
- emit stateChanged(deviceState);
- qWarning("QAudioOutput: open error");
- return false;
+ if ( settings.channels() <= 2) {
+ if(waveOutOpen(&hWaveOut, devId, &wfx,
+ (DWORD_PTR)&waveOutProc,
+ (DWORD_PTR) this,
+ CALLBACK_FUNCTION) != MMSYSERR_NOERROR) {
+ errorState = QAudio::OpenError;
+ deviceState = QAudio::StoppedState;
+ emit stateChanged(deviceState);
+ qWarning("QAudioOutput: open error");
+ return false;
+ }
+ } else {
+ WAVEFORMATEXTENSIBLE wfex;
+ wfex.Format.wFormatTag = WAVE_FORMAT_EXTENSIBLE;
+ wfex.Format.nChannels = settings.channels();
+ wfex.Format.wBitsPerSample = settings.sampleSize();
+ wfex.Format.nSamplesPerSec = settings.frequency();
+ wfex.Format.nBlockAlign = wfex.Format.nChannels*wfex.Format.wBitsPerSample/8;
+ wfex.Format.nAvgBytesPerSec=wfex.Format.nSamplesPerSec*wfex.Format.nBlockAlign;
+ wfex.Samples.wValidBitsPerSample=wfex.Format.wBitsPerSample;
+ static const GUID _KSDATAFORMAT_SUBTYPE_PCM = {
+ 0x00000001, 0x0000, 0x0010, {0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}};
+ wfex.SubFormat=_KSDATAFORMAT_SUBTYPE_PCM;
+ wfex.Format.cbSize=22;
+
+ wfex.dwChannelMask = SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT;
+ if (settings.channels() >= 4)
+ wfex.dwChannelMask |= SPEAKER_BACK_LEFT | SPEAKER_BACK_RIGHT;
+ if (settings.channels() >= 6)
+ wfex.dwChannelMask |= SPEAKER_FRONT_CENTER | SPEAKER_LOW_FREQUENCY;
+ if (settings.channels() == 8)
+ wfex.dwChannelMask |= SPEAKER_SIDE_LEFT | SPEAKER_SIDE_RIGHT;
+
+ if(waveOutOpen(&hWaveOut, devId, &wfex.Format,
+ (DWORD_PTR)&waveOutProc,
+ (DWORD_PTR) this,
+ CALLBACK_FUNCTION) != MMSYSERR_NOERROR) {
+ errorState = QAudio::OpenError;
+ deviceState = QAudio::StoppedState;
+ emit stateChanged(deviceState);
+ qWarning("QAudioOutput: open error");
+ return false;
+ }
}
totalTimeValue = 0;
diff --git a/src/multimedia/video/qabstractvideobuffer.cpp b/src/multimedia/video/qabstractvideobuffer.cpp
index e9d30d0730..db05ee5911 100644
--- a/src/multimedia/video/qabstractvideobuffer.cpp
+++ b/src/multimedia/video/qabstractvideobuffer.cpp
@@ -73,6 +73,7 @@ QT_BEGIN_NAMESPACE
\value GLTextureHandle The handle of the buffer is an OpenGL texture ID.
\value XvShmImageHandle The handle contains pointer to shared memory XVideo image.
\value CoreImageHandle The handle contains pointer to Mac OS X CIImage.
+ \value QPixmapHandle The handle of the buffer is a QPixmap.
\value UserHandle Start value for user defined handle types.
\sa handleType()
diff --git a/src/multimedia/video/qabstractvideobuffer.h b/src/multimedia/video/qabstractvideobuffer.h
index a8389db126..98e12da7fe 100644
--- a/src/multimedia/video/qabstractvideobuffer.h
+++ b/src/multimedia/video/qabstractvideobuffer.h
@@ -63,6 +63,7 @@ public:
GLTextureHandle,
XvShmImageHandle,
CoreImageHandle,
+ QPixmapHandle,
UserHandle = 1000
};