1

奇妙な問題。ビデオファイル(.mov)からフレームを取得し、明示的な処理を行わずにAVAssetWriterを使用して別のファイルに書き込みます。実際には、あるメモリバッファから別のメモリバッファにフレームをコピーし、PixelbufferAdaptorを介してそれらをフラッシュします。次に、結果のファイルを取得し、元のファイルを削除し、元のファイルの代わりに結果のファイルを配置して、同じ操作を実行します。興味深いのは、ファイルのサイズが絶えず大きくなることです。誰かが理由を説明できますか?

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];}
4

1 に答える 1

0

さて、謎は解けたようです。問題は不適切なコーデック構成にありました。これは私が現在使用している構成オプションのセットであり、次のように機能しているようです。

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];

現在、ファイルサイズは大きくなりますが、ペースははるかに遅くなります。ファイルサイズとビデオ品質の間にはトレードオフがあります-サイズの縮小は品質に影響します。

于 2012-06-02T18:22:57.263 に答える