Day02 ffmpeg打开文件

1. 打开文件的原形定义如下:
/**
 * Open an input stream and read the header. The codecs are not opened.
 * The stream must be closed with avformat_close_input().
 *
 * @param ps Pointer to user-supplied AVFormatContext (allocated by avformat_alloc_context).
 *           May be a pointer to NULL, in which case an AVFormatContext is allocated by this
 *           function and written into ps.
 *           Note that a user-supplied AVFormatContext will be freed on failure.
 * @param url URL of the stream to open.
 * @param fmt If non-NULL, this parameter forces a specific input format.
 *            Otherwise the format is autodetected.
 * @param options  A dictionary filled with AVFormatContext and demuxer-private options.
 *                 On return this parameter will be destroyed and replaced with a dict containing
 *                 options that were not found. May be NULL.
 *
 * @return 0 on success, a negative AVERROR on failure.
 *
 * @note If you want to use custom IO, preallocate the format context and set its pb field.
 */
int avformat_open_input(AVFormatContext **ps, const char *url,
                        const AVInputFormat *fmt, AVDictionary **options);

avformat_open_input() 是 FFmpeg 中用于打开多媒体文件并初始化 AVFormatContext 的函数。它主要负责以下几件事情:

1. 打开文件

  • 文件路径解析:根据传入的文件路径,avformat_open_input() 会尝试打开对应的文件。如果路径无效或文件不存在,函数会返回错误。
  • 文件句柄创建:如果文件成功打开,FFmpeg 会为该文件创建一个文件句柄(AVIOContext),用于后续的读取操作。

2. 探测文件格式

  • 格式探测:avformat_open_input() 会尝试探测文件的格式。FFmpeg 内置了多种文件格式的探测器(如 MP4、AVI、MKV、FLV 等),通过读取文件的头部信息(如文件签名或魔数),确定文件的容器格式,并不会初始化codec相关参数
  • 分配 AVFormatContext:一旦文件格式被探测到,FFmpeg 会分配一个 AVFormatContext 结构体,并将其与文件句柄关联。AVFormatContext 是 FFmpeg 中用于管理多媒体文件的上下文结构,包含了文件的格式信息、流信息等。

3. 初始化文件读取

  • 初始化输入流:avformat_open_input() 会初始化文件的输入流,准备好后续的读取操作。这包括设置文件的读取缓冲区、初始化文件的 I/O 操作等。
  • 设置文件格式处理:根据探测到的文件格式,FFmpeg 会加载对应的文件格式处理模块(AVInputFormat)。这个模块包含了处理该文件格式所需的函数和数据结构,例如如何解析文件头、如何读取流信息等。

4. 返回 AVFormatContext

  • 返回上下文指针:如果文件成功打开并且格式探测成功,avformat_open_input() 会返回一个指向 AVFormatContext 的指针。这个指针可以用于后续的文件处理操作,如读取流信息、解码数据等。
  • 错误处理:如果文件打开失败或格式探测失败,函数会返回错误码(如 AVERROR(EIO)AVERROR(ENOSYS)),并且 AVFormatContext 指针为 nullptr

 2. 获取媒体文件流信息, 原型如下:

/**
 * Read packets of a media file to get stream information. This
 * is useful for file formats with no headers such as MPEG. This
 * function also computes the real framerate in case of MPEG-2 repeat
 * frame mode.
 * The logical file position is not changed by this function;
 * examined packets may be buffered for later processing.
 *
 * @param ic media file handle
 * @param options  If non-NULL, an ic.nb_streams long array of pointers to
 *                 dictionaries, where i-th member contains options for
 *                 codec corresponding to i-th stream.
 *                 On return each dictionary will be filled with options that were not found.
 * @return >=0 if OK, AVERROR_xxx on error
 *
 * @note this function isn't guaranteed to open all the codecs, so
 *       options being non-empty at return is a perfectly normal behavior.
 *
 * @todo Let the user decide somehow what information is needed so that
 *       we do not waste time getting stuff the user does not need.
 */
int avformat_find_stream_info(AVFormatContext *ic, AVDictionary **options);
avformat_find_stream_info() 是 FFmpeg 中的一个关键函数,用于从打开的多媒体文件中提取流信息。它通常在 avformat_open_input() 成功打开文件后调用,用于进一步分析文件内容,获取关于文件中各个流(如视频流、音频流、字幕流等)的详细信息。

主要功能

  1. 流探测:
    • avformat_find_stream_info() 会扫描文件,探测文件中包含的所有流(音频流、视频流、字幕流等)。
    • 它会尝试读取文件的头部信息和部分数据,以确定文件中包含的流的数量和类型。
  2. 流参数解析:
    • 对于每个流,函数会解析流的编解码器参数(如编解码器类型、编解码器ID、视频分辨率、音频采样率等)。
    • 这些参数会被存储在 AVFormatContextstreams 数组中,每个流对应一个 AVStream 结构体。
  3. 编解码器初始化:
    • 函数会根据流的编解码器参数,初始化对应的编解码器(如果需要)。
    • 这包括设置编解码器的上下文(AVCodecContext),为后续的编解码操作做准备。
  4. 时间戳和帧率信息:
    • 对于视频流,函数会尝试解析帧率信息(如帧率、时间戳等)。
    • 对于音频流,函数会解析采样率、声道数等信息。
  5. 更新 AVFormatContext
    • 函数会更新 AVFormatContext 的相关字段,如 nb_streams(流的数量)、duration(文件总时长)等。

 

posted @ 2025-04-25 20:13  笑不出花的旦旦  阅读(40)  评论(0)    收藏  举报