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
,用于在按下录制按钮后将电影写入存储器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
s在屏幕上100%正常,而frameTime
却要求订购GPUImageMovieWriter
- …如果是,我如何确保输入的
s有效?我尝试添加frameTime
跳过任何在大多数情况下有效的编号较少的帧。不幸的是,当我在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是不确定的(帧时间)==是的
对于第一次输入的帧时
是的,整个框架中的计时代码需要一些爱。多个视频源之间没有同步,我没有说明