first commit
This commit is contained in:
233
project/fm_viewer/fav/AudioOutput.h
Normal file
233
project/fm_viewer/fav/AudioOutput.h
Normal file
@@ -0,0 +1,233 @@
|
||||
/******************************************************************************
|
||||
QtAV: Multimedia framework based on Qt and FFmpeg
|
||||
Copyright (C) 2012-2016 Wang Bin <wbsecg1@gmail.com>
|
||||
|
||||
* This file is part of QtAV
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library 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
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef QAV_AUDIOOUTPUT_H
|
||||
#define QAV_AUDIOOUTPUT_H
|
||||
|
||||
#include <QtCore/QObject>
|
||||
#include <QtCore/QStringList>
|
||||
#include "AVOutput.h"
|
||||
#include "AudioFrame.h"
|
||||
|
||||
/*!
|
||||
* AudioOutput ao;
|
||||
* ao.setAudioFormat(fmt);
|
||||
* ao.open();
|
||||
* while (has_data) {
|
||||
* data = read_data(ao->bufferSize());
|
||||
* ao->play(data, pts);
|
||||
* }
|
||||
* ao->close();
|
||||
* See QtAV/tests/ao/main.cpp for detail
|
||||
*/
|
||||
namespace FAV {
|
||||
|
||||
class AudioFormat;
|
||||
class AudioOutputPrivate;
|
||||
class Q_AV_EXPORT AudioOutput : public QObject, public AVOutput
|
||||
{
|
||||
Q_OBJECT
|
||||
DPTR_DECLARE_PRIVATE(AudioOutput)
|
||||
Q_ENUMS(DeviceFeature)
|
||||
Q_FLAGS(DeviceFeatures)
|
||||
Q_PROPERTY(qreal volume READ volume WRITE setVolume NOTIFY volumeChanged)
|
||||
Q_PROPERTY(bool mute READ isMute WRITE setMute NOTIFY muteChanged)
|
||||
Q_PROPERTY(DeviceFeatures deviceFeatures READ deviceFeatures WRITE setDeviceFeatures NOTIFY deviceFeaturesChanged)
|
||||
Q_PROPERTY(QStringList backends READ backends WRITE setBackends NOTIFY backendsChanged)
|
||||
public:
|
||||
/*!
|
||||
* \brief DeviceFeature Feature enum
|
||||
* Features supported by the audio playback api (we call device or backend here)
|
||||
* If a feature is not supported, e.g. SetVolume, then a software implementation is used.
|
||||
*/
|
||||
enum DeviceFeature {
|
||||
NoFeature = 0,
|
||||
SetVolume = 1, /// Use backend volume control api rather than software scale. Ignore if backend does not support.
|
||||
SetMute = 1 << 1,
|
||||
SetSampleRate = 1 << 2, /// NOT IMPLEMENTED
|
||||
SetSpeed = 1 << 3, /// NOT IMPLEMENTED
|
||||
};
|
||||
Q_DECLARE_FLAGS(DeviceFeatures, DeviceFeature)
|
||||
/*!
|
||||
* \brief backendsAvailable
|
||||
* All registered backends in default priority order
|
||||
* \return
|
||||
*/
|
||||
static QStringList backendsAvailable();
|
||||
/*!
|
||||
* \brief AudioOutput
|
||||
* Audio format set to preferred sample format and channel layout
|
||||
*/
|
||||
AudioOutput(QObject *parent = 0);
|
||||
~AudioOutput();
|
||||
/*!
|
||||
* \brief setBackends
|
||||
* set the given backends. Old backend instance and backend() is updated soon if backendsChanged.
|
||||
* It is called internally with a default backend names when AudioOutput is created.
|
||||
*/
|
||||
void setBackends(const QStringList &backendNames = QStringList());
|
||||
QStringList backends() const;
|
||||
/*!
|
||||
* \brief backend
|
||||
* backend name currently in use
|
||||
*/
|
||||
QString backend() const;
|
||||
|
||||
|
||||
QString status() const;
|
||||
/*!
|
||||
* \brief flush
|
||||
* Play the buffered audio data
|
||||
* \return
|
||||
*/
|
||||
void flush();
|
||||
/*!
|
||||
* \brief clear
|
||||
* Clear audio buffers and set time to 0. The default behavior is flush and reset time
|
||||
*/
|
||||
void clear();
|
||||
bool open();
|
||||
bool close();
|
||||
bool isOpen() const;
|
||||
/*!
|
||||
* \brief play
|
||||
* Play out the given audio data. It may block current thread until the data can be written to audio device
|
||||
* for async playback backend, or until the data is completely played for blocking playback backend.
|
||||
* \param data Audio data to play
|
||||
* \param pts Timestamp for this data. Useful if need A/V sync. Ignore it if only play audio
|
||||
* \return false if currently isPaused(), no backend is available or backend failed to play
|
||||
*/
|
||||
bool play(const QByteArray& data, qreal pts = 0.0);
|
||||
/*!
|
||||
* \brief pause
|
||||
* Pause audio rendering. play() will fail.
|
||||
*/
|
||||
void pause(bool value);
|
||||
bool isPaused() const;
|
||||
/*!
|
||||
* \brief setAudioFormat
|
||||
* Set/Request to use the given \l format. If it's not supported, an preferred format will be used.
|
||||
* \param format requested format
|
||||
* \return actual format to use. Invalid format if backend is not available
|
||||
* NOTE: Check format support may fail for some backends (OpenAL) if it's closed.
|
||||
*/
|
||||
AudioFormat setAudioFormat(const AudioFormat& format);
|
||||
const AudioFormat& requestedFormat() const;
|
||||
/*!
|
||||
* \brief audioFormat
|
||||
* \return actual format for requested format
|
||||
*/
|
||||
const AudioFormat& audioFormat() const;
|
||||
/*!
|
||||
* \brief setVolume
|
||||
* Set volume level.
|
||||
* If SetVolume feature is not set or not supported, software implementation will be used.
|
||||
* Call this after open(), because it will call backend api if SetVolume feature is enabled
|
||||
* \param volume linear. 1.0: original volume.
|
||||
*/
|
||||
void setVolume(qreal value);
|
||||
qreal volume() const;
|
||||
/*!
|
||||
* \brief setMute
|
||||
* If SetMute feature is not set or not supported, software implementation will be used.
|
||||
* Call this after open(), because it will call backend api if SetMute feature is enabled
|
||||
*/
|
||||
void setMute(bool value = true);
|
||||
bool isMute() const;
|
||||
/*!
|
||||
* \brief setSpeed set audio playing speed
|
||||
* Currently only store the value and does nothing else in audio output. You may change sample rate to get the same effect.
|
||||
* The speed affects the playing only if audio is available and clock type is
|
||||
* audio clock. For example, play a video contains audio without special configurations.
|
||||
* To change the playing speed in other cases, use AVPlayer::setSpeed(qreal)
|
||||
* \param speed linear. > 0
|
||||
* TODO: resample internally
|
||||
*/
|
||||
void setSpeed(qreal speed);
|
||||
qreal speed() const;
|
||||
/*!
|
||||
* \brief isSupported
|
||||
* check \a isSupported(format.sampleFormat()) and \a isSupported(format.channelLayout())
|
||||
* \param format
|
||||
* \return true if \a format is supported. default is true
|
||||
* NOTE: may fail for some backends if it's closed, for example OpenAL
|
||||
*/
|
||||
bool isSupported(const AudioFormat& format) const;
|
||||
/*!
|
||||
* \brief bufferSamples
|
||||
* Number of samples that audio output accept in 1 buffer. Feed the audio output this size of data every time.
|
||||
* Smaller buffer samples gives more buffers for a given data to avoid stutter. But if it's too small, the duration of 1 buffer will be too small to play, for example 1ms. Currently the default value is 512.
|
||||
* Some backends(OpenAL) are affected significantly by this property
|
||||
*/
|
||||
int bufferSamples() const;
|
||||
void setBufferSamples(int value);
|
||||
int bufferSize() const; /// bufferSamples()*bytesPerSample
|
||||
/*!
|
||||
* \brief bufferCount
|
||||
* Total buffer count. If it's not large enough, playing high sample rate audio may be poor.
|
||||
* The default value is 16. TODO: depending on audio format(sample rate?)
|
||||
* Some backends(OpenAL) are affected significantly by this property
|
||||
*/
|
||||
int bufferCount() const;
|
||||
void setBufferCount(int value);
|
||||
int bufferSizeTotal() const { return bufferCount() * bufferSize();}
|
||||
/*!
|
||||
* \brief setDeviceFeatures
|
||||
* Unsupported features will not be set.
|
||||
* You can call this in a backend ctor.
|
||||
*/
|
||||
void setDeviceFeatures(DeviceFeatures value);
|
||||
/*!
|
||||
* \brief deviceFeatures
|
||||
* \return features set by setFeatures() excluding unsupported features
|
||||
*/
|
||||
DeviceFeatures deviceFeatures() const;
|
||||
/*!
|
||||
* \brief supportedDeviceFeatures
|
||||
* Supported features of the backend, defined by AudioOutput(DeviceFeatures,AudioOutput&,QObject*) in a backend ctor
|
||||
*/
|
||||
DeviceFeatures supportedDeviceFeatures() const;
|
||||
qreal timestamp() const;
|
||||
// timestamp of current playing data
|
||||
Q_SIGNALS:
|
||||
void volumeChanged(qreal);
|
||||
void muteChanged(bool);
|
||||
void deviceFeaturesChanged();
|
||||
void backendsChanged();
|
||||
protected:
|
||||
// Store and fill data to audio buffers
|
||||
bool receiveData(const QByteArray &data, qreal pts = 0.0);
|
||||
/*!
|
||||
* \brief waitForNextBuffer
|
||||
* wait until you can feed more data
|
||||
*/
|
||||
bool waitForNextBuffer();
|
||||
private Q_SLOTS:
|
||||
void reportVolume(qreal value);
|
||||
void reportMute(bool value);
|
||||
private:
|
||||
void onCallback();
|
||||
friend class AudioOutputBackend;
|
||||
Q_DISABLE_COPY(AudioOutput)
|
||||
};
|
||||
|
||||
} //namespace FAV
|
||||
#endif // QAV_AUDIOOUTPUT_H
|
||||
Reference in New Issue
Block a user