-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathXAudioThread.cpp
More file actions
124 lines (111 loc) · 2.12 KB
/
Copy pathXAudioThread.cpp
File metadata and controls
124 lines (111 loc) · 2.12 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
#include "XAudioThread.h"
#include "XDecode.h"
#include "XAudioPlay.h"
#include "XResample.h"
#include "AVFrameRAII.h"
#include <iostream>
using namespace std;
void XAudioThread::SetPause(bool isPause) {
//amux.lock();
this->isPause = isPause;
if (ap) ap->SetPause(isPause);
//amux.unlock();
}
void XAudioThread::Clear() {
XDecodeThread::Clear();
lock_guard<mutex> lck(amux);
if (ap)ap->Clear();
}
void XAudioThread::Close() {
XDecodeThread::Close();
unique_lock<mutex> lck(amux);
if (res) {
res->Close();
res.reset();
}
if (ap) {
ap->Close();
ap = nullptr;
}
}
bool XAudioThread::Open(AVCodecParameters* para, int sampleRate, int channels)
{
if (!para)return false;
unique_lock<mutex> lck(amux);
pts = 0;
bool re = true;
if (!res->Open(para, false))
{
cout << "XResample open failed!" << endl;
re = false;
}
ap->sampleRate = sampleRate;
ap->channels = channels;
if (!ap->Open())
{
re = false;
cout << "XAudioPlay open failed!" << endl;
}
if (!decode->Open(para))
{
cout << "audio XDecode open failed!" << endl;
re = false;
}
lck.unlock();
cout << "XAudioThread::Open :" << re << endl;
return re;
}
void XAudioThread::run()
{
unsigned char* pcm = new unsigned char[1024 * 1024 * 10];
while (!isExit)
{
unique_lock<mutex> lck(amux);
if (isPause) {
lck.unlock();
msleep(5);
continue;
}
shared_ptr<AVPacketRAII> pkt = Pop();
bool re = decode->Send(pkt);
if (!re)
{
lck.unlock();
msleep(1);
continue;
}
//一次send 多次recv
while (!isExit)
{
shared_ptr<AVFrameRAII> frame = decode->Recv();
if (!frame) break;
//减去缓冲中未播放的时间
pts = decode->pts - ap->GetNoPlayMs();
//cout << "audio pts = " << pts << endl;
//重采样
int size = res->Resample(frame, pcm);
//播放音频
while (!isExit)
{
if (size <= 0)break;
//缓冲未播完,空间不够
if (ap->GetFree() < size || isPause)
{
msleep(1);
continue;
}
ap->Write(pcm, size);
break;
}
}
lck.unlock();
}
delete pcm;
}
XAudioThread::XAudioThread() :res(make_shared<XResample>())
{
if (!ap) ap = XAudioPlay::Get();
}
XAudioThread::~XAudioThread()
{
}