Iphone GPUImageMovieWriter帧呈现时间

Iphone GPUImageMovieWriter帧呈现时间,iphone,objective-c,ios,opengl-es,gpuimage,Iphone,Objective C,Ios,Opengl Es,Gpuimage,我有一个连接了两个输入的GPUImageColorDodgeBlend过滤器: 一个GPUImageVideoCamera从iPhone摄像机获取帧 一个GPUImageMovie,这是一个(MP4)视频文件,我想把它放在实时摄像机提要上 然后将GPUImageColorDodgeBlend连接到两个输出: 一个GPUImageImageView,以提供正在运行的混合的实时预览 一个GPUImageMovieWriter,用于在按下录制按钮后将电影写入存储器 现在,在视频开始录制之前,一切都会1

我有一个连接了两个输入的
GPUImageColorDodgeBlend
过滤器:

  • 一个
    GPUImageVideoCamera
    从iPhone摄像机获取帧
  • 一个
    GPUImageMovie
    ,这是一个(MP4)视频文件,我想把它放在实时摄像机提要上
  • 然后将
    GPUImageColorDodgeBlend
    连接到两个输出:

  • 一个
    GPUImageImageView
    ,以提供正在运行的混合的实时预览
  • 一个
    GPUImageMovieWriter
    ,用于在按下录制按钮后将电影写入存储器
  • 现在,在视频开始录制之前,一切都会100%正常。
    GPUImageVideo
    与实时摄像头视频精细混合,不会报告任何问题或警告

    然而,当
    GPUImageMovieWriter
    开始录制时,事情开始随机出错。大约80-90%的时间里,
    GPUImageMovieWriter
    工作正常,没有错误或警告,输出视频写得正确

    然而,大约有10-20%的时间(据我所见,这是相当随机的),在录制过程中似乎出现了问题(尽管屏幕预览仍然可以正常工作)

    具体地说,我开始得到数百个&数百个
    程序在以下时间追加像素缓冲区:
    错误

    此错误源于
    GPUImageWriter
    中的
    -(void)newFrameReadyAtTime:(CMTime)frameTime atIndex:(NSInteger)textureIndex
    方法

    此问题由报告给此方法的
    帧时间
    值的问题触发

    从我所看到的情况来看,问题是由于写入程序有时接收到摄像机编号的帧(这些帧往往具有极高的时间值,如64616612394291,时间刻度为100000000)。但是,有时写入程序会获得由编号低得多的
    GPUImageMovie
    编号的帧(如200200,时间刻度为30000

    只要帧值增加,
    GPUImageWriter
    似乎很高兴,但一旦帧值减少,它就会停止写入,并在以下时间发出添加像素缓冲区的
    程序:
    错误

    我似乎在做一些相当常见的事情,而且这还没有被报告为bug,所以我的问题是(对任何或所有这些问题的答案都很感激——它们不一定都需要作为单独的问题依次回答):

    • frameTime
      值从何而来?
      frameTime
      是根据
      GPUImageVideoCamera
      源还是根据
      GPUImageMovie
      源进行编号的,为什么看起来如此随意?为什么它在每个帧之间都是可选的——帧编号方案不应该在所有帧中都是一致的吗

    • 我认为此问题是由非递增的
      帧时间
      s引起的,对吗

    • …如果是这样,为什么
      GPUImageView
      接受并显示
      frameTime
      s在屏幕上100%正常,而
      GPUImageMovieWriter
      却要求订购

    • …如果是,我如何确保输入的
      frameTime
      s有效?我尝试添加
      if(frameTime.value
      跳过任何在大多数情况下有效的编号较少的帧。不幸的是,当我在
      GPUImageMovie
      上设置
      playsAtActualSpeed
      时,由于所有帧都在某一点后被跳过,因此效果往往会差得多


    也许这是一个bug,在这种情况下,我需要在GitHub上报告它——但我很想知道在
    帧时
    的工作原理中是否有我忽略的地方。

    我找到了一个解决这个问题的潜在解决方案,我现在已经将其作为一个黑客实现了,但可以想象的是,它可以扩展到一个适当的解决方案

    我将计时的来源追溯到
    GPUImageTwoInputFilter
    ,它实质上是将两个输入源多路复用到单个帧输出中

    在方法
    -(void)NewFrameReadyAtime:(CMTime)frameTime atIndex:(NSInteger)textureIndex
    中,过滤器等待从第一个源(
    textureInput==0
    )和第二个源收集帧,然后在这些帧上转发到其目标

    问题是(在我看来),该方法只是简单地使用了第二帧的
    frameTime
    (不包括
    CMTIME\u不确定的静止图像(frameTime)==YES
    ,我现在不考虑,因为我不处理静止图像),这可能并不总是同一帧(无论出于什么原因)

    检查两个帧并将其发送以进行处理的相关代码如下:

      if ((hasReceivedFirstFrame && hasReceivedSecondFrame) || updatedMovieFrameOppositeStillImage)
        {
            [super newFrameReadyAtTime:frameTime atIndex:0]; // this line has the problem
            hasReceivedFirstFrame = NO;
            hasReceivedSecondFrame = NO;
        }
    
    我所做的是将上面的代码调整为
    [super-newframereadyatime:firstFrameTime-atIndex:0]
    ,这样它总是使用来自第一个输入的
    frameTime
    ,而完全忽略来自第二个输入的
    frameTime
    。到目前为止,它都是这样工作的。(考虑到
    GPUImageMovieWriter
    似乎坚持增加
    frameTime
    s(按现状的方法无法保证),仍有人想让我知道为什么这样写。)


    警告:如果只处理静止图像,这几乎肯定会完全中断,在这种情况下,
    CMTIME\u是不确定的(帧时间)==是的
    对于第一次输入的
    帧时

    是的,整个框架中的计时代码需要一些爱。多个视频源之间没有同步,我没有说明