開始アドレスはさらに間違ってしまいます
この記事は、後の学習とデータ参照を容易にするために、主にFFMPEG の最も重要な構造間の関係に関する一連の記事を統合しています。
構造間のリンク
[外部リンク画像の転送に失敗しました。ソース サイトにはリーチ防止メカニズムがある可能性があります。画像を保存して直接アップロードすることをお勧めします (img-cfJn4l60-1610869259427)(06_struct/struct-relationship.jpeg)]
a) ソリューションプロトコル (http、rtsp、rtmp、mms)
AVIOContext、URLProtocol、および URLContext には、主にビデオとオーディオで使用されるプロトコルの種類とステータスが格納されます。URLProtocol は、入力ビデオとオーディオで使用されるカプセル化形式を保存します。各プロトコルは URLProtocol 構造に対応します。(注: FFMPEG のファイルもプロトコル「ファイル」とみなされます)
b) カプセル化解除 (flv、avi、rmvb、mp4)
AVFormatContext は主にビデオとオーディオのパッケージ形式に含まれる情報を格納し、AVInputFormat は入力ビデオとオーディオで使用されるパッケージ形式を格納します。各ビデオおよびオーディオ パッケージ形式は AVInputFormat 構造に対応します。
c) デコード (h264、mpeg2、aac、mp3)
各 AVStream は、ビデオ/オーディオ ストリームに関連するデータを格納します。各 AVStream は、ビデオ/オーディオ ストリームで使用されるデコード方法に関連するデータを格納する AVCodecContext に対応します。各 AVCodecContext は、ビデオに対応するデコーダを含む AVCodec に対応します。 /オーディオ . 各デコーダは AVCodec 構造に対応します。
d) セーブデータ
ビデオの場合、各構造には通常 1 つのフレームが格納されます。オーディオには複数のフレームが含まれる場合があります。
デコード前のデータ: AVPacket
、デコード後のデータ: AVFrame
AVFrame (libavutil/frame.h)
AVFrame は、多くのストリーム パラメーターを含む構造体です。AVFrame 構造は通常、生データ (つまり、YUV、ビデオの RGB、オーディオの PCM などの非圧縮データ) を格納するために使用され、いくつかの関連情報も含まれています。例えば、マクロブロックタイプテーブル、QPテーブル、動きベクトルテーブルなどのデータが復号化時に保存される。関連データもエンコード中に保存されます。したがって、FFMPEG をストリーム解析に使用する場合、AVFrame は非常に重要な構造になります。
#define AV_NUM_DATA_POINTERS 8
- uint8_t *data[AV_NUM_DATA_POINTERS] : デコードされた生データ (YUV、ビデオの場合は RGB、オーディオの場合は PCM)
- int linesize[AV_NUM_DATA_POINTERS] : data 内のデータの「1 行」のサイズ。注: これは必ずしも画像の幅と等しいわけではなく、通常は画像の幅よりも大きくなります。
- int width, height : ビデオフレームの幅と高さ (1920x1080,1280x720…)
- int nb_samples : オーディオの AVFrame には複数のオーディオ フレームが含まれる場合があり、このタグには複数のオーディオ フレームが含まれます。
- int 形式: デコード後の元のデータ型 (YUV420、YUV422、RGB24…)、不明または -1 に設定されていません。
- int key_frame : キーフレームかどうか
- enum AVPictureType pict_type : フレームタイプ (I、B、P...)
- AVRational sample_aspect_ratio:宽高比(16:9,4:3…)
- int64_t pts : タイムスタンプを表示します
- int coded_picture_number : コード化されたフレーム番号
- int display_picture_number : 表示フレーム番号
- int8_t *qscale_table:QP表
- int Channels : オーディオチャンネルの数
- int interlaced_frame : インターレースかどうか
このうち、sample_aspect_ratio アスペクト比はスコアであり、AVRational構造は次のとおりです。
typedef struct AVRational{
int num; ///< Numerator 分子
int den; ///< Denominator 分母
} AVRational;
QP テーブルqscale_table :
QP テーブルは、各マクロブロックの QP 値を格納するメモリを指します。マクロブロックのラベルは、左から右の順に 1 行ずつ表示されます。各マクロブロックは 1 QP に対応します。qscale_table[0] は行 1、列 1 のマクロブロックの QP 値、qscale_table[1] は行 1、列 2 のマクロブロックの QP 値、qscale_table[2] は行 1 のマクロブロックの QP 値です。列 3 。など...
マクロブロックの数は次の式で計算されます (注: マクロブロックのサイズは 16x16)、各行のマクロブロックの数:
int mb_stride = pCodecCtx->幅/16+1
マクロブロックの総数:
int mb_sum = ((pCodecCtx->高さ+15)>>4)*(pCodecCtx->幅/16+1)
AVFormatContext (libavformat/avformat.h)
FFMPEG で開発する場合、AVFormatContext は全体のデータ構造であり、多くの関数がこれをパラメータとして使用します。FFMPEGのカプセル化解除(flv、mp4、rmvb、avi)関数の構造です。(ここではデコードの場合を考えてみましょう)
- AVInputFormat *iformat : 入力コンテナ形式データ
- AVOutputFormat *oformat : 出力コンテナ形式データ
- AVIOContext *pb : 入力データ用のバッファー
- AVIOContext *pb : 入力データ用のバッファー
- unsigned int nb_streams : ビデオおよびオーディオ ストリームの数
- AVStream **ストリーム: ビデオおよびオーディオ ストリーム
- char ファイル名[1024] : ファイル名
- char *url : 入出力URL
- int64_t 持続時間: 持続時間 (単位: マイクロ秒 us、秒に変換するには 1000000 で割る必要があります)
- int bit_rate : ビットレート (単位は bps、kbps に変換するには 1000 で割る必要があります)
- int packet_size : パケットの長さ
- AVDictionary *metadata : メタデータ
このうち、ビデオのメタデータは av_dict_get() 関数を通じて取得されます。AVDictionary および AVDictionaryEntry にカプセル化されます。
struct AVDictionary {
int count;
AVDictionaryEntry *elems;
};
typedef struct AVDictionaryEntry {
char *key;
char *value;
} AVDictionaryEntry;
AVStream(libavformat/avformat.h)
AVStream は、各ビデオ/オーディオ ストリームに関する情報を格納する構造です。
- int Index : ビデオ/オーディオ ストリームを識別します (AVFormatContext 内)
- AVCodecContext *codec : ビデオ/オーディオ ストリームの AVCodecContext へのポイント (両者は 1 対 1 対応)
- AVRational time_base : タイムベース。この値により、PTS と DTS をリアルタイムに変換できます。このフィールドは FFMPEG の他の構造でも使用できますが、私の経験によれば、AVStream の time_base のみが使用可能です。PTS*time_base=リアルタイム
- int64_t period : ビデオ/オーディオ ストリームの長さ
- int64_t nb_frames : 既知の場合、このストリーム内のフレーム数
- AVDictionary *metadata : メタデータ情報
- AVRational avg_frame_rate : フレーム レート (注: ビデオの場合、これは非常に重要です)
- AVPacketattached_pic : 添付された画像。たとえば、一部の MP3、AAC オーディオ ファイルに添付されたアルバム アートなどです。
AVIOContext (libavformat/avio.h)
AVIOContext は、FFMPEG が入出力データを管理するための構造です。
- unsigned char *buffer : バッファ開始位置
- int bug_size : バッファ サイズ (デフォルト 32768)
- unsigned char *buf_ptr : 現在のポインタによって読み取られる位置
- unsigned char *buf_end : バッファの終了場所
- * void opaque : URLContext 構造体
その中で、opaqueが指す URLContext は次のとおりです。
typedef struct URLContext {
const AVClass *av_class; /**< information for av_log(). Set by url_open(). */
const struct URLProtocol *prot;
void *priv_data;
char *filename; /**< specified URL */
int flags;
int max_packet_size; /**< if non zero, the stream is packetized with this max packet size */
int is_streamed; /**< true if streamed (no seek possible), default = false */
int is_connected;
AVIOInterruptCB interrupt_callback;
int64_t rw_timeout; /**< maximum time to wait for (network) read/write operation completion, in mcs */
const char *protocol_whitelist;
const char *protocol_blacklist;
int min_packet_size; /**< if non zero, the stream is packetized with this min packet size */
} URLContext;
URLContext 構造体には URLProtocol 構造体もあります。注: 各プロトコル (rtp、rtmp、file など) は URLProtocol に対応します。この構造は、FFMPEG が提供するヘッダー ファイルにもありません。FFMPEG ソース コードからその定義を見つけます。
typedef struct URLProtocol {
const char *name;
int (*url_open)( URLContext *h, const char *url, int flags);
int (*url_open2)(URLContext *h, const char *url, int flags, AVDictionary **options);
int (*url_accept)(URLContext *s, URLContext **c);
int (*url_handshake)(URLContext *c);
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);
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 (*url_get_multi_file_handle)(URLContext *h, int **handles,
int *numhandles);
int (*url_get_short_seek)(URLContext *h);
int (*url_shutdown)(URLContext *h, int flags);
int priv_data_size;
const AVClass *priv_data_class;
int flags;
int (*url_check)(URLContext *h, int mask);
int (*url_open_dir)(URLContext *h);
int (*url_read_dir)(URLContext *h, AVIODirEntry **next);
int (*url_close_dir)(URLContext *h);
int (*url_delete)(URLContext *h);
int (*url_move)(URLContext *h_src, URLContext *h_dst);
const char *default_whitelist;
} URLProtocol;
AVCodecContext (libavcodec/avcodec.h)
AVCodecContext はより多くの変数を含む構造体です (最も変数が多い構造体に近いと感じます)。この記事では、構造内の各変数の意味と機能を簡単に分析します。(ここではデコードのみを考慮します)
- enum AVMediaType codec_type : コーデックのタイプ (ビデオ、オーディオ、字幕など)
- struct AVCodec *codec : 使用されるデコーダ AVCodec (H.264、MPEG2...)
- int bit_rate : 平均ビットレート
- uint8_t *extradata; int extradata_size : 特定のエンコーダーに含まれる追加情報 (H.264 デコーダー、ストア SPS、PPS など)
- AVRational time_base : このパラメータに従って、PTS を実際の時間 (秒単位) に変換できます。
- int width, height : ビデオの場合、幅と高さを表します。
- int refs : 動き推定のための参照フレームの数 (H.264 には複数のフレームが存在し、一般に MPEG2 などは存在しません)
- int sample_rate : サンプルレート (オーディオ)
- int Channels : チャンネル数 (オーディオ)
- enum AVSampleFormat sample_fmt : サンプリング形式
- int Frame_size : フレーム内の各チャネルのサンプリング レート (オーディオ)
- int profile : type (H.264 では、他のエンコーディング標準も必要です)
- int level : レベル (プロファイルとあまり変わらない)
その内、 1. コーデックの種類: codec_type
enum AVMediaType {
AVMEDIA_TYPE_UNKNOWN = -1, ///< Usually treated as AVMEDIA_TYPE_DATA
AVMEDIA_TYPE_VIDEO,
AVMEDIA_TYPE_AUDIO,
AVMEDIA_TYPE_DATA, ///< Opaque data information usually continuous
AVMEDIA_TYPE_SUBTITLE,
AVMEDIA_TYPE_ATTACHMENT, ///< Opaque data information usually sparse
AVMEDIA_TYPE_NB
};
2. FFMPEG のオーディオ サンプリング形式: sample_fmt
enum AVSampleFormat {
AV_SAMPLE_FMT_NONE = -1,
AV_SAMPLE_FMT_U8, ///< unsigned 8 bits
AV_SAMPLE_FMT_S16, ///< signed 16 bits
AV_SAMPLE_FMT_S32, ///< signed 32 bits
AV_SAMPLE_FMT_FLT, ///< float
AV_SAMPLE_FMT_DBL, ///< double
AV_SAMPLE_FMT_U8P, ///< unsigned 8 bits, planar
AV_SAMPLE_FMT_S16P, ///< signed 16 bits, planar
AV_SAMPLE_FMT_S32P, ///< signed 32 bits, planar
AV_SAMPLE_FMT_FLTP, ///< float, planar
AV_SAMPLE_FMT_DBLP, ///< double, planar
AV_SAMPLE_FMT_S64, ///< signed 64 bits
AV_SAMPLE_FMT_S64P, ///< signed 64 bits, planar
AV_SAMPLE_FMT_NB ///< Number of sample formats. DO NOT USE if linking dynamically
};
3.FFMPEG中型:profile
#define FF_PROFILE_UNKNOWN -99
#define FF_PROFILE_RESERVED -100
#define FF_PROFILE_AAC_MAIN 0
#define FF_PROFILE_AAC_LOW 1
#define FF_PROFILE_AAC_SSR 2
#define FF_PROFILE_AAC_LTP 3
#define FF_PROFILE_AAC_HE 4
#define FF_PROFILE_AAC_HE_V2 28
#define FF_PROFILE_AAC_LD 22
#define FF_PROFILE_AAC_ELD 38
#define FF_PROFILE_DTS 20
#define FF_PROFILE_DTS_ES 30
#define FF_PROFILE_DTS_96_24 40
#define FF_PROFILE_DTS_HD_HRA 50
#define FF_PROFILE_DTS_HD_MA 60
#define FF_PROFILE_MPEG2_422 0
#define FF_PROFILE_MPEG2_HIGH 1
#define FF_PROFILE_MPEG2_SS 2
#define FF_PROFILE_MPEG2_SNR_SCALABLE 3
#define FF_PROFILE_MPEG2_MAIN 4
#define FF_PROFILE_MPEG2_SIMPLE 5
#define FF_PROFILE_H264_CONSTRAINED (1<<9) // 8+1; constraint_set1_flag
#define FF_PROFILE_H264_INTRA (1<<11) // 8+3; constraint_set3_flag
#define FF_PROFILE_H264_BASELINE 66
#define FF_PROFILE_H264_CONSTRAINED_BASELINE (66|FF_PROFILE_H264_CONSTRAINED)
#define FF_PROFILE_H264_MAIN 77
#define FF_PROFILE_H264_EXTENDED 88
#define FF_PROFILE_H264_HIGH 100
#define FF_PROFILE_H264_HIGH_10 110
#define FF_PROFILE_H264_HIGH_10_INTRA (110|FF_PROFILE_H264_INTRA)
#define FF_PROFILE_H264_HIGH_422 122
#define FF_PROFILE_H264_HIGH_422_INTRA (122|FF_PROFILE_H264_INTRA)
#define FF_PROFILE_H264_HIGH_444 144
#define FF_PROFILE_H264_HIGH_444_PREDICTIVE 244
#define FF_PROFILE_H264_HIGH_444_INTRA (244|FF_PROFILE_H264_INTRA)
#define FF_PROFILE_H264_CAVLC_444 44
#define FF_PROFILE_VC1_SIMPLE 0
#define FF_PROFILE_VC1_MAIN 1
#define FF_PROFILE_VC1_COMPLEX 2
#define FF_PROFILE_VC1_ADVANCED 3
#define FF_PROFILE_MPEG4_SIMPLE 0
#define FF_PROFILE_MPEG4_SIMPLE_SCALABLE 1
#define FF_PROFILE_MPEG4_CORE 2
#define FF_PROFILE_MPEG4_MAIN 3
#define FF_PROFILE_MPEG4_N_BIT 4
#define FF_PROFILE_MPEG4_SCALABLE_TEXTURE 5
#define FF_PROFILE_MPEG4_SIMPLE_FACE_ANIMATION 6
#define FF_PROFILE_MPEG4_BASIC_ANIMATED_TEXTURE 7
#define FF_PROFILE_MPEG4_HYBRID 8
#define FF_PROFILE_MPEG4_ADVANCED_REAL_TIME 9
#define FF_PROFILE_MPEG4_CORE_SCALABLE 10
#define FF_PROFILE_MPEG4_ADVANCED_CODING 11
#define FF_PROFILE_MPEG4_ADVANCED_CORE 12
#define FF_PROFILE_MPEG4_ADVANCED_SCALABLE_TEXTURE 13
#define FF_PROFILE_MPEG4_SIMPLE_STUDIO 14
#define FF_PROFILE_MPEG4_ADVANCED_SIMPLE 15
AVコーデック(libavcodec/avcodec.h)
AVCodec は、コーデック情報を格納する構造体です。
- const char *name : コーデックの名前 (比較的短い)
- const char *long_name : コーデックの名前、フルネーム、比較的長い
- enum AVMediaType type : ビデオ、オーディオ、または字幕のタイプを示します。
- enum AVCodecID id : ID、重複なし
- const AVRational *supported_framerates : サポートされているフレームレート (ビデオのみ)
- const enum AVPixelFormat *pix_fmts : サポートされているピクセル形式 (ビデオのみ)
- const int *supported_samplerates : サポートされているサンプル レート (オーディオのみ)
- const enum AVSampleFormat *sample_fmts : サポートされているサンプル形式 (オーディオのみ)
- const uint64_t *channel_layouts : サポートされるチャンネル数 (オーディオのみ)
- int priv_data_size : プライベートデータのサイズ
その中で、AVMediaType構造は次のとおりです。
enum AVMediaType {
AVMEDIA_TYPE_UNKNOWN = -1, ///< Usually treated as AVMEDIA_TYPE_DATA
AVMEDIA_TYPE_VIDEO,
AVMEDIA_TYPE_AUDIO,
AVMEDIA_TYPE_DATA, ///< Opaque data information usually continuous
AVMEDIA_TYPE_SUBTITLE,
AVMEDIA_TYPE_ATTACHMENT, ///< Opaque data information usually sparse
AVMEDIA_TYPE_NB
};
AVCodecID構造:
enum AVCodecID {
AV_CODEC_ID_NONE,
/* video codecs */
AV_CODEC_ID_MPEG1VIDEO,
AV_CODEC_ID_MPEG2VIDEO, ///< preferred ID for MPEG-1/2 video decoding
AV_CODEC_ID_H261,
AV_CODEC_ID_H263,
//...(代码太长,略)
}
AVPixelFormat構造体:
enum AVPixelFormat {
AV_PIX_FMT_NONE = -1,
AV_PIX_FMT_YUV420P, ///< planar YUV 4:2:0, 12bpp, (1 Cr & Cb sample per 2x2 Y samples)
AV_PIX_FMT_YUYV422, ///< packed YUV 4:2:2, 16bpp, Y0 Cb Y1 Cr
AV_PIX_FMT_RGB24, ///< packed RGB 8:8:8, 24bpp, RGBRGB...
//...(代码太长,略)
}
AVPacket(libavcodec/avcodec.h)
AVPacket は、圧縮符号化データに関する情報を格納する構造体です。たとえば、H.264 の場合。通常、1 AVPacket のデータが NAL に相当します。注: ここでは単なる対応関係を示しており、まったく同じではありません。それらの間にはわずかな違いがあります。FFMPEG クラス ライブラリを使用して、マルチメディア ファイル内の H.264 ストリームを分離します。したがって、FFMPEG をビデオおよびオーディオ処理に使用する場合、多くの場合、取得した AVPacket データをファイルに直接書き込むことで、ビデオおよびオーディオ コード ストリーム ファイルを取得できます。
- int64_t pts : タイムスタンプを表示します
- int64_t dts : デコードされたタイムスタンプ
- uint8_t *data : 圧縮符号化データ
- int size : データのサイズ
- int stream_index : AVPacket が属するビデオ/オーディオ ストリームを識別します。