简体   繁体   English

为什么AVAssetWriter会放大视频文件?

[英]Why AVAssetWriter inflates video file?

Strange problem. 奇怪的问题。 I take frames from a video file (.mov) and write them with AVAssetWriter to another file without any explicit processing. 我从视频文件(.mov)中获取帧,并使用AVAssetWriter将其写入另一个文件,而无需任何显式处理。 Actually I just copy the frame from one memory buffer to another and them flush them through PixelbufferAdaptor. 实际上,我只是将帧从一个内存缓冲区复制到另一个,然后通过PixelbufferAdaptor刷新它们。 Then I take the resulting file, delete the original file, put the resulting file instead the original and do the same operation. 然后,我取出生成的文件,删除原始文件,将生成的文件代替原始文件,然后执行相同的操作。 Interesting thing is that the size of the file constantly grows! 有趣的是文件的大小不断增长! Can somebody explain why? 有人可以解释为什么吗?

if(adaptor.assetWriterInput.readyForMoreMediaData==YES) {
            CVImageBufferRef cvimgRef=nil;
            CMTime lastTime=CMTimeMake(fcounter++, 30); 
            CMTime presentTime=CMTimeAdd(lastTime, frameTime);
            CMSampleBufferRef framebuffer=nil;
            CGImageRef frameImg=nil;
            if ( [asr status]==AVAssetReaderStatusReading ){
                framebuffer =   [asset_reader_output copyNextSampleBuffer];
                frameImg    =   [self imageFromSampleBuffer:framebuffer withColorSpace:rgbColorSpace];
            }
            if(frameImg && screenshot){
                //CVImageBufferRef imageBuffer = CMSampleBufferGetImageBuffer(framebuffer);
                CVReturn stat= CVPixelBufferLockBaseAddress(screenshot, 0);

                 pxdata=CVPixelBufferGetBaseAddress(screenshot);
                 bufferSize = CVPixelBufferGetDataSize(screenshot);
                // Get the number of bytes per row for the pixel buffer.
                 bytesPerRow = CVPixelBufferGetBytesPerRow(screenshot);
                // Get the pixel buffer width and height.
                 width = CVPixelBufferGetWidth(screenshot);
                 height = CVPixelBufferGetHeight(screenshot);
                 // Create a Quartz direct-access data provider that uses data we supply.
                 CGDataProviderRef dataProvider = CGDataProviderCreateWithData(NULL, pxdata, bufferSize, NULL);

                CGImageAlphaInfo ai=CGImageGetAlphaInfo(frameImg);
                size_t bpx=CGImageGetBitsPerPixel(frameImg);
                CGColorSpaceRef fclr=CGImageGetColorSpace(frameImg);

                 // Create a bitmap image from data supplied by the data provider.
                 CGImageRef cgImage = CGImageCreate(width, height, 8, 32, bytesPerRow,rgbColorSpace, kCGImageAlphaNoneSkipLast | kCGBitmapByteOrder32Big,dataProvider, NULL, true, kCGRenderingIntentDefault);
                 CGDataProviderRelease(dataProvider);

                stat= CVPixelBufferLockBaseAddress(finalPixelBuffer, 0);
                pxdata=CVPixelBufferGetBaseAddress(finalPixelBuffer);
                bytesPerRow = CVPixelBufferGetBytesPerRow(finalPixelBuffer);
                CGContextRef context = CGBitmapContextCreate(pxdata, imgsize.width,imgsize.height, 8, bytesPerRow, rgbColorSpace, kCGImageAlphaNoneSkipLast);
                CGContextDrawImage(context, CGRectMake(0, 0, CGImageGetWidth(frameImg), CGImageGetHeight(frameImg)), frameImg);
                //CGColorSpaceRef rgbColorSpace = CGColorSpaceCreateDeviceRGB();
                //CGImageRef myMaskedImage;
                    const float myMaskingColors[6] = { 0, 0, 0, 1, 0, 0 };
                   CGImageRef  myColorMaskedImage = CGImageCreateWithMaskingColors (cgImage, myMaskingColors);
                 //CGContextDrawImage(context, CGRectMake(0, 0, CGImageGetWidth(myColorMaskedImage), CGImageGetHeight(myColorMaskedImage)), myColorMaskedImage);

                [adaptor appendPixelBuffer:finalPixelBuffer withPresentationTime:presentTime];}

well, the mystery seems to be solved. 好吧,这个谜团似乎已经解决了。 The problem was in inappropriate codec configuration. 问题出在不正确的编解码器配置中。 This is set of configuration options I use now and it seems to do the work: 这是我现在使用的配置选项集,它似乎可以完成工作:

NSDictionary *codecSettings = [NSDictionary dictionaryWithObjectsAndKeys:
                                   [NSNumber numberWithInt:1100000], AVVideoAverageBitRateKey,
                                   [NSNumber numberWithInt:5],AVVideoMaxKeyFrameIntervalKey,
                                   nil];
    NSDictionary *videoSettings = [NSDictionary dictionaryWithObjectsAndKeys:
                                   AVVideoCodecH264, AVVideoCodecKey,
                                   [NSNumber numberWithInt:[SharedApplicationData sharedData].overlayView.frame.size.width], AVVideoWidthKey,
                                   [NSNumber numberWithInt:[SharedApplicationData sharedData].overlayView.frame.size.height], AVVideoHeightKey,
                                   codecSettings,AVVideoCompressionPropertiesKey,
                                   nil];

    AVAssetWriterInput* writerInput = [AVAssetWriterInput
                                       assetWriterInputWithMediaType:AVMediaTypeVideo
                                       outputSettings:videoSettings];

Now the file size still grows but at much slower pace. 现在文件大小仍在增加,但速度要慢得多。 There is a tradeoff between the file size and the video quality - size reduction affects the quality. 在文件大小和视频质量之间需要权衡取舍-减小大小会影响质量。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM