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
著作権は著者に帰属します。商用転載の場合は著者に連絡して許可を得てください。非商用転載の場合は出典を示してください。