一、AVPacket
AVPacket是FFmpeg中很重要的一个数据结构,它保存了解复用之后,解码之前的数据(仍然是压缩后的数据)和关于这些数据的一些附加信息,如显示时间戳(pts)、解码时间戳(dts)、数据时长,所在媒体流的索引等。
对于视频(Video)来说,AVPacket通常包含一个压缩的Frame,而音频(Audio)则有可能包含多个压缩的Frame。并且,一个Packet有可能是空的,不包含任何压缩数据,只含有side data(side data,容器提供的关于Packet的一些附加信息。例如,在编码结束的时候更新一些流的参数)。
1、新建AVPacket
AVPacket* pkt = av_packet_alloc();
2、释放AVPacket
av_packet_free(&pkt);
二、AVCodecParserContext
AVCodecParserContext从码流中读出完整的包
1、初始化
parser = av_parser_init(codec->id);
2、解码
ret = av_parser_parse2(parser, c, &pkt->data, &pkt->size,
data, data_size,
AV_NOPTS_VALUE, AV_NOPTS_VALUE, 0);
3、关闭
av_parser_close(parser);
三、AVFrame
AVFrame结构体一般用于存储原始数据(即非压缩数据,例如对视频来说是YUV,RGB,对音频来说是PCM),此外还包含了一些相关的信息。比如说,解码的时候存储了宏块类型表,QP表,运动矢量表等数据。编码的时候也存储了相关的数据。因此在使用FFMPEG进行码流分析的时候,AVFrame是一个很重要的结构体。
字段
nb_samples:一帧的采样数
1、申请AVFrame
av_frame_alloc();
2、释放AVFrame
av_frame_free(&decoded_frame);
四、AVCodecContext
AVCodecContext - 描述编解码器上下文的数据结构,包含了众多编解码器需要的参数信息,保存AVCodec指针和与codec相关的数据,包含了流中所使用的关于编解码器的所有信息。
1、申请AVCodecContext
根据 AVCodec 分配合适的 AVCodecContext
c = avcodec_alloc_context3(codec);
if (!c) {
fprintf(stderr, "Could not allocate audio codec context\n");
exit(1);
}
2、参数设置
解码不需要设置参数,编码需要设置
2.1 音频编码
需要设置比特率(bit_rate)、采样率(sample_rate)、音频格式(sample_fmt)、通道格式类型(ch_layout)
/* put sample parameters */
c->bit_rate = 64000;`在这里插入代码片`
/* check that the encoder supports s16 pcm input */
c->sample_fmt = AV_SAMPLE_FMT_S16;
if (!check_sample_fmt(codec, c->sample_fmt)) {
fprintf(stderr, "Encoder does not support sample format %s",
av_get_sample_fmt_name(c->sample_fmt));
exit(1);
}
/* select other audio parameters supported by the encoder */
c->sample_rate = select_sample_rate(codec);
ret = select_channel_layout(codec, &c->ch_layout);
if (ret < 0)
exit(1);
2.1.1 sample_fmt
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_S64, ///< signed 64 bits
AV_SAMPLE_FMT_S64P, ///< signed 64 bits, planar
AV_SAMPLE_FMT_NB ///< Number of sample formats. DO NOT USE if linking dynamically
};
2.1.2 通道格式类型
channels 为 音频的 通道数 1 2 3 4 5…
channel_layout 为音频 通道格式类型 如 单通道 双通道 …
2.2 视频编码
需要设置比特率(bit_rate)、图像宽度(width)、图像高度(height)、
gop_size(the number of pictures in a group of pictures)、pix_fmt(Pixel format, see AV_PIX_FMT_xxx)、time_base、framerate、max_b_frames
/* put sample parameters */
c->bit_rate = 400000;
/* resolution must be a multiple of two */
c->width = 352;
c->height = 288;
/* frames per second */
c->time_base = (AVRational){1, 25};
c->framerate = (AVRational){25, 1};
/* emit one intra frame every ten frames
* check frame pict_type before passing frame
* to encoder, if frame->pict_type is AV_PICTURE_TYPE_I
* then gop_size is ignored and the output of encoder
* will always be I frame irrespective to gop_size
*/
c->gop_size = 10;
c->max_b_frames = 1;
c->pix_fmt = AV_PIX_FMT_YUV420P;
if (codec->id == AV_CODEC_ID_H264)
av_opt_set(c->priv_data, "preset", "slow", 0);
3、释放AVCodecContext
avcodec_free_context(&c);
五、AVCodec
编解码器对象,编解码器,采用链表维护,每一个都有其对应的名字、类型、CodecID和对数据进行处理的编解码函数指针,每种编解码格式(例如H.264、AAC等)对应一个该结构体。每个AVCodecContext中含有一个AVCodec;
1、获取解码器
/* find the MPEG audio decoder */
codec = avcodec_find_decoder(AV_CODEC_ID_MP2);
2、打开解码器
/* open it */
if (avcodec_open2(c, codec, NULL) < 0) {
fprintf(stderr, "Could not open codec\n");
exit(1);
}
六、AVCodecParameters
编解码参数,每个AVStream中都含有一个AVCodecParameters,用来存放当前流的编解码参数。
七、AVStream
未完待续…