AVAssetWriterInputPixelBufferAdaptor appendPixelBuffer

ara*_*ide 3 iphone ios

我使用下面的代码将图像写入视频

-(void) writeImagesToMovieAtPath:(NSString *) path withSize:(CGSize) size
{
    NSLog(@"Write Started");

    NSError *error = nil;

    AVAssetWriter *videoWriter = [[AVAssetWriter alloc] initWithURL:
                                  [NSURL fileURLWithPath:path] fileType:AVFileTypeMPEG4
                                                              error:&error];
    NSParameterAssert(videoWriter);

    NSDictionary *videoSettings = [NSDictionary dictionaryWithObjectsAndKeys:
                                   AVVideoCodecH264, AVVideoCodecKey,
                                   [NSNumber numberWithInt:size.width], AVVideoWidthKey,
                                   [NSNumber numberWithInt:size.height], AVVideoHeightKey,
                                   nil];

    AVAssetWriterInput* videoWriterInput = [[AVAssetWriterInput
                                             assetWriterInputWithMediaType:AVMediaTypeVideo
                                             outputSettings:videoSettings] retain];


    AVAssetWriterInputPixelBufferAdaptor *adaptor = [AVAssetWriterInputPixelBufferAdaptor
                                                     assetWriterInputPixelBufferAdaptorWithAssetWriterInput:videoWriterInput
                                                     sourcePixelBufferAttributes:nil];

    NSParameterAssert(videoWriterInput);
    NSParameterAssert([videoWriter canAddInput:videoWriterInput]);
    videoWriterInput.expectsMediaDataInRealTime = YES;
    [videoWriter addInput:videoWriterInput];

    //Start a session:
    [videoWriter startWriting];
    [videoWriter startSessionAtSourceTime:kCMTimeZero];

    CVPixelBufferRef buffer = NULL;

    //convert uiimage to CGImage.

    int frameCount = 16;
    int kRecordingFPS = 30;
    UIImage * im = [UIImage imageNamed:@"IMG_0103.JPG"];

    NSArray * imageArray = [[NSArray alloc]initWithObjects:im,im,im,im,im,im,im,im,im,im,im,im,im,im,im,im, nil];

    for(UIImage * img in imageArray)
    {
        buffer = [self pixelBufferFromCGImage:[img CGImage] andSize:size];

        BOOL append_ok = NO;
        int j = 0;
        while (!append_ok && j < 30)
        {
            if (adaptor.assetWriterInput.readyForMoreMediaData)
            {
                printf("appending %d attemp %d\n", frameCount, j);

                CMTime frameTime = CMTimeMake(frameCount,(int32_t) kRecordingFPS);
                append_ok = [adaptor appendPixelBuffer:buffer withPresentationTime:frameTime];

                if(buffer)
                    CVBufferRelease(buffer);
                [NSThread sleepForTimeInterval:0.05];
            }
            else
            {
                printf("adaptor not ready %d, %d\n", frameCount, j);
                [NSThread sleepForTimeInterval:0.1];
            }
            j++;
        }
        if (!append_ok) {
            printf("error appending image %d times %d\n", frameCount, j);
        }
        frameCount++;
    }


    //Finish the session:
    [videoWriterInput markAsFinished];
    [videoWriter finishWriting];
    NSLog(@"Write Ended");
    [videoWriterInput release];
    [videoWriter release];
    [imageArray release];
}
Run Code Online (Sandbox Code Playgroud)

它第一次工作,但如果我运行2,3次或更多的代码,它报告:

?appending 0 0-0 attemp 0
?appending 0 0-0 attemp 1
My App(11385,0xb0103000) malloc: *** error for object 0x9ab4270: double free
*** set a breakpoint in malloc_error_break to debug
?appending 0 0-0 attemp 2
My App(11385,0xb0103000) malloc: *** error for object 0x9ab4270: double free
*** set a breakpoint in malloc_error_break to debug
?appending 0 0-0 attemp 3
Run Code Online (Sandbox Code Playgroud)

Soemtime它导致崩溃

我试图找到原因,但没有结果,

您的评论欢迎

Har*_*ari 10

而不是使用[NSThread sleepForTimeInterval:0.1]; 使用 while(!adaptor.assetWriterInput.readyForMoreMediaData){}

因为很多次readyForMoreMediaData在0.1时间间隔内从未设置为YES.

还试着释放appendPixelBuffer占用的内存:withPresentationTime:方法实际上这个方法阻止你成功运行

  • 我遇到了同样的问题,但是不明白您对“您只能在appendPixelBuffer:withPresentationTime:方法中进行管理”的评论。我如何在该方法内释放内存?据我所知,appendPixelBuffer:withPresentationTime:是AVAssetWriterInputPixelBufferAdaptor类的方法,无法更改。 (2认同)