[FFmpeg 戦闘] H264 ビデオ エンコード

転載元: https://cloud.tencent.com/developer/article/1153356

H264ビデオ符号化技術は、シーケンスフレーム画像を圧縮する技術です。冗長データが存在するため、圧縮が可能です。ビデオシーケンスのフレーム画像の冗長データには主に次のようなものがあります。

  • 空間的冗長性: 同じ物体表面上のサンプリング点の色は空間的連続性を持ち、同一または類似しています。
  • 時間的冗長性: 連続した写真間には相関関係があり、たとえば部屋で二人が会話している場合、背景は変化せず、人物の位置と動きだけが変化します。
  • 構造の冗長性: 特定の構造は、ハニカム、市松模様の床など、単純な画像パターンの繰り返しです。
  • 知識の冗長性: 特定のイメージの理解は知識に関連しています。例えば、人間の顔は、目、鼻、口などの構造が一定の位置に配置されています。固定構造を持つ画像要素のモデルを構築し、それを画像ライブラリと組み合わせて、わずかなパラメータだけで特徴付けることができます。
  • 視覚的な冗長性: 画像フィールドに対する人間の目の感度は不均一かつ非線形です。彩度には比較的鈍感ですが、明るさにはより敏感です。高輝度領域では、明るさの変化に対する人間の目の感度が低下します。オブジェクトのエッジには敏感ですが、内部領域には鈍感です。これらの視覚的特徴に基づいて画像情報を選択することができる。

H264 は、ITU-T の VCEG と ISO/IEC の MPEG のジョイント ビデオ チーム (JVT) によって開発されたデジタル ビデオ コーディング規格で、2003 年 3 月に正式にリリースされました。ネットワークに適した構造と構文を採用しており、ビット エラーやパケット損失の処理に役立ちます。符号化技術に関しては、統一 VLC シンボル符号化、高精度マルチモード変位推定、4X4 ブロックに基づく整数変換、階層符号化構文などにより、H264 アルゴリズムは高い符号化効率を実現しています。導入された複雑なエンコード アルゴリズムによりエンコードのパフォーマンスが低下し、リアルタイム エンコードに課題が生じます。エンコード処理時間は、主にエンコード アルゴリズムの実装とハードウェア アクセラレーションの最適化によって短縮されます。

x264 は、H264 エンコーディングを実装するために VideoLAN 組織によって実装されたオープン ソース ライブラリです。ソース コードは から入手できますgit clone http://git.videolan.org/git/x264.git

オープンソース ライブラリ x264 を使用したエンコード

エンコードパラメータを構成する

エンコーディングパラメータは構造体を通じて設定されますx264_param_tint x264_param_default_preset( x264_param_t *param, const char *preset, const char *tune )プリセットパラメータは関数を通じて取得できます。

x264_param_t param;
x264_param_default_preset(¶m, "medium", NULL);

次に、プリセットパラメータに基づいて、必要に応じて特定のパラメータを変更できます。

param.i_csp = X264_CSP_I420;
param.i_width = width;
param.i_height = height;
param.b_vfr_input = 0;
param.b_repeat_headers = 1;
param.b_annexb = 1;

i_csp は入力フレームのカラー形式を指定し、i_width と i_height はフレームのサイズを指定します。b_vfr_input はレート制御の基準を指定します。0 はフレーム レート設定に基づき、1 は各フレームのタイムスタンプに基づきます。b_repeat_headers は 1 で、SPS と PPS が各キー フレームの前に追加されることを指定します。b_annexb は 1 で、各 NAL ユニットの先頭に 4 ビットの開始コードを追加することを意味します。

設定を有効にし、プロファイルを指定します。

x264_param_apply_profile(¶m, "high");x264_encoder_open(¶m );

エンコードする入力画像フレーム

入力フレームのデータは構造体で表現されますx264_picture_t

typedef struct x264_picture_t{
    
        /* In: force picture type (if not auto)
     *     If x264 encoding parameters are violated in the forcing of picture types,
     *     x264 will correct the input picture type and log a warning.
     * Out: type of the picture encoded */
    int     i_type;    /* In: force quantizer for != X264_QP_AUTO */
    int     i_qpplus1;    /* In: pic_struct, for pulldown/doubling/etc...used only if b_pic_struct=1.
     *     use pic_struct_e for pic_struct inputs
     * Out: pic_struct element associated with frame */
    int     i_pic_struct;    /* Out: whether this frame is a keyframe.  Important when using modes that result in
     * SEI recovery points being used instead of IDR frames. */
    int     b_keyframe;    /* In: user pts, Out: pts of encoded picture (user)*/
    int64_t i_pts;    /* Out: frame dts. When the pts of the first frame is close to zero,
     *      initial frames may have a negative dts which must be dealt with by any muxer */
    int64_t i_dts;    /* In: custom encoding parameters to be set from this frame forwards
           (in coded order, not display order). If NULL, continue using
           parameters from the previous frame.  Some parameters, such as
           aspect ratio, can only be changed per-GOP due to the limitations
           of H.264 itself; in this case, the caller must force an IDR frame
           if it needs the changed parameter to apply immediately. */
    x264_param_t *param;    /* In: raw image data */
    /* Out: reconstructed image data.  x264 may skip part of the reconstruction process,
            e.g. deblocking, in frames where it isn't necessary.  To force complete
            reconstruction, at a small speed cost, set b_full_recon. */
    x264_image_t img;    /* In: optional information to modify encoder decisions for this frame
     * Out: information about the encoded frame */
    x264_image_properties_t prop;    /* Out: HRD timing information. Output only when i_nal_hrd is set. */
    x264_hrd_t hrd_timing;    /* In: arbitrary user SEI (e.g subtitles, AFDs) */
    x264_sei_t extra_sei;    /* private user data. copied from input to output frames. */
    void *opaque;
} x264_picture_t;

入力フレームの画像データは基本的に x264_image_t 構造体に格納されます。

typedef struct x264_image_t{
    
        int     i_csp;       /* Colorspace */
    int     i_plane;     /* Number of image planes */
    int     i_stride[4]; /* Strides for each plane */
    uint8_t *plane[4];   /* Pointers to each plane */} x264_image_t;

i_csp は色空間タイプを表し、i_plane はチャネル数を表します。一般的に使用されるのは yuv420p で、これには y、u、v の 3 つのチャネルがあります。データは、 plane[0] が指すメモリ ブロックに保存されます。plan[0]、plane[1]、plane[2] は、それぞれ y、u、v の 3 つのチャネルのデータ メモリの開始位置を指します。i_stride[0]、i_stride[1]、i_stride[2] は、3 つのチャネル y、u、v のデータの各行が占める長さを表します。

yuv420p のデータストレージ構造は次のとおりです。

ここに画像の説明を挿入します

符号化データの生成

コーディングには関数を使用しますint x264_encoder_encode( x264_t *h, x264_nal_t **pp_nal, int *pi_nal, x264_picture_t *pic_in, x264_picture_t *pic_out )

    i_frame_size = x264_encoder_encode( h, &nal, &i_nal, &pic, &pic_out );    if( i_frame_size < 0 )        goto fail;    else if( i_frame_size ) {
    
            int i;        for (i = 0; i < i_nal; i++) 
            printf("i_nal = %d, i_frame_size = %d, nal i_payload = %d\n", i_nal, i_frame_size, nal[i].i_payload);
        }

コピー

エンコードによって生成されたデータは nal です。

i_nal = 4, i_frame_size = 13534, nal i_payload = 29i_nal = 4, i_frame_size = 13534, nal i_payload = 10i_nal = 4, i_frame_size = 13534, nal i_payload = 690i_nal = 4, i_frame_size = 13534, nal i_payload = 12805i_nal = 1, i_frame_size = 67, nal i_payload = 67i_nal = 1, i_frame_size = 1159, nal i_payload = 1159

コピー

nal は構造体で表されますx264_nal_t

/* The data within the payload is already NAL-encapsulated; the ref_idc and type
 * are merely in the struct for easy access by the calling application.
 * All data returned in an x264_nal_t, including the data in p_payload, is no longer
 * valid after the next call to x264_encoder_encode.  Thus it must be used or copied
 * before calling x264_encoder_encode or x264_encoder_headers again. */typedef struct x264_nal_t{
    
        int i_ref_idc;  /* nal_priority_e */
    int i_type;     /* nal_unit_type_e */
    int b_long_startcode;    int i_first_mb; /* If this NAL is a slice, the index of the first MB in the slice. */
    int i_last_mb;  /* If this NAL is a slice, the index of the last MB in the slice. */

    /* Size of payload (including any padding) in bytes. */
    int     i_payload;    /* If param->b_annexb is set, Annex-B bytestream with startcode.
     * Otherwise, startcode is replaced with a 4-byte size.
     * This size is the size used in mp4/similar muxing; it is equal to i_payload-4 */
    uint8_t *p_payload;    /* Size of padding in bytes. */
    int i_padding;
} x264_nal_t;

コピー

nal のデータは に保存されますp_payload次の形式で保存します。

ここに画像の説明を挿入します

各 nal データのポインタとデータ長を介して各 nal に個別にアクセスすることも、データ開始アドレス uint8 *p_payload と nal[0] の合計長 i_frame_size を介してすべての nal データに一度にアクセスすることもできます。nal をビデオコンテナに書き込む場合は1 番目のアクセス方法が使用され、h264 コード ストリームを生成する場合は 2 番目のアクセス方法が使用されます。

出てくるナルは主に以下の種類があります。

  • NAL_SPS: シーケンスパラメータセット
  • NAL_PPS: ピクチャパラメータセット
  • NAL_SEI: 補足的な拡張情報
  • NAL_SLICE_IDR: IDR ピクチャのコード化されたスライス
  • NAL_SLICE: noe-IDR ピクチャのコーデック スライス

NALデータ

H264 ビデオ符号化規格は、異なるネットワーク間のビデオ伝送に適合していますが、その主な理由は、画像圧縮データがネットワーク抽象化層 (NAL、Network Abstraction Layer) とビデオ符号化データに分割されるという階層構造の導入にあります。これにより、圧縮符号化とネットワーク伝送の分離が実現され、符号化層を異なるネットワーク構造に移植できるようになります。これにより、H264 は現在のさまざまなビデオ メモリ ネットワークに対してネットワーク親和性が高くなるだけでなく、将来のネットワークにも高度に適応できるようになります。

NAL では、データのカプセル化形式と統一ネットワーク インターフェイスが定義されており、データはネットワーク抽象化層ユニット (NALU) にパッケージ化され、ネットワーク内でのデータ送信が容易になります。ヘッダー情報には、ストレージ フラグとタイプ フラグが含まれます。ストレージ フラグは、現在のデータが参照フレームに属していないことを示し、サーバーがネットワークの混雑に基づいてデータを破棄できるようにするために使用されます。画像のデータ型。

NAL は、フレーミング、論理チャネルのシグナリング、タイミング情報の利用、フレーム終了信号のシーケンスなど、下位層ネットワークのセグメント化されたフォーマットを使用してデータをカプセル化する責任を負います。NAL は、回線交換チャネル上のビデオ伝送フォーマットと、RTP/UDP/IP を使用したネットワーク上のビデオ伝送フォーマットをサポートします。さまざまな特性を持つネットワーク上の VCL データ形式をカスタマイズする H264 NAL の機能を向上させるために、VCL と NAL の間で定義されたパケットベースのインターフェイス、パッケージング、および対応するシグナリングも NAL の一部です。


著者について: taoxiong (Xiong Tao)、Tiantian Ptu AND エンジニア

  >>> 音视频开发 视频教程: https://ke.qq.com/course/3202131?flowToken=1031864 
  >>> 音视频开发学习资料、教学视频,免费分享有需要的可以自行添加学习交流群: 739729163  领取

おすすめ

転載: blog.csdn.net/weixin_52622200/article/details/131481319