目标c-来自GPUImageMovie的视频在开头有一个红色框架



感谢您看到这个问题。

我用GPUImageMovieComposition和GPUImageWriter制作了一部电影,有时(5%~10%)电影开头有红色边框。

请教我为什么会出现这种现象。

我使用AVFileTypeMPEG4作为示例文件类型,但AVFileTypeQuickTimeMovie也是一样的。

_movieFile = [[GPUImageMovieComposition alloc] initWithComposition:composition andVideoComposition:videoComposition andAudioMix:nil];
_movieFile.playAtActualSpeed = YES;
_movieWriter = [[GPUImageMovieWriter alloc] initWithMovieURL:processedMovieURL
                                                        size:CGSizeMake(1280.0, 720.0)
                                                    fileType:AVFileTypeMPEG4
                                              outputSettings:videoSetting];
_movieWriter.shouldPassthroughAudio = NO;
[_movieWriter setVideoInputReadyCallback:nil];
[_movieWriter setHasAudioTrack:YES audioSettings:audioSetting];
[_movieFile addTarget:_movieWriter];
_movieFile.audioEncodingTarget = _movieWriter;
[_movieFile enableSynchronizedEncodingUsingMovieWriter:_movieWriter];    
[_movieWriter startRecording];
[_movieFile startProcessing];

解决方案

终于我可以找到解决。。。但不是完美的方式。。。

我修改了
- (void)processMovieFrame:(CVPixelBufferRef)movieFrame withSampleTime:(CMTime)currentSampleTime
在CCD_ 2小比特处。

当设置了currentSampleTime时,所有红色帧都具有currentSampleTime.value == 0所以我避免在currentSampleTime.value == 0 时设置currentSampleTime

以下是我实际使用的一些代码。

 for (id<GPUImageInput> currentTarget in targets)
  {
       NSInteger indexOfObject = [targets indexOfObject:currentTarget];
       NSInteger targetTextureIndex = [[targetTextureIndices objectAtIndex:indexOfObject] integerValue];
       if(currentSampleTime.value != 0){
           [currentTarget newFrameReadyAtTime:currentSampleTime atIndex:targetTextureIndex];
       }
   }

在我的案例中,GPUImageMovieWriter录制的视频开头没有红色帧,只有空白帧

问题是,音频样本出现的时间早于视频帧,而assetWriter会话启动的时间也早于第一个视频帧可用的时间。

我已经通过修改processAudioBuffer函数来修复了这个问题,并替换了这个代码

if (CMTIME_IS_INVALID(startTime))
{
  runSynchronouslyOnContextQueue(_movieWriterContext, ^{
    if ((audioInputReadyCallback == NULL) && (assetWriter.status != AVAssetWriterStatusWriting))
    {
      [assetWriter startWriting];
    }
    [assetWriter startSessionAtSourceTime:currentSampleTime];
    startTime = currentSampleTime;
  });
}

在这个上

if (CMTIME_IS_INVALID(startTime))
{
  NSLog(@"0: Had to drop an audio frame: %@", CFBridgingRelease(CMTimeCopyDescription(kCFAllocatorDefault, currentSampleTime)));
  if (_shouldInvalidateAudioSampleWhenDone)
  {
    CMSampleBufferInvalidate(audioBuffer);
  }
  CFRelease(audioBuffer);
  return;
}

该修复程序适用于2014年5月27日至7月1日的GPUImage的最新版本。

到目前为止,我找到的唯一解决方案是恢复到提交e98cc813b。我通过使用git平分并对同一视频执行一批处理测试来解决这个问题。这个提交已经具备了我的项目所需的所有功能,只需要做一些更改就可以使它更加稳定。您可以在此处查看更改:https://github.com/crazyjooe/GPUImage.

此外,经过大量测试,我可以说处理本身变得更加稳定,尤其是在取消方面。我想知道在引入了所有变化之后,视频处理是如何变得不那么可靠和稳定的。

相关内容

最新更新