File_Stream_deal.c
6.9 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
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
#include "AudioDeal/FF_Statement.h"
#include "../Resample/pcm_Resample.h"
#include "AudioDeal/AudioDeal.h"
#include "AudioDeal/Filter/FF_Filter.h"
#include "JZsdkLib.h"
#include "AudioDeal/Alsa/pcm_AlsaPlay.h"
/******************************
*
* 用于处理mp3流的.c
* 输入mp3数据 → 解码成pcm → pcm流处理模块
*
* ******************************/
static AVCodecParserContext *parser = NULL;
static AVCodecContext *cdc_ctx = NULL;
static AVPacket *pkt;
static AVFrame *decoded_frame = NULL;
static const AVCodec *codec;
T_JZsdkReturnCode Stream_Player_decode(struct AudioDealInfo *AD_Info, AVCodecContext *dec_ctx, AVPacket *pkt, AVFrame *frame);
T_JZsdkReturnCode File_Stream_deal_Init(enum AVCodecID id)
{
pkt = av_packet_alloc();
if(!pkt)
{
JZSDK_LOG_ERROR("av_packet_alloc failed.");
}
codec = avcodec_find_decoder(id);
if (!codec) {
JZSDK_LOG_ERROR("Codec not found\n");
}
parser = av_parser_init(codec->id);
if (!parser) {
JZSDK_LOG_ERROR("Parser not found\n");
}
cdc_ctx = avcodec_alloc_context3(codec);
if (!cdc_ctx) {
JZSDK_LOG_ERROR("Could not allocate audio codec context\n");
}
/* open it */
if (avcodec_open2(cdc_ctx, codec, NULL) < 0)
{
JZSDK_LOG_ERROR("Could not open codec\n");
}
JZSDK_LOG_INFO("File_Stream_deal_Init success");
}
//输入mp3的实时数据,以及本次数据的长度
T_JZsdkReturnCode mp3_Stream_Interface_Mp3Data(struct AudioDealInfo *AD_Info, unsigned int in_sampleRate, unsigned char *data, int dataSize)
{
//JZSDK_LOG_DEBUG("mp3_Stream_Interface_Mp3Data");
T_JZsdkReturnCode ret = JZ_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
//将数据输入到
while(dataSize > 0 && (AD_Info->AudioDeal_ResampleAndFilter_Execute_Flag == JZ_FLAGCODE_ON))
{
//printf("开始解码\n");
//如果解码器不存在,初始化解码器
if (!decoded_frame)
{
if (!(decoded_frame = av_frame_alloc()))
{
JZSDK_LOG_ERROR("Could not allocate audio frame\n");
return JZ_ERROR_SYSTEM_MODULE_CODE_FAILURE;
}
}
//printf("alloc后\n");
//检查参数,并将正确的数据输入到pkt中
//parser 解析器
//cdc_ctx 上下文
//pkt输出的数据指针
//data datasize 输入的数据指针
//pts、dts、pos:时间戳和位置信息,一般可以设置为AV_NOPTS_VALUE和0。
int ret = av_parser_parse2(parser, cdc_ctx, &pkt->data, &pkt->size, data, dataSize, AV_NOPTS_VALUE, AV_NOPTS_VALUE, 0);
if (ret < 0) {
JZSDK_LOG_ERROR("Error while parsing\n");
return JZ_ERROR_SYSTEM_MODULE_CODE_FAILURE;
}
//printf("av_parser_parse2\n");
//重置重采样器
FF_Resample_Reset(AD_Info, in_sampleRate, (AVChannelLayout)AV_CHANNEL_LAYOUT_MONO, AV_SAMPLE_FMT_S16);
//printf("FF_Resample_Reset\n");
//检查滤波器
FF_Filter_Init(AD_Info, 0x01);
//printf("FF_Filter_Init %d \n", pkt->size );
//数据指针 往后一个解析长度
//长度指针 减少一个被解析数据的长度
data += ret;
dataSize -= ret;
//如果输出有长度 解码输出的数据
if (pkt->size > 0)
{
ret = Stream_Player_decode(AD_Info, cdc_ctx, pkt, decoded_frame);
if(ret == JZ_ERROR_SYSTEM_MODULE_CODE_HARDLY_FAILURE)
{
return JZ_ERROR_SYSTEM_MODULE_CODE_HARDLY_FAILURE;
}
}
}
}
//
T_JZsdkReturnCode Stream_Player_decode(struct AudioDealInfo *AD_Info, AVCodecContext *dec_ctx, AVPacket *pkt, AVFrame *frame)
{
int ret;
//JZSDK_LOG_DEBUG("Stream_Player_decode");
//发送数据包给解码器解码,已将数据解码为pcm原始数据
ret = avcodec_send_packet(dec_ctx, pkt);
if (ret < 0)
{
JZSDK_LOG_ERROR("Error submitting the packet to the decoder, ret=%d\n",ret);
//return JZ_ERROR_SYSTEM_MODULE_CODE_HARDLY_FAILURE;
return JZ_ERROR_SYSTEM_MODULE_CODE_FAILURE;
}
//申请内存
AVFrame *eq_frame = av_frame_alloc();
AVFrame *temp_frame = av_frame_alloc();
//JZSDK_LOG_DEBUG("alloc");
/* read all the output frames (in general there may be any number of them */
//读取输出的帧
while ( (ret >= 0) && (AD_Info->AudioDeal_ResampleAndFilter_Execute_Flag == JZ_FLAGCODE_ON) )
{
//从解码器中读取解码后的音频帧数据
ret = avcodec_receive_frame(dec_ctx, frame);
//输出帧不可用 、 输出帧 已用完
if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF)
{
continue;;
}
else if (ret < 0)
{
JZSDK_LOG_ERROR("Error during decoding\n");
//释放掉输出的变量
av_frame_free(&eq_frame);
av_frame_free(&temp_frame);
//JZSDK_LOG_DEBUG("提前释放后\n");
return JZ_ERROR_SYSTEM_MODULE_CODE_FAILURE;
}
int out_nb_samples = 0;
//JZSDK_LOG_DEBUG("播放前");
//重采样解码后的数据
void* resampledData = FF_Resample_Send_And_Get_ResampleData(AD_Info, frame->data, frame->nb_samples, &out_nb_samples);
//滤波
if(AD_Info->FilterMode != JZ_FLAGCODE_OFF)
{
temp_frame->data[0] = (unsigned char*)resampledData;
temp_frame->nb_samples = out_nb_samples;
//将临时帧 放入 均衡滤波器
FF_Filter_push_frame_to_fliter(AD_Info, temp_frame);
while(AD_Info->AudioDeal_ResampleAndFilter_Execute_Flag == JZ_FLAGCODE_ON)
{
//得到滤波器输出的音频帧 eq_frame
int fret = FF_Filter_get_frame_from_filter(AD_Info, eq_frame);
if (fret != JZ_ERROR_SYSTEM_MODULE_CODE_SUCCESS)
{
break;
}
//播放改滤波后的帧
Pcm_AlsaPlay(AD_Info, (unsigned char*)eq_frame->data[0], eq_frame->nb_samples);
av_frame_unref(eq_frame);
}
av_frame_unref(temp_frame);
}
else //不滤波
{
//直接播放
//JZSDK_LOG_INFO("播放 %d 数据",out_nb_samples);
Pcm_AlsaPlay(AD_Info ,resampledData, out_nb_samples);
}
FF_Resample_freeReasmpleData(resampledData);
}
//JZSDK_LOG_DEBUG("怀疑释放前\n");
//释放掉输出的变量
av_frame_unref(temp_frame);
av_frame_unref(eq_frame);
//JZSDK_LOG_DEBUG("怀疑释放后\n");
}
T_JZsdkReturnCode mp3_Stream_Interface_Mp3Data_Stop(struct AudioDealInfo *AD_Info)
{
// pkt->data = NULL;
// pkt->size = 0;
// Stream_Player_decode(AD_Info, cdc_ctx, pkt, decoded_frame);
}