pcm_Resample.c
6.2 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
#include "AudioDeal/FF_Statement.h"
#include "pcm_Resample.h"
#include "JZsdkLib.h"
#include "../AudioDeal.h"
//pcm的重采样结构体记录组
struct pcm_Resample
{
SwrContext *m_swr;
int In_SampleRate; //输入音频的码率
//unsigned int InCHLayout;
AVChannelLayout InCHLayout;
enum AVSampleFormat InFormat;
int Out_SampleRate; //输出音频的码率
//unsigned int Out_CHLayout;
AVChannelLayout Out_CHLayout;
enum AVSampleFormat Out_Format;
}pcm_Resample;
//初始化重编码器
/*****************
*
* 输入变量
* 音频库结构体
* 输入的音频采样率 输入的音频频道数, 输入的音频格式
* *************/
T_JZsdkReturnCode FF_Resample_Init(struct AudioDealInfo *AD_Info,
unsigned int in_sampleRate, AVChannelLayout in_ch_layout, enum AVSampleFormat in_format)
{
// 尝试获取或分配ResampleInfo
struct pcm_Resample **ResampleInfoPtr = (struct pcm_Resample **)&AD_Info->ResampleInfo;
if (*ResampleInfoPtr == NULL) {
// 分配内存
*ResampleInfoPtr = (struct pcm_Resample *)malloc(sizeof(struct pcm_Resample));
if (*ResampleInfoPtr == NULL) {
// 内存分配失败处理
return JZ_ERROR_SYSTEM_MODULE_CODE_INVALID_PARAMETER; // 使用更具体的错误码
}
(*ResampleInfoPtr)->m_swr = NULL;
}
// 现在你可以安全地使用ResampleInfo了
struct pcm_Resample *ResampleInfo = *ResampleInfoPtr;
if (ResampleInfo->m_swr == NULL) {
ResampleInfo->m_swr = swr_alloc();
if (!ResampleInfo->m_swr) {
JZSDK_LOG_ERROR("Failed to allocate the resampling context");
return JZ_ERROR_SYSTEM_MODULE_CODE_INVALID_PARAMETER; // 或者更具体的错误码
}
}
ResampleInfo->In_SampleRate = in_sampleRate;
ResampleInfo->InFormat = in_format;
//ResampleInfo->InCHLayout = in_ch_layout;
av_channel_layout_copy(&(ResampleInfo->InCHLayout), &in_ch_layout);
ResampleInfo->Out_SampleRate = AD_Info->Target_SampleRate;
ResampleInfo->Out_Format = AD_Info->Target_SampleFormat;
//ResampleInfo->Out_CHLayout = AD_Info->Target_ChannelLayout;
av_channel_layout_copy(&(ResampleInfo->Out_CHLayout), &AD_Info->Target_ChannelLayout);
//记录当前输入的比特率
AD_Info->Raw_SampleRate = in_sampleRate;
AD_Info->Raw_SampleFormat = in_format;
//AD_Info->Raw_ChannelLayout = in_ch_layout;
av_channel_layout_copy(&(AD_Info->Raw_ChannelLayout), &in_ch_layout);
// 设置输入参数
//av_opt_set_int(ResampleInfo->m_swr, "in_channel_layout", ResampleInfo->InCHLayout, 0);
av_opt_set_chlayout(ResampleInfo->m_swr, "in_chlayout", &ResampleInfo->InCHLayout, 0);
av_opt_set_sample_fmt(ResampleInfo->m_swr, "in_sample_fmt", ResampleInfo->InFormat, 0);
av_opt_set_int(ResampleInfo->m_swr, "in_sample_rate", ResampleInfo->In_SampleRate, 0);
// 设置输出参数
//av_opt_set_int(ResampleInfo->m_swr, "out_channel_layout", ResampleInfo->Out_CHLayout, 0);
av_opt_set_chlayout(ResampleInfo->m_swr, "out_chlayout", &ResampleInfo->Out_CHLayout, 0);
av_opt_set_sample_fmt(ResampleInfo->m_swr, "out_sample_fmt", ResampleInfo->Out_Format, 0);
av_opt_set_int(ResampleInfo->m_swr, "out_sample_rate", ResampleInfo->Out_SampleRate, 0);
// 初始化重采样上下文
if (swr_init(ResampleInfo->m_swr) < 0) {
printf("Failed to initialize the resampling context\n");
swr_free(&ResampleInfo->m_swr); // 释放已分配的 SwrContext
ResampleInfo->m_swr = NULL;
return JZ_ERROR_SYSTEM_MODULE_CODE_FAILURE;
}
return JZ_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
}
//重置重编码器
T_JZsdkReturnCode FF_Resample_Reset(struct AudioDealInfo *AD_Info,
unsigned int in_sampleRate, AVChannelLayout in_ch_layout, enum AVSampleFormat in_format)
{
int ResetFlag = JZ_FLAGCODE_OFF;
//对比编码器新设置与当前设置是否相同
int ret = av_channel_layout_compare(&in_ch_layout, &AD_Info->Raw_ChannelLayout);
if (ret != 0)
{
ResetFlag = JZ_FLAGCODE_ON;
}
if (in_sampleRate != AD_Info->Raw_SampleRate)
{
ResetFlag = JZ_FLAGCODE_ON;
}
if (in_format != AD_Info->Raw_SampleFormat)
{
ResetFlag = JZ_FLAGCODE_ON;
}
if (ResetFlag == JZ_FLAGCODE_OFF)
{
return JZ_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
}
struct pcm_Resample *ResampleInfo = (struct pcm_Resample *)AD_Info->ResampleInfo;
ret = 0;
if(ResampleInfo->m_swr != NULL)
{
swr_free(&ResampleInfo->m_swr);
ResampleInfo->m_swr = NULL;
}
return FF_Resample_Init(AD_Info, in_sampleRate, in_ch_layout, in_format);
}
void *FF_Resample_Send_And_Get_ResampleData(struct AudioDealInfo *AD_Info, unsigned char **src, int nb_samples, int *out_nb_samples)
{
int ret = 0;
unsigned char *dst = NULL;
struct pcm_Resample *ResampleInfo = (struct pcm_Resample *)AD_Info->ResampleInfo;
//按采样率缩放样本数量
*out_nb_samples = av_rescale_rnd(nb_samples, ResampleInfo->Out_SampleRate, ResampleInfo->In_SampleRate, AV_ROUND_UP);
//printf("重采样得到的预计输出样本数量为%d\n",*out_nb_samples);
//放置输出数据的数组
ret = av_samples_alloc(&dst, NULL, 2, *out_nb_samples, AV_SAMPLE_FMT_S16, 0);
if (ret < 0) {
printf("[ERROR][Resample]av_samples_alloc failed\n");
return NULL;
}
JZSDK_LOG_INFO("原长度 *out_nb_samples:%d",*out_nb_samples);
//重采样
ret = swr_convert(ResampleInfo->m_swr, &dst, *out_nb_samples, (const uint8_t**)src, nb_samples);
if (ret < 0) {
printf("[ERROR][Resample]swr_convert failed\n");
av_freep(&dst); // 释放之前分配的内存
return NULL;
}
JZSDK_LOG_INFO("重采样后长度:%d", ret);
*out_nb_samples = ret;
return (void*)dst;
}
//用于释放掉,执行重采样后得到的新数据的内存
T_JZsdkReturnCode FF_Resample_freeReasmpleData(void *dst)
{
if (dst != NULL)
{
av_free(dst);
dst = NULL;
}
return JZ_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
}