`

图解FFMPEG打开媒体的函数avformat_open_input

 
阅读更多

 

此前写了好几篇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详解

    我自己写的avformat_open_input函数的解析,需要了解ffmpeg源码结构的可以看一下

    avformat_open_input 读管道实例

    修改了下example中的remuxing.c, 读取管道里的数据进行处理,注意事项已经编译命令放到文件的开头

    FFmpeg-QT实现摄像头rtsp实时显示

    3. **解析RTSP流**:使用FFmpeg的`avformat_open_input`函数打开RTSP流,并通过`avformat_find_stream_info`获取流的信息。这些信息包括视频和音频的编码格式、分辨率等。 4. **解码流**:使用`avcodec_find_...

    MFC 播放FFMPEG SDL视频所需库

    使用`avformat_open_input`函数打开RTSP视频流,并使用`avformat_find_stream_info`获取流信息: ```cpp AVFormatContext *iformat_ctx = NULL; if (avformat_open_input(&iformat_ctx, "rtsp://your_rtsp_url", ...

    ffmpeg录制视频(需要安装x11grab)--C++编程

    4. **打开输入设备**:调用`avformat_open_input`以打开`x11grab`设备。如果成功,你可以获取到输入流并准备开始捕获屏幕内容。 5. **创建输出流**:根据需要的视频编码格式(如H.264)创建一个新的`AVStream`,...

    QT C++ ffmpeg 调用usb 摄像头显示 并录制 H264录制视频

    在该线程中,你可以使用FFmpeg的`avdevice_open_input()`函数打开USB摄像头,然后使用`avformat_find_stream_info()`获取流信息。 ```cpp AVFormatContext *fmtCtx = nullptr; if (avformat_open_input(&fmtCtx, ...

    FFmpeg-master.zip_FFmpeg-master_ffmpeg_ffmpeg 播放

    2. **打开输入文件**:使用 `avformat_open_input()` 函数打开视频文件。你需要提供文件路径,FFmpeg 将自动检测其格式。成功后,`avformat_find_stream_info()` 用于获取媒体文件的流信息,包括音频和视频轨道。 3...

    ffmpeg教程 C++ MFC VC

    - avformat_open_input()打开输入文件,avformat_find_stream_info()获取流信息,avio_open()创建IO上下文,av_read_frame()读取一帧。 6. **音视频过滤** - FFmpeg的libavfilter模块支持各种视觉效果和处理,如...

    ffmpeg.zip_FFmpeg 内存_JMdecode_ffmpeg open_opencv_ffmpeg_视频帧

    2. **打开和读取视频流**:通过 avformat_open_input() 打开视频文件,然后用 av_find_stream_info() 获取流信息。 3. **解码视频帧**:使用 av_read_frame() 读取包,avcodec_decode_video2() 或 avcodec_decode_...

    qt整合ffmpeg实现点击按钮调用ffmpeg解码视频转成一张张的图片

    首先,需要使用 FFmpeg 的 avformat_open_input 函数打开视频文件,接着调用 avformat_find_stream_info 获取流信息。在这个过程中,我们可能需要处理各种不同的视频编码格式,因此需要使用 avcodec_find_decoder ...

    qt_ffmpeg_rtsp_rtsp取流_qtffmpeg流媒体_qt+ffmpeg_QT_qt_ffmpeg_rtsp

    2. **打开RTSP流**: 使用`avformat_open_input()`函数指定RTSP URL,以打开连接到RTSP服务器的流。这需要一个`AVFormatContext`结构体,它是FFmpeg中的核心数据结构,包含了媒体流的所有信息。 3. **读取流信息**: ...

    ffmpeg_dsl_camera.rar_55_ffmpeg_ffmpeg 64_ffmpeg camera_ffmpeg 库

    3. 打开设备:使用 `avformat_open_input()` 函数打开选定的摄像头设备,并通过 `avformat_find_stream_info()` 获取设备的流信息。 4. 分析流:对每个视频流,获取相应的编解码器上下文(`AVCodecContext`),然后...

    simplest_ffmpeg_player.zip_ffmpeg_ffmpeg player C++_ffmpeg 播放器_f

    2. **打开视频文件**:使用 `avformat_open_input()` 打开视频文件。这个函数会根据文件的扩展名和内部元数据选择合适的解封装器。接着,调用 `avformat_find_stream_info()` 获取视频的流信息,如流的数量、类型、...

    ffmpeg探测网络流格式方法源码

    3. 使用FFmpeg的`avformat_open_input`或`avio_open`打开UDP流。 4. 调用`avformat_find_stream_info`来探测流的格式信息,此过程会分析接收到的数据包以识别其类型和编码格式。 5. 设置解码器,开始解码和播放流。 ...

    QT + ffmpeg 播放 rtsp,rtmp,udp视频流

    3. **打开流**:根据不同的流类型,如`avformat_open_input()`函数打开RTSP、RTMP或UDP流。对于RTSP,需要设置相应的URL;RTMP则可能需要服务器地址和流名;UDP流需要指定接收的IP地址和端口。 4. **获取流信息**:...

    ffmpeg-5.0.1-essentials_build(windows)

    FFmpeg 是一个强大的开源命令行工具,用于处理各种多媒体文件,包括视频、音频转换、流媒体处理等。在这个“ffmpeg-5.0.1-essentials_build(windows)”压缩包中,你将找到适用于 Windows 操作系统的 FFmpeg 基础版本...

    simplest_ffmpeg_player_2.zip_ffmpeg sdl_ffmpeg vc_ffmpeg 播放_ffmp

    4. **打开和解码 H264 文件**:使用 FFmpeg 的 avformat_open_input 函数打开视频文件,然后调用 avformat_find_stream_info 解析流信息。找到 H264 视频流后,分配并初始化解码器上下文,然后用 avcodec_decode_...

    FFmpeg.AutoGen-master_c#ffmpeg_FFmpeg.AutoGen_ffmpeg_ladysef_pay

    在"FFmpeg.AutoGen.master_c#ffmpeg_FFmpeg.AutoGen_ffmpeg_ladysef_pay"项目中,"ladysef_pay"可能是指该项目的一个特定分支或特性,可能是针对某种支付场景或者由用户“ladysef”贡献的特殊功能。不过,由于具体...

    ffmpeg analyse document

    `ffmpeg - avformat_open_input.vsd` 文件描绘了`avformat_open_input()`函数的工作流程,这是FFmpeg打开输入文件的核心函数。它涉及查找并加载合适的 demuxer,读取文件头信息,以及初始化内部数据结构。 3. **...

    simplest_ffmpeg_decoder.zip_FFmpeg解码_ffmpeg_ffmpeg visual c_ffmp

    在“simplest_ffmpeg_decoder”中,开发者可能首先会使用`avformat_open_input`打开输入视频文件,然后调用`avformat_find_stream_info`获取文件的流信息,包括流的数量、类型和编码格式。接着,通过`av_find_best_...

Global site tag (gtag.js) - Google Analytics