ffmpeg源码分析01(结构体)

AVFormatContext(位于avformat.h中)

typedef struct AVFormatContext { const AVClass *av_class; //桥接AVOption,方便给结构体变量赋值 struct AVInputFormat *iformat; //输入数据的封装格式 struct AVOutputFormat *oformat; //输出数据的封装格式 void *priv_data; AVIOContext *pb; //输入数据的缓存 int ctx_flags; unsigned int nb_streams; //音视频流的个数 AVStream **streams; //音视频流(比如video\audio) char filename[1024]; //输入或输出数据的文件名 int64_t start_time; //第一帧的位置 int64_t duration; //流的持续时间(单位:微秒us,转换为秒需要除以1000000) int bit_rate; //总流比特率(bit / s),如果不可用则为0。 unsigned int probesize; //从输入读取的用于确定输入容器格式的数据的最大大小。 AVDictionary *metadata; //元数据 AVFormatInternal *internal; AVCodec *video_codec; //视频编解码器 AVCodec *audio_codec; //音频编解码器 AVCodec *subtitle_codec; //字母编解码器 } AVFormatContext;

AVInputFormat(位于avformat.h中)
AVInputFormat 是类似COM 接口的数据结构,表示输入文件容器格式,着重于功能函数,一种文件容器格式对应一个AVInputFormat 结构,在程序运行时有多个实例,位于avoformat.h文件中。
const char *name; //格式名列表.也可以分配一个新名字。 const char *long_name; //格式的描述性名称,意味着比名称更易于阅读。 int flags; //可用的flag有: AVFMT_NOFILE, AVFMT_NEEDNUMBER, AVFMT_SHOW_IDS, AVFMT_GENERIC_INDEX, AVFMT_TS_DISCONT, AVFMT_NOBINSEARCH, AVFMT_NOGENSEARCH, AVFMT_NO_BYTE_SEEK, AVFMT_SEEK_TO_PTS. const char *extensions; //文件扩展名 const AVClass *priv_class; //一个模拟类型列表.用来在probe的时候check匹配的类型。 struct AVInputFormat *next; //用于把所有支持的输入文件容器格式连接成链表,便于遍历查找。 int priv_data_size; //标示具体的文件容器格式对应的Context 的大小。 int (*read_probe)(AVProbeData *); //判断一个给定的文件是否有可能被解析为这种格式。 给定的buf足够大,所以你没有必要去检查它,除非你需要更多 。 int (*read_header)(struct AVFormatContext *); //读取format头并初始化AVFormatContext结构体,如果成功,返回0。创建新的流需要调用avformat_new_stream。 int (*read_header2)(struct AVFormatContext *, AVDictionary **options); //新加的函数指针,用于打开进一步嵌套输入的格式。 int (*read_packet)(struct AVFormatContext *, AVPacket *pkt); //读取一个数据包并将其放在“pkt”中。 pts和flag也被设置。 int (*read_close)(struct AVFormatContext *); //关闭流。 AVFormatContext和Streams不会被此函数释放。 int (*read_seek)(struct AVFormatContext *, int stream_index, int64_t timestamp, int flags); int64_t (*read_timestamp)(struct AVFormatContext *s, int stream_index, int64_t *pos, int64_t pos_limit); //获取stream [stream_index] .time_base单位中的下一个时间戳。 int (*read_play)(struct AVFormatContext *); //开始/继续播放 - 仅当使用基于网络的(RTSP)格式时才有意义。 int (*read_pause)(struct AVFormatContext *); //暂停播放 - 仅当使用基于网络的(RTSP)格式时才有意义。 int (*read_seek2)(struct AVFormatContext *s, int stream_index, int64_t min_ts, int64_t ts, int64_t max_ts, int flags); //寻求时间戳ts。 int (*get_device_list)(struct AVFormatContext *s, struct AVDeviceInfoList *device_list); 返回设备列表及其属性。 int (*create_device_capabilities)(struct AVFormatContext *s, struct AVDeviceCapabilitiesQuery *caps); //初始化设备能力子模块。 int (*free_device_capabilities)(struct AVFormatContext *s, struct AVDeviceCapabilitiesQuery *caps); //释放设备能力子模块。

AVInputFormat(位于avformat.h中)
AVOutputFormat 结构主要包含的信息有:封装名称描述,编码格式信息(video/audio 默认编码格式,支持的编码格式列表),一些对封装的操作函数(write_header,write_packet,write_tailer等) const char *name; const char *long_name; //格式的描述性名称,易于阅读。 enum AVCodecID audio_codec; //默认的音频编解码器 enum AVCodecID video_codec; //默认的视频编解码器 enum AVCodecID subtitle_codec; //默认的字幕编解码器 struct AVOutputFormat *next; int (*write_header)(struct AVFormatContext *); int (*write_packet)(struct AVFormatContext *, AVPacket *pkt); //写一个数据包。 如果在标志中设置AVFMT_ALLOW_FLUSH,则pkt可以为NULL。 int (*write_trailer)(struct AVFormatContext *); int (*interleave_packet)(struct AVFormatContext *, AVPacket *out, AVPacket *in, int flush); int (*control_message)(struct AVFormatContext *s, int type, void *data, size_t data_size); //允许从应用程序向设备发送消息。 int (*write_uncoded_frame)(struct AVFormatContext *, int stream_index,AVFrame **frame, unsigned flags); //写一个未编码的AVFrame。 int (*init)(struct AVFormatContext *); //初始化格式。 可以在此处分配数据,并设置在发送数据包之前需要设置的任何AVFormatContext或AVStream参数。 void (*deinit)(struct AVFormatContext *); //取消初始化格式。 int (*check_bitstream)(struct AVFormatContext *, const AVPacket *pkt); //设置任何必要的比特流过滤,并提取全局头部所需的任何额外数据。

AVIOContent(位于avio.h中)
AVIOContent是FFmpeg管理输入输出数据的结构体.例如打开一个视频文件的时候,先把数据从硬盘读入buffer,然后在送给解码器用于解码。
unsigned char *buffer; //缓存开始位置。 int buffer_size; //缓冲区的大小。 unsigned char *buf_ptr; //当前指针在缓冲区中的位置,即当前指针读取到的位置。 unsigned char *buf_end; //缓存结束的位置void *opaque; //一个私有指针,传递给read / write / seek / ...函数。 opaque指向了URLContext。URLContext结构体中还有一个结构体URLProtocol。 ps:每种协议(rtp,rtmp,file等)对应一个URLProtocol。int64_t pos; //当前缓冲区在文件中的位置。 int must_flush; //如果下一次seek需要刷新则为真。 int eof_reached; //是否读到eof,文件结尾。 int (*read_pause)(void *opaque, int pause); //暂停或恢复播放网络流媒体协议 - 例如 MMS。 int64_t (*read_seek)(void *opaque, int stream_index, int64_t timestamp, int flags); //使用指定的stream_index查找流中给定的时间戳(对于不支持寻找字节位置的网络流协议)。 其中opaque指向了URLContext。 typedef struct URLContext { const AVClass *av_class; ///< information for av_log(). Set by url_open(). struct URLProtocol *prot; int flags; int is_streamed; /**< true if streamed (no seek possible), default = false */ int max_packet_size; /**< if non zero, the stream is packetized with this max packet size */ void *priv_data; char *filename; /**< specified URL */ int is_connected; AVIOInterruptCB interrupt_callback; } URLContext; URLContext结构体中还有一个结构体URLProtocol。注:每种协议(rtp,rtmp,file等)对应一个URLProtocol。 typedef struct URLProtocol { const char *name; int (*url_open)(URLContext *h, const char *url, int flags); int (*url_read)(URLContext *h, unsigned char *buf, int size); int (*url_write)(URLContext *h, const unsigned char *buf, int size); int64_t (*url_seek)(URLContext *h, int64_t pos, int whence); int (*url_close)(URLContext *h); struct URLProtocol *next; int (*url_read_pause)(URLContext *h, int pause); int64_t (*url_read_seek)(URLContext *h, int stream_index, int64_t timestamp, int flags); int (*url_get_file_handle)(URLContext *h); int priv_data_size; const AVClass *priv_data_class; int flags; int (*url_check)(URLContext *h, int mask); } URLProtocol; 在这个结构体中,除了一些回调函数接口之外,有一个变量const char *name,该变量存储了协议的名称。每一种输入协议都对应这样一个结构体。 比如说,文件协议中代码如下(file.c): URLProtocol ff_file_protocol = { .name= "file", .url_open= file_open, .url_read= file_read, .url_write= file_write, .url_seek= file_seek, .url_close= file_close, .url_get_file_handle = file_get_handle, .url_check= file_check, }; libRTMP中代码如下(libRTMP.c): URLProtocol ff_rtmp_protocol = { .name= "rtmp", .url_open= rtmp_open, .url_read= rtmp_read, .url_write= rtmp_write, .url_close= rtmp_close, .url_read_pause= rtmp_read_pause, .url_read_seek= rtmp_read_seek, .url_get_file_handle = rtmp_get_file_handle, .priv_data_size= sizeof(RTMP), .flags= URL_PROTOCOL_FLAG_NETWORK, }; udp协议代码如下(udp.c): URLProtocol ff_udp_protocol = { .name= "udp", .url_open= udp_open, .url_read= udp_read, .url_write= udp_write, .url_close= udp_close, .url_get_file_handle = udp_get_file_handle, .priv_data_size= sizeof(UDPContext), .flags= URL_PROTOCOL_FLAG_NETWORK, }; 等号右边的函数是完成具体读写功能的函数。可以看一下file协议的几个函数(其实就是读文件,写文件这样的操作)(file.c): /* standard file protocol */ static int file_read(URLContext *h, unsigned char *buf, int size) { int fd = (intptr_t) h->priv_data; int r = read(fd, buf, size); return (-1 == r)?AVERROR(errno):r; } static int file_write(URLContext *h, const unsigned char *buf, int size) { int fd = (intptr_t) h->priv_data; int r = write(fd, buf, size); return (-1 == r)?AVERROR(errno):r; }

【ffmpeg源码分析01(结构体)】AVStream(位于avformat.h中)
是存储每一个视频/音频流信息的结构体
int index; //在AVFormatContext中的索引,这个数字是自动生成的,可以通过这个数字从AVFormatContext::streams表中索引到该流。标识该视频/音频流 int id; //流的标识,依赖于具体的容器格式。解码:由libavformat设置。编码:由用户设置,如果未设置则由libavformat替换。 AVCodecContext *codec; //指向该流对应的AVCodecContext结构,调用avformat_open_input时生成。 AVRational time_base; //这是表示帧时间戳的基本时间单位(以秒为单位)。该流中媒体数据的pts和dts都将以这个时间基准为粒度。 int64_t start_time; //流的起始时间,以流的时间基准为单位。如需设置,100%确保你设置它的值真的是第一帧的pts。 int64_t duration; //解码:流的持续时间。如果源文件未指定持续时间,但指定了比特率,则将根据比特率和文件大小估计该值。 int64_t nb_frames; //此流中的帧数(如果已知)或0。 enum AVDiscard discard; //选择哪些数据包可以随意丢弃,不需要去demux。 AVRational sample_aspect_ratio; //样本长宽比(如果未知,则为0)。 AVDictionary *metadata; //元数据信息。 AVRational avg_frame_rate; //平均帧速率。解封装:可以在创建流时设置为libavformat,也可以在avformat_find_stream_info()中设置。封装:可以由调用者在avformat_write_header()之前设置。 AVPacket attached_pic; //附带的图片。比如说一些MP3,AAC音频文件附带的专辑封面。 int probe_packets; //编解码器用于probe的包的个数。 int codec_info_nb_frames; //在av_find_stream_info()期间已经解封装的帧数。 int request_probe; //流探测状态,1表示探测完成,0表示没有探测请求,rest 执行探测。 int skip_to_keyframe; //表示应丢弃直到下一个关键帧的所有内容。 int skip_samples; //在从下一个数据包解码的帧开始时要跳过的采样数。 int64_t start_skip_samples; //如果不是0,则应该从流的开始跳过的采样的数目。 int64_t first_discard_sample; //如果不是0,则应该从流中丢弃第一个音频样本。int64_t pts_reorder_error[MAX_REORDER_DELAY+1]; uint8_t pts_reorder_error_count[MAX_REORDER_DELAY+1]; //内部数据,从pts生成dts。int64_t last_dts_for_order_check; uint8_t dts_ordered; uint8_t dts_misordered; //内部数据,用于分析dts和检测故障mpeg流。 AVRational display_aspect_ratio; //显示宽高比。

AVCodecContent(位于avcodec.h文件中)
AVCodecContext 结构表示程序运行的当前Codec使用的上下文,着重于所有Codec共有的属性(并且是在程序运行时才能确定其值)和关联其他结构的字段。extradata和extradata_size两个字段表述了相应Codec使用的私有数据;codec字段关联相应的编解码器;priv_data字段关联各个具体编解码器独有的属性context,和AVCodec结构中的priv_data_size配对使用。
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差不太多) int delay; //编码:从编码器输入到解码器输出的帧延迟数。解码:除了规范中规定的标准解码器外产生的帧延迟数。 int sample_rate; //采样率(仅音频)。 int channels; //声道数(仅音频)。 int frame_size; //音频帧中每个声道的采样数。编码:由libavcodec在avcodec_open2()中设置。 解码:可以由一些解码器设置以指示恒定的帧大小. int frame_number; //帧计数器,由libavcodec设置。解码:从解码器返回的帧的总数。编码:到目前为止传递给编码器的帧的总数。 uint64_t channel_layout; //音频声道布局。编码:由用户设置。解码:由用户设置,可能被libavcodec覆盖。 enum AVAudioServiceType audio_service_type; //音频流传输的服务类型。编码:由用户设置。解码:由libavcodec设置。 1.codec_type:编解码器类型有以下几种 enum AVMediaType { AVMEDIA_TYPE_UNKNOWN = -1,///< Usually treated as AVMEDIA_TYPE_DATA AVMEDIA_TYPE_VIDEO, AVMEDIA_TYPE_AUDIO, AVMEDIA_TYPE_DATA,///< Opaque data information usually continuous AVMEDIA_TYPE_SUBTITLE, AVMEDIA_TYPE_ATTACHMENT,///< Opaque data information usually sparse AVMEDIA_TYPE_NB }; 2.sample_fmt:在FFMPEG中音频采样格式有以下几种: enum AVSampleFormat { AV_SAMPLE_FMT_NONE = -1, AV_SAMPLE_FMT_U8,///< unsigned 8 bits AV_SAMPLE_FMT_S16,///< signed 16 bits AV_SAMPLE_FMT_S32,///< signed 32 bits AV_SAMPLE_FMT_FLT,///< float AV_SAMPLE_FMT_DBL,///< double AV_SAMPLE_FMT_U8P,///< unsigned 8 bits, planar AV_SAMPLE_FMT_S16P,///< signed 16 bits, planar AV_SAMPLE_FMT_S32P,///< signed 32 bits, planar AV_SAMPLE_FMT_FLTP,///< float, planar AV_SAMPLE_FMT_DBLP,///< double, planar AV_SAMPLE_FMT_NB///< Number of sample formats. DO NOT USE if linking dynamically }; 3.profile:在FFMPEG中型有以下几种,可以看出AAC,MPEG2,H.264,VC-1,MPEG4都有型的概念。 #define FF_PROFILE_UNKNOWN -99 #define FF_PROFILE_RESERVED -100 #define FF_PROFILE_AAC_MAIN 0 #define FF_PROFILE_AAC_LOW1 #define FF_PROFILE_AAC_SSR2 #define FF_PROFILE_AAC_LTP3 #define FF_PROFILE_AAC_HE4 #define FF_PROFILE_AAC_HE_V2 28 #define FF_PROFILE_AAC_LD22 #define FF_PROFILE_AAC_ELD38 #define FF_PROFILE_DTS20 #define FF_PROFILE_DTS_ES30 #define FF_PROFILE_DTS_96_2440 #define FF_PROFILE_DTS_HD_HRA50 #define FF_PROFILE_DTS_HD_MA60 #define FF_PROFILE_MPEG2_4220 #define FF_PROFILE_MPEG2_HIGH1 #define FF_PROFILE_MPEG2_SS2 #define FF_PROFILE_MPEG2_SNR_SCALABLE3 #define FF_PROFILE_MPEG2_MAIN4 #define FF_PROFILE_MPEG2_SIMPLE 5 #define FF_PROFILE_H264_CONSTRAINED(1<<9)// 8+1; constraint_set1_flag #define FF_PROFILE_H264_INTRA(1<<11) // 8+3; constraint_set3_flag #define FF_PROFILE_H264_BASELINE66 #define FF_PROFILE_H264_CONSTRAINED_BASELINE (66|FF_PROFILE_H264_CONSTRAINED) #define FF_PROFILE_H264_MAIN77 #define FF_PROFILE_H264_EXTENDED88 #define FF_PROFILE_H264_HIGH100 #define FF_PROFILE_H264_HIGH_10110 #define FF_PROFILE_H264_HIGH_10_INTRA(110|FF_PROFILE_H264_INTRA) #define FF_PROFILE_H264_HIGH_422122 #define FF_PROFILE_H264_HIGH_422_INTRA(122|FF_PROFILE_H264_INTRA) #define FF_PROFILE_H264_HIGH_444144 #define FF_PROFILE_H264_HIGH_444_PREDICTIVE244 #define FF_PROFILE_H264_HIGH_444_INTRA(244|FF_PROFILE_H264_INTRA) #define FF_PROFILE_H264_CAVLC_44444 #define FF_PROFILE_VC1_SIMPLE0 #define FF_PROFILE_VC1_MAIN1 #define FF_PROFILE_VC1_COMPLEX2 #define FF_PROFILE_VC1_ADVANCED 3 #define FF_PROFILE_MPEG4_SIMPLE0 #define FF_PROFILE_MPEG4_SIMPLE_SCALABLE1 #define FF_PROFILE_MPEG4_CORE2 #define FF_PROFILE_MPEG4_MAIN3 #define FF_PROFILE_MPEG4_N_BIT4 #define FF_PROFILE_MPEG4_SCALABLE_TEXTURE5 #define FF_PROFILE_MPEG4_SIMPLE_FACE_ANIMATION6 #define FF_PROFILE_MPEG4_BASIC_ANIMATED_TEXTURE7 #define FF_PROFILE_MPEG4_HYBRID8 #define FF_PROFILE_MPEG4_ADVANCED_REAL_TIME9 #define FF_PROFILE_MPEG4_CORE_SCALABLE10 #define FF_PROFILE_MPEG4_ADVANCED_CODING11 #define FF_PROFILE_MPEG4_ADVANCED_CORE12 #define FF_PROFILE_MPEG4_ADVANCED_SCALABLE_TEXTURE 13 #define FF_PROFILE_MPEG4_SIMPLE_STUDIO14 #define FF_PROFILE_MPEG4_ADVANCED_SIMPLE15

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:私有数据的大小 1,enum AVCodecID id enum AVCodecID { AV_CODEC_ID_NONE, /* video codecs */ AV_CODEC_ID_MPEG1VIDEO, AV_CODEC_ID_MPEG2VIDEO, ///< preferred ID for MPEG-1/2 video decoding AV_CODEC_ID_MPEG2VIDEO_XVMC, AV_CODEC_ID_H261, AV_CODEC_ID_H263, AV_CODEC_ID_RV10, AV_CODEC_ID_RV20, AV_CODEC_ID_MJPEG, AV_CODEC_ID_MJPEGB, AV_CODEC_ID_LJPEG, AV_CODEC_ID_SP5X, AV_CODEC_ID_JPEGLS, AV_CODEC_ID_MPEG4, AV_CODEC_ID_RAWVIDEO, AV_CODEC_ID_MSMPEG4V1, AV_CODEC_ID_MSMPEG4V2, AV_CODEC_ID_MSMPEG4V3, AV_CODEC_ID_WMV1, AV_CODEC_ID_WMV2, AV_CODEC_ID_H263P, AV_CODEC_ID_H263I, AV_CODEC_ID_FLV1, AV_CODEC_ID_SVQ1, AV_CODEC_ID_SVQ3, AV_CODEC_ID_DVVIDEO, AV_CODEC_ID_HUFFYUV, AV_CODEC_ID_CYUV, AV_CODEC_ID_H264, ...(代码太长,略) } 2,const enum AVPixelFormat *pix_fmts enum AVPixelFormat { AV_PIX_FMT_NONE = -1, AV_PIX_FMT_YUV420P,///< planar YUV 4:2:0, 12bpp, (1 Cr & Cb sample per 2x2 Y samples) AV_PIX_FMT_YUYV422,///< packed YUV 4:2:2, 16bpp, Y0 Cb Y1 Cr AV_PIX_FMT_RGB24,///< packed RGB 8:8:8, 24bpp, RGBRGB... AV_PIX_FMT_BGR24,///< packed RGB 8:8:8, 24bpp, BGRBGR... AV_PIX_FMT_YUV422P,///< planar YUV 4:2:2, 16bpp, (1 Cr & Cb sample per 2x1 Y samples) AV_PIX_FMT_YUV444P,///< planar YUV 4:4:4, 24bpp, (1 Cr & Cb sample per 1x1 Y samples) AV_PIX_FMT_YUV410P,///< planar YUV 4:1:0,9bpp, (1 Cr & Cb sample per 4x4 Y samples) AV_PIX_FMT_YUV411P,///< planar YUV 4:1:1, 12bpp, (1 Cr & Cb sample per 4x1 Y samples) AV_PIX_FMT_GRAY8,///

AVPacket(位于avcodec.h文件中)
是存储压缩编码数据相关信息的结构体
AVPacket中的字段可分为两部分:数据的缓存及管理和数据的属性。 关于数据的属性有以下字段: pts: (int64_t)显示时间,结合AVStream->time_base转换成时间戳 dts: (int64_t)解码时间,结合AVStream->time_base转换成时间戳 size: (int)data的大小stream_index: (int)packet在stream的index位置 flags: (int)标示,结合AV_PKT_FLAG使用,其中最低为1表示该数据是一个关键帧。 #define AV_PKT_FLAG_KEY0x0001 //关键帧 #define AV_PKT_FLAG_CORRUPT 0x0002 //损坏的数据 #define AV_PKT_FLAG_DISCARD0x0004 /丢弃的数据 side_data_elems: (int)边缘数据元数个数 duration: (int64_t)数据的时长,以所属媒体流的时间基准为单位,未知则值为默认值0 pos: (int64_t )数据在流媒体中的位置,未知则值为默认值-1 convergence_duration:该字段已deprecated,不在使用 关于数据缓存,AVPacket本身只是个容器,不直接的包含数据,而是通过数据缓存的指针引用数据。AVPacket包含两种数据 uint8_t *data:指向保存压缩数据的指针,这就是AVPacket的实际数据。例如对于H.264来说。1个AVPacket的data通常对应一个NAL。 注意:在这里只是对应,而不是一模一样。他们之间有微小的差别:使用FFMPEG类库分离出多媒体文件中的H.264码流(https://blog.csdn.net/leixiaohua1020/article/details/11800877) 因此在使用FFMPEG进行视音频处理的时候,常常可以将得到的AVPacket的data数据直接写成文件,从而得到视音频的码流文件。 AVPacketSideData *side_data:容器提供的一些附加数据 AVBufferRef *buf:用来管理data指针引用的数据缓存,其使用在后面介绍。

AVFrame(位于frame.h文件中)
解压缩数据(包含了yuv和pcm数据)的结构体
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 interlaced_frame:是否是隔行扫描 uint8_t motion_subsample_log2:一个宏块中的运动矢量采样个数,取log的 1.data[] 对于packed格式的数据(例如RGB24),会存到data[0]里面。 对于planar格式的数据(例如YUV420P),则会分开成data[0],data[1],data[2]...(YUV420P中data[0]存Y,data[1]存U,data[2]存V 2.pict_type enum AVPictureType { AV_PICTURE_TYPE_NONE = 0, ///< Undefined AV_PICTURE_TYPE_I,///< Intra AV_PICTURE_TYPE_P,///< Predicted AV_PICTURE_TYPE_B,///< Bi-dir predicted AV_PICTURE_TYPE_S,///< S(GMC)-VOP MPEG4 AV_PICTURE_TYPE_SI,///< Switching Intra AV_PICTURE_TYPE_SP,///< Switching Predicted AV_PICTURE_TYPE_BI,///< BI type }; 3.sample_aspect_ratio /** * rational number numerator/denominator */ typedef struct AVRational{ int num; ///< numerator int den; ///< denominator } AVRational; 4.qscale_table QP表指向一块内存,里面存储的是每个宏块的QP值。宏块的标号是从左往右,一行一行的来的。每个宏块对应1个QP。 qscale_table[0]就是第1行第1列宏块的QP值;qscale_table[1]就是第1行第2列宏块的QP值;qscale_table[2]就是第1行第3列宏块的QP值。以此类推... 宏块的个数用下式计算: 注:宏块大小是16x16的。 每行宏块数: int mb_stride = pCodecCtx->width/16+1 宏块的总数: int mb_sum = ((pCodecCtx->height+15)>>4)*(pCodecCtx->width/16+1) 5.motion_subsample_log2 1个运动矢量所能代表的画面大小(用宽或者高表示,单位是像素),注意,这里取了log2。 代码注释中给出以下数据: 4->16x16, 3->8x8, 2-> 4x4, 1-> 2x2 即1个运动矢量代表16x16的画面的时候,该值取4;1个运动矢量代表8x8的画面的时候,该值取3...以此类推 6.motion_val 运动矢量表存储了一帧视频中的所有运动矢量。 7.mb_type 宏块类型表存储了一帧视频中的所有宏块的类型。其存储方式和QP表差不多。只不过其是uint32类型的,而QP表是uint8类型的。每个宏块对应一个宏块类型变量。

    推荐阅读