GPUImageMovieWriter录制视频问题

GPUImageMovieWriter录制视频问题
1、两个movie叠加的时候,每个movie解码出一帧都会走到GPUImageTwoInputFilter的newFrameReadyAtTime

- (void)newFrameReadyAtTime:(CMTime)frameTime atIndex:(NSInteger)textureIndex;

{

    // You can set up infinite update loops, so this helps to short circuit them

    if (hasReceivedFirstFrame && hasReceivedSecondFrame)

    {

        return;

    }

    

    BOOL updatedMovieFrameOppositeStillImage = NO;

      if (textureIndex == 0)

    {

        hasReceivedFirstFrame = YES;

        firstFrameTime = frameTime;

        if (secondFrameCheckDisabled)

        {

            hasReceivedSecondFrame = YES;

        }

        

        if (!CMTIME_IS_INDEFINITE(frameTime))

        {

            if CMTIME_IS_INDEFINITE(secondFrameTime)

            {

                updatedMovieFrameOppositeStillImage = YES;

            }

        }

    }

    else

    {

        hasReceivedSecondFrame = YES;

        secondFrameTime = frameTime;

        if (firstFrameCheckDisabled)

        {

            hasReceivedFirstFrame = YES;

        }

        if (!CMTIME_IS_INDEFINITE(frameTime))

        {

            if CMTIME_IS_INDEFINITE(firstFrameTime)

            {

                updatedMovieFrameOppositeStillImage = YES;

            }

        }

    }


    // || (hasReceivedFirstFrame && secondFrameCheckDisabled) || (hasReceivedSecondFrame && firstFrameCheckDisabled)

    if ((hasReceivedFirstFrame && hasReceivedSecondFrame) || updatedMovieFrameOppositeStillImage)

    {

        CMTime passOnFrameTime = (!CMTIME_IS_INDEFINITE(firstFrameTime)) ? firstFrameTime : secondFrameTime;

        [super newFrameReadyAtTime:passOnFrameTime atIndex:0]; // Bugfix when trying to record: always use time from first input (unless indefinite, in which case use the second input)

        hasReceivedFirstFrame = NO;

        hasReceivedSecondFrame = NO;

    }

}

因为两个movie在不同的线程,如果2个movie帧率不一样,因为录制的时候是全速的,这样可能movie1已经来到上面方法很多次,而movie2才来一帧,这样就导致movie1

丢失了帧。解决方法:

- (BOOL)readNextVideoFrameFromOutput:(AVAssetReaderOutput *)readerVideoTrackOutput;

{

    if (reader.status == AVAssetReaderStatusReading && ! videoEncodingIsFinished)

    {

        CMSampleBufferRef sampleBufferRef = [readerVideoTrackOutput copyNextSampleBuffer];

        if (sampleBufferRef) 

        {


            if (_playAtActualSpeed)

            {

               ...

            }else{

                //这里判断另外一个movie是否准备,没准备就等一下

            }


            __unsafe_unretained GPUImageMovie *weakSelf = self;

            runSynchronouslyOnVideoProcessingQueue(^{

                [weakSelf processMovieFrame:sampleBufferRef];

                CMSampleBufferInvalidate(sampleBufferRef);

                CFRelease(sampleBufferRef);

            });


            return YES;

        }

        else

        {

            if (!keepLooping) {

                videoEncodingIsFinished = YES;

                if( videoEncodingIsFinished && audioEncodingIsFinished )

                    [self endProcessing];

            }

        }

    }

    else if (synchronizedMovieWriter != nil)

    {

        if (reader.status == AVAssetReaderStatusCompleted)

        {

            [self endProcessing];

        }

    }

    return NO;

}



2、使用GPUImageMovieWriter的processAudioBuffer写音频时,如果是写太快,可能导致音频丢失,可以在线程中sleep一下。

 When expectsMediaDataInRealTime is YES, readyForMoreMediaData will become NO only when the input cannot process media samples as quickly as they are being provided by the client. If readyForMoreMediaData becomes NO for a real-time source, the client may need to drop samples or consider reducing the data rate of appended samples.


3、使用GPUImageThreeInput,需要自己写fragment shafer,init的时候传入。


评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值