FFMPEG解码器流程初步接触
(大部分内容来源于雷霄骅的博客,再次对表示深切的感谢与追悼)
接触到的类型:
AVFrame ——原始数据块
AVCodecContext ——解码参数
AVFormatContext ——码流参数结构体,用于FFMPEG的解封装
AVCodec ——解码器
AVPacket ——储存压缩编码数据
对应类型说明:
1.AVFrame(avcodec.h)
uint8_t *data[AV_NUM_DATA_POINTERS]:解码后原始数据(对视频来说是YUV,RGB,对音频来说是PCM)int linesize[AV_NUM_DATA_POINTERS]:data中“一行”数据的大小。注意:未必等于图像的宽,一般大于图像的宽。
int width, height:视频帧宽和高(1920x1080,1280x720…)
int nb_samples:音频的一个AVFrame中可能包含多个音频帧,在此标记包含了几个
int format:解码后原始数据类型(YUV420,YUV422,RGB24…)
int key_frame:是否是关键帧
enum AVPictureType pict_type:帧类型(I,B,P…)
AVRational sample_aspect_ratio:宽高比(16:9,4:3…)
int64_t pts:显示时间戳
int coded_picture_number:编码帧序号
int display_picture_number:显示帧序号
int8_t *qscale_table:QP表
uint8_t *mbskip_table:跳过宏块表
int16_t (*motion_val[2])[2]:运动矢量表
uint32_t *mb_type:宏块类型表
short *dct_coeff:DCT系数,这个没有提取过
int8_t *ref_index[2]:运动估计参考帧列表(貌似H.264这种比较新的标准才会涉及到多参考帧)
int interlacd_frame:是否是隔行扫描
uint8_t motion_subsample_log2:一个宏块中的运动矢量采样个数,取log的
析构:av_frame_free(&AVFrame)
2.AVPacket(avcodec.h)
uint8_t *data:压缩编码的数据。
例如对于H.264来说。1个AVPacket的data通常对应一个NAL。*注意:在这里只是对应,而不是一模一样。他们之间有微小的差别:使用FFMPEG类库分离出多媒体文件中的H.264码流
因此在使用FFMPEG进行视音频处理的时候,常常可以将得到的AVPacket的data数据直接写成文件,从而得到视音频的码流文件。
int size:data的大小*
int64_t pts:显示时间戳
int64_t dts:解码时间戳
int stream_index:标识该AVPacket所属的视频/音频流。*
析构:av_free_packet(&AVPacket)
3.AVCodec(avcodec.h)
const char *name:编解码器的名字,比较短const char *long_name:编解码器的名字,全称,比较长
enum AVMediaType type:指明了类型,是视频,音频,还是字幕
enum AVCodecID id:ID,不重复
const AVRational *supported_framerates:支持的帧率(仅视频)
const enum AVPixelFormat *pix_fmts:支持的像素格式(仅视频)
const int *supported_samplerates:支持的采样率(仅音频)
const enum AVSampleFormat *sample_fmts:支持的采样格式(仅音频)
const uint64_t *channel_layouts:支持的声道数(仅音频)
int priv_data_size:私有数据的大小
4.AVCodecContext(avcodec.h)
enum AVMediaType codec_type:编解码器的类型(视频,音频…)struct AVCodec *codec:采用的解码器AVCodec(H.264,MPEG2…)
int bit_rate:平均比特率
uint8_t *extradata; int extradata_size:针对特定编码器包含的附加信息(例如对于H.264解码器来说,存储SPS,PPS等)
AVRational time_base:根据该参数,可以把PTS转化为实际的时间(单位为秒s)
int width, height:如果是视频的话,代表宽和高
int refs:运动估计参考帧的个数(H.264的话会有多帧,MPEG2这类的一般就没有了)
int sample_rate:采样率(音频)
int channels:声道数(音频)
enum AVSampleFormat sample_fmt:采样格式
int profile:型(H.264里面就有,其他编码标准应该也有)
int level:级(和profile差不太多)
5.AVFormatContext(avformat.h)
struct AVInputFormat *iformat:输入数据的封装格式AVIOContext *pb:输入数据的缓存
unsigned int nb_streams:视音频流的个数
AVStream **streams:视音频流
char filename[1024]:文件名
int64_t duration:时长(单位:微秒us,转换为秒需要除以1000000)
int bit_rate:比特率(单位bps,转换为kbps需要除以1000)
AVDictionary *metadata:元数据
Title:解码流程示意:
初始化对应ffmpeg对象
->operation:注册必须的设备
->operation:装填对应的结构体数据(手动装填一些)
->使用解码器解码
重要函数:
fun:初始化解码器
avcodec_init();fun:初始化Packet
av_init_packet(&AVPacket);
fun:创建解码器(例子为H264格式)
AVCodec* avcodec_find_decoder(CODEC_ID_H264);
fun:创建AVCodecContext结构体
AVCodecConText* avcodec_alloc_context3();
fun:注册ffmpeg设备
av_register_all();
fun:创建AVFrame
AVFrame* av_frame_alloc();
fun:解码关键函数
param:got_picture_ptr解码失败或完成时返回0
return:返回剩余解码大小
int avcodec_decode_video2(AVCodecContext* avctx, AVFrame* picture,int* got_picture_ptr,const AVPacket* avpacket);
尚未完成