Using libavformat and libavcodec(1)

本文介绍如何使用FFmpeg的libavformat和libavcodec库来读取视频文件中的视频流,并进行解码。文章通过示例代码详细解释了从初始化到打开文件、获取流信息、寻找解码器直至解码视频帧的全过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

http://www.inb.uni-luebeck.de/~boehme/using_libavcodec.html

 

The libavformat and libavcode libraries that come with ffmpeg are a great way of accessing a large variety of video file formats. Unfortunately, there is no real documentation on using these libraries in your own programs(at least I couldn't find any), and the example programs aren't really very helpful either.

 

 

This situation meant that, when I used libavformat/libavcodec on a recent project, it took quite a lot of experimentation to find out how to use them. Here's what I learned - hopefully I'll be able to save others from having to go through the same trial-and-error process. There's also a small demo program that you can download. The code I'll present works with libavformat/libavcodec as included in version 0.4.8 of ffmpeg (the most recent version as I'm writing this). If you find that later versions break the code, please let me know.

 

In this document, I'll only cover how to read video streams from a file; audio streams work pretty much the same way, but I haven't actually used them, so I can't present any example code.

 

In case you're wondering why there are two libraries, libavformat and libavcodec: Many video file formats(AVI being a prime example) don't actually specify which codec(s) should be used to encode audio and video data; they merely define how an audio and a video stream(or, potentially, several audio/video streams) should be combined into a single file. This  is why sometimes, when you open an AVI file, you get only sound, but no picture - because the right video codec isn't installed on your system. Thus, libavformat deals with parsing video files and separating the streams contained in them, and libavcodec deals with decoding raw audio and video streams.

 

 

Opening a Video File

First things first - let's look at how to open a video file and get at the streams contained in it. The first thing we need to do is to initialize libavformat/libavcodec.

 

This registers all available file formats and codecs with the library so they will be used automatically when a file with the corresponding format/codec is opened. Note that you only need to call av_register_all() once, so it's probably best to do this somewhere in your startup code. If you like, it's possible to register only certain individual file formats and codecs, but there's usually no reason why you would have to do that.

 

Next off, opening the file:

 

The last three parameters specify the file format, buffer size and format parameters; by simply specifying NULL or 0 we ask libavformat to auto-detect the format and use a default buffer size. Replace handle_error() with appropriate error handling code for your application.

 

Next, we need to retrieve information about the streams contained in the file:

 

This fill the streams field of the AVFormatContext with valid information. As a debugging aid, we'll dump this information onto standard error, but of course you don't have to do this in a a production application

 

As mentioned in the introduction, we'll handle only video streams, not audio streams, To make things nice and easy, we simply use the first video stream we find:

 

OK,so now we've got a pointer to the so-called codec context for our video stream, but we still have to find the actual codec and open it:

 

(So what's up with those "truncated bitstreams"? Well, as we'll see in a moment, the data in a video stream is split up into packets. Since the amount of data per video frame can vary, the boundaires between two video frames need to coincide with a packet boundary. Here, we're telling the codec that we can handle this situation.)

 

One important piece of information that is stored in the AVCodeContext structure is the frame rate of the video. To allow for non-integer frame rates (like NTSC's 29.97 fps), the rate is stored as a fraction, with the numerator in pCodecCtx->frame_rate and the denominator in pCodecCtx->frame_rate_base. While testing the library with different video files, I noticed that some codec(notably ASF) seem to fill these fields incorrectly(frame_rate_base contains 1 instead of 1000). The following hack fixes this:

 

Note that it shouldn't be a problem to leave this fix in place even if the bug is corrected some day - it's unlikely that a video would have a frame rate of more than 1000 fps.

One more thing left to do: Allocate a video frame to store the decoded images in:

 

That's it!Now let's start decoding some video.

ed psutil-7.0.0-cp36-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (279 kB) Downloading scipy-1.15.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (35.5 MB) ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 35.5/35.5 MB 14.6 MB/s eta 0:00:00 Downloading tornado-6.5.1-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (443 kB) Downloading absl_py-2.3.1-py3-none-any.whl (135 kB) Using cached jinja2-3.1.6-py3-none-any.whl (134 kB) Using cached MarkupSafe-3.0.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (21 kB) Installing collected packages: tornado, scipy, psutil, ml-dtypes, MarkupSafe, decorator, cloudpickle, attrs, absl-py, jinja2 ERROR: pip's dependency resolver does not currently take into account all the packages that are installed. This behaviour is the source of the following dependency conflicts. op-compile-tool 0.1.0 requires getopt, which is not installed. op-compile-tool 0.1.0 requires inspect, which is not installed. op-compile-tool 0.1.0 requires multiprocessing, which is not installed. Successfully installed MarkupSafe-3.0.2 absl-py-2.3.1 attrs-25.3.0 cloudpickle-3.1.1 decorator-5.2.1 jinja2-3.1.6 ml-dtypes-0.5.1 psutil-7.0.0 scipy-1.15.3 tornado-6.5.1 (wanxiang_env) [root@localhost pythonenv]# sudo yum install -y pkg-config libavformat-dev libavcodec-dev libavdevice-dev libavutil-dev libavfilter-dev libswscale-dev libswresample-dev Repository appstream is listed more than once in the configuration Repository baseos is listed more than once in the configuration Repository extras is listed more than once in the configuration Repository powertools is listed more than once in the configuration github_git-lfs 88 B/s | 833 B 00:09 github_git-lfs-source 155 B/s | 833 B 00:05 软件包 pkgconf-pkg-config-1.4.2-1.el8.aarch64 已安装。 未找到匹配的参数: libavformat-dev 未找到匹配的参数: libavcodec-dev 未找到匹配的参数: libavdevice-dev 未找到匹配的参数: libavutil-dev 未找到匹配的参数: libavfilter-dev 未找到匹配的参数: libswscale-dev 未找到匹配的参数: libswresample-dev 错误:没有任何匹配: libavformat-dev libavcodec-dev libavdevice-dev libavutil-dev libavfilter-dev libswscale-dev libswresample-dev (wanxiang_env) [root@localhost pythonenv]# 报错了
07-18
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值