[ffmpeg] 音视频编码

本文主要梳理 ffmpeg 中音视频编码的常用函数

API调用

常用 API

c 复制代码
const AVCodec *avcodec_find_encoder(enum AVCodecID id);
AVCodecContext *avcodec_alloc_context3(const AVCodec *codec);
void avcodec_free_context(AVCodecContext **avctx);
int avcodec_open2(AVCodecContext *avctx, const AVCodec *codec, AVDictionary **options); 
int avcodec_close(AVCodecContext *avctx); 
int avcodec_send_frame(AVCodecContext *avctx, const AVFrame *frame);
int avcodec_receive_packet(AVCodecContext *avctx, AVPacket *avpkt);

class

c 复制代码
static const AVClass av_codec_context_class = {
    .class_name              = "AVCodecContext",
    .item_name               = context_to_name,
    .option                  = avcodec_options,
    .version                 = LIBAVUTIL_VERSION_INT,
    .log_level_offset_offset = offsetof(AVCodecContext, log_level_offset),
    .child_next              = codec_child_next,
    .child_class_iterate     = codec_child_class_iterate,
    .category                = AV_CLASS_CATEGORY_ENCODER,
    .get_category            = get_category,
};

初始化和销毁

avcodec_find_encoder 找到编码器

avcodec_alloc_context3 创建 context 结构体

视频:设置编码器参数,码率,宽高,时间基,帧率,GOP,视频格式,编码器ID

avcodec_open2 打开编码器

avcodec_close 关闭编码器

avcodec_free_context 销毁上下文

编码

avcodec_send_frame

avcodec_receive_packet

avcodec_receive_packet 传出来的 packet 使用结束需要调用 av_packet_unref 让 packet 的引用计数减一,不然会有内存泄漏

demo

c 复制代码
m_vc = avcodec_alloc_context3(codec);
m_vc->bit_rate = m_vBitrate;
m_vc->width = m_outWidth;
m_vc->height = m_outHeight;
// 时间基数
m_vc->time_base = { 1, m_outFPS };
m_vc->framerate = { m_outFPS, 1 };

m_vc->gop_size = 50;
m_vc->max_b_frames = 0;

m_vc->pix_fmt = AV_PIX_FMT_YUV420P;
m_vc->codec_id = AV_CODEC_ID_H264;
av_opt_set(m_vc->priv_data, "preset", "superfast", 0);
m_vc->flags |= AV_CODEC_FLAG_GLOBAL_HEADER;

int ret = avcodec_open2(m_vc, codec, NULL);
ret = avcodec_send_frame(m_vc, m_yuv);
p = av_packet_alloc();
ret = avcodec_receive_packet(m_vc, p);
if (ret != 0 || p->size <= 0)
{
	av_packet_free(&p);
	return NULL;
}
//xxx
av_packet_unref(p);

if (m_vc)
{
	avcodec_close(m_vc);
	avcodec_free_context(&m_vc);
}

其他

codec.h 所有API

c 复制代码
const AVCodec *av_codec_iterate(void **opaque);
const AVCodec *avcodec_find_decoder(enum AVCodecID id);
const AVCodec *avcodec_find_decoder_by_name(const char *name);
const AVCodec *avcodec_find_encoder(enum AVCodecID id);
const AVCodec *avcodec_find_encoder_by_name(const char *name);
int av_codec_is_encoder(const AVCodec *codec);
int av_codec_is_decoder(const AVCodec *codec);
const char *av_get_profile_name(const AVCodec *codec, int profile);
const AVCodecHWConfig *avcodec_get_hw_config(const AVCodec *codec, int index);

avcodec.h 所有API

c 复制代码
unsigned avcodec_version(void);
const char *avcodec_configuration(void);
const char *avcodec_license(void);
AVCodecContext *avcodec_alloc_context3(const AVCodec *codec);
void avcodec_free_context(AVCodecContext **avctx);
const AVClass *avcodec_get_class(void);
const AVClass *avcodec_get_frame_class(void);
const AVClass *avcodec_get_subtitle_rect_class(void); 
int avcodec_parameters_from_context(AVCodecParameters *par, const AVCodecContext *codec); 
int avcodec_parameters_to_context(AVCodecContext *codec, const AVCodecParameters *par);
int avcodec_open2(AVCodecContext *avctx, const AVCodec *codec, AVDictionary **options); 
int avcodec_close(AVCodecContext *avctx); 
void avsubtitle_free(AVSubtitle *sub); 
int avcodec_default_get_buffer2(AVCodecContext *s, AVFrame *frame, int flags); 
int avcodec_default_get_encode_buffer(AVCodecContext *s, AVPacket *pkt, int flags);
void avcodec_align_dimensions(AVCodecContext *s, int *width, int *height);
void avcodec_align_dimensions2(AVCodecContext *s, int *width, int *height, int linesize_align[AV_NUM_DATA_POINTERS]);
int avcodec_enum_to_chroma_pos(int *xpos, int *ypos, enum AVChromaLocation pos);
enum AVChromaLocation avcodec_chroma_pos_to_enum(int xpos, int ypos);
int avcodec_decode_subtitle2(AVCodecContext *avctx, AVSubtitle *sub, int *got_sub_ptr, AVPacket *avpkt);
int avcodec_send_packet(AVCodecContext *avctx, const AVPacket *avpkt);
int avcodec_receive_frame(AVCodecContext *avctx, AVFrame *frame);
int avcodec_send_frame(AVCodecContext *avctx, const AVFrame *frame);
int avcodec_receive_packet(AVCodecContext *avctx, AVPacket *avpkt);
int avcodec_get_hw_frames_parameters(AVCodecContext *avctx, AVBufferRef *device_ref, enum AVPixelFormat hw_pix_fmt, AVBufferRef **out_frames_ref);
const AVCodecParser *av_parser_iterate(void **opaque);
AVCodecParserContext *av_parser_init(int codec_id);
int av_parser_parse2(AVCodecParserContext *s, AVCodecContext *avctx, uint8_t **poutbuf, int *poutbuf_size, const uint8_t *buf, int buf_size, int64_t pts, int64_t dts, int64_t pos);
void av_parser_close(AVCodecParserContext *s);
int avcodec_encode_subtitle(AVCodecContext *avctx, uint8_t *buf, int buf_size, const AVSubtitle *sub);
unsigned int avcodec_pix_fmt_to_codec_tag(enum AVPixelFormat pix_fmt);
enum AVPixelFormat avcodec_find_best_pix_fmt_of_list(const enum AVPixelFormat *pix_fmt_list, enum AVPixelFormat src_pix_fmt, int has_alpha, int *loss_ptr);
enum AVPixelFormat avcodec_default_get_format(struct AVCodecContext *s, const enum AVPixelFormat * fmt);
void avcodec_string(char *buf, int buf_size, AVCodecContext *enc, int encode);
int avcodec_default_execute(AVCodecContext *c, int (*func)(AVCodecContext *c2, void *arg2),void *arg, int *ret, int count, int size);
int avcodec_default_execute2(AVCodecContext *c, int (*func)(AVCodecContext *c2, void *arg2, int, int),void *arg, int *ret, int count);
int avcodec_fill_audio_frame(AVFrame *frame, int nb_channels, enum AVSampleFormat sample_fmt, const uint8_t *buf, int buf_size, int align);
void avcodec_flush_buffers(AVCodecContext *avctx);
int av_get_audio_frame_duration(AVCodecContext *avctx, int frame_bytes);
void av_fast_padded_malloc(void *ptr, unsigned int *size, size_t min_size);
void av_fast_padded_mallocz(void *ptr, unsigned int *size, size_t min_size);
int avcodec_is_open(AVCodecContext *s);
相关推荐
lxkj_202430 分钟前
使用线程局部存储解决ffmpeg中多实例调用下自定义日志回调问题
ffmpeg
简鹿办公3 小时前
如何提取某站 MV 视频中的音乐为 MP3 音频
音视频·简鹿视频格式转换器·视频提取mp3音频
yufengxinpian3 小时前
集成了高性能ARM Cortex-M0+处理器的一款SimpleLink 2.4 GHz无线模块-RF-BM-2340B1
单片机·嵌入式硬件·音视频·智能硬件
runing_an_min5 小时前
ffmpeg视频滤镜:替换部分帧-freezeframes
ffmpeg·音视频·freezeframes
ruizhenggang5 小时前
ffmpeg本地编译不容易发现的问题 — Error:xxxxx not found!
ffmpeg
runing_an_min7 小时前
ffmpeg视频滤镜:提取缩略图-framestep
ffmpeg·音视频·framestep
小曲曲8 小时前
接口上传视频和oss直传视频到阿里云组件
javascript·阿里云·音视频
安静读书10 小时前
Python解析视频FPS(帧率)、分辨率信息
python·opencv·音视频
佑华硬盘拷贝机10 小时前
音频档案批量拷贝:专业SD拷贝机解决方案
音视频
EasyNVR10 小时前
NVR管理平台EasyNVR多个NVR同时管理:全方位安防监控视频融合云平台方案
安全·音视频·监控·视频监控