代码对一些数据没做判断,仅仅是做个备忘!请谨慎参考!
#include <libavutil/opt.h>
#include <libavutil/samplefmt.h>
#include <libswresample/swresample.h>
#include <stdio.h>
#include "libavcodec/avcodec.h"
#include "libavutil/imgutils.h"
#include "libswresample/swresample.h"
/**
* @brief 音频重采样 AV_SAMPLE_FMT_S16-->AV_SAMPLE_FMT_FLTP
* @param argc
* @param argv
* @return
*/
int main(int argc, char **argv) {
SwrContext *swr_context = NULL;
uint8_t *in_buf = NULL;
uint8_t **in_data = NULL;
int in_size = 0;
uint8_t **out_data = NULL;
int out_size = 0;
int line_size = 0;
int in_nb_samples = 1024;
int in_channel_count = 2;
int out_channel_count = 2;
int64_t in_ch_layout = AV_CH_LAYOUT_STEREO;
int64_t out_ch_layout = AV_CH_LAYOUT_STEREO;
int in_sample_rate = 44100, out_sample_rate = 44100;
int out_nb_samples = 0, max_out_nb_samples = 0;
enum AVSampleFormat in_sample_fmt = AV_SAMPLE_FMT_S16;
enum AVSampleFormat out_sample_fmt = AV_SAMPLE_FMT_FLTP;
FILE *in_file;
FILE *out_file;
int read_size;
int ret;
in_file = fopen(argv[1], "rb");
out_file = fopen(argv[2], "wb");
swr_context = swr_alloc();
if (!swr_context) {
printf("error 1\n");
exit(1);
}
av_opt_set_int(swr_context, "in_sample_rate", in_sample_rate, 0);
av_opt_set_int(swr_context, "in_channel_layout", in_ch_layout, 0);
av_opt_set_sample_fmt(swr_context, "in_sample_fmt", in_sample_fmt, 0);
av_opt_set_int(swr_context, "out_sample_rate", out_sample_rate, 0);
av_opt_set_int(swr_context, "out_channel_layout", out_ch_layout, 0);
av_opt_set_sample_fmt(swr_context, "out_sample_fmt", out_sample_fmt, 0);
ret = swr_init(swr_context);
if (ret < 0) {
printf("error 2\n");
exit(1);
}
ret = av_samples_alloc_array_and_samples(&in_data, &in_size, in_channel_count,
in_nb_samples, in_sample_fmt, 0);
if (ret < 0) {
printf("error 6\n");
exit(1);
}
out_nb_samples = max_out_nb_samples = av_rescale_rnd(
in_nb_samples, out_sample_rate, in_sample_rate, AV_ROUND_UP);
ret = av_samples_alloc_array_and_samples(&out_data, &out_size,
out_channel_count, out_nb_samples,
out_sample_fmt, 0);
if (ret < 0) {
printf("error 7\n");
exit(1);
}
//一次重采样多少数据
int bytes_per_frame = av_samples_get_buffer_size(
&line_size, in_channel_count, in_nb_samples, in_sample_fmt, 0);
in_buf = av_malloc(bytes_per_frame);
while ((read_size = fread(in_buf, 1, bytes_per_frame, in_file)) ==
bytes_per_frame) {
ret = av_samples_fill_arrays(in_data, &in_size, in_buf, in_channel_count,
in_nb_samples, in_sample_fmt, 0);
if (ret < 0) {
printf("error 3\n");
exit(1);
}
int64_t delay = swr_get_delay(swr_context, in_sample_rate);
out_nb_samples = av_rescale_rnd(in_nb_samples + delay, out_sample_rate,
in_sample_rate, AV_ROUND_UP);
if (out_nb_samples > max_out_nb_samples) {
av_freep(&out_data[0]);
av_freep(&out_data[1]);
ret = av_samples_alloc(out_data, out_size, out_channel_count,
out_nb_samples, out_sample_fmt, 0);
if (ret < 0) break;
max_out_nb_samples = out_nb_samples;
}
printf("out_nb_samples:%i\n", out_nb_samples);
ret = swr_convert(swr_context, out_data, out_nb_samples,
(const uint8_t **)in_data, in_nb_samples);
int bytes_per_sample = av_get_bytes_per_sample(AV_SAMPLE_FMT_FLTP);
// FLTP写成packeted样式
// for (int i = 0; i < ret; i++) {
// for (int j = 0; j < out_channel_count; j++) {
// fwrite(out_data[j] + i * bytes_per_sample, 1, bytes_per_sample,
// out_file);
// }
// }
// FLTP写成planar样式
int each_planr_size =
bytes_per_sample * ret;
for (int j = 0; j < out_channel_count; j++) {
fwrite(out_data[j], 1, each_planr_size, out_file);
}
}
end:
fclose(in_file);
fclose(out_file);
av_freep(&in_buf);
av_freep(&in_data[0]);
av_freep(&in_data);
av_freep(&out_data[0]);
av_freep(&out_data[1]);
av_freep(&out_data);
swr_free(&swr_context);
printf("Hello World!\n");
return 0;
}