H.264编码器在需要时强制插入关键帧

废话不多说,直接上关键部分的代码


-(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");
        }
    }
}




  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值