iOS H264 エンコーディングとデコーディング

H264 ハードウェア ソリューションと iOS システムでの表示手順

iOS 8.0 システム以前は、Apple はシステムのハードウェア エンコードおよびデコード機能を公開していませんでしたが、Mac OS システムには、ハードウェア エンコードおよびデコードを処理するための Video ToolBox というフレームワークが常にありました.iOS 8.0 以降、Apple はこのフレームワークを導入しました。 iOS システムに。

1. VideoToolbox の基本的なデータ構造:

1. CVPixelBuffer: エンコード前とデコード後の画像データ構造。

2. CMTime、CMClock、および CMTimebase: タイムスタンプ関連。時間は 64 ビット/32 ビットの形式で表示されます。

3. CMBlockBuffer: エンコード後の結果画像のデータ構造。

4. CMVideoFormatDescription: 画像の保存方法、コーデック、およびその他のフォーマットの説明。

5. CMSampleBuffer: エンコードおよびデコード前後のビデオ画像を格納するコンテナ データ構造。

次の図は、H264 デコード前後のデータ構造の概略図です。

2. ハード ソリューションの使用方法:

H264 のコード ストリームは、ビデオ画像データと H264 パラメータ情報を含む NALU ユニットで構成されます。このうち、ビデオ画像データは CMBlockBuffer であり、H264 のパラメータ情報は FormatDesc に結合できます。具体的には、パラメータ情報には、SPS(Sequence Parameter Set)やPPS(Picture Parameter Set)がある。次の図は、H264 ストリームの構造を示しています。

デコード方法 1: (システムが提供する AVSampleBufferDisplayLayer を介してデコードおよび表示)

1. H264 ハードウェア ソリューション パラメータを初期化します。

1) sps と pps を抽出してフォーマット記述を生成します。


//sps

_spsSize =format.getCsd_0_size()-4;_sps = (uint8_t *)malloc(_spsSize);memcpy(_sps,format.getCsd_0()+4, _spsSize);

//pps

_ppsSize =format.getCsd_1_size()-4;_pps = (uint8_t *)malloc(_ppsSize);memcpy(_pps,format.getCsd_1()+4, _ppsSize);


2) CMVideoFormatDescriptionCreateFromH264ParameterSets 関数を使用して、CMVideoFormatDescriptionRef を構築します。


CMVideoFormatDescriptionCreateFromH264ParameterSets(kCFAllocatorDefault,                                                    

2, //param カウント parameterSetPointers, parameterSetSizes, 4, //nalstartcodesize&_decoderFormatDescription);


2. デコードする前に、H264 コード ストリームを CMSampleBuffer に変換します。

  1) CMBlockBufferCreateWithMemoryBlock インターフェイスを使用して、CMBlockBufferRef を構築します。

CMBlockBufferRef blockBuffer=NULL;CMBlockBufferCreateWithMemoryBlock(kCFAllocatorDefault, (void*)frame.bytes, frame.length, kCFAllocatorNull,NULL,0, frame.length,0,&blockBuffer);

  2) 上記に従って、CMVideoFormatDescriptionRef、CMBlockBufferRef、およびオプションの時間情報を取得し、CMSampleBufferCreate インターフェイスを使用して、デコードする元のデータである CMSampleBuffer データを取得します。

CMSampleBufferRef sampleBuffer =NULL;CMSampleBufferCreateReady(kCFAllocatorDefault, blockBuffer, _decoderFormatDescription,1,0,NULL,1, sampleSizeArray, &sampleBuffer);

3.ハードソリューションの画像表示:

システムが提供する AVSampleBufferDisplayLayer によってデコードおよび表示されます。

AVSampleBufferDisplayLayer は、エンコードされた H264 データを具体的に表示する Apple が提供するディスプレイ レイヤーであり、CALayer のサブクラスであるため、その使用法は他の CALayer と同様です。このレイヤーにはハードウェアデコード機能が組み込まれており、元のCMSampleBufferのデコードされた画像を画面に直接表示できます。これは非常にシンプルで便利です。

CFArrayRef 添付ファイル = CMSampleBufferGetSampleAttachmentsArray(sampleBuffer,YES);CFMutableDictionaryRef dict = (CFMutableDictionaryRef)CFArrayGetValueAtIndex(attachments,0);CFDictionarySetValue(dict, kCMSampleAttachmentKey_DisplayImmediately, kCFBooleanTrue);if(status == kCMBlockBufferNoErr) {

if([_avslayer isReadyForMoreMediaData]) {dispatch_sync(dispatch_get_main_queue(),^{        

    [_avslayer enqueueSampleBuffer:sampleBuffer];      

    });   

  }    

CFRelease(サンプルバッファ);

}


デコード方法 2: (VTDecompression インターフェイスを介して CMSampleBuffer をイメージにデコードし、UIImageView または OpenGL を介してイメージを表示します)

1. H264 ハードウェア ソリューション パラメータを初期化します。

方法 1 に基づいて、VTDecompressionSessionCreate インターフェイスを使用して VTDecompressionSessionRef を構築します (VTDecompressionSession を初期化し、デコーダーの関連情報を設定します)。

VTDecompressionSessionRef _deocderSession;VTDecompressionSessionCreate(kCFAllocatorDefault, _decoderFormatDescription,NULL, attrs, &callBackRecord, &_deocderSession);

2. デコードする前に、H264 コード ストリームを CMSampleBuffer に変換します。

同じ方法

3. VTDecompressionSessionDecodeFrame インターフェイスを使用して、CMSampleBuffer データを CVPixelBufferRef データにデコードします。

CVPixelBufferRef outputPixelBuffer=NULL;

VTDecompressionSessionDecodeFrame(_deocderSession,

サンプルバッファ、

フラグ、

&outputPixelBuffer,

&flagOut);

4. CVPixelBufferRef データを UIImage に変換して表示します。

CIImage*ciImage= [CIImage imageWithCVPixelBuffer:outputPixelBuffer];UIImage*uiImage= [UIImage imageWithCIImage:ciImage];

3. プログラムの流れ図:

デコード方法1

デコード方法 2

4. 2 つのデコード方法の比較:

デコード方法 1:

利点: このメソッドは、システムによって提供される AVSampleBufferDisplayLayer ディスプレイ レイヤーを介してデコードおよび表示します。このレイヤーには、ハードウェアデコード機能が組み込まれており、元のCMSampleBufferのデコードされた画像を画面に直接表示します。これは非常にシンプルで便利であり、実行効率が高く、メモリ使用量が比較的少ないです。

短所: デコードされたデータから画像データを直接取得して適切に処理することはできず、デコードされたデータを他のアプリケーションで直接使用することはできません (通常、より複雑な変換が必要です)。

デコード方法 2:

利点: このメソッドは、VTDecompressionSessionDecodeFrame インターフェイスを介して CVPixelBufferRef データを取得します. CVPixelBufferRef データから画像データを直接取得し、それに応じて処理できるため、他のアプリケーションに便利です.

短所: デコードの実行効率が比較的低く、占有されるメモリが比較的大きくなります。

').addClass('プレナンバリング').hide(); $(this).addClass('has-numbering').parent().append($numbering); for (i = 1; i <= 行; i++) { $numbering.append($('

').text(i)); }; $numbering.fadeIn(1700); }); });

以上、H264 ハード ソリューションと iOS システムでの表示手順について、コンテンツの側面も含めて紹介しました。IOS 開発に関心のある友人の参考になれば幸いです。

個人の github にデモ アドレスを追加: h264 ハード デコーディング デモ



著者: Round Moon
リンク: https://www.jianshu.com/p/fb78ee430949
出典: Jianshu
著作権は著者に帰属します。商用転載の場合は著者に連絡して許可を得てください。非商用転載の場合は出典を示してください。

                   

          

     

     

おすすめ

転載: blog.csdn.net/ForeverMyheart/article/details/106192874