[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);
相关推荐
微帧Visionular7 小时前
AI视频单帧清晰,播放时却闪烁,原因是什么?
人工智能·深度学习·音视频
辰辰观影9 小时前
Windows网盘视频播放器推荐:无广告4K HDR怎么选
音视频
2601_9668274510 小时前
电视端云盘在线播放怎么选?支持4K HDR的应用推荐
音视频
开开心心就好11 小时前
音频降噪剪辑工具,音量裁剪一键处理
运维·服务器·前端·spring·ocr·音视频·1024程序员节
zslefour15 小时前
使用ffmpeg遍历获取音频文件相关信息
ffmpeg
AI视频工具指南15 小时前
AI视频的声音和画面怎么配合?先分清谁在传递信息
人工智能·aigc·音视频
辰辰观影17 小时前
无广告播放器推荐来啦
音视频
TrueDei17 小时前
GStreamer 使用 valve 分别控制音视频流的暂停与恢复
音视频
Android系统攻城狮18 小时前
Linux FFmpeg深度解析之avcodec_parameters_from_context调用流程与实战(十六)
linux·运维·ffmpeg·音视频进阶·ffmpeg音视频·车载音视频进阶
一条破秋裤18 小时前
基于 Hi3516CV610 的立定跳远视频测量系统调研与实施方案
arm开发·音视频