此前写了好几篇ffmpeg源代码分析文章,列表如下:
图解FFMPEG打开媒体的函数avformat_open_input
ffmpeg 源代码简单分析 : av_register_all()
ffmpeg 源代码简单分析 : avcodec_register_all()
ffmpeg 源代码简单分析 : av_read_frame()
ffmpeg 源代码简单分析 : avcodec_decode_video2()
============================
FFMPEG打开媒体的的过程开始于avformat_open_input,因此该函数的重要性不可忽视。
在该函数中,FFMPEG完成了:
输入输出结构体AVIOContext的初始化;
输入数据的协议(例如RTMP,或者file)的识别(通过一套评分机制):1判断文件名的后缀 2读取文件头的数据进行比对;
使用获得最高分的文件协议对应的URLProtocol,通过函数指针的方式,与FFMPEG连接(非专业用词);
剩下的就是调用该URLProtocol的函数进行open,read等操作了
以下是通过eclipse+MinGW调试FFMPEG源代码获得的函数调用关系图
可见最终都调用了URLProtocol结构体中的函数指针。
URLProtocol结构如下,是一大堆函数指针的集合(avio.h文件)
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;URLProtocol功能就是完成各种输入协议的读写等操作
但输入协议种类繁多,它是怎样做到“大一统”的呢?
原来,每个具体的输入协议都有自己对应的URLProtocol。
比如file协议(FFMPEG把文件也当做一种特殊的协议)(*file.c文件)
URLProtocol ff_pipe_protocol = { .name = "pipe", .url_open = pipe_open, .url_read = file_read, .url_write = file_write, .url_get_file_handle = file_get_handle, .url_check = file_check, };
或者rtmp协议(此处使用了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, };
可见它们把各自的函数指针都赋值给了URLProtocol结构体的函数指针
因此avformat_open_input只需调用url_open,url_read这些函数就可以完成各种具体输入协议的open,read等操作了
相关推荐
我自己写的avformat_open_input函数的解析,需要了解ffmpeg源码结构的可以看一下
修改了下example中的remuxing.c, 读取管道里的数据进行处理,注意事项已经编译命令放到文件的开头
3. **解析RTSP流**:使用FFmpeg的`avformat_open_input`函数打开RTSP流,并通过`avformat_find_stream_info`获取流的信息。这些信息包括视频和音频的编码格式、分辨率等。 4. **解码流**:使用`avcodec_find_...
使用`avformat_open_input`函数打开RTSP视频流,并使用`avformat_find_stream_info`获取流信息: ```cpp AVFormatContext *iformat_ctx = NULL; if (avformat_open_input(&iformat_ctx, "rtsp://your_rtsp_url", ...
4. **打开输入设备**:调用`avformat_open_input`以打开`x11grab`设备。如果成功,你可以获取到输入流并准备开始捕获屏幕内容。 5. **创建输出流**:根据需要的视频编码格式(如H.264)创建一个新的`AVStream`,...
在该线程中,你可以使用FFmpeg的`avdevice_open_input()`函数打开USB摄像头,然后使用`avformat_find_stream_info()`获取流信息。 ```cpp AVFormatContext *fmtCtx = nullptr; if (avformat_open_input(&fmtCtx, ...
2. **打开输入文件**:使用 `avformat_open_input()` 函数打开视频文件。你需要提供文件路径,FFmpeg 将自动检测其格式。成功后,`avformat_find_stream_info()` 用于获取媒体文件的流信息,包括音频和视频轨道。 3...
- avformat_open_input()打开输入文件,avformat_find_stream_info()获取流信息,avio_open()创建IO上下文,av_read_frame()读取一帧。 6. **音视频过滤** - FFmpeg的libavfilter模块支持各种视觉效果和处理,如...
2. **打开和读取视频流**:通过 avformat_open_input() 打开视频文件,然后用 av_find_stream_info() 获取流信息。 3. **解码视频帧**:使用 av_read_frame() 读取包,avcodec_decode_video2() 或 avcodec_decode_...
首先,需要使用 FFmpeg 的 avformat_open_input 函数打开视频文件,接着调用 avformat_find_stream_info 获取流信息。在这个过程中,我们可能需要处理各种不同的视频编码格式,因此需要使用 avcodec_find_decoder ...
2. **打开RTSP流**: 使用`avformat_open_input()`函数指定RTSP URL,以打开连接到RTSP服务器的流。这需要一个`AVFormatContext`结构体,它是FFmpeg中的核心数据结构,包含了媒体流的所有信息。 3. **读取流信息**: ...
3. 打开设备:使用 `avformat_open_input()` 函数打开选定的摄像头设备,并通过 `avformat_find_stream_info()` 获取设备的流信息。 4. 分析流:对每个视频流,获取相应的编解码器上下文(`AVCodecContext`),然后...
2. **打开视频文件**:使用 `avformat_open_input()` 打开视频文件。这个函数会根据文件的扩展名和内部元数据选择合适的解封装器。接着,调用 `avformat_find_stream_info()` 获取视频的流信息,如流的数量、类型、...
3. 使用FFmpeg的`avformat_open_input`或`avio_open`打开UDP流。 4. 调用`avformat_find_stream_info`来探测流的格式信息,此过程会分析接收到的数据包以识别其类型和编码格式。 5. 设置解码器,开始解码和播放流。 ...
3. **打开流**:根据不同的流类型,如`avformat_open_input()`函数打开RTSP、RTMP或UDP流。对于RTSP,需要设置相应的URL;RTMP则可能需要服务器地址和流名;UDP流需要指定接收的IP地址和端口。 4. **获取流信息**:...
FFmpeg 是一个强大的开源命令行工具,用于处理各种多媒体文件,包括视频、音频转换、流媒体处理等。在这个“ffmpeg-5.0.1-essentials_build(windows)”压缩包中,你将找到适用于 Windows 操作系统的 FFmpeg 基础版本...
4. **打开和解码 H264 文件**:使用 FFmpeg 的 avformat_open_input 函数打开视频文件,然后调用 avformat_find_stream_info 解析流信息。找到 H264 视频流后,分配并初始化解码器上下文,然后用 avcodec_decode_...
在"FFmpeg.AutoGen.master_c#ffmpeg_FFmpeg.AutoGen_ffmpeg_ladysef_pay"项目中,"ladysef_pay"可能是指该项目的一个特定分支或特性,可能是针对某种支付场景或者由用户“ladysef”贡献的特殊功能。不过,由于具体...
`ffmpeg - avformat_open_input.vsd` 文件描绘了`avformat_open_input()`函数的工作流程,这是FFmpeg打开输入文件的核心函数。它涉及查找并加载合适的 demuxer,读取文件头信息,以及初始化内部数据结构。 3. **...
在“simplest_ffmpeg_decoder”中,开发者可能首先会使用`avformat_open_input`打开输入视频文件,然后调用`avformat_find_stream_info`获取文件的流信息,包括流的数量、类型和编码格式。接着,通过`av_find_best_...