当前位置:网站首页>Ffmpeg audio coding
Ffmpeg audio coding
2022-07-23 11:56:00 【Mr.codeee】
1. brief introduction
Encode audio data , hold pcm The original data is encoded as MP3 perhaps AAC.
2. technological process

2.1 In the use of FFmpeg API Before , Need to register first API, And then you can use it API. Of course , The new version of the library does not need to call the following methods .
av_register_all()2.2 Find the encoder , This example demonstrates coding MP3
// Find the encoder
codec = avcodec_find_encoder(AV_CODEC_ID_MP3);
if (!codec)
{
fprintf(stderr, "Codec not found\n");
exit(1);
}2.3 apply AVCodecContext
// apply AVCodecContext
AVCodecContext* codec_ctx = nullptr;
codec_ctx = avcodec_alloc_context3(codec);
if (!codec_ctx)
{
fprintf(stderr, "Could not allocate audio codec context\n");
exit(1);
}2.4 Set audio parameters
You need to specify some parameters for configuring the encoder . Like audio , For example, its sampling rate , Track number , Coding format, etc . You also need to configure the parameters of the encoded output data , as follows , The parameter setting here is input PCM yes 48000,FLT, Bit rate 25600, The output parameters follow codec_ctx The parameters are basically similar
// Set parameters
codec_ctx->bit_rate = 256000;
codec_ctx->sample_fmt = AV_SAMPLE_FMT_FLTP;
// Check that this format is not supported
if (!check_sample_fmt(codec, codec_ctx->sample_fmt))
{
fprintf(stderr, "Encoder does not support sample format %s",av_get_sample_fmt_name(codec_ctx->sample_fmt));
exit(1);
}
codec_ctx->sample_rate = 48000;
codec_ctx->channel_layout = select_channel_layout(codec);
codec_ctx->channels = av_get_channel_layout_nb_channels(codec_ctx->channel_layout);
frame->nb_samples = codec_ctx->frame_size;
frame->format = codec_ctx->sample_fmt;
frame->channel_layout = codec_ctx->channel_layout;
frame->channels = codec_ctx->channels;
2.5 Turn on the encoder
// Turn on the encoder
if (avcodec_open2(codec_ctx, codec, NULL) < 0)
{
fprintf(stderr, "Could not open codec\n");
exit(1);
}2.6 Allocate frame space
/* allocate the data buffers */
int ret = av_frame_get_buffer(frame, 0);
if (ret < 0)
{
fprintf(stderr, "Could not allocate audio data buffers\n");
exit(1);
}2.7 Calculate the size of audio frame data
After setting the parameters of the encoder and the parameters related to the data frame to be encoded , Audio sampling can be calculated according to several parameters buffer Size .
// Calculate audio frame information
int buffer_size = av_samples_get_buffer_size(NULL, codec_ctx->channels, codec_ctx->frame_size, codec_ctx->sample_fmt, 0);
if (buffer_size < 0)
{
exit(1);
}2.8 Read pcm file , Start coding , Write to local MP3 file .
When ready , We can start coding . The new interface of audio coding is also sent to the encoder , Then encode by receiving . The core code of the code is as follows , The encoded data is stored in AVPacket in , take pkt Write the data in to the local file .
while (!feof(fp))
{
// Read data from file
int count = fread(pcmBuffer, sizeof(char), buffer_size, fp);
// Read locally packed Data to planar
f32le_convert_to_fltp((float*)pcmBuffer, (float*)pcmBuffer2, frame->nb_samples);
ret = av_samples_fill_arrays(frame->data, frame->linesize,
(const uint8_t*)pcmBuffer2, frame->channels,
frame->nb_samples, AV_SAMPLE_FMT_FLTP, 0);
// Start coding
ret = avcodec_send_frame(codec_ctx, frame);
while (ret >= 0)
{
ret = avcodec_receive_packet(codec_ctx, pkt);
if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF)
{
break;
}
else if (ret < 0)
{
break;
}
// The encoded data is written to the local file
fwrite(pkt->data, 1, pkt->size, f);
av_packet_unref(pkt);
}
}3. Source code
This example demonstrates reading from local pcm file , After encoding, write to MP3 In file .
#include "pch.h"
#include <iostream>
extern "C"
{
#include "libavformat/avformat.h"
#include "libavutil/dict.h"
#include "libavutil/opt.h"
#include "libavutil/timestamp.h"
#include "libswscale/swscale.h"
#include "libswresample/swresample.h"
#include "libavutil/imgutils.h"
};
/* check that a given sample format is supported by the encoder */
static int check_sample_fmt(const AVCodec* codec, enum AVSampleFormat sample_fmt)
{
const enum AVSampleFormat* p = codec->sample_fmts;
while (*p != AV_SAMPLE_FMT_NONE)
{
if (*p == sample_fmt)
return 1;
p++;
}
return 0;
}
/* just pick the highest supported samplerate */
static int select_sample_rate(const AVCodec* codec)
{
const int* p;
int best_samplerate = 0;
if (!codec->supported_samplerates)
return 44100;
p = codec->supported_samplerates;
while (*p)
{
if (!best_samplerate || abs(44100 - *p) < abs(44100 - best_samplerate))
best_samplerate = *p;
p++;
}
return best_samplerate;
}
/* select layout with the highest channel count */
static int select_channel_layout(const AVCodec* codec)
{
const uint64_t* p;
uint64_t best_ch_layout = 0;
int best_nb_channels = 0;
if (!codec->channel_layouts)
return AV_CH_LAYOUT_STEREO;
p = codec->channel_layouts;
while (*p) {
int nb_channels = av_get_channel_layout_nb_channels(*p);
if (nb_channels > best_nb_channels) {
best_ch_layout = *p;
best_nb_channels = nb_channels;
}
p++;
}
return best_ch_layout;
}
void f32le_convert_to_fltp(float* f32le, float* fltp, int nb_samples)
{
float* fltp_l = fltp; // Left channel
float* fltp_r = fltp + nb_samples; // Right channel
for (int i = 0; i < nb_samples; i++)
{
fltp_l[i] = f32le[i * 2]; // 0 1 - 2 3
fltp_r[i] = f32le[i * 2 + 1]; // You can try to annotate the left channel or the right channel to listen to the sound
}
}
int main()
{
//av_register_all();
avformat_network_init();
AVCodec* codec = nullptr;
// Find the encoder
codec = avcodec_find_encoder(AV_CODEC_ID_MP3);
if (!codec)
{
fprintf(stderr, "Codec not found\n");
exit(1);
}
// apply AVCodecContext
AVCodecContext* codec_ctx = nullptr;
codec_ctx = avcodec_alloc_context3(codec);
if (!codec_ctx)
{
fprintf(stderr, "Could not allocate audio codec context\n");
exit(1);
}
// Set parameters
codec_ctx->bit_rate = 256000;
codec_ctx->sample_fmt = AV_SAMPLE_FMT_FLTP;
// Check that this format is not supported
if (!check_sample_fmt(codec, codec_ctx->sample_fmt))
{
fprintf(stderr, "Encoder does not support sample format %s",av_get_sample_fmt_name(codec_ctx->sample_fmt));
exit(1);
}
codec_ctx->sample_rate = 48000;
codec_ctx->channel_layout = select_channel_layout(codec);
codec_ctx->channels = av_get_channel_layout_nb_channels(codec_ctx->channel_layout);
// Turn on the encoder
if (avcodec_open2(codec_ctx, codec, NULL) < 0)
{
fprintf(stderr, "Could not open codec\n");
exit(1);
}
AVPacket *pkt = av_packet_alloc();
if (!pkt)
{
fprintf(stderr, "could not allocate the packet\n");
exit(1);
}
AVFrame *frame = av_frame_alloc();
if (!frame)
{
fprintf(stderr, "Could not allocate audio frame\n");
exit(1);
}
frame->nb_samples = codec_ctx->frame_size;
frame->format = codec_ctx->sample_fmt;
frame->channel_layout = codec_ctx->channel_layout;
frame->channels = codec_ctx->channels;
/* allocate the data buffers */
int ret = av_frame_get_buffer(frame, 0);
if (ret < 0)
{
fprintf(stderr, "Could not allocate audio data buffers\n");
exit(1);
}
// Calculate audio frame information
int buffer_size = av_samples_get_buffer_size(NULL, codec_ctx->channels, codec_ctx->frame_size, codec_ctx->sample_fmt, 0);
if (buffer_size < 0)
{
exit(1);
}
uint8_t* pcmBuffer = (uint8_t*)av_malloc(buffer_size);
if (!pcmBuffer)
{
exit(1);
}
uint8_t* pcmBuffer2 = (uint8_t*)av_malloc(buffer_size);
if (!pcmBuffer2)
{
exit(1);
}
// Open the output file
char fileName[20] = "output.mp3";
FILE* f = fopen(fileName, "wb");
if (!f)
{
fprintf(stderr, "Could not open %s\n", fileName);
exit(1);
}
// Open the input file
const char* inputUrl = "test.pcm";
FILE* fp = fopen(inputUrl, "rb");
if (!fp)
{
fprintf(stderr, "Could not open %s\n", inputUrl);
exit(1);
}
while (!feof(fp))
{
// Read data from file
int count = fread(pcmBuffer, sizeof(char), buffer_size, fp);
// Read locally packed Data to planar
f32le_convert_to_fltp((float*)pcmBuffer, (float*)pcmBuffer2, frame->nb_samples);
ret = av_samples_fill_arrays(frame->data, frame->linesize,
(const uint8_t*)pcmBuffer2, frame->channels,
frame->nb_samples, AV_SAMPLE_FMT_FLTP, 0);
// Start coding
ret = avcodec_send_frame(codec_ctx, frame);
while (ret >= 0)
{
ret = avcodec_receive_packet(codec_ctx, pkt);
if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF)
{
break;
}
else if (ret < 0)
{
break;
}
// The encoded data is written to the local file
fwrite(pkt->data, 1, pkt->size, f);
av_packet_unref(pkt);
}
}
fclose(fp);
fclose(f);
avcodec_close(codec_ctx);
avcodec_free_context(&codec_ctx);
av_frame_free(&frame);
av_packet_free(&pkt);
return 0;
}
边栏推荐
猜你喜欢

