Created
August 23, 2016 08:14
-
-
Save zhaoxiaobao/6322b0fb2fdc8467100284df4bf31253 to your computer and use it in GitHub Desktop.
LFLiveKit中VideoToolbox进行硬编代码
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
static void VideoCompressonOutputCallback(void *VTref, void *VTFrameRef, OSStatus status, VTEncodeInfoFlags infoFlags, CMSampleBufferRef sampleBuffer) | |
{ | |
if(!sampleBuffer) return; | |
CFArrayRef array = CMSampleBufferGetSampleAttachmentsArray(sampleBuffer, true); | |
if(!array) return; | |
CFDictionaryRef dic = (CFDictionaryRef)CFArrayGetValueAtIndex(array, 0); | |
if(!dic) return; | |
BOOL keyframe = !CFDictionaryContainsKey(dic, kCMSampleAttachmentKey_NotSync); | |
uint64_t timeStamp = [((__bridge_transfer NSNumber*)VTFrameRef) longLongValue]; | |
LFHardwareVideoEncoder *videoEncoder = (__bridge LFHardwareVideoEncoder *)VTref; | |
if(status != noErr){ | |
return; | |
} | |
if (keyframe && !videoEncoder->sps) | |
{ | |
CMFormatDescriptionRef format = CMSampleBufferGetFormatDescription(sampleBuffer); | |
size_t sparameterSetSize, sparameterSetCount; | |
const uint8_t *sparameterSet; | |
OSStatus statusCode = CMVideoFormatDescriptionGetH264ParameterSetAtIndex(format, 0, &sparameterSet, &sparameterSetSize, &sparameterSetCount, 0 ); | |
if (statusCode == noErr) | |
{ | |
size_t pparameterSetSize, pparameterSetCount; | |
const uint8_t *pparameterSet; | |
OSStatus statusCode = CMVideoFormatDescriptionGetH264ParameterSetAtIndex(format, 1, &pparameterSet, &pparameterSetSize, &pparameterSetCount, 0 ); | |
if (statusCode == noErr) | |
{ | |
videoEncoder->sps = [NSData dataWithBytes:sparameterSet length:sparameterSetSize]; | |
videoEncoder->pps = [NSData dataWithBytes:pparameterSet length:pparameterSetSize]; | |
if(videoEncoder->enabledWriteVideoFile){ | |
NSMutableData *data = [[NSMutableData alloc] init]; | |
uint8_t header[] = {0x00,0x00,0x00,0x01}; | |
[data appendBytes:header length:4]; | |
[data appendData:videoEncoder->sps]; | |
[data appendBytes:header length:4]; | |
[data appendData:videoEncoder->pps]; | |
fwrite(data.bytes, 1,data.length,videoEncoder->fp); | |
} | |
} | |
} | |
} | |
CMBlockBufferRef dataBuffer = CMSampleBufferGetDataBuffer(sampleBuffer); | |
size_t length, totalLength; | |
char *dataPointer; | |
OSStatus statusCodeRet = CMBlockBufferGetDataPointer(dataBuffer, 0, &length, &totalLength, &dataPointer); | |
if (statusCodeRet == noErr) { | |
size_t bufferOffset = 0; | |
static const int AVCCHeaderLength = 4; | |
while (bufferOffset < totalLength - AVCCHeaderLength) { | |
// Read the NAL unit length | |
uint32_t NALUnitLength = 0; | |
memcpy(&NALUnitLength, dataPointer + bufferOffset, AVCCHeaderLength); | |
NALUnitLength = CFSwapInt32BigToHost(NALUnitLength); | |
LFVideoFrame *videoFrame = [LFVideoFrame new]; | |
videoFrame.timestamp = timeStamp; | |
videoFrame.data = [[NSData alloc] initWithBytes:(dataPointer + bufferOffset + AVCCHeaderLength) length:NALUnitLength]; | |
videoFrame.isKeyFrame = keyframe; | |
videoFrame.sps = videoEncoder->sps; | |
videoFrame.pps = videoEncoder->pps; | |
if(videoEncoder.h264Delegate && [videoEncoder.h264Delegate respondsToSelector:@selector(videoEncoder:videoFrame:)]){ | |
[videoEncoder.h264Delegate videoEncoder:videoEncoder videoFrame:videoFrame]; | |
} | |
if(videoEncoder->enabledWriteVideoFile){ | |
NSMutableData *data = [[NSMutableData alloc] init]; | |
if(keyframe){ | |
uint8_t header[] = {0x00,0x00,0x00,0x01}; | |
[data appendBytes:header length:4]; | |
}else{ | |
uint8_t header[] = {0x00,0x00,0x01}; | |
[data appendBytes:header length:3]; | |
} | |
[data appendData:videoFrame.data]; | |
fwrite(data.bytes, 1,data.length,videoEncoder->fp); | |
} | |
bufferOffset += AVCCHeaderLength + NALUnitLength; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment