[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);
相关推荐
mo47763 小时前
Webrtc音频模块(四) 音频采集
音视频·webrtc
icy、泡芙3 小时前
T527-----音频调试
linux·驱动开发·音视频
易我数据恢复大师3 小时前
怎么提取音频保存到本地?电脑音频提取方法
音视频·软件·音频提取
野蛮的大西瓜3 小时前
开源呼叫中心中,如何将ASR与IVR菜单结合,实现动态的IVR交互
人工智能·机器人·自动化·音视频·信息与通信
嘟嘟实验室6 小时前
微信小程序xr-frame透明视频实现
微信小程序·ffmpeg·音视频·xr
红米饭配南瓜汤7 小时前
WebRTC服务质量(09)- Pacer机制(01) 流程概述
网络·音视频·webrtc
是十一月末10 小时前
Python进阶之opencv图片和视频基本读取关闭
python·opencv·音视频·cv2
泰勒朗斯10 小时前
如何编译Opencv +ffmpeg linux 明明安装了ffmpeg但是opencv就是找不到
linux·opencv·ffmpeg
gomogomono12 小时前
HDR视频技术之十一:HEVCH.265 的 HDR 编码方案
音视频·h.265·hdr·yuv
Eric.Lee202114 小时前
moviepy将图片序列制作成视频并加载字幕 - python 实现
开发语言·python·音视频·moviepy·字幕视频合成·图像制作为视频