-
Notifications
You must be signed in to change notification settings - Fork 76
Expand file tree
/
Copy pathFFTAudioFrameQueue.m
More file actions
122 lines (103 loc) · 2.73 KB
/
FFTAudioFrameQueue.m
File metadata and controls
122 lines (103 loc) · 2.73 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
//
// FFTAudioFrameQueue.m
// FFmpegTutorial
//
// Created by qianlongxu on 2022/10/6.
//
#import "FFTAudioFrameQueue.h"
#import "FFTPlayerHeader.h"
#import <libavutil/frame.h>
@interface FFTAudioFrameQueue()
{
//音频frame已经读的数据
int _audioFrameRead;
}
@end
@implementation FFTAudioFrameQueue
- (instancetype)init
{
self = [self initWithCapacity:15];
if (self) {
}
return self;
}
- (void)enQueue:(AVFrame *)frame
{
FFFrameItem *item = [[FFFrameItem alloc] initWithAVFrame:frame];
if (frame->pts != AV_NOPTS_VALUE) {
item.pts = frame->pts * self.streamTimeBase;
}
item.duration = av_q2d((AVRational){frame->nb_samples, frame->sample_rate});
[self push:item];
}
- (int)doFillAudioBuffers:(uint8_t * [2])buffer
byteSize:(int)bufferSize
{
FFFrameItem *item = [self peek];
if (!item) {
return 0;
}
AVFrame *frame = item.frame;
int data_size = audio_buffer_size(frame);
int leave = data_size - _audioFrameRead;
if (leave <= 0) {
_audioFrameRead = 0;
[self pop];
return 0;
}
int cpSize = MIN(bufferSize,leave);
for (int i = 0; i < 2; i++) {
uint8_t *dst = buffer[i];
uint8_t *src = (uint8_t *)(frame->data[i]);
if (NULL != src && NULL != dst) {
memcpy(dst, src + _audioFrameRead, cpSize);
} else {
break;
}
}
_audioFrameRead += cpSize;
if (data_size - _audioFrameRead <= 0) {
_audioFrameRead = 0;
[self pop];
}
return cpSize;
}
- (double)clock
{
FFFrameItem *item = [self peek];
if (!item) {
return [self peekLast].pts;
}
AVFrame *frame = item.frame;
int data_size = audio_buffer_size(frame);
float percent = 1.0 * _audioFrameRead / data_size;
double audio_clock = item.pts + percent * item.frame->nb_samples / item.frame->sample_rate;
//double bytes_per_sec = self.sampleRate * self.audioClk.bytesPerSample;
//double audio_clock = audio_pts - 2.0 * (ap->offset + filled) / bytes_per_sec;
return audio_clock;
}
- (int)fillBuffers:(uint8_t * _Nonnull [_Nullable 2])buffer
byteSize:(int)bufferSize
{
uint8_t * dst[2] = { 0 };
dst[0] = buffer[0];
dst[1] = buffer[1];
int totalFilled = 0;
while (bufferSize > 0) {
int filled = [self doFillAudioBuffers:dst byteSize:bufferSize];
if (filled) {
totalFilled += filled;
bufferSize -= filled;
if (dst[0]) {
dst[0] += filled;
}
if (dst[1]) {
dst[1] += filled;
}
} else {
break;
}
}
return totalFilled;
}
@end