Jon*_*lis 5 iphone opengl-es objective-c ios gpuimage
我有一个GPUImageColorDodgeBlend连接两个输入的过滤器:
GPUImageVideoCamera从iPhone摄像机这是越来越帧.GPUImageMovie是我想奠定了直播相机饲料中(MP4)视频文件.将GPUImageColorDodgeBlend然后被连接到两个输出:
GPUImageImageView提供实时混合的实时预览.GPUImageMovieWriter按下录制按钮后将电影写入存储.现在,在视频开始录制之前,一切都可以正常运行.它GPUImageVideo与现场摄像机视频混合在一起,没有报告任何问题或警告.
但是,当GPUImageMovieWriter开始录制时,事情随机开始出错.大约80-90%的时间,GPUImageMovieWriter工作完美,没有错误或警告,输出视频写得正确.
然而,大约10-20%的时间(从我可以看到,这是相当随机的),在录制过程中似乎出现了问题(虽然屏幕预览继续正常工作).
具体来说,我开始收到数百和数百个Program appending pixel buffer at time:错误.
此错误源自中的- (void)newFrameReadyAtTime:(CMTime)frameTime atIndex:(NSInteger)textureIndex方法GPUImageWriter.
此问题由frameTime报告给此方法的值的问题触发.
从我所看到的,问题是由作家有时接收由摄像机编号的帧(其往往具有极高的时间值,如64616612394291,时间刻度为1000000000)引起的.但是,有时候作者会得到编号GPUImageMovie较低的帧(比如200200,时间刻度为30000).
GPUImageWriter只要帧值增加,似乎很高兴,但是一旦帧值减小,它就会停止写入并发出Program appending pixel buffer at time:错误.
我似乎做了一些相当普遍的事情,并且这在任何地方都没有作为一个bug报告,所以我的问题是(对任何或所有这些的答案都很感激 - 它们并不一定都需要按顺序回答题):
这些frameTime值来自何处- 为什么它frameTime根据GPUImageVideoCamera来源或GPUImageMovie来源编号似乎是如此随意?为什么每个帧之间都有替代方案 - 帧编号方案不应该在所有帧中统一吗?
我是否认为这个问题是由不增加的frameTimes 引起的?
......如果是这样,为什么在100%的时间内GPUImageView接受并frameTime在屏幕上显示s就好了,但是GPUImageMovieWriter需要订购?
......如果是这样,我怎样才能确保frameTime进来的s有效?我尝试添加if (frameTime.value < previousFrameTime.value) return;以跳过任何较少编号的帧 - 大部分时间都可以.不幸的是,当我设置playsAtActualSpeed时,GPUImageMovie这往往变得远没有效果,因为所有帧最终都会在某个点之后被跳过.
... 或者这可能是一个错误,在这种情况下我需要在GitHub上报告 - 但是我有兴趣知道是否有一些我在这里frameTime工作的时候忽略了什么.
我找到了这个问题的潜在解决方案,目前我已将其作为黑客实现,但可以想象可以扩展到适当的解决方案。
我已经追踪了时序的来源,GPUImageTwoInputFilter基本上将两个输入源多路复用为单个帧输出。
在方法 中- (void)newFrameReadyAtTime:(CMTime)frameTime atIndex:(NSInteger)textureIndex,过滤器会等待,直到从第一个源 ( ) 和第二个源收集到帧textureInput == 0,然后将这些帧转发到其目标。
问题(我的看法)是该方法只是使用frameTime第二个帧的(不包括我现在不考虑的静态图像的情况CMTIME_IS_INDEFINTE(frameTime) == YES,因为我不处理静态图像)可能并不总是相同的框架(无论出于何种原因)。
检查两个帧并将其发送进行处理的相关代码如下:
if ((hasReceivedFirstFrame && hasReceivedSecondFrame) || updatedMovieFrameOppositeStillImage)
{
[super newFrameReadyAtTime:frameTime atIndex:0]; // this line has the problem
hasReceivedFirstFrame = NO;
hasReceivedSecondFrame = NO;
}
Run Code Online (Sandbox Code Playgroud)
我所做的就是调整上面的代码,[super newFrameReadyAtTime:firstFrameTime atIndex:0]以便它始终使用第一个frameTime输入中的并完全忽略第二个输入中的 。到目前为止,一切都像这样运行良好。(仍然有兴趣让我知道为什么这样写,因为这似乎坚持增加s,而按原样方法并不能保证这一点。)frameTimeGPUImageMovieWriterframeTime
警告:如果您只处理静态图像,这几乎肯定会完全崩溃,在这种情况下,您CMTIME_IS_INDEFINITE(frameTime) == YES的第一个输入将是frameTime.
| 归档时间: |
|
| 查看次数: |
1194 次 |
| 最近记录: |