ffmpeg对pcm编码代码实现
以下是使用FFmpeg进行PCM编码的代码实现:
```
include <stdio.h>
include <stdlib.h>
include <string.h>
include <errno.h>
include <fcntl.h>
include <unistd.h>
extern "C" { #include <libavcodec/avcodec.h> }
int main(int argc, char* argv[]) { if (argc < 2) { fprintf(stderr, "Usage: %s \n", argv[0]); exit(1); }
AVCodec *codec;
AVCodecContext *context;
AVFrame *frame;
AVPacket packet;
int ret;
av_register_all();
codec = avcodec_find_encoder(AV_CODEC_ID_PCM_S16LE);
if (!codec) {
fprintf(stderr, "Failed to find PCM codec\n");
exit(1);
}
context = avcodec_alloc_context3(codec);
if (!context) {
fprintf(stderr, "Failed to allocate codec context\n");
exit(1);
}
context->sample_fmt = AV_SAMPLE_FMT_S16;
context->channel_layout = AV_CH_LAYOUT_MONO;
context->sample_rate = 44100;
context->bit_rate = 16 * 44100; // 16-bit PCM has a bit rate of 16 * sample rate
context->codec_id = AV_CODEC_ID_PCM_S16LE;
context->codec_type = AVMEDIA_TYPE_AUDIO;
ret = avcodec_open2(context, codec, NULL);
if (ret < 0) {
fprintf(stderr, "Failed to open codec: %s\n", av_err2str(ret));
exit(1);
}
frame = av_frame_alloc();
if (!frame) {
fprintf(stderr, "Failed to allocate frame\n");
exit(1);
}
frame->format = context->sample_fmt;
frame->channel_layout = context->channel_layout;
frame->sample_rate = context->sample_rate;
frame->nb_samples = 1024; // arbitrary number of samples
ret = av_frame_get_buffer(frame, 0);
if (ret < 0) {
fprintf(stderr, "Failed to allocate buffer for frame: %s\n", av_err2str(ret));
exit(1);
}
FILE *input_file = fopen(argv[1], "rb");
if (!input_file) {
fprintf(stderr, "Failed to open input file '%s': %s\n", argv[1], strerror(errno));
exit(1);
}
int output_fd = open("output.pcm", O_WRONLY | O_TRUNC | O_CREAT, S_IRUSR | S_IWUSR);
if (output_fd < 0) {
fprintf(stderr, "Failed to open output file: %s\n", strerror(errno));
exit(1);
}
while (!feof(input_file)) {
ret = fread(frame->data[0], 1, av_samples_get_buffer_size(NULL, context->channels, frame->nb_samples, context->sample_fmt), input_file);
if (ret <= 0)
break;
frame->pts = av_rescale_q(av_gettime(), (AVRational){1, AV_TIME_BASE}, context->time_base);
ret = avcodec_send_frame(context, frame);
if (ret < 0) {
fprintf(stderr, "Error sending frame to encoder: %s\n", av_err2str(ret));
exit(1);
}
while (1) {
ret = avcodec_receive_packet(context, &packet);
if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF)
break;
else if (ret < 0) {
fprintf(stderr, "Error receiving packet from encoder: %s\n", av_err2str(ret));
exit(1);
}
write(output_fd, packet.data, packet.size);
av_packet_unref(&packet);
}
}
avcodec_send_frame(context, NULL); // flush encoder
while (1) {
ret = avcodec_receive_packet(context, &packet);
if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF)
break;
else if (ret < 0) {
fprintf(stderr, "Error flushing encoder: %s\n", av_err2str(ret));
exit(1);
}
write(output_fd, packet.data, packet.size);
av_packet_unref(&packet);
}
fclose(input_file);
close(output_fd);
av_frame_free(&frame);
avcodec_free_context(&context);
return 0;
} ```
这个程序将读取输入文件的PCM数据并使用FFmpeg的PCM编码器将其编码为16位单声道PCM格式。编码后的输出存储在名为“output.pcm”的文件中。请注意,此程序仅用于演示目的,并且没有处理错误或边界情况。实际应用程序需要更多的错误检查和健壮性。
相关学习资料推荐,点击下方链接免费报名,先码住不迷路~】
音视频免费学习地址:FFmpeg/WebRTC/RTMP/NDK/Android音视频流媒体高级开发
【免费分享】音视频学习资料包、大厂面试题、技术视频和学习路线图,资料包括(C/C++,Linux,FFmpeg webRTC rtmp hls rtsp ffplay srs 等等)有需要的可以点击788280672加群免费领取~
