AVFrame 结构体是 FFmpeg 中用于描述媒体数据帧(视频、音频等)的结构体。它包含了媒体数据帧的各种参数和数据信息,是进行媒体数据的编解码和处理的必要元素。下面是关于 AVFrame 结构体的详细介绍,同时也给出一个简单的代码示例。
AVFrame 结构体定义
AVFrame 结构体的定义可以在 FFmpeg 的 frame.h 头文件中找到。其定义如下:
typedef struct AVFrame {...
} AVFrame;
AVFrame 结构体成员变量
AVFrame 结构体包含了丰富的参数和数据信息,其中一些重要的成员变量如下:
data[AV_NUM_DATA_POINTERS]
:一个指针数组,用于存放媒体数据帧的各个通道的数据指针。例如,在视频帧中,该数组通常包含一至三个指针,分别对应红色、绿色和蓝色通道的数据。在音频帧中,该数组通常只包含一个指针,对应音频通道的数据。
linesize[AV_NUM_DATA_POINTERS]
:一个整数数组,表示各个通道数据的每行字节数。
extended_data
:指向 data 数组的第一个元素的指针,用于支持一些非标准的媒体数据格式。
width、height、format
:媒体数据帧的宽度、高度和像素格式,用于指示帧的尺寸和颜色特征。
pts
:帧的时间戳(Presentation Timestamp),用于表示该帧数据在整个媒体流中的展示时间。
pkt_pts、pkt_dts
:AVPacket 结构体中的时间戳,用于与解码后的 AVFrame 结构体中的时间戳进行比较、计算和修正。
nb_samples
:音频帧中采样的数量。
sample_rate、channels、channel_layout
:音频帧的采样率、声道数和声道布局。
key_frame
:视频帧是否为关键帧。
repeat_pict
:视频帧是否需要重复播放,用于实现帧率调整等功能。
crop_top、crop_left、crop_bottom、crop_right
:当前帧的裁剪区域。
此外,AVFrame 结构体还包含了一些额外的参数和标志位,如 metadata、pktpos、pktsize 等,这些参数也可以根据具体的媒体数据类型和应用需求进行设置和调整。
AVFrame 结构体使用示例
下面是一个简单的代码示例,用于解码视频帧并将其保存为 BMP 图像文件:
// 打开视频文件,获取 AVFormatContext 结构体
...// 找到视频流的解码器并打开
...// 分配 AVPacket 和 AVFrame 结构体
AVPacket *pkt = av_packet_alloc();
AVFrame *frame = av_frame_alloc();while (av_read_frame(fmt_ctx, pkt) >= 0) {if (pkt->stream_index == video_stream_index) {// 解码视频帧int ret = avcodec_send_packet(codec_ctx, pkt);if (ret < 0) {// 发送数据包失败av_packet_unref(pkt);break;}while (ret >= 0) {ret = avcodec_receive_frame(codec_ctx, frame);if (ret < 0) {break;}// 写入 BMP 文件char filename[64];snprintf(filename, sizeof(filename), "frame-%d.bmp", codec_ctx->frame_number);write_frame_to_bmp(frame, filename);// 释放帧数据内存av_frame_unref(frame);}}av_packet_unref(pkt);
}// 释放资源
...
在上面的代码中,AVPacket 和 AVFrame 结构体分别用于存储从视频流中读取的未解码的数据包和已解码的视频帧数据。通过调用 avcodecsendpacket() 和 avcodecreceiveframe() 函数,可以将数据包送入解码器进行解码并获取解码后的视频帧数据。解码后的视频帧数据可以通过自定义的 writeframeto_bmp() 函数将其保存为 BMP 文件。
需要注意的是,在使用 AVFrame 结构体时,需要根据具体的媒体数据类型和应用需求进行参数的调整和处理,以便实现媒体数据的正确处理和传输。此外,还需要进行相应的内存管理和资源释放操作,以防止内存泄漏和资源浪费。