AVAssetWriterInput
에 대한 iOS 설명서에서 nil
을 outputSettings
사전에 전달하여 입력 데이터를 다시 인코딩하지 않도록 지정할 수 있습니다.원시 NAL 단위 AVAssetWriter 사용
출력에 미디어 인코딩에 사용되는 설정이 추가됩니다. 추가 된 샘플을 다시 인코딩하지 않도록 지정하려면 nil을 전달하십시오.
나는 원시 H.264의 NAL들의 스트림을 전달하기 위해이 기능을 이용하려면,하지만 난 AVAssetWriterInput의 appendSampleBuffer
방법으로 전달할 수있는 데 문제가 CMSampleBuffer
로 내 원시 바이트 스트림을 적응하는 데 문제. 내 NAL 스트림에는 SPS/PPS/IDR/P NAL (1, 5, 7, 8) 만 포함됩니다. AVAssetWriter에서 미리 인코딩 된 H264 데이터를 사용하는 방법에 대한 설명서 또는 결정적인 대답을 찾을 수 없었습니다. 결과 비디오 파일을 재생할 수 없습니다.
NAL 단위를 올바르게 CMSampleBuffers
에 포장 할 수 있습니까? 시작 코드 접두사를 사용해야합니까? 길이 접두어? CMSampleBuffer
당 하나의 NAL 만 넣어야하는지 확인해야합니까? 나의 마지막 목표는 H264/AAC로 MP4 또는 MOV 컨테이너를 만드는 것입니다. 나는 내가 실제로 해요 전에 유효한 시간 생각으로 writeSampleBuffer
방법의 내부 샘플 버퍼에 CMSampleBufferSetOutputPresentationTimeStamp
를 호출하고있어
-(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];
});
}
참고 : 여기에
내가 함께 놀았 던 코드입니다 그것을 추가하려고합니다.도움을 주시면 감사하겠습니다.
적어도 내 문제 중 일부는 CMSampleTimingInfo를 처리하는 방법이었습니다.나는 실제 타임 스탬프를 채우기 위해'setOutputPresentationTimeStamp'를 사용하고 있다고 언급했다. 이제 CMSampleTimingInfo의 다른 필드를 채워야한다는 것을 알았습니다. 나는'decodeTimeStamp'을'kCMTimeInvalid'로,'duration'을'CMTimeMake (1, 30)'로 설정하고 있습니다. 적절한 총 시간을 가진 검색 가능한 비디오 컨테이너를 얻었지만 비디오가 없습니다 (VLC에서 테스트). – bsirang