目录
词汇概述
工具 | 功能简介 | 结构 | 定义文件 |
demuxer | 对指定的容器URL进行解复用 | AVInputFormat | 在format中的***dec.c |
muxer | 对数据复用到指定的容器URL | AVOutputFormat | 在format中的***enc.c |
decoder | 对AVPacket进行解码 | AVCodec | 在codec中的***dec.c |
encoder | 对AVPacket进行编码 | AVCodec | 在codec中的***enc.c |
demuxer
AVInputFormat ff_live_flv_demuxer = { | ||||||
.name = "live_flv", | ||||||
.long_name = NULL_IF_CONFIG_SMALL("live RTMP FLV (Flash Video)"), | ||||||
.priv_data_size = sizeof(FLVContext), | ||||||
.read_probe = live_flv_probe, | ||||||
.read_header = flv_read_header, | ||||||
.read_packet = flv_read_packet, | ||||||
.read_seek = flv_read_seek, | ||||||
.read_close = flv_read_close, | ||||||
.extensions = "flv", | ||||||
.priv_class = &live_flv_class, | ||||||
.flags = AVFMT_TS_DISCONT | ||||||
}; | ||||||
查找 | 在avformat_open_input时,往往通过输入的url文件名,查找最匹配的AVInputFormat | |||||
以上的read_probe/extensions/name等参数就作为选择项,通过遍历注册的所有demuxer,最终选择一个得分最高的AVInputFormat | ||||||
关联 | 该结构关联在AVFormatContext中的AVInputFormat |
muxer
AVOutputFormat ff_flv_muxer = { | |||||
.name = "flv", | |||||
.long_name = NULL_IF_CONFIG_SMALL("FLV (Flash Video)"), | |||||
.mime_type = "video/x-flv", | |||||
.extensions = "flv", | |||||
.priv_data_size = sizeof(FLVContext), | |||||
.audio_codec = CONFIG_LIBMP3LAME ? AV_CODEC_ID_MP3 : AV_CODEC_ID_ADPCM_SWF, | |||||
.video_codec = AV_CODEC_ID_FLV1, | |||||
.init = flv_init, | |||||
.write_header = flv_write_header, | |||||
.write_packet = flv_write_packet, | |||||
.write_trailer = flv_write_trailer, | |||||
.check_bitstream= flv_check_bitstream, | |||||
.codec_tag = (const AVCodecTag* const []) { | |||||
flv_video_codec_ids, flv_audio_codec_ids, 0 | |||||
}, | |||||
.flags = AVFMT_GLOBALHEADER | AVFMT_VARIABLE_FPS | | |||||
AVFMT_TS_NONSTRICT, | |||||
.priv_class = &flv_muxer_class, | |||||
}; | |||||
查找 | 在avformat_alloc_output_context2中,根据输入的url容器,查找最匹配的AVOutputFormat | ||||
以上的extensions/mime_type等参数作为选择项,通过遍历注册的所有muxer,最终选择一个得分最高的AVOutputFormat | |||||
关联 | 该结构关联在AVFormatContext中的AVOutputFormat | ||||
属性 | audio_codec/video_codec:作为使用该输出格式需要设置的编码类型 |
decoder
AVCodec ff_h264_decoder = { | |
.name = "h264", | |
.long_name = NULL_IF_CONFIG_SMALL("H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10"), | |
.type = AVMEDIA_TYPE_VIDEO, | |
.id = AV_CODEC_ID_H264, | |
.priv_data_size = sizeof(H264Context), | |
.init = h264_decode_init, | |
.close = h264_decode_end, | |
.decode = h264_decode_frame, | |
.capabilities = /*AV_CODEC_CAP_DRAW_HORIZ_BAND |*/ AV_CODEC_CAP_DR1 | | |
AV_CODEC_CAP_DELAY | AV_CODEC_CAP_SLICE_THREADS | | |
AV_CODEC_CAP_FRAME_THREADS, | |
.hw_configs = (const AVCodecHWConfigInternal*[]) { | |
#if CONFIG_H264_DXVA2_HWACCEL | |
HWACCEL_DXVA2(h264), | |
#endif | |
#if CONFIG_H264_D3D11VA_HWACCEL | |
HWACCEL_D3D11VA(h264), | |
#endif | |
#if CONFIG_H264_D3D11VA2_HWACCEL | |
HWACCEL_D3D11VA2(h264), | |
#endif | |
#if CONFIG_H264_NVDEC_HWACCEL | |
HWACCEL_NVDEC(h264), | |
#endif | |
#if CONFIG_H264_VAAPI_HWACCEL | |
HWACCEL_VAAPI(h264), | |
#endif | |
#if CONFIG_H264_VDPAU_HWACCEL | |
HWACCEL_VDPAU(h264), | |
#endif | |
#if CONFIG_H264_VIDEOTOOLBOX_HWACCEL | |
HWACCEL_VIDEOTOOLBOX(h264), | |
#endif | |
NULL | |
}, | |
.caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_EXPORTS_CROPPING, | |
.flush = flush_dpb, | |
.init_thread_copy = ONLY_IF_THREADS_ENABLED(decode_init_thread_copy), | |
.update_thread_context = ONLY_IF_THREADS_ENABLED(ff_h264_update_thread_context), | |
.profiles = NULL_IF_CONFIG_SMALL(ff_h264_profiles), | |
.priv_class = &h264_class, | |
}; | |
查找 | 往往通过format的avformat_find_stream_info得到输入url中的各个流的codec_id,通过该codec_id就可以很容易找到对应的AVCodec了 |
关联 | 该结构关联在AVCodecContext的AVCodec |
属性 | AV_CODEC_CAP_DELAY:表示解码的数据并不能马上输出,往往在放完AVPacket之后, |
还需要通过av_read_frame继续读取AVFrame,直到出现EOF, 才能将解码器中解码的全部数据读取完毕。 | |
AV_CODEC_CAP_SLICE_THREADS / AV_CODEC_CAP_FRAME_THREADS:该解码器能够多线程运行的方式 |
encoder
AVCodec ff_libx264_encoder = { | |
.name = "libx264", | |
.long_name = NULL_IF_CONFIG_SMALL("libx264 H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10"), | |
.type = AVMEDIA_TYPE_VIDEO, | |
.id = AV_CODEC_ID_H264, | |
.priv_data_size = sizeof(X264Context), | |
.init = X264_init, | |
.encode2 = X264_frame, | |
.close = X264_close, | |
.capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_AUTO_THREADS | | |
AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE, | |
.priv_class = &x264_class, | |
.defaults = x264_defaults, | |
.init_static_data = X264_init_static, | |
.caps_internal = FF_CODEC_CAP_INIT_CLEANUP, | |
.wrapper_name = "libx264", | |
}; | |
备注:ffmpeg中并不是包含所有编解码器,例如H264编码器,需要借助外界的libx264来完成 | |
编码器一般不存在查找问题,往往用户需要将其编码为何种类型是很确定;因此编码器也就不存在probe的功能 | |
关联 | 该结构关联在AVCodecContext的AVCodec |
属性 | AV_CODEC_CAP_DELAY:其功能于解码器相同。 |
当将需要的编码的AVFrame全部放入完毕,还需要通过avcodec_send_frame向编码器植入空frame,将其中所有的frame取出。 | |
AV_CODEC_CAP_AUTO_THREADS:通过设置AVCodcecContext中的线程数量为0,编码器在执行的过程中根据cpu数量进行分配 |