1 В избранное 0 Ответвления 0

OSCHINA-MIRROR/zhouws-chn-ZPlay_VideoPlayer

Присоединиться к Gitlife
Откройте для себя и примите участие в публичных проектах с открытым исходным кодом с участием более 10 миллионов разработчиков. Приватные репозитории также полностью бесплатны :)
Присоединиться бесплатно
В этом репозитории не указан файл с открытой лицензией (LICENSE). При использовании обратитесь к конкретному описанию проекта и его зависимостям в коде.
Клонировать/Скачать
zffaudio.cpp 4.7 КБ
Копировать Редактировать Web IDE Исходные данные Просмотреть построчно История
tang_god Отправлено 27.08.2020 02:34 80f89a6
#include "zffaudio.h"
#include "zffmpeg.h"
#include <QFile>
#include <QDebug>
QAtomicPointer<ZFFaudio> ZFFaudio::_instance = 0;
QMutex ZFFaudio::_mutex;
ZFFaudio::ZFFaudio()
{
// StartPlay();
}
ZFFaudio * ZFFaudio::getInstance()
{
// 使用双重检测。
/*! testAndSetOrders操作保证在原子操作前和后的的内存访问
* 不会被重新排序。
*/
if (_instance.testAndSetOrdered(0, 0)) // 第一次检测
{
QMutexLocker locker(&_mutex); // 加互斥锁。
_instance.testAndSetOrdered(0, new ZFFaudio); // 第二次检测。
}
return _instance;
}
void ZFFaudio::terminate() {
_canBeRun = false;
}
void ZFFaudio::start(Priority pro) {
_canBeRun = true;
QThread::start(pro);
}
void ZFFaudio::run() {
char out[20000] = { 0 };
// QFile file("F:/QT5_project/ZPlay/e.pcm");
// file.open(QIODevice::WriteOnly | QIODevice::Text);
while (_canBeRun) {
if ((GetFree() > output->periodSize()) &&
(ZFFmpeg::getInstance()->audioList.list.size() > 0)) {
QMutexLocker locker(&ZFFmpeg::getInstance()->audioList._mutex);
AVPacket pkt = ZFFmpeg::getInstance()->audioList.list.takeFirst();
curTimestampSec = ZFFmpeg::getInstance()->GetPts(&pkt);
AVFrame *audioFrame = ZFFmpeg::getInstance()->Decode(&pkt); // 解码音频
av_packet_unref(&pkt); // 释放pkt包
int len = ToPCM(out, audioFrame);
av_frame_free(&audioFrame);
// qDebug("ZFFaudio::run curTimestampSec:%f, ", curTimestampSec);
this->Write(out, len);
} else {
msleep(1);
}
}
// file.close();
}
int ZFFaudio::ToPCM(char *out, AVFrame *Pcm)
{
AVFormatContext *ic = ZFFmpeg::getInstance()->GetFormatCtx();
int audioStream = ZFFmpeg::getInstance()->GetAudioStream();
if (!ic || !Pcm || !out) // 文件未打开,解码器未打开,无数据
{
return 0;
}
AVCodecContext *ctx = ic->streams[audioStream]->codec; // 音频解码器上下文
uint8_t *data[1];
data[0] = (uint8_t *)out;
// 音频的重采样过程
int len =
swr_convert(ZFFmpeg::getInstance()->GetACtx(),
data,
44100,
(const uint8_t **)Pcm->data,
Pcm->nb_samples);
if (len <= 0)
{
return 0;
}
// out_buffer_size = len * ctx->channels *
// av_get_bytes_per_sample(AV_SAMPLE_FMT_S16);
return av_samples_get_buffer_size(NULL,
ctx->channels,
Pcm->nb_samples,
AV_SAMPLE_FMT_S16,
0);
}
void ZFFaudio::StopPlay()
{
if (output) // 为打开AudioOutput
{
output->stop();
delete output;
output = NULL;
io = NULL;
}
}
// 首先设置播放的格式以及参数
bool ZFFaudio::StartPlay()
{
qDebug("ZFFaudio::StartPlay %d %d %d\n", sampleRate, sampleSize, channel);
StopPlay();
QAudioOutput *out; // 播放音频
QAudioFormat fmt; // 设置音频输出格式
fmt.setSampleRate(sampleRate); // 1秒的音频采样率
fmt.setSampleSize(16); // 声音样本的大小
fmt.setChannelCount(channel); // 声道
fmt.setCodec("audio/pcm"); // 解码格式
fmt.setByteOrder(QAudioFormat::LittleEndian);
fmt.setSampleType(QAudioFormat::UnSignedInt); // 设置音频类型
output = new QAudioOutput(fmt);
io = output->start(); // 播放开始
return true;
}
void ZFFaudio::PlayAudio(bool isplay)
{
if (!output)
{
return;
}
if (isplay)
{
output->resume(); // 恢复播放
}
else
{
output->suspend(); // 暂停播放
}
}
int ZFFaudio::GetFree()
{
if (!output)
{
return 0;
}
int free = output->bytesFree(); // 剩余的空间
return free;
}
bool ZFFaudio::Write(const char *data, int datasize)
{
// qDebug("%d, %d",output->periodSize(),output->bytesFree());
// while (output->bytesFree()<output->periodSize()) {
// msleep(1);
// }
if (io) io->write(data, datasize); // 将获取的音频写入到缓冲区中
return true;
}
void ZFFaudio::stop() {
_canBeRun = false;
// curTimestampSec = 0;
}
void ZFFaudio::init(int sampleRate, int channel, int sampleSize)
{
this->sampleRate = sampleRate;
this->channel = channel;
this->sampleSize = sampleSize;
StartPlay();
}

Опубликовать ( 0 )

Вы можете оставить комментарий после Вход в систему

1
https://api.gitlife.ru/oschina-mirror/zhouws-chn-ZPlay_VideoPlayer.git
git@api.gitlife.ru:oschina-mirror/zhouws-chn-ZPlay_VideoPlayer.git
oschina-mirror
zhouws-chn-ZPlay_VideoPlayer
zhouws-chn-ZPlay_VideoPlayer
master