mirror of
https://github.com/wang-bin/QtAV.git
synced 2026-10-28 19:16:48 +08:00
audio: add dsound. not tested
This commit is contained in:
@@ -0,0 +1,418 @@
|
||||
/******************************************************************************
|
||||
AudioOutputDSound.cpp: description
|
||||
Copyright (C) 2012-2014 Wang Bin <wbsecg1@gmail.com>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
******************************************************************************/
|
||||
|
||||
|
||||
#include "QtAV/AudioOutput.h"
|
||||
#include "QtAV/private/AudioOutput_p.h"
|
||||
#include "prepost.h"
|
||||
#include <QtCore/QLibrary>
|
||||
#include <QtCore/QVector>
|
||||
|
||||
#include <windows.h>
|
||||
#define DIRECTSOUND_VERSION 0x0600
|
||||
#include <dsound.h>
|
||||
#include "QtAV/private/AVCompat.h"
|
||||
|
||||
namespace QtAV {
|
||||
class AudioOutputDSoundPrivate;
|
||||
class AudioOutputDSound : public AudioOutput
|
||||
{
|
||||
DPTR_DECLARE_PRIVATE(AudioOutputDSound)
|
||||
public:
|
||||
AudioOutputDSound();
|
||||
~AudioOutputDSound();
|
||||
//AudioOutputId id() const
|
||||
virtual bool open();
|
||||
virtual bool close();
|
||||
virtual bool isSupported(const AudioFormat& format) const;
|
||||
virtual void waitForNextBuffer();
|
||||
protected:
|
||||
virtual bool write();
|
||||
};
|
||||
|
||||
extern AudioOutputId AudioOutputId_DSound;
|
||||
FACTORY_REGISTER_ID_AUTO(AudioOutput, DSound, "DirectSound")
|
||||
|
||||
void RegisterAudioOutputDSound_Man()
|
||||
{
|
||||
FACTORY_REGISTER_ID_MAN(AudioOutput, DSound, "DirectSound")
|
||||
}
|
||||
|
||||
|
||||
template <class T> void SafeRelease(T **ppT) {
|
||||
if (*ppT) {
|
||||
(*ppT)->Release();
|
||||
*ppT = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
// use the definitions from the win32 api headers when they define these
|
||||
#define WAVE_FORMAT_IEEE_FLOAT 0x0003
|
||||
#define WAVE_FORMAT_DOLBY_AC3_SPDIF 0x0092
|
||||
#define WAVE_FORMAT_EXTENSIBLE 0xFFFE
|
||||
/* GUID SubFormat IDs */
|
||||
/* We need both b/c const variables are not compile-time constants in C, giving
|
||||
* us an error if we use the const GUID in an enum */
|
||||
|
||||
#ifndef _KSDATAFORMAT_SUBTYPE_PCM_
|
||||
#define _KSDATAFORMAT_SUBTYPE_PCM_ {0x00000001, 0x0000, 0x0010, {0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}}
|
||||
static const GUID VLC_KSDATAFORMAT_SUBTYPE_PCM = {0xE923AABF, 0xCB58, 0x4471, {0xA1, 0x19, 0xFF, 0xFA, 0x01, 0xE4, 0xCE, 0x62}};
|
||||
#define KSDATAFORMAT_SUBTYPE_PCM VLC_KSDATAFORMAT_SUBTYPE_PCM
|
||||
#endif
|
||||
|
||||
#ifndef _KSDATAFORMAT_SUBTYPE_IEEE_FLOAT_
|
||||
#define _KSDATAFORMAT_SUBTYPE_IEEE_FLOAT_ {0x00000003, 0x0000, 0x0010, {0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}}
|
||||
static const GUID VLC_KSDATAFORMAT_SUBTYPE_IEEE_FLOAT = {0x00000003, 0x0000, 0x0010, {0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}};
|
||||
#define KSDATAFORMAT_SUBTYPE_IEEE_FLOAT VLC_KSDATAFORMAT_SUBTYPE_PCM
|
||||
#endif
|
||||
|
||||
#ifndef _KSDATAFORMAT_SUBTYPE_UNKNOWN_
|
||||
#define _KSDATAFORMAT_SUBTYPE_UNKNOWN_ {0x00000000, 0x0000, 0x0000, {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}
|
||||
static const GUID VLC_KSDATAFORMAT_SUBTYPE_UNKNOWN = {0x00000000, 0x0000, 0x0000, {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}};
|
||||
#define KSDATAFORMAT_SUBTYPE_UNKNOWN VLC_KSDATAFORMAT_SUBTYPE_UNKNOWN
|
||||
#endif
|
||||
|
||||
#ifndef _WAVEFORMATEXTENSIBLE_
|
||||
typedef struct {
|
||||
WAVEFORMATEX Format;
|
||||
union {
|
||||
WORD wValidBitsPerSample; /* bits of precision */
|
||||
WORD wSamplesPerBlock; /* valid if wBitsPerSample==0 */
|
||||
WORD wReserved; /* If neither applies, set to zero. */
|
||||
} Samples;
|
||||
DWORD dwChannelMask; /* which channels are */
|
||||
/* present in stream */
|
||||
GUID SubFormat;
|
||||
} WAVEFORMATEXTENSIBLE, *PWAVEFORMATEXTENSIBLE;
|
||||
#endif
|
||||
|
||||
/* Microsoft speaker definitions. key/values are equal to FFmpeg's */
|
||||
#define SPEAKER_FRONT_LEFT 0x1
|
||||
#define SPEAKER_FRONT_RIGHT 0x2
|
||||
#define SPEAKER_FRONT_CENTER 0x4
|
||||
#define SPEAKER_LOW_FREQUENCY 0x8
|
||||
#define SPEAKER_BACK_LEFT 0x10
|
||||
#define SPEAKER_BACK_RIGHT 0x20
|
||||
#define SPEAKER_FRONT_LEFT_OF_CENTER 0x40
|
||||
#define SPEAKER_FRONT_RIGHT_OF_CENTER 0x80
|
||||
#define SPEAKER_BACK_CENTER 0x100
|
||||
#define SPEAKER_SIDE_LEFT 0x200
|
||||
#define SPEAKER_SIDE_RIGHT 0x400
|
||||
#define SPEAKER_TOP_CENTER 0x800
|
||||
#define SPEAKER_TOP_FRONT_LEFT 0x1000
|
||||
#define SPEAKER_TOP_FRONT_CENTER 0x2000
|
||||
#define SPEAKER_TOP_FRONT_RIGHT 0x4000
|
||||
#define SPEAKER_TOP_BACK_LEFT 0x8000
|
||||
#define SPEAKER_TOP_BACK_CENTER 0x10000
|
||||
#define SPEAKER_TOP_BACK_RIGHT 0x20000
|
||||
#define SPEAKER_RESERVED 0x80000000
|
||||
|
||||
static int channelMaskToMS(qint64 av) {
|
||||
if (av >= (qint64)SPEAKER_RESERVED)
|
||||
return 0;
|
||||
return (int)av;
|
||||
}
|
||||
|
||||
static int channelLayoutToMS(qint64 av) {
|
||||
return channelMaskToMS(av);
|
||||
}
|
||||
|
||||
static const char* dserr2str(int err) {
|
||||
switch (err) {
|
||||
case DS_OK: return "DS_OK";
|
||||
case DS_NO_VIRTUALIZATION: return "DS_NO_VIRTUALIZATION";
|
||||
case DSERR_ALLOCATED: return "DS_NO_VIRTUALIZATION";
|
||||
case DSERR_CONTROLUNAVAIL: return "DSERR_CONTROLUNAVAIL";
|
||||
case DSERR_INVALIDPARAM: return "DSERR_INVALIDPARAM";
|
||||
case DSERR_INVALIDCALL: return "DSERR_INVALIDCALL";
|
||||
case DSERR_GENERIC: return "DSERR_GENERIC";
|
||||
case DSERR_PRIOLEVELNEEDED: return "DSERR_PRIOLEVELNEEDED";
|
||||
case DSERR_OUTOFMEMORY: return "DSERR_OUTOFMEMORY";
|
||||
case DSERR_BADFORMAT: return "DSERR_BADFORMAT";
|
||||
case DSERR_UNSUPPORTED: return "DSERR_UNSUPPORTED";
|
||||
case DSERR_NODRIVER: return "DSERR_NODRIVER";
|
||||
case DSERR_ALREADYINITIALIZED: return "DSERR_ALREADYINITIALIZED";
|
||||
case DSERR_NOAGGREGATION: return "DSERR_NOAGGREGATION";
|
||||
case DSERR_BUFFERLOST: return "DSERR_BUFFERLOST";
|
||||
case DSERR_OTHERAPPHASPRIO: return "DSERR_OTHERAPPHASPRIO";
|
||||
case DSERR_UNINITIALIZED: return "DSERR_UNINITIALIZED";
|
||||
case DSERR_NOINTERFACE: return "DSERR_NOINTERFACE";
|
||||
case DSERR_ACCESSDENIED: return "DSERR_ACCESSDENIED";
|
||||
default: return "unknown";
|
||||
}
|
||||
}
|
||||
|
||||
class AudioOutputDSoundPrivate : public AudioOutputPrivate
|
||||
{
|
||||
public:
|
||||
AudioOutputDSoundPrivate()
|
||||
: AudioOutputPrivate()
|
||||
, dll(NULL)
|
||||
, prim_buf(NULL)
|
||||
, stream_buf(NULL)
|
||||
, write_offset(0)
|
||||
{
|
||||
}
|
||||
~AudioOutputDSoundPrivate() {
|
||||
}
|
||||
bool loadDll();
|
||||
bool unloadDll();
|
||||
bool init();
|
||||
void destroy() {
|
||||
SafeRelease(&dsound);
|
||||
SafeRelease(&prim_buf);
|
||||
SafeRelease(&stream_buf);
|
||||
unloadDll();
|
||||
}
|
||||
bool createDSoundBuffers();
|
||||
|
||||
HINSTANCE dll;
|
||||
LPDIRECTSOUND dsound; ///direct sound object
|
||||
LPDIRECTSOUNDBUFFER prim_buf; ///primary direct sound buffer
|
||||
LPDIRECTSOUNDBUFFER stream_buf; ///secondary direct sound buffer (stream buffer)
|
||||
int write_offset; ///offset of the write cursor in the direct sound buffer
|
||||
};
|
||||
|
||||
AudioOutputDSound::AudioOutputDSound()
|
||||
:AudioOutput(*new AudioOutputDSoundPrivate())
|
||||
{
|
||||
}
|
||||
|
||||
AudioOutputDSound::~AudioOutputDSound()
|
||||
{
|
||||
close();
|
||||
}
|
||||
|
||||
bool AudioOutputDSound::open()
|
||||
{
|
||||
DPTR_D(AudioOutputDSound);
|
||||
if (!d.init())
|
||||
return false;
|
||||
if (!d.createDSoundBuffers())
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool AudioOutputDSound::close()
|
||||
{
|
||||
DPTR_D(AudioOutputDSound);
|
||||
d.destroy();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool AudioOutputDSound::isSupported(const AudioFormat &format) const
|
||||
{
|
||||
Q_UNUSED(format);
|
||||
return true;
|
||||
}
|
||||
|
||||
void AudioOutputDSound::waitForNextBuffer()
|
||||
{
|
||||
DPTR_D(AudioOutputDSound);
|
||||
if (!d.dsound)
|
||||
return;
|
||||
DWORD read_offset;
|
||||
d.stream_buf->GetCurrentPosition(&read_offset /*play*/, NULL /*write*/);
|
||||
int remain = d.write_offset - read_offset;
|
||||
if (remain < 0LL) {
|
||||
remain += d.bufferSizeTotal();
|
||||
}
|
||||
if (remain > 0) {
|
||||
// don't need AudioOutputPrivate buffer queue
|
||||
unsigned long duration = d.format.durationForBytes((qint64)remain)/1000LL;
|
||||
QMutexLocker lock(&d.mutex);
|
||||
Q_UNUSED(lock);
|
||||
d.cond.wait(&d.mutex, duration);
|
||||
}
|
||||
d.bufferRemoved(); //TODO: virtual void noWait();
|
||||
}
|
||||
|
||||
bool AudioOutputDSound::write() //TODO: deprecated, use write(AudioFrame or QByteArray)
|
||||
{
|
||||
DPTR_D(AudioOutputDSound);
|
||||
LPVOID dst1, dst2;
|
||||
DWORD size1, size2;
|
||||
if (d.write_offset > d.bufferSizeTotal())
|
||||
d.write_offset = 0;
|
||||
HRESULT res = d.stream_buf->Lock(d.write_offset, d.data.size(), &dst1, &size1, &dst2, &size2, 0);
|
||||
if (res == DSERR_BUFFERLOST) {
|
||||
d.stream_buf->Restore();
|
||||
res = d.stream_buf->Lock(d.write_offset, d.data.size(), &dst1, &size1, &dst2, &size2, 0);
|
||||
}
|
||||
if (res != DS_OK) {
|
||||
qWarning("Can not lock secondary buffer (%s)", dserr2str(res));
|
||||
return false;
|
||||
}
|
||||
memcpy(dst1, d.data.constData(), size1);
|
||||
if (dst2)
|
||||
memcpy(dst2, d.data.constData() + size1, size2);
|
||||
d.write_offset += size1 + size2;
|
||||
if (d.write_offset > d.bufferSizeTotal())
|
||||
d.write_offset = size2;
|
||||
res = d.stream_buf->Unlock(dst1, size1, dst2, size2);
|
||||
if (res != DS_OK) {
|
||||
qWarning("Unloack error (%s)",dserr2str(res));
|
||||
//return false;
|
||||
}
|
||||
DWORD status;
|
||||
d.stream_buf->GetStatus(&status);
|
||||
if (!(status & DSBSTATUS_PLAYING)) {
|
||||
d.stream_buf->Play(0, 0, DSBPLAY_LOOPING);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool AudioOutputDSoundPrivate::loadDll()
|
||||
{
|
||||
dll = LoadLibrary(TEXT("dsound.dll"));
|
||||
if (!dll) {
|
||||
qWarning("Can not load dsound.dll");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool AudioOutputDSoundPrivate::unloadDll()
|
||||
{
|
||||
if (dll)
|
||||
FreeLibrary(dll);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool AudioOutputDSoundPrivate::init()
|
||||
{
|
||||
if (!loadDll())
|
||||
return false;
|
||||
typedef HRESULT (WINAPI *DirectSoundCreateFunc)(LPGUID, LPDIRECTSOUND *, LPUNKNOWN);
|
||||
//typedef HRESULT (WINAPI *DirectSoundEnumerateFunc)(LPDSENUMCALLBACKA, LPVOID);
|
||||
DirectSoundCreateFunc dsound_create = (DirectSoundCreateFunc)GetProcAddress(dll, "DirectSoundCreate");
|
||||
//DirectSoundEnumerateFunc dsound_enumerate = (DirectSoundEnumerateFunc)GetProcAddress(dll, "DirectSoundEnumerateA");
|
||||
if (!dsound_create) {
|
||||
qWarning("Failed to resolve 'DirectSoundCreate'");
|
||||
unloadDll();
|
||||
return false;
|
||||
}
|
||||
if (FAILED(dsound_create(NULL/*dev guid*/, &dsound, NULL))){
|
||||
unloadDll();
|
||||
return false;
|
||||
}
|
||||
/* DSSCL_EXCLUSIVE: can modify the settings of the primary buffer, only the sound of this app will be hearable when it will have the focus.
|
||||
*/
|
||||
if (FAILED(dsound->SetCooperativeLevel(GetDesktopWindow(), DSSCL_EXCLUSIVE))) {
|
||||
qWarning("Cannot set direct sound cooperative level");
|
||||
SafeRelease(&dsound);
|
||||
return false;
|
||||
}
|
||||
qDebug("DirectSound initialized.");
|
||||
DSCAPS dscaps;
|
||||
memset(&dscaps, 0, sizeof(DSCAPS));
|
||||
dscaps.dwSize = sizeof(DSCAPS);
|
||||
if (FAILED(dsound->GetCaps(&dscaps))) {
|
||||
qWarning("Cannot get device capabilities.");
|
||||
SafeRelease(&dsound);
|
||||
return false;
|
||||
}
|
||||
if (dscaps.dwFlags & DSCAPS_EMULDRIVER)
|
||||
qDebug("DirectSound is emulated");
|
||||
|
||||
write_offset = 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a DirectSound buffer of the required format.
|
||||
*
|
||||
* This function creates the buffer we'll use to play audio.
|
||||
* In DirectSound there are two kinds of buffers:
|
||||
* - the primary buffer: which is the actual buffer that the soundcard plays
|
||||
* - the secondary buffer(s): these buffers are the one actually used by
|
||||
* applications and DirectSound takes care of mixing them into the primary.
|
||||
*
|
||||
* Once you create a secondary buffer, you cannot change its format anymore so
|
||||
* you have to release the current one and create another.
|
||||
*/
|
||||
bool AudioOutputDSoundPrivate::createDSoundBuffers()
|
||||
{
|
||||
WAVEFORMATEXTENSIBLE wformat;
|
||||
// TODO: Dolby Digital AC3
|
||||
ZeroMemory(&wformat, sizeof(WAVEFORMATEXTENSIBLE));
|
||||
wformat.Format.cbSize = 0;
|
||||
wformat.Format.nChannels = format.channels();
|
||||
wformat.Format.nSamplesPerSec = format.sampleRate();
|
||||
wformat.Format.wFormatTag = WAVE_FORMAT_PCM;
|
||||
wformat.Format.wBitsPerSample = format.bytesPerSample() * 8;
|
||||
wformat.Format.nBlockAlign = wformat.Format.nChannels * format.bytesPerSample();
|
||||
wformat.Format.nAvgBytesPerSec = wformat.Format.nSamplesPerSec * wformat.Format.nBlockAlign;
|
||||
wformat.dwChannelMask = channelLayoutToMS(format.channelLayoutFFmpeg());
|
||||
if (format.channels() > 2) {
|
||||
wformat.Format.cbSize = sizeof(WAVEFORMATEXTENSIBLE) - sizeof(WAVEFORMATEX);
|
||||
wformat.Format.wFormatTag = WAVE_FORMAT_EXTENSIBLE;
|
||||
wformat.SubFormat = KSDATAFORMAT_SUBTYPE_PCM;
|
||||
wformat.Samples.wValidBitsPerSample = wformat.Format.wBitsPerSample;
|
||||
}
|
||||
// fill in primary sound buffer descriptor
|
||||
DSBUFFERDESC dsbpridesc;
|
||||
memset(&dsbpridesc, 0, sizeof(DSBUFFERDESC));
|
||||
dsbpridesc.dwSize = sizeof(DSBUFFERDESC);
|
||||
dsbpridesc.dwFlags = DSBCAPS_PRIMARYBUFFER;
|
||||
dsbpridesc.dwBufferBytes = 0;
|
||||
dsbpridesc.lpwfxFormat = NULL;
|
||||
// create primary buffer and set its format
|
||||
HRESULT res = dsound->CreateSoundBuffer(&dsbpridesc, &prim_buf, NULL);
|
||||
if (res != DS_OK) {
|
||||
destroy();
|
||||
qWarning("Cannot create primary buffer (%s)", dserr2str(res));
|
||||
return false;
|
||||
}
|
||||
res = prim_buf->SetFormat((WAVEFORMATEX *)&wformat);
|
||||
if (res != DS_OK) {
|
||||
qWarning("Cannot set primary buffer format (%s), using standard setting (bad quality)", dserr2str(res));
|
||||
}
|
||||
qDebug("primary buffer created");
|
||||
|
||||
// fill in the secondary sound buffer (=stream buffer) descriptor
|
||||
DSBUFFERDESC dsbdesc;
|
||||
memset(&dsbdesc, 0, sizeof(DSBUFFERDESC));
|
||||
dsbdesc.dwSize = sizeof(DSBUFFERDESC);
|
||||
dsbdesc.dwFlags = DSBCAPS_GETCURRENTPOSITION2 /** Better position accuracy */
|
||||
| DSBCAPS_GLOBALFOCUS /** Allows background playing */
|
||||
| DSBCAPS_CTRLVOLUME; /** volume control enabled */
|
||||
dsbdesc.dwBufferBytes = bufferSizeTotal();
|
||||
dsbdesc.lpwfxFormat = (WAVEFORMATEX *)&wformat;
|
||||
// Needed for 5.1 on emu101k - shit soundblaster
|
||||
if (format.channels() > 2)
|
||||
dsbdesc.dwFlags |= DSBCAPS_LOCHARDWARE;
|
||||
// now create the stream buffer
|
||||
res = dsound->CreateSoundBuffer(&dsbdesc, &stream_buf, NULL);
|
||||
if (res != DS_OK) {
|
||||
if (dsbdesc.dwFlags & DSBCAPS_LOCHARDWARE) {
|
||||
// Try without DSBCAPS_LOCHARDWARE
|
||||
dsbdesc.dwFlags &= ~DSBCAPS_LOCHARDWARE;
|
||||
res = dsound->CreateSoundBuffer(&dsbdesc, &stream_buf, NULL);
|
||||
}
|
||||
if (res != DS_OK) {
|
||||
destroy();
|
||||
qWarning("Cannot create secondary (stream)buffer (%s)", dserr2str(res));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
qDebug( "Secondary (stream)buffer created");
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace QtAV
|
||||
@@ -166,9 +166,6 @@ static ALenum audioFormatToAL(const AudioFormat& fmt)
|
||||
return format;
|
||||
}
|
||||
|
||||
const int kBufferSize = 1024*4;
|
||||
const int kBufferCount = 8;
|
||||
|
||||
class AudioOutputOpenALPrivate : public AudioOutputPrivate
|
||||
{
|
||||
public:
|
||||
|
||||
@@ -28,6 +28,7 @@ namespace QtAV {
|
||||
AudioOutputId AudioOutputId_PortAudio = 1;
|
||||
AudioOutputId AudioOutputId_OpenAL = 2;
|
||||
AudioOutputId AudioOutputId_OpenSL = 3;
|
||||
AudioOutputId AudioOutputId_DSound = 4;
|
||||
|
||||
QVector<AudioOutputId> GetRegistedAudioOutputIds()
|
||||
{
|
||||
@@ -40,6 +41,7 @@ FACTORY_DEFINE(AudioOutput)
|
||||
extern void RegisterAudioOutputPortAudio_Man();
|
||||
extern void RegisterAudioOutputOpenAL_Man();
|
||||
extern void RegisterAudioOutputOpenSL_Man();
|
||||
extern void RegisterAudioOutputDSound_Man();
|
||||
|
||||
void AudioOutput_RegisterAll()
|
||||
{
|
||||
@@ -52,6 +54,9 @@ void AudioOutput_RegisterAll()
|
||||
#if QTAV_HAVE(OPENSL)
|
||||
RegisterAudioOutputOpenSL_Man();
|
||||
#endif //QTAV_HAVE(OPENSL)
|
||||
#if QTAV_HAVE(DSOUND)
|
||||
extern void RegisterAudioOutputDSound_Man();
|
||||
#endif
|
||||
}
|
||||
|
||||
} //namespace QtAV
|
||||
|
||||
@@ -37,6 +37,7 @@ Q_AV_EXPORT QVector<AudioOutputId> GetRegistedAudioOutputIds();
|
||||
extern Q_AV_EXPORT AudioOutputId AudioOutputId_PortAudio;
|
||||
extern Q_AV_EXPORT AudioOutputId AudioOutputId_OpenAL;
|
||||
extern Q_AV_EXPORT AudioOutputId AudioOutputId_OpenSL;
|
||||
extern Q_AV_EXPORT AudioOutputId AudioOutputId_DSound;
|
||||
|
||||
|
||||
Q_AV_EXPORT void AudioOutput_RegisterAll();
|
||||
|
||||
@@ -29,8 +29,13 @@
|
||||
#include <QtCore/QVector>
|
||||
#include <limits>
|
||||
|
||||
// TODO:writeChunk(), write(QByteArray) { while writeChunk() }, users define writeChunk()
|
||||
namespace QtAV {
|
||||
|
||||
// chunk
|
||||
const int kBufferSize = 1024*4;
|
||||
const int kBufferCount = 8;
|
||||
|
||||
class Q_AV_PRIVATE_EXPORT AudioOutputPrivate : public AVOutputPrivate
|
||||
{
|
||||
public:
|
||||
@@ -48,6 +53,7 @@ public:
|
||||
}
|
||||
virtual ~AudioOutputPrivate(){}
|
||||
|
||||
int bufferSizeTotal() { return nb_buffers * kBufferCount; }
|
||||
typedef struct {
|
||||
qreal timestamp;
|
||||
int data_size;
|
||||
|
||||
+346
-340
@@ -1,340 +1,346 @@
|
||||
TEMPLATE = lib
|
||||
TARGET = QtAV
|
||||
QT += core gui
|
||||
greaterThan(QT_MAJOR_VERSION, 4) {
|
||||
QT += widgets
|
||||
}
|
||||
CONFIG *= qtav-buildlib
|
||||
INCLUDEPATH += $$[QT_INSTALL_HEADERS]
|
||||
|
||||
#var with '_' can not pass to pri?
|
||||
STATICLINK = 0
|
||||
PROJECTROOT = $$PWD/..
|
||||
!include(libQtAV.pri): error("could not find libQtAV.pri")
|
||||
preparePaths($$OUT_PWD/../out)
|
||||
|
||||
RESOURCES += ../i18n/QtAV.qrc \
|
||||
shaders/shaders.qrc
|
||||
|
||||
win32 {
|
||||
RC_FILE = $${PROJECTROOT}/res/QtAV.rc
|
||||
#no depends for rc file by default, even if rc includes a header. Makefile target use '/' as default, so not works iwth win cmd
|
||||
rc.target = $$clean_path($$RC_FILE) #rc obj depends on clean path target
|
||||
rc.depends = $$PWD/QtAV/version.h
|
||||
#why use multiple rule failed? i.e. add a rule without command
|
||||
isEmpty(QMAKE_SH) {
|
||||
rc.commands = @copy /B $$system_path($$RC_FILE)+,, #change file time
|
||||
} else {
|
||||
rc.commands = @touch $$RC_FILE #change file time
|
||||
}
|
||||
QMAKE_EXTRA_TARGETS += rc
|
||||
}
|
||||
# copy runtime libs to qt sdk
|
||||
!ios: copy_sdk_libs = $$DESTDIR/$$qtSharedLib($$NAME)
|
||||
#plugin.depends = #makefile target
|
||||
#windows: copy /y file1+file2+... dir. need '+'
|
||||
for(f, copy_sdk_libs) {
|
||||
win32: copy_sdk_libs_cmd += $$quote(-\$\(COPY_FILE\) \"$$system_path($$f)\" \"$$system_path($$[QT_INSTALL_BINS])\")
|
||||
else: copy_sdk_libs_cmd += $$quote(-\$\(COPY_FILE\) \"$$system_path($$f)\" \"$$system_path($$[QT_INSTALL_LIBS])\")
|
||||
}
|
||||
#join values seperated by space. so quote is needed
|
||||
copy_sdk_libs_cmd = $$join(copy_sdk_libs_cmd,$$escape_expand(\\n\\t))
|
||||
#just append as a string to $$QMAKE_POST_LINK
|
||||
isEmpty(QMAKE_POST_LINK): QMAKE_POST_LINK = $$copy_sdk_libs_cmd
|
||||
else: QMAKE_POST_LINK = $${QMAKE_POST_LINK}$$escape_expand(\\n\\t)$$copy_sdk_libs_cmd
|
||||
|
||||
OTHER_FILES += $$RC_FILE
|
||||
TRANSLATIONS = $${PROJECTROOT}/i18n/QtAV_zh_CN.ts
|
||||
|
||||
## sse2 sse4_1 may be defined in Qt5 qmodule.pri but is not included. Qt4 defines sse and sse2
|
||||
sse4_1|config_sse4_1|contains(TARGET_ARCH_SUB, sse4.1) {
|
||||
CONFIG += sse2 #only sse4.1 is checked. sse2 now can be disabled if sse4.1 is disabled
|
||||
DEFINES += QTAV_HAVE_SSE4_1=1
|
||||
## TODO: use SSE4_1_SOURCES
|
||||
# all x64 processers supports sse2. unknown option for vc
|
||||
*msvc* {
|
||||
!isEqual(QT_ARCH, x86_64)|!x86_64: QMAKE_CXXFLAGS += $$QMAKE_CFLAGS_SSE4_1
|
||||
} else {
|
||||
QMAKE_CXXFLAGS += $$QMAKE_CFLAGS_SSE4_1 #gcc -msse4.1
|
||||
}
|
||||
}
|
||||
sse2|config_sse2|contains(TARGET_ARCH_SUB, sse2) {
|
||||
DEFINES += QTAV_HAVE_SSE2=1
|
||||
# all x64 processers supports sse2. unknown option for vc
|
||||
*msvc* {
|
||||
!isEqual(QT_ARCH, x86_64)|!x86_64: QMAKE_CXXFLAGS += $$QMAKE_CFLAGS_SSE2
|
||||
} else {
|
||||
QMAKE_CXXFLAGS += $$QMAKE_CFLAGS_SSE2 #gcc -msse2
|
||||
}
|
||||
}
|
||||
|
||||
*msvc* {
|
||||
#link FFmpeg and portaudio which are built by gcc need /SAFESEH:NO
|
||||
QMAKE_LFLAGS += /SAFESEH:NO
|
||||
INCLUDEPATH += compat/msvc
|
||||
}
|
||||
#UINT64_C: C99 math features, need -D__STDC_CONSTANT_MACROS in CXXFLAGS
|
||||
DEFINES += __STDC_CONSTANT_MACROS
|
||||
android: CONFIG += config_opensl
|
||||
android: LIBS += -lavcodec-55 -lavformat-55 -lavutil-52 -lswscale-2
|
||||
else: LIBS += -lavcodec -lavformat -lavutil -lswscale
|
||||
config_avfilter {
|
||||
DEFINES += QTAV_HAVE_AVFILTER=1
|
||||
SOURCES += LibAVFilter.cpp
|
||||
HEADERS += QtAV/LibAVFilter.h
|
||||
android: LIBS += -lavfilter-4
|
||||
else: LIBS += -lavfilter
|
||||
}
|
||||
config_swresample {
|
||||
DEFINES += QTAV_HAVE_SWRESAMPLE=1
|
||||
SOURCES += AudioResamplerFF.cpp
|
||||
android: LIBS += -lswresample-0
|
||||
else: LIBS += -lswresample
|
||||
}
|
||||
config_avresample {
|
||||
DEFINES += QTAV_HAVE_AVRESAMPLE=1
|
||||
SOURCES += AudioResamplerLibav.cpp
|
||||
android: LIBS += -lavresample-1
|
||||
else: LIBS += -lavresample
|
||||
}
|
||||
config_ipp {
|
||||
DEFINES += QTAV_HAVE_IPP=1
|
||||
ICCROOT = $$(IPPROOT)/../compiler
|
||||
INCLUDEPATH += $$(IPPROOT)/include
|
||||
SOURCES += ImageConverterIPP.cpp
|
||||
message("QMAKE_TARGET.arch" $$QMAKE_TARGET.arch)
|
||||
*64|contains(QMAKE_TARGET.arch, x86_64)|contains(TARGET_ARCH, x86_64) {
|
||||
IPPARCH=intel64
|
||||
} else {
|
||||
IPPARCH=ia32
|
||||
}
|
||||
LIBS *= -L$$(IPPROOT)/lib/$$IPPARCH -lippcc -lippcore -lippi \
|
||||
-L$$(IPPROOT)/../compiler/lib/$$IPPARCH -lsvml -limf
|
||||
#omp for static link. _t is multi-thread static link
|
||||
}
|
||||
config_portaudio {
|
||||
SOURCES += AudioOutputPortAudio.cpp
|
||||
DEFINES *= QTAV_HAVE_PORTAUDIO=1
|
||||
LIBS *= -lportaudio
|
||||
#win32: LIBS *= -lwinmm #-lksguid #-luuid
|
||||
}
|
||||
config_openal {
|
||||
SOURCES += AudioOutputOpenAL.cpp
|
||||
DEFINES *= QTAV_HAVE_OPENAL=1
|
||||
win32: LIBS += -lOpenAL32
|
||||
unix:!mac:!blackberry: LIBS += -lopenal
|
||||
blackberry: LIBS += -lOpenAL
|
||||
mac: LIBS += -framework OpenAL
|
||||
mac: DEFINES += HEADER_OPENAL_PREFIX
|
||||
}
|
||||
config_opensl {
|
||||
SOURCES += AudioOutputOpenSL.cpp
|
||||
DEFINES *= QTAV_HAVE_OPENSL=1
|
||||
LIBS += -lOpenSLES
|
||||
}
|
||||
config_gdiplus {
|
||||
DEFINES *= QTAV_HAVE_GDIPLUS=1
|
||||
SOURCES += GDIRenderer.cpp
|
||||
SDK_HEADERS += QtAV/GDIRenderer.h
|
||||
LIBS += -lgdiplus -lGdi32
|
||||
}
|
||||
config_direct2d {
|
||||
DEFINES *= QTAV_HAVE_DIRECT2D=1
|
||||
!*msvc*: INCLUDEPATH += $$PROJECTROOT/contrib/d2d1headers
|
||||
SOURCES += Direct2DRenderer.cpp
|
||||
SDK_HEADERS += QtAV/Direct2DRenderer.h
|
||||
#LIBS += -lD2d1
|
||||
}
|
||||
config_xv {
|
||||
DEFINES *= QTAV_HAVE_XV=1
|
||||
SOURCES += XVRenderer.cpp
|
||||
SDK_HEADERS += QtAV/XVRenderer.h
|
||||
LIBS += -lXv
|
||||
}
|
||||
config_gl {
|
||||
QT *= opengl
|
||||
DEFINES *= QTAV_HAVE_GL=1
|
||||
SOURCES += GLWidgetRenderer.cpp GLWidgetRenderer2.cpp
|
||||
SDK_HEADERS += QtAV/GLWidgetRenderer.h QtAV/GLWidgetRenderer2.h
|
||||
OTHER_FILES += shaders/planar.f.glsl shaders/rgb.f.glsl
|
||||
}
|
||||
CONFIG += config_cuda #config_dllapi config_dllapi_cuda
|
||||
#CONFIG += config_cuda_link
|
||||
config_cuda {
|
||||
DEFINES += QTAV_HAVE_CUDA=1
|
||||
HEADERS += cuda/dllapi/nv_inc.h cuda/helper_cuda.h
|
||||
SOURCES += VideoDecoderCUDA.cpp
|
||||
INCLUDEPATH += $$PWD/cuda cuda/dllapi
|
||||
config_dllapi:config_dllapi_cuda {
|
||||
DEFINES += QTAV_HAVE_DLLAPI_CUDA=1
|
||||
INCLUDEPATH += ../depends/dllapi/src
|
||||
include(../depends/dllapi/src/libdllapi.pri)
|
||||
SOURCES += cuda/dllapi/cuda.cpp cuda/dllapi/nvcuvid.cpp cuda/dllapi/cuviddec.cpp
|
||||
} else:config_cuda_link {
|
||||
DEFINES += CUDA_LINK
|
||||
INCLUDEPATH += $$(CUDA_PATH)/include
|
||||
LIBS += -L$$(CUDA_PATH)/lib
|
||||
isEqual(TARGET_ARCH, x86): LIBS += -L$$(CUDA_PATH)/lib/Win32
|
||||
else: LIBS += -L$$(CUDA_PATH)/lib/x64
|
||||
LIBS += -lnvcuvid -lcuda
|
||||
}
|
||||
SOURCES += cuda/cuda_api.cpp
|
||||
HEADERS += cuda/cuda_api.h
|
||||
}
|
||||
config_dxva {
|
||||
DEFINES *= QTAV_HAVE_DXVA=1
|
||||
SOURCES += VideoDecoderDXVA.cpp
|
||||
LIBS += -lOle32
|
||||
}
|
||||
config_vaapi* {
|
||||
DEFINES *= QTAV_HAVE_VAAPI=1
|
||||
SOURCES += VideoDecoderVAAPI.cpp
|
||||
LIBS += -lva #dynamic load va-glx va-x11 using dllapi
|
||||
}
|
||||
config_libcedarv {
|
||||
DEFINES *= QTAV_HAVE_CEDARV=1
|
||||
SOURCES += VideoDecoderCedarv.cpp
|
||||
LIBS += -lvecore -lcedarv
|
||||
}
|
||||
macx:!ios: CONFIG += config_vda
|
||||
config_vda {
|
||||
DEFINES *= QTAV_HAVE_VDA=1
|
||||
SOURCES += VideoDecoderVDA.cpp
|
||||
LIBS += -framework VideoDecodeAcceleration -framework CoreVideo
|
||||
}
|
||||
SOURCES += \
|
||||
AVCompat.cpp \
|
||||
QtAV_Global.cpp \
|
||||
utils/GPUMemCopy.cpp \
|
||||
utils/OpenGLHelper.cpp \
|
||||
QAVIOContext.cpp \
|
||||
ShaderManager.cpp \
|
||||
AudioThread.cpp \
|
||||
AVThread.cpp \
|
||||
AudioDecoder.cpp \
|
||||
AudioFormat.cpp \
|
||||
AudioFrame.cpp \
|
||||
AudioOutput.cpp \
|
||||
AudioOutputTypes.cpp \
|
||||
AudioResampler.cpp \
|
||||
AudioResamplerTypes.cpp \
|
||||
AVDecoder.cpp \
|
||||
AVDemuxer.cpp \
|
||||
AVDemuxThread.cpp \
|
||||
ColorTransform.cpp \
|
||||
Frame.cpp \
|
||||
Filter.cpp \
|
||||
FilterContext.cpp \
|
||||
FilterManager.cpp \
|
||||
GraphicsItemRenderer.cpp \
|
||||
ImageConverter.cpp \
|
||||
ImageConverterFF.cpp \
|
||||
QPainterRenderer.cpp \
|
||||
OSD.cpp \
|
||||
OSDFilter.cpp \
|
||||
Packet.cpp \
|
||||
AVError.cpp \
|
||||
AVPlayer.cpp \
|
||||
AVClock.cpp \
|
||||
VideoCapture.cpp \
|
||||
VideoFormat.cpp \
|
||||
VideoFrame.cpp \
|
||||
VideoRenderer.cpp \
|
||||
VideoRendererTypes.cpp \
|
||||
VideoOutput.cpp \
|
||||
VideoOutputEventFilter.cpp \
|
||||
WidgetRenderer.cpp \
|
||||
AVOutput.cpp \
|
||||
OutputSet.cpp \
|
||||
OpenGLVideo.cpp \
|
||||
VideoShader.cpp \
|
||||
Statistics.cpp \
|
||||
VideoDecoder.cpp \
|
||||
VideoDecoderTypes.cpp \
|
||||
VideoDecoderFFmpeg.cpp \
|
||||
VideoDecoderFFmpegHW.cpp \
|
||||
VideoThread.cpp \
|
||||
CommonTypes.cpp
|
||||
|
||||
SDK_HEADERS *= \
|
||||
QtAV/QtAV.h \
|
||||
QtAV/dptr.h \
|
||||
QtAV/QtAV_Global.h \
|
||||
QtAV/AudioResampler.h \
|
||||
QtAV/AudioResamplerTypes.h \
|
||||
QtAV/AudioDecoder.h \
|
||||
QtAV/AudioFormat.h \
|
||||
QtAV/AudioFrame.h \
|
||||
QtAV/AudioOutput.h \
|
||||
QtAV/AudioOutputTypes.h \
|
||||
QtAV/AVDecoder.h \
|
||||
QtAV/AVDemuxer.h \
|
||||
QtAV/CommonTypes.h \
|
||||
QtAV/Filter.h \
|
||||
QtAV/FilterContext.h \
|
||||
QtAV/Frame.h \
|
||||
QtAV/GraphicsItemRenderer.h \
|
||||
QtAV/ImageConverter.h \
|
||||
QtAV/ImageConverterTypes.h \
|
||||
QtAV/QPainterRenderer.h \
|
||||
QtAV/OSD.h \
|
||||
QtAV/OSDFilter.h \
|
||||
QtAV/OpenGLVideo.h \
|
||||
QtAV/VideoShader.h \
|
||||
QtAV/Packet.h \
|
||||
QtAV/AVError.h \
|
||||
QtAV/AVPlayer.h \
|
||||
QtAV/VideoCapture.h \
|
||||
QtAV/VideoRenderer.h \
|
||||
QtAV/VideoRendererTypes.h \
|
||||
QtAV/VideoOutput.h \
|
||||
QtAV/WidgetRenderer.h \
|
||||
QtAV/AVOutput.h \
|
||||
QtAV/AVClock.h \
|
||||
QtAV/VideoDecoder.h \
|
||||
QtAV/VideoDecoderTypes.h \
|
||||
QtAV/VideoFormat.h \
|
||||
QtAV/VideoFrame.h \
|
||||
QtAV/FactoryDefine.h \
|
||||
QtAV/Statistics.h \
|
||||
QtAV/SurfaceInterop.h \
|
||||
QtAV/version.h
|
||||
|
||||
# QtAV/private/* may be used by developers to extend QtAV features without changing QtAV library
|
||||
# headers not in QtAV/ and it's subdirs are used only by QtAV internally
|
||||
HEADERS *= \
|
||||
$$SDK_HEADERS \
|
||||
utils/BlockingQueue.h \
|
||||
utils/GPUMemCopy.h \
|
||||
utils/OpenGLHelper.h \
|
||||
QtAV/prepost.h \
|
||||
QtAV/AVDemuxThread.h \
|
||||
QtAV/AVThread.h \
|
||||
QtAV/AudioThread.h \
|
||||
QtAV/VideoThread.h \
|
||||
QtAV/ColorTransform.h \
|
||||
QtAV/VideoDecoderFFmpegHW.h \
|
||||
QtAV/private/factory.h \
|
||||
QtAV/private/singleton.h \
|
||||
QtAV/private/AVCompat.h \
|
||||
QtAV/private/AudioOutput_p.h \
|
||||
QtAV/private/AudioResampler_p.h \
|
||||
QtAV/private/AVThread_p.h \
|
||||
QtAV/private/AVDecoder_p.h \
|
||||
QtAV/private/AVOutput_p.h \
|
||||
QtAV/private/Filter_p.h \
|
||||
QtAV/private/FilterManager.h \
|
||||
QtAV/private/Frame_p.h \
|
||||
QtAV/private/ImageConverter_p.h \
|
||||
QtAV/private/OutputSet.h \
|
||||
QtAV/private/QAVIOContext.h \
|
||||
QtAV/private/ShaderManager.h \
|
||||
QtAV/private/VideoShader_p.h \
|
||||
QtAV/private/VideoDecoder_p.h \
|
||||
QtAV/private/VideoDecoderFFmpegHW_p.h \
|
||||
QtAV/private/VideoOutputEventFilter.h \
|
||||
QtAV/private/VideoRenderer_p.h \
|
||||
QtAV/private/QPainterRenderer_p.h
|
||||
|
||||
SDK_INCLUDE_FOLDER = QtAV
|
||||
include($$PROJECTROOT/deploy.pri)
|
||||
TEMPLATE = lib
|
||||
TARGET = QtAV
|
||||
QT += core gui
|
||||
greaterThan(QT_MAJOR_VERSION, 4) {
|
||||
QT += widgets
|
||||
}
|
||||
CONFIG *= qtav-buildlib
|
||||
INCLUDEPATH += $$[QT_INSTALL_HEADERS]
|
||||
|
||||
#var with '_' can not pass to pri?
|
||||
STATICLINK = 0
|
||||
PROJECTROOT = $$PWD/..
|
||||
!include(libQtAV.pri): error("could not find libQtAV.pri")
|
||||
preparePaths($$OUT_PWD/../out)
|
||||
|
||||
RESOURCES += ../i18n/QtAV.qrc \
|
||||
shaders/shaders.qrc
|
||||
|
||||
win32 {
|
||||
RC_FILE = $${PROJECTROOT}/res/QtAV.rc
|
||||
#no depends for rc file by default, even if rc includes a header. Makefile target use '/' as default, so not works iwth win cmd
|
||||
rc.target = $$clean_path($$RC_FILE) #rc obj depends on clean path target
|
||||
rc.depends = $$PWD/QtAV/version.h
|
||||
#why use multiple rule failed? i.e. add a rule without command
|
||||
isEmpty(QMAKE_SH) {
|
||||
rc.commands = @copy /B $$system_path($$RC_FILE)+,, #change file time
|
||||
} else {
|
||||
rc.commands = @touch $$RC_FILE #change file time
|
||||
}
|
||||
QMAKE_EXTRA_TARGETS += rc
|
||||
}
|
||||
# copy runtime libs to qt sdk
|
||||
!ios: copy_sdk_libs = $$DESTDIR/$$qtSharedLib($$NAME)
|
||||
#plugin.depends = #makefile target
|
||||
#windows: copy /y file1+file2+... dir. need '+'
|
||||
for(f, copy_sdk_libs) {
|
||||
win32: copy_sdk_libs_cmd += $$quote(-\$\(COPY_FILE\) \"$$system_path($$f)\" \"$$system_path($$[QT_INSTALL_BINS])\")
|
||||
else: copy_sdk_libs_cmd += $$quote(-\$\(COPY_FILE\) \"$$system_path($$f)\" \"$$system_path($$[QT_INSTALL_LIBS])\")
|
||||
}
|
||||
#join values seperated by space. so quote is needed
|
||||
copy_sdk_libs_cmd = $$join(copy_sdk_libs_cmd,$$escape_expand(\\n\\t))
|
||||
#just append as a string to $$QMAKE_POST_LINK
|
||||
isEmpty(QMAKE_POST_LINK): QMAKE_POST_LINK = $$copy_sdk_libs_cmd
|
||||
else: QMAKE_POST_LINK = $${QMAKE_POST_LINK}$$escape_expand(\\n\\t)$$copy_sdk_libs_cmd
|
||||
|
||||
OTHER_FILES += $$RC_FILE
|
||||
TRANSLATIONS = $${PROJECTROOT}/i18n/QtAV_zh_CN.ts
|
||||
|
||||
## sse2 sse4_1 may be defined in Qt5 qmodule.pri but is not included. Qt4 defines sse and sse2
|
||||
sse4_1|config_sse4_1|contains(TARGET_ARCH_SUB, sse4.1) {
|
||||
CONFIG += sse2 #only sse4.1 is checked. sse2 now can be disabled if sse4.1 is disabled
|
||||
DEFINES += QTAV_HAVE_SSE4_1=1
|
||||
## TODO: use SSE4_1_SOURCES
|
||||
# all x64 processers supports sse2. unknown option for vc
|
||||
*msvc* {
|
||||
!isEqual(QT_ARCH, x86_64)|!x86_64: QMAKE_CXXFLAGS += $$QMAKE_CFLAGS_SSE4_1
|
||||
} else {
|
||||
QMAKE_CXXFLAGS += $$QMAKE_CFLAGS_SSE4_1 #gcc -msse4.1
|
||||
}
|
||||
}
|
||||
sse2|config_sse2|contains(TARGET_ARCH_SUB, sse2) {
|
||||
DEFINES += QTAV_HAVE_SSE2=1
|
||||
# all x64 processers supports sse2. unknown option for vc
|
||||
*msvc* {
|
||||
!isEqual(QT_ARCH, x86_64)|!x86_64: QMAKE_CXXFLAGS += $$QMAKE_CFLAGS_SSE2
|
||||
} else {
|
||||
QMAKE_CXXFLAGS += $$QMAKE_CFLAGS_SSE2 #gcc -msse2
|
||||
}
|
||||
}
|
||||
|
||||
win32: CONFIG += config_dsound
|
||||
|
||||
*msvc* {
|
||||
#link FFmpeg and portaudio which are built by gcc need /SAFESEH:NO
|
||||
#QMAKE_LFLAGS += /SAFESEH:NO
|
||||
INCLUDEPATH += compat/msvc
|
||||
}
|
||||
#UINT64_C: C99 math features, need -D__STDC_CONSTANT_MACROS in CXXFLAGS
|
||||
DEFINES += __STDC_CONSTANT_MACROS
|
||||
android: CONFIG += config_opensl
|
||||
android: LIBS += -lavcodec-55 -lavformat-55 -lavutil-52 -lswscale-2
|
||||
else: LIBS += -lavcodec -lavformat -lavutil -lswscale
|
||||
config_avfilter {
|
||||
DEFINES += QTAV_HAVE_AVFILTER=1
|
||||
SOURCES += LibAVFilter.cpp
|
||||
HEADERS += QtAV/LibAVFilter.h
|
||||
android: LIBS += -lavfilter-4
|
||||
else: LIBS += -lavfilter
|
||||
}
|
||||
config_swresample {
|
||||
DEFINES += QTAV_HAVE_SWRESAMPLE=1
|
||||
SOURCES += AudioResamplerFF.cpp
|
||||
android: LIBS += -lswresample-0
|
||||
else: LIBS += -lswresample
|
||||
}
|
||||
config_avresample {
|
||||
DEFINES += QTAV_HAVE_AVRESAMPLE=1
|
||||
SOURCES += AudioResamplerLibav.cpp
|
||||
android: LIBS += -lavresample-1
|
||||
else: LIBS += -lavresample
|
||||
}
|
||||
config_ipp {
|
||||
DEFINES += QTAV_HAVE_IPP=1
|
||||
ICCROOT = $$(IPPROOT)/../compiler
|
||||
INCLUDEPATH += $$(IPPROOT)/include
|
||||
SOURCES += ImageConverterIPP.cpp
|
||||
message("QMAKE_TARGET.arch" $$QMAKE_TARGET.arch)
|
||||
*64|contains(QMAKE_TARGET.arch, x86_64)|contains(TARGET_ARCH, x86_64) {
|
||||
IPPARCH=intel64
|
||||
} else {
|
||||
IPPARCH=ia32
|
||||
}
|
||||
LIBS *= -L$$(IPPROOT)/lib/$$IPPARCH -lippcc -lippcore -lippi \
|
||||
-L$$(IPPROOT)/../compiler/lib/$$IPPARCH -lsvml -limf
|
||||
#omp for static link. _t is multi-thread static link
|
||||
}
|
||||
config_dsound {
|
||||
SOURCES += AudioOutputDSound.cpp
|
||||
DEFINES *= QTAV_HAVE_DSOUND=1
|
||||
}
|
||||
config_portaudio {
|
||||
SOURCES += AudioOutputPortAudio.cpp
|
||||
DEFINES *= QTAV_HAVE_PORTAUDIO=1
|
||||
LIBS *= -lportaudio
|
||||
#win32: LIBS *= -lwinmm #-lksguid #-luuid
|
||||
}
|
||||
config_openal {
|
||||
SOURCES += AudioOutputOpenAL.cpp
|
||||
DEFINES *= QTAV_HAVE_OPENAL=1
|
||||
win32: LIBS += -lOpenAL32
|
||||
unix:!mac:!blackberry: LIBS += -lopenal
|
||||
blackberry: LIBS += -lOpenAL
|
||||
mac: LIBS += -framework OpenAL
|
||||
mac: DEFINES += HEADER_OPENAL_PREFIX
|
||||
}
|
||||
config_opensl {
|
||||
SOURCES += AudioOutputOpenSL.cpp
|
||||
DEFINES *= QTAV_HAVE_OPENSL=1
|
||||
LIBS += -lOpenSLES
|
||||
}
|
||||
config_gdiplus {
|
||||
DEFINES *= QTAV_HAVE_GDIPLUS=1
|
||||
SOURCES += GDIRenderer.cpp
|
||||
SDK_HEADERS += QtAV/GDIRenderer.h
|
||||
LIBS += -lgdiplus -lgdi32
|
||||
}
|
||||
config_direct2d {
|
||||
DEFINES *= QTAV_HAVE_DIRECT2D=1
|
||||
!*msvc*: INCLUDEPATH += $$PROJECTROOT/contrib/d2d1headers
|
||||
SOURCES += Direct2DRenderer.cpp
|
||||
SDK_HEADERS += QtAV/Direct2DRenderer.h
|
||||
#LIBS += -lD2d1
|
||||
}
|
||||
config_xv {
|
||||
DEFINES *= QTAV_HAVE_XV=1
|
||||
SOURCES += XVRenderer.cpp
|
||||
SDK_HEADERS += QtAV/XVRenderer.h
|
||||
LIBS += -lXv
|
||||
}
|
||||
config_gl {
|
||||
QT *= opengl
|
||||
DEFINES *= QTAV_HAVE_GL=1
|
||||
SOURCES += GLWidgetRenderer.cpp GLWidgetRenderer2.cpp
|
||||
SDK_HEADERS += QtAV/GLWidgetRenderer.h QtAV/GLWidgetRenderer2.h
|
||||
OTHER_FILES += shaders/planar.f.glsl shaders/rgb.f.glsl
|
||||
}
|
||||
CONFIG += config_cuda #config_dllapi config_dllapi_cuda
|
||||
#CONFIG += config_cuda_link
|
||||
config_cuda {
|
||||
DEFINES += QTAV_HAVE_CUDA=1
|
||||
HEADERS += cuda/dllapi/nv_inc.h cuda/helper_cuda.h
|
||||
SOURCES += VideoDecoderCUDA.cpp
|
||||
INCLUDEPATH += $$PWD/cuda cuda/dllapi
|
||||
config_dllapi:config_dllapi_cuda {
|
||||
DEFINES += QTAV_HAVE_DLLAPI_CUDA=1
|
||||
INCLUDEPATH += ../depends/dllapi/src
|
||||
include(../depends/dllapi/src/libdllapi.pri)
|
||||
SOURCES += cuda/dllapi/cuda.cpp cuda/dllapi/nvcuvid.cpp cuda/dllapi/cuviddec.cpp
|
||||
} else:config_cuda_link {
|
||||
DEFINES += CUDA_LINK
|
||||
INCLUDEPATH += $$(CUDA_PATH)/include
|
||||
LIBS += -L$$(CUDA_PATH)/lib
|
||||
isEqual(TARGET_ARCH, x86): LIBS += -L$$(CUDA_PATH)/lib/Win32
|
||||
else: LIBS += -L$$(CUDA_PATH)/lib/x64
|
||||
LIBS += -lnvcuvid -lcuda
|
||||
}
|
||||
SOURCES += cuda/cuda_api.cpp
|
||||
HEADERS += cuda/cuda_api.h
|
||||
}
|
||||
config_dxva {
|
||||
DEFINES *= QTAV_HAVE_DXVA=1
|
||||
SOURCES += VideoDecoderDXVA.cpp
|
||||
LIBS += -lole32
|
||||
}
|
||||
config_vaapi* {
|
||||
DEFINES *= QTAV_HAVE_VAAPI=1
|
||||
SOURCES += VideoDecoderVAAPI.cpp
|
||||
LIBS += -lva #dynamic load va-glx va-x11 using dllapi
|
||||
}
|
||||
config_libcedarv {
|
||||
DEFINES *= QTAV_HAVE_CEDARV=1
|
||||
SOURCES += VideoDecoderCedarv.cpp
|
||||
LIBS += -lvecore -lcedarv
|
||||
}
|
||||
macx:!ios: CONFIG += config_vda
|
||||
config_vda {
|
||||
DEFINES *= QTAV_HAVE_VDA=1
|
||||
SOURCES += VideoDecoderVDA.cpp
|
||||
LIBS += -framework VideoDecodeAcceleration -framework CoreVideo
|
||||
}
|
||||
SOURCES += \
|
||||
AVCompat.cpp \
|
||||
QtAV_Global.cpp \
|
||||
utils/GPUMemCopy.cpp \
|
||||
utils/OpenGLHelper.cpp \
|
||||
QAVIOContext.cpp \
|
||||
ShaderManager.cpp \
|
||||
AudioThread.cpp \
|
||||
AVThread.cpp \
|
||||
AudioDecoder.cpp \
|
||||
AudioFormat.cpp \
|
||||
AudioFrame.cpp \
|
||||
AudioOutput.cpp \
|
||||
AudioOutputTypes.cpp \
|
||||
AudioResampler.cpp \
|
||||
AudioResamplerTypes.cpp \
|
||||
AVDecoder.cpp \
|
||||
AVDemuxer.cpp \
|
||||
AVDemuxThread.cpp \
|
||||
ColorTransform.cpp \
|
||||
Frame.cpp \
|
||||
Filter.cpp \
|
||||
FilterContext.cpp \
|
||||
FilterManager.cpp \
|
||||
GraphicsItemRenderer.cpp \
|
||||
ImageConverter.cpp \
|
||||
ImageConverterFF.cpp \
|
||||
QPainterRenderer.cpp \
|
||||
OSD.cpp \
|
||||
OSDFilter.cpp \
|
||||
Packet.cpp \
|
||||
AVError.cpp \
|
||||
AVPlayer.cpp \
|
||||
AVClock.cpp \
|
||||
VideoCapture.cpp \
|
||||
VideoFormat.cpp \
|
||||
VideoFrame.cpp \
|
||||
VideoRenderer.cpp \
|
||||
VideoRendererTypes.cpp \
|
||||
VideoOutput.cpp \
|
||||
VideoOutputEventFilter.cpp \
|
||||
WidgetRenderer.cpp \
|
||||
AVOutput.cpp \
|
||||
OutputSet.cpp \
|
||||
OpenGLVideo.cpp \
|
||||
VideoShader.cpp \
|
||||
Statistics.cpp \
|
||||
VideoDecoder.cpp \
|
||||
VideoDecoderTypes.cpp \
|
||||
VideoDecoderFFmpeg.cpp \
|
||||
VideoDecoderFFmpegHW.cpp \
|
||||
VideoThread.cpp \
|
||||
CommonTypes.cpp
|
||||
|
||||
SDK_HEADERS *= \
|
||||
QtAV/QtAV.h \
|
||||
QtAV/dptr.h \
|
||||
QtAV/QtAV_Global.h \
|
||||
QtAV/AudioResampler.h \
|
||||
QtAV/AudioResamplerTypes.h \
|
||||
QtAV/AudioDecoder.h \
|
||||
QtAV/AudioFormat.h \
|
||||
QtAV/AudioFrame.h \
|
||||
QtAV/AudioOutput.h \
|
||||
QtAV/AudioOutputTypes.h \
|
||||
QtAV/AVDecoder.h \
|
||||
QtAV/AVDemuxer.h \
|
||||
QtAV/CommonTypes.h \
|
||||
QtAV/Filter.h \
|
||||
QtAV/FilterContext.h \
|
||||
QtAV/Frame.h \
|
||||
QtAV/GraphicsItemRenderer.h \
|
||||
QtAV/ImageConverter.h \
|
||||
QtAV/ImageConverterTypes.h \
|
||||
QtAV/QPainterRenderer.h \
|
||||
QtAV/OSD.h \
|
||||
QtAV/OSDFilter.h \
|
||||
QtAV/OpenGLVideo.h \
|
||||
QtAV/VideoShader.h \
|
||||
QtAV/Packet.h \
|
||||
QtAV/AVError.h \
|
||||
QtAV/AVPlayer.h \
|
||||
QtAV/VideoCapture.h \
|
||||
QtAV/VideoRenderer.h \
|
||||
QtAV/VideoRendererTypes.h \
|
||||
QtAV/VideoOutput.h \
|
||||
QtAV/WidgetRenderer.h \
|
||||
QtAV/AVOutput.h \
|
||||
QtAV/AVClock.h \
|
||||
QtAV/VideoDecoder.h \
|
||||
QtAV/VideoDecoderTypes.h \
|
||||
QtAV/VideoFormat.h \
|
||||
QtAV/VideoFrame.h \
|
||||
QtAV/FactoryDefine.h \
|
||||
QtAV/Statistics.h \
|
||||
QtAV/SurfaceInterop.h \
|
||||
QtAV/version.h
|
||||
|
||||
# QtAV/private/* may be used by developers to extend QtAV features without changing QtAV library
|
||||
# headers not in QtAV/ and it's subdirs are used only by QtAV internally
|
||||
HEADERS *= \
|
||||
$$SDK_HEADERS \
|
||||
utils/BlockingQueue.h \
|
||||
utils/GPUMemCopy.h \
|
||||
utils/OpenGLHelper.h \
|
||||
QtAV/prepost.h \
|
||||
QtAV/AVDemuxThread.h \
|
||||
QtAV/AVThread.h \
|
||||
QtAV/AudioThread.h \
|
||||
QtAV/VideoThread.h \
|
||||
QtAV/ColorTransform.h \
|
||||
QtAV/VideoDecoderFFmpegHW.h \
|
||||
QtAV/private/factory.h \
|
||||
QtAV/private/singleton.h \
|
||||
QtAV/private/AVCompat.h \
|
||||
QtAV/private/AudioOutput_p.h \
|
||||
QtAV/private/AudioResampler_p.h \
|
||||
QtAV/private/AVThread_p.h \
|
||||
QtAV/private/AVDecoder_p.h \
|
||||
QtAV/private/AVOutput_p.h \
|
||||
QtAV/private/Filter_p.h \
|
||||
QtAV/private/FilterManager.h \
|
||||
QtAV/private/Frame_p.h \
|
||||
QtAV/private/ImageConverter_p.h \
|
||||
QtAV/private/OutputSet.h \
|
||||
QtAV/private/QAVIOContext.h \
|
||||
QtAV/private/ShaderManager.h \
|
||||
QtAV/private/VideoShader_p.h \
|
||||
QtAV/private/VideoDecoder_p.h \
|
||||
QtAV/private/VideoDecoderFFmpegHW_p.h \
|
||||
QtAV/private/VideoOutputEventFilter.h \
|
||||
QtAV/private/VideoRenderer_p.h \
|
||||
QtAV/private/QPainterRenderer_p.h
|
||||
|
||||
SDK_INCLUDE_FOLDER = QtAV
|
||||
include($$PROJECTROOT/deploy.pri)
|
||||
|
||||
Reference in New Issue
Block a user