废话不多说,直接上关键部分的代码
-(void)encode:(CMSampleBufferRef)sampleBuffer isCrop:(BOOL)isCrop
{
log4cplus_debug("h264", "encoder video data\n");
if (self.error) {
log4cplus_error("h264", "error = %d",self.error);
}
if(self.error == Error_Restart5TimesStillFailured)
{
log4cplus_debug("h264", "%s,restart encoder more than 5 times, %d",__func__,__LINE__);
[self.delegate didRestartFailured];
}
[m_lock lock];
if(self.isReadyForEncode)
{
if(compressionSession == NULL)
{
log4cplus_error("h264", "%s,compressionSession =null, %d",__func__,__LINE__);
goto RELEASE_BUFFER;
}
//the first frame must be iframe then create the reference timeStamp;
static BOOL isFirstFrame = YES;
if(isFirstFrame)
{
CMTime pts = CMSampleBufferGetPresentationTimeStamp(sampleBuffer);
log4cplus_info("h264","g_vstarttime = %f",CMTimeGetSeconds(pts));
g_vstarttime = CMTimeGetSeconds(pts);// system absolutly time(s)
g_tvustartcaptureTime = CTimeThread::GetCurrentTime();
if(ntp_time_offset != 0)
{
g_tvustartcaptureTime = g_tvustartcaptureTime - (ntp_time_offset/1000);
}
log4cplus_error("h264","CAPTURETIME = %u, %ld",g_tvustartcaptureTime, ntp_time_offset);
isFirstFrame = NO;
}
if(initialized == false){
log4cplus_error("h264", "h264 encoder is not ready\n");
goto RELEASE_BUFFER;
}
[self doSetBitrate];
CVImageBufferRef imageBuffer = CMSampleBufferGetImageBuffer(sampleBuffer);
CMTime presentationTimeStamp = CMSampleBufferGetPresentationTimeStamp(sampleBuffer);
// 关键步骤 begin
OSStatus status = noErr;
if (g_needForceInsertKeyFrame) {
NSDictionary *properties = @{(__bridge NSString *)kVTEncodeFrameOptionKey_ForceKeyFrame:@YES};
status = VTCompressionSessionEncodeFrame(compressionSession, imageBuffer, presentationTimeStamp, kCMTimeInvalid, (__bridge CFDictionaryRef)properties, NULL, NULL);// 强制插入关键帧 (__bridge CFDictionaryRef)properties 该参数必须设置为YES,并在编码时传入,就能立即插入一帧关键帧
g_needForceInsertKeyFrame = false;
}else {
status = VTCompressionSessionEncodeFrame(compressionSession, imageBuffer, presentationTimeStamp, kCMTimeInvalid, NULL, NULL, NULL);
}
// 关键步骤 end
//NSAssert(status == noErr, @"assert : Encoder frame failured!");
if(status != noErr)
{
NSLog(@"H264: VTCompressionSessionEncodeFrame failed");
VTCompressionSessionCompleteFrames(compressionSession, kCMTimeInvalid);
VTCompressionSessionInvalidate(compressionSession);
CFRelease(compressionSession);
compressionSession = NULL;
_error = Error_EncodeFrameFailured;
[m_lock unlock];
if (isCrop) {
if (sampleBuffer != NULL) {
CFRelease(sampleBuffer);
log4cplus_debug("h264", "Release crop sample buffer");
}
}
[self.delegate didEncoderErrorOccured:Error_EncodeFrameFailured];
return;
}
}
// if sample buffer are from system needn't to release, if sample buffer are from we create need to release.
RELEASE_BUFFER:
[m_lock unlock];
if (isCrop) {
if (sampleBuffer != NULL) {
CFRelease(sampleBuffer);
log4cplus_debug("h264", "Release crop sample buffer");
}
}
}
版权声明:本文为GZgengzhen原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。