web-dev-qa-db-ja.com

H264Videoストリームのサイズを取得する

H264ストリームからサイズ(高さと幅)をフェッチしようとしています。 mpeg2ストリームから同じ詳細をフェッチするには、シーケンスヘッダーの開始コード((01B3))に続く4バイトを調べる必要があることを知っています。同じロジックがH264でも機能しますか?私が得るどんな助けにも感謝します。

23
DRT

いいえ!!!

シーケンスパラメータセットからビデオディメンションを抽出するには、複雑な関数を実行する必要があります。これを行う方法?さて、まず、独自のExp-Golombデコーダーを作成するか、オンラインで見つける必要があります... live555ソースコードのどこかに、たとえば、あるものがある...

次に、SPSフレームを1つ取得する必要があります。これには_NAL=0x67_(NALはH.264フレームの最初のバイト)があり、SDPのBase64エンコード文字列として_sprop-parameter-sets_で見つけることができます。最初のコンマの前の最初のBase64文字列です。他のカンマ区切りの文字列には画像パラメータセットがあります...これはSDPからの1つのSPSです_Z0KAKYiLQDIBL0IAAB1MAAK/IAg=_このようなものをBase64からバイト配列にデコードする必要があります。

次に、バイト配列内のNAL UNIT HEADERが後に続くRAW BYTE SEQUENCE PAYLOADを抽出する必要があります!!!通常は1バイトの長さですが、念のため読んでください... RBSPには、seq_parameter_set_data( )関数の実行に必要なバイトが含まれています。したがって、最初にNAL UNIT HEADER(1バイト以上)を取り除く必要があります。

これは、SPS NAL UNITからRBSPバイトを抽出する関数です。

NAL UNIT

次に、SPS(RBSPバイト)がある場合、このバイト配列のビットを解析する関数を実行する必要があります。ここに解析されたすべてのパラメーターを持つ関数があります(ドキュメント全体はここにあります: http://www.itu.int/rec/T-REC-H.264-201003-I/en およびそれは無料です): How to decode SPS

そこに奇妙なものが表示されます...まず、ビデオのサイズは次のように計算されます:

_Width = ((pic_width_in_mbs_minus1 +1)*16) - frame_crop_right_offset*2 - frame_crop_left_offset*2;
Height = ((2 - frame_mbs_only_flag)* (pic_height_in_map_units_minus1 +1) * 16) - (frame_crop_top_offset * 2) - (frame_crop_bottom_offset * 2);
_

2番目の、そして最も重要なのは、このコード表のDESCRIPTOR列に、最初の列の太字のテキストパラメーターを読み取るために何をすべきかが示されていることです。これが意味するところは次のとおりです。

  • u(N)-Nビット長の符号なし数値を読み取ります
  • s(N)-Nビット長の符号付き数値を読み取ります
  • ue(v)-符号なしのExp-Golomb数を読み取ります(vは可変長のため、ue()と同じです)
  • se(v)-符号付きExp-Golomb番号を読み取ります

これがExp-Golombデコーダーが便利な場所です...

したがって、この関数を実装し、SPSを解析すると、幅と高さが得られます。楽しい... :)

48
Cipi

サイズの計算は残念ながら間違っており、次のようになります。

width = ((pic_width_in_mbs_minus1 +1)*16) - frame_crop_left_offset*2 - frame_crop_right_offset*2;
height= ((2 - frame_mbs_only_flag)* (pic_height_in_map_units_minus1 +1) * 16) - (frame_crop_top_offset * 2) - (frame_crop_bottom_offset * 2);
21
Andreas Larsson

実際にトリミングパラメータは、SPSで[frame_cropping_flag]が有効になっている場合にのみ使用する必要があります。 H.264をお楽しみください!

5
Mike Doilnitsyn

フレームサイズの計算に関して、上記の式は正しくありません。

chroma_format_idcが存在する場合は、SPSから抽出する必要があります。 chroma_format_idcが存在しない場合は、1(4:2:0クロマ形式)と見なされます。その場合、separate_color_plane_flagは設定されません。つまり、chromaArrayType = chroma_format_idcsubWidthCsubHeightCは2と等しくありません。

変数cropUnitXとcropUnitYは次のように導出されます:

  • chromaArrayType0と等しい場合、cropUnitXおよびcropUnitYは次のように導出されます。

    cropUnitX = 1
    cropUnitY = 2 - frame_mbs_only_flag
    
  • それ以外の場合(chromaArrayType12、または3と等しい)、cropUnitXおよびcropUnitYは次のように導出されます。

    cropUnitX = subWidthC
    cropUnitY = subHeightC * ( 2 - frame_mbs_only_flag )
    

これで、上記の式でcropUnitXおよびcropUnitYを使用して、フレームサイズの正しい値を取得できます。

2
kytodrk