一、视频播放流程
(PS:视频的播放流程跟音频的及其相似!!)
1、打开视频文件
通过 avformat_open_input() 打开媒体文件并分配和初始化
AVFormatContext 结构体。
函数原型如下:
int avformat_open_input(AVFormatContext **ps, const char *url,
AVInputFormat *fmt, AVDictionary **options);
参数说明:
- `ps`:指向 `AVFormatContext` 结构体指针的指针,用于存储打
开的媒体文件的信息。
-
`url`:要打开的媒体文件的 URL 或文件路径。
-
`fmt`:指定输入格式,通常可以设置为 `NULL`,由 FFmpeg 根
据文件内容自动检测。
- `options`:附加选项,可以传入一些额外的选项参数。
2、查找输入流信息
调用 avformat_find_stream_info() 函数将会读取媒体文件中的
帧,解析它们的头部,
并填充 AVFormatContext 中的流信息,通过访问
AVFormatContext 的 streams 字段来获取每个流的详细信息。
函数原型如下:
int avformat_find_stream_info(AVFormatContext *ic,
AVDictionary **options);
参数说明:
- `ic`:指向已打开媒体文件的 `AVFormatContext` 结构体的指
针。
- `options`:指向包含附加选项的 `AVDictionary` 指针。
3、查找流索引
使用 av_find_best_stream() 从媒体文件中找到最佳的流索引
函数原型如下:
int av_find_best_stream(AVFormatContext *ic, enum
AVMediaType type, int wanted_stream, int related_stream,
AVCodec **decoder_ret, int flags);
参数说明:
- `ic`:指向已打开媒体文件的 `AVFormatContext` 结构体的指
针。
- `type`:要查找的流类型,可以是 `AVMEDIA_TYPE_VIDEO`、
`AVMEDIA_TYPE_AUDIO` 等。
- `wanted_stream`:期望的流索引,如果为负值,则表示没有特
定的偏好。
-
`related_stream`:相关流索引,用于查找与之相关的最佳流。
-
`decoder_ret`:用于返回找到的解码器。
-
`flags`:附加标志,可以用来指定额外的查找选项。
4、查找解码器
使用 avcodec_find_decoder() 查找符合指定解码器名称的解码
器。
函数原型如下:
AVCodec *avcodec_find_decoder(enum AVCodecID id);
参数说明:
- `id`:要查找的解码器的 ID。
5、初始化解码上下文
调用 avcodec_alloc_context3() 函数会为特定的编解码器分配一
个 AVCodecContext 结构体,并对其进行初始化。
AVCodecContext 结构体包含了编解码器的相关参数和状态信
息,比如编解码器类型、解码参数、帧率等。
函数原型如下:
AVCodecContext *avcodec_alloc_context3(const AVCodec
*codec);
参数说明:
- `codec`:指定要使用的编解码器,可以通过
`avcodec_find_decoder()` 或其他方式获取。
6、获取解码参数
调用 `avcodec_parameters_to_context()` 函数可以方便地将
`AVCodecParameters` 结构体中的参数(如编解码器类型、帧
率、分辨率等)复制到 `AVCodecContext` 结构体中,从而准备
进行编解码操作。
函数原型如下:
int avcodec_parameters_to_context(AVCodecContext *codec,
const AVCodecParameters *par);
参数说明:
-
`codec`:要填充参数的 `AVCodecContext` 结构体指针。
-
`par`:包含编解码器参数的 `AVCodecParameters` 结构体指
针。
7、打开解码器
调用 `avcodec_open2()` 函数可以打开并初始化指定的编解码器
上下文,使其准备好进行编解码操作。
函数原型如下:
int avcodec_open2(AVCodecContext *avctx, const AVCodec
*codec, AVDictionary **options);
参数说明:
-
`avctx`:要打开和初始化的编解码器上下文。
-
`codec`:要使用的编解码器,可以通过
`avcodec_find_decoder()` 或其他方式获取。
- `options`:可选的字典参数,用于设置编解码器的选项。
8、获取图像转换上下文
通过调用`sws_getContext`函数获取一个用于执行图像转换的上
下文对象,然后可以使用该上下文对象来进行图像转换操作。
函数原型如下:
struct SwsContext *sws_getContext(int srcW, int srcH, enum AVPixelFormat srcFormat,
int dstW, int dstH, enum AVPixelFormat dstFormat,
int flags, SwsFilter *srcFilter, SwsFilter *dstFilter, const double *param);
参数说明:
-
`srcW`: 源图像的宽度
-
`srcH`: 源图像的高度
-
`srcFormat`: 源图像的像素格式
-
`dstW`: 目标图像的宽度
-
`dstH`: 目标图像的高度
-
`dstFormat`: 目标图像的像素格式
-
`flags`: 可以指定一些转换的选项
-
`srcFilter`: 源图像滤镜
-
`dstFilter`: 目标图像滤镜
-
`param`: 一组额外的参数
9、读取视频源文件
调用 `av_read_frame()` 函数可以从输入文件或流中读取一帧音视
频数据,并将其存储在 AVPacket 结构体中。
函数原型如下:
int av_read_frame(AVFormatContext *s, AVPacket *pkt);
参数说明:
-
`s`:输入文件或流的 AVFormatContext 上下文。
-
`pkt`:存储读取到的音视频帧数据的 AVPacket 结构体。
12、发送音频数据到解码器
调用 `avcodec_send_packet()` 函数可以将 AVPacket 数据包发送
给解码器进行解码。在发送完所有数据包后,需要调用
`avcodec_send_packet()` 传递一个空的 AVPacket 指针,以便告
知解码器已经发送完所有数据。
函数原型如下:
int avcodec_send_packet(AVCodecContext *avctx, const AVPacket *avpkt);
参数说明:
-
`avctx`:指向 AVCodecContext 结构体的指针,表示解码器上下文。
-
`avpkt`:指向要发送给解码器的 AVPacket 数据包的指针。
13、从解码器接收解码后的视频数据
调用 `avcodec_receive_frame()` 函数可以从解码器中接收解码后
的音视频帧数据,并将其存储在 AVFrame 结构体中。
函数原型如下:
int avcodec_receive_frame(AVCodecContext *avctx, AVFrame
*frame);
参数说明:
- `avctx`:指向 AVCodecContext 结构体的指针,表示解码器上
下文。
- `frame`:用于存储接收到的解码后的 AVFrame 帧数据的结构体。
14、分配图像数据缓冲区
通过调用`av_image_alloc`函数为图像数据分配内存,并
将分配的内存绑定到指定的指针数组和行大小数组中,以便后续
在这些内存区域中存储图像数据。
函数原型如下所示:
int av_image_alloc(uint8_t *pointers[4], int linesizes[4], int w, int h, enum AVPixelFormat pix_fmt, int align);
参数解释:
-
`pointers`: 用于存储图像数据的指针数组
-
`linesizes`: 每个图像数据平面的行大小
-
`w`: 图像宽度
-
`h`: 图像高度
-
`pix_fmt`: 像素格式
-
`align`: 内存对齐参数
15、执行图像转换和缩放操作
通过调用`sws_scale`函数,可以使用提供的SwcContext对象和输入图像数据,对图像进行转换和缩放操作,然后将结果存储到输出图像数据中。
函数原型如下所示:
int sws_scale(struct SwsContext *c, const uint8_t *const srcSlice[], const int srcStride[], int srcSliceY, int srcSliceH, uint8_t *const dst[], const int dstStride[]);
参数解释:
-
`c`: SwsContext对象,用于存储图像转换相关信息
-
`srcSlice`: 指向输入图像数据的指针数组
-
`srcStride`: 输入图像每个平面的跨度(stride)
-
`srcSliceY`: 输入图像的起始行
-
`srcSliceH`: 输入图像的高度
-
`dst`: 指向输出图像数据的指针数组
-
`dstStride`: 输出图像每个平面的跨度(stride)
16、显示图像
直接显示执行 sws_scale 后的图像便可。
二、代码例程
音頻播放:点击跳转
視頻播放:点击跳转
觉得有帮助的话,打赏一下呗。。