目次
FFmpegライブラリの紹介
FFmpeg関数の紹介
FFmpeg関数の紹介-パッケージフォーマット関連
FFmpegデコード機能の紹介-デコーダー関連
FFmpeg3.xコンポーネント登録方法
FFmpeg4.xコンポーネントの登録方法
Ffmpeg4.0.2コンポーネント登録方法
FFmpegデータ構造の紹介
FFmpegデータ構造間の関係
AVFormatContextとAVInputFormatの関係
AVCodecContextとAVCodecの関係
FFmpegデータ構造間の関係
FFmpegデータ構造分析
FFmpegライブラリの紹介
- FFMPEGには8つの一般的に使用されるライブラリがあります:
AVUtil |
コアツールライブラリ、以下の他の多くのモジュールは、いくつかの基本的なオーディオおよびビデオ処理操作を行うためにこのライブラリに依存します。 |
AVFormat |
ファイル形式とプロトコルライブラリ。このモジュールは最も重要なモジュールの1つであり、プロトコルレイヤー、Demuxerレイヤー、Muxerレイヤーをカプセル化して、プロトコルとフォーマットを開発者に透過的にします。 |
AVCodec |
コーデックライブラリはコーデックレイヤーをカプセル化しますが、一部のコーデックには独自のライセンスがあります。FFmpegはデフォルトでlibx264、FDK-AACなどのライブラリを追加しませんが、FFmpegはプラットフォームのようなものであり、他のサードパーティが使用できます。コーデックプラグインの形で追加され、開発者に統一されたインターフェイスを提供します。 |
AVFilter |
オーディオとビデオのフィルターライブラリ、このモジュールはオーディオの特殊効果とビデオの特殊効果を含む処理を提供します。FFmpegAPIを使用したエンコードとデコードのプロセスでは、このモジュールを直接使用してオーディオとビデオの特殊効果を実行するのは非常に便利で非常に効率的です。データ。メソッド。 |
AVDevice |
入出力デバイスライブラリ。たとえば、サウンドまたはビデオを再生するためにツールffplayをコンパイルする必要がある場合は、モジュールがオンになっていることを確認する必要があります。また、デバイスモジュールはSDLをプリコンパイルする必要があります。サウンドおよびビデオ再生用のSDLライブラリ。 |
SwrRessample |
リサンプリングモジュールは、オーディオに使用することができ、デジタルオーディオは、デジタルチャネルの周波数、データフォーマット、サンプルレートの複数の基本的な変換情報などに使用することができる。 |
SWScale |
このモジュールは、画像フォーマットを変換するモジュールです。たとえば、YUVデータをRGBデータに変換したり、ズームサイズを1280 * 720から800 * 480に変更したりできます。 |
PostProc |
このモジュールは後処理に使用できます。AVFilterを使用する場合、このモジュールのいくつかの基本機能がFilterで使用されるため、このモジュールのスイッチをオンにする必要があります。 |
FFmpeg関数の紹介
av_register_all() |
すべてのコンポーネントを登録します。4.0は非推奨になりました |
avdevice_register_all() |
V4L2などのデバイスを登録します。 |
avformat_network_init(); |
ネットワークライブラリとネットワーク暗号化プロトコルに関連するライブラリ(opensslなど)を初期化します |
FFmpeg関数の紹介-パッケージフォーマット関連
avformat_alloc_context() |
AVFormatContext構造のメモリを申請し、簡単な初期化を実行する責任があります |
avformat_free_context() |
構造内のすべてと構造自体を解放します |
avformat_close_input() |
デマルチプレクサをオフにします。閉じた後、リリースするためにavformat_free_contextを使用する必要はなくなりました。 |
avformat_open_input() |
入力オーディオおよびビデオファイルを開く |
avformat_find_stream_info() |
オーディオおよびビデオファイル情報を取得する |
av_read_frame() |
オーディオとビデオのパッケージを読む |
avformat_seek_file() |
ポジショニングファイル(時間でポジショニング可能) |
av_seek_frame() |
ファイルを見つけます(ファイルサイズで見つけることができます) |
FFmpegデコード機能の紹介-デコーダー関連
avcodec_alloc_context3() |
デコーダーコンテキストを割り当てる |
avcodec_find_decoder() |
IDに基づいてデコーダーを検索する |
avcodec_find_decoder_by_name() |
デコーダー名によると |
avcodec_open2() |
コーデックを開く |
avcodec_decode_video2() |
解码一帧视频数据(不建议使用) |
avcodec_decode_audio4() |
解码一帧音频数据(不建议使用) |
avcodec_send_packet() |
发送编码数据包 |
avcodec_receive_frame() |
接收解码后数据 |
avcodec_free_context() |
释放解码器上下文,包含了avcodec_close() |
avcodec_close() |
关闭解码器 |
- avcodec_find_decoder():
- avcodec_find_decoder_by_name():
- 根据指定的名字查找,如果找不到指定名字,就是没有找到。
- 如果上下文保存在解码器里面,多路解码的时候肯定有冲突。
- 设计解码器要做到可重入,通过AVCodexContex保存解码后的上下文数据
- AVCodexContex,avcosex_open2():让解码器和上下文做关联。
FFmpeg 3.x 组件注册方式
- 使用ffmpeg,首先要执行av_register_all,把全局的解码器、编码器等结构体注册到各自全局的对象链表里,以便后面查找调用
FFmpeg 4.x 组件注册方式
- FFmpeg内部去做,不需要用户调用API去注册。
- 以codec编解码器为例:
./configure:7203:print_enabled_components libavcodec/codec_list.c AVCodec codec_list $CODEC_LIST
- 这里会生成一个codec_list.c 文件,里面只有static const AVCodec * const codec_list[]数组。
- 2. 在libavcodec/allcodecs.c将static const AVCodec * const codec_list[]的编解码器用链表的方式组织起来
Ffmpeg 4.0.2 组件注册方式
- FFmepg内部去做,不需要用户调用API去注册。
- 对于demuxer/muxer(解复用器,也称容器)则对应
- 1. libavformat/muxer_list.c
- libavformat/demuxer_list.c 这两个文件也是在configure的时候生成,也就是说直接下载源码是没有这两个文件的。
- 2. 在libavformat/allformats.c将demuxer_list[]和muexr_list[]以链表的方式组织。
- 其他组件也是类似的方式
FFmpeg数据结构简介
AVFormatContext |
封装格式上下文结构体,也是统领全局的结构体,保存了视频文件封装格式相关信息。 |
AVInputFormat demuxer AVOutputFormat muxer |
每种封装格式(例如FLV, MKV, MP4, AVI)对应一个该结构体。 |
AVStream |
视频文件中每个视频(音频)流对应一个该结构体。 |
AVCodecContext |
编解码器上下文结构体,保存了视频(音频)编解码相关信息。 |
AVCodec |
每种视频(音频)编解码器(例如H.264解码器)对应一个该结构体。 |
AVPacket |
存储一帧压缩编码数据。 |
AVFrame |
存储一帧解码后像素(采样)数据。 |
FFmpeg数据结构之间的关系
AVFormatContext和AVInputFormat之间的关系
- AVFormatContext API调用
- AVInputFormat 主要是FFMPEG内部调用
- 数据
- AVFormatContext 封装格式上下文结构体
- struct AVInputFormat *iformat;
- 方法:所有的方法可重入的
- AVInputFormat 每种封装格式(例如FLV, MKV, MP4)
- int (*read_header)(struct AVFormatContext *);
- int (*read_packet)(struct AVFormatContext *, AVPacket *pkt);
int avformat_open_input(AVFormatContext **ps, const char *filename,
AVInputFormat *fmt, AVDictionary **options)
AVCodecContext和AVCodec之间的关系
- 数据
- AVCodecContext 编码器上下文结构体
- struct AVCodec *codec;
- 方法:
int (*decode)(AVCodecContext *, void *outdata, int *outdata_size, AVPacket *avpkt);
int (*encode2)(AVCodecContext *avctx, AVPacket *avpkt, const AVFrame *frame, int *got_packet_ptr);
FFmpeg数据结构之间的关系
- AVFormatContext, AVStream和AVCodecContext之间的关系
- 区分不同的码流(AVPacket 里面也有一个index的字段)
video_index = av_find_best_stream(ic, AVMEDIA_TYPE_VIDEO, -1,-1, NULL, 0)
audio_index = av_find_best_stream(ic, AVMEDIA_TYPE_AUDIO, -1,-1, NULL, 0)
FFmpeg数据结构分析
iformat |
输入媒体的AVInputFormat,比如指向AVInputFormatff_flv_demuxer |
nb_streams |
输入媒体的AVStream 个数 |
streams |
输入媒体的AVStream []数组 |
duration |
输入媒体的时长(以微秒为单位),计算方式可以参考av_dump_format()函数 |
bit_rate |
输入媒体的码率 |
name |
封装格式名称 |
extensions |
封装格式的扩展名 |
id |
封装格式ID |
一些封装格式处理的接口函数 |
比如read_packet() |
index |
标识该视频/音频流 |
time_base |
该流的时基, PTS*time_base=真正的时间(秒) |
avg_frame_rate |
该流的帧率 |
duration |
该视频/音频流长度 |
codecpar |
编解码器参数属性 |
codec_type |
媒体类型,比如AVMEDIA_TYPE_VIDEO AVMEDIA_TYPE_AUDIO等 |
codec_id |
编解码器类型, 比如AV_CODEC_ID_H264 AV_CODEC_ID_AAC |
codec |
编解码器的AVCodec,比如指向AVCodecff_aac_latm_decoder |
width, height |
图像的宽高(只针对视频) |
pix_fmt |
像素格式(只针对视频) |
sample_rate |
采样率(只针对音频) |
channels |
声道数(只针对音频) |
sample_fmt |
采样格式(只针对音频) |
name |
编解码器名称 |
type |
编解码器类型 |
id |
编解码器ID |
一些编解码的接口函数 |
比如int (*decode)() |
pts |
显示时间戳 |
dts |
解码时间戳 |
data |
压缩编码数据 |
size |
压缩编码数据大小 |
pos |
数据的偏移地址 |
stream_index |
所属的AVStream |
data |
解码后的图像像素数据(音频采样数据) |
linesize |
对视频来说是图像中一行像素的大小;对音频来说是整个音频帧的大小 |
width, height |
图像的宽高(只针对视频) |
key_frame |
是否为关键帧(只针对视频) |
pict_type |
帧类型(只针对视频) 。例如I, P, B |
sample_rate |
音频采样率(只针对音频) |
nb_samples |
音频每通道采样数(只针对音频) |
pts |
显示时间戳 |