ffmpeg對(duì)pcm編碼代碼實(shí)現(xiàn)
以下是使用FFmpeg進(jìn)行PCM編碼的代碼實(shí)現(xiàn):
```
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;
} ```
這個(gè)程序?qū)⒆x取輸入文件的PCM數(shù)據(jù)并使用FFmpeg的PCM編碼器將其編碼為16位單聲道PCM格式。編碼后的輸出存儲(chǔ)在名為“output.pcm”的文件中。請(qǐng)注意,此程序僅用于演示目的,并且沒有處理錯(cuò)誤或邊界情況。實(shí)際應(yīng)用程序需要更多的錯(cuò)誤檢查和健壯性。
相關(guān)學(xué)習(xí)資料推薦,點(diǎn)擊下方鏈接免費(fèi)報(bào)名,先碼住不迷路~】
音視頻免費(fèi)學(xué)習(xí)地址:FFmpeg/WebRTC/RTMP/NDK/Android音視頻流媒體高級(jí)開發(fā)
【免費(fèi)分享】音視頻學(xué)習(xí)資料包、大廠面試題、技術(shù)視頻和學(xué)習(xí)路線圖,資料包括(C/C++,Linux,F(xiàn)Fmpeg webRTC rtmp hls rtsp ffplay srs 等等)有需要的可以點(diǎn)擊788280672加群免費(fèi)領(lǐng)取~