Data warehouse 4.0 notes - user behavior data collection III

Upload pictures to qiniu cloud through the web call interface

8、 Collection framework and generics

Image fuzzy processing batch production fuzzy data set
![[deployment] cluster deployment and startup of presto-server-0.261.tar.gz](/img/37/1185b2321b003a7793c8c37891008c.png)
[deployment] cluster deployment and startup of presto-server-0.261.tar.gz
![[pyrodiomics] the extracted image omics characteristic value is abnormal (many 0 and 1)](/img/73/628e0188e1e2c13e0963746759f691.png)
[pyrodiomics] the extracted image omics characteristic value is abnormal (many 0 and 1)

Adding environment variables and templates to systemctl service

数仓4.0笔记---用户行为数据生成

Development of digital collection system: what are the main features of NFT?

Installation and process creation of activiti app used by activiti workflow
随机推荐
Project instances used by activiti workflow
Entrepôt de données 4.0 Notes - acquisition de données sur le comportement de l'utilisateur II
Activiti7 Quick Start experience sharing
MySQL transaction
数仓4.0笔记---用户行为数据生成
MySQL备份
Internet communication
Data warehouse 4.0 notes - data warehouse environment construction - Yan configuration
MySQL数据库
Window runs gradle build ----- stacktrace. Exception occurs when the file framework-4.3.0.build-snapshot-schema.zip is not found
Mysql database
打印直角三角型、等腰三角型、菱形
串
MySQL storage engine
NFT digital collection development: Jingdong "Qida bear takes you to the capital" tourism package
LearnOpenGL - Introduction
1. Initial experience of MySQL
虚函数
One of scala variables and data types
Machine learning algorithm for large factory interview (5) recommendation system algorithm