入力データを再エンコードしないように指定するために辞書をAVAssetWriterInput
渡すことができるiOS ドキュメントで気付きました。nil
outputSettings
出力に追加されるメディアのエンコードに使用される設定。追加されたサンプルを再エンコードしないことを指定するには、nil を渡します。
この機能を利用して生の H.264 NAL のストリームを渡したいのですが、生のバイト ストリームCMSampleBuffer
を AVAssetWriterInput のappendSampleBuffer
メソッドに渡すことができる に適応させるのに問題があります。NAL のストリームには、SPS/PPS/IDR/P NAL (1、5、7、8) のみが含まれています。AVAssetWriter で事前にエンコードされた H264 データを使用する方法に関するドキュメントや決定的な回答を見つけることができませんでした。結果のビデオ ファイルは再生できません。
NALユニットを適切にパッケージ化するにはどうすればよいCMSampleBuffers
ですか? 開始コードのプレフィックスを使用する必要がありますか? 長さのプレフィックス?1 つにつき NAL を 1 つだけ配置する必要がありCMSampleBuffer
ますか? 私の最終目標は、H264/AAC で MP4 または MOV コンテナーを作成することです。
これが私が遊んでいるコードです:
-(void)addH264NAL:(NSData *)nal
{
dispatch_async(recordingQueue, ^{
//Adapting the raw NAL into a CMSampleBuffer
CMSampleBufferRef sampleBuffer = NULL;
CMBlockBufferRef blockBuffer = NULL;
CMFormatDescriptionRef formatDescription = NULL;
CMItemCount numberOfSampleTimeEntries = 1;
CMItemCount numberOfSamples = 1;
CMVideoFormatDescriptionCreate(kCFAllocatorDefault, kCMVideoCodecType_H264, 480, 360, nil, &formatDescription);
OSStatus result = CMBlockBufferCreateWithMemoryBlock(kCFAllocatorDefault, NULL, [nal length], kCFAllocatorDefault, NULL, 0, [nal length], kCMBlockBufferAssureMemoryNowFlag, &blockBuffer);
if(result != noErr)
{
NSLog(@"Error creating CMBlockBuffer");
return;
}
result = CMBlockBufferReplaceDataBytes([nal bytes], blockBuffer, 0, [nal length]);
if(result != noErr)
{
NSLog(@"Error filling CMBlockBuffer");
return;
}
const size_t sampleSizes = [nal length];
CMSampleTimingInfo timing = { 0 };
result = CMSampleBufferCreate(kCFAllocatorDefault, blockBuffer, YES, NULL, NULL, formatDescription, numberOfSamples, numberOfSampleTimeEntries, &timing, 1, &sampleSizes, &sampleBuffer);
if(result != noErr)
{
NSLog(@"Error creating CMSampleBuffer");
}
[self writeSampleBuffer:sampleBuffer ofType:AVMediaTypeVideo];
});
}
実際に追加しようとする前に、有効な時間と思われるメソッドCMSampleBufferSetOutputPresentationTimeStamp
内のサンプルバッファーを呼び出していることに注意してください。writeSampleBuffer
どんな助けでも大歓迎です。