Tag: cmsamplebufferref

核心图像 – 在CMSampleBufferRef上渲染一个透明的图像会导致它周围的黑框

我正在使用AVFoundation的AVCaptureVideoDataOutput录制的video上添加水印/徽标。 我的类被设置为sampleBufferDelegate并接收CMSamplebufferRefs。 我已经将某些效果应用于CMSampleBufferRefs CVPixelBuffer,并将其传回给AVAssetWriter。 左上angular的徽标使用透明PNG提供。 我遇到的问题是,一旦写入video,UIImage的透明部分是黑色的。 任何人都知道我做错了什么或可能会忘记? 下面的代码片段: //somewhere in the init of the class; _eaglContext = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2]; _ciContext = [CIContext contextWithEAGLContext:_eaglContext options: @{ kCIContextWorkingColorSpace : [NSNull null] }]; //samplebufferdelegate method: – (void) captureOutput:(AVCaptureOutput *)captureOutput didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer fromConnection:(AVCaptureConnection *)connection { CVPixelBufferRef pixelBuffer = CMSampleBufferGetImageBuffer(sampleBuffer); CVPixelBufferLockBaseAddress(pixelBuffer, 0); …. UIImage *logoImage = [UIImage imageNamed:@"logo.png"]; CIImage *renderImage […]

与原始NAL单位一起使用AVAssetWriter

我注意到在AVAssetWriterInput的iOS文档中,你可以传递nil给outputSettings字典来指定input数据不应该被重新编码。 用于编码附加到输出的媒体的设置。 通过零来指定附加的样本不应该被重新编码。 我想利用这个function来传递一个H.264原始NALstream,但是我无法将我的原始字节stream转换成一个CMSampleBuffer ,我可以将它传递到AVAssetWriterInput的appendSampleBuffer方法中。 我的NALstream只包含SPS / PPS / IDR / P NAL(1,5,7,8)。 我一直无法find有关如何使用预编码的H264数据与AVAssetWriter的文件或结论性的答案。 生成的video文件无法播放。 我如何正确打包NUM单元到CMSampleBuffers ? 我是否需要使用起始码前缀? 长度前缀? 我是否需要确保每个CMSampleBuffer只放置一个NAL? 我的最终目标是创build一个H264 / AAC的MP4或MOV容器。 这是我一直在玩的代码: -(void)addH264NAL:(NSData *)nal { dispatch_async(recordingQueue, ^{ //Adapting the raw NAL into a CMSampleBuffer CMSampleBufferRef sampleBuffer = NULL; CMBlockBufferRef blockBuffer = NULL; CMFormatDescriptionRef formatDescription = NULL; CMItemCount numberOfSampleTimeEntries = 1; CMItemCount numberOfSamples = […]

捕获仍然没有压缩UIImage(从CMSampleBufferRef)?

我需要从CMSampleBufferRef的未压缩的图像数据获取UIImage 。 我正在使用的代码: captureStillImageOutput captureStillImageAsynchronouslyFromConnection:connection completionHandler:^(CMSampleBufferRef imageSampleBuffer, NSError *error) { // that famous function from Apple docs found on a lot of websites // does NOT work for still images UIImage *capturedImage = [self imageFromSampleBuffer:imageSampleBuffer]; } http://developer.apple.com/library/ios/#qa/qa1702/_index.html是imageFromSampleBuffer函数的链接。 但它不能正常工作。 🙁 有一个jpegStillImageNSDataRepresentation:imageSampleBuffer方法,但它提供了压缩的数据(以及因为JPEG)。 捕获静止图像后,如何使用最原始的非压缩数据创buildUIImage ? 也许,我应该指定一些设置video输出? 我目前正在使用这些: captureStillImageOutput = [[AVCaptureStillImageOutput alloc] init]; captureStillImageOutput.outputSettings = @{ (id)kCVPixelBufferPixelFormatTypeKey : @(kCVPixelFormatType_32BGRA) […]

为什么AVSampleBufferDisplayLayer停止显示从AVCaptureVideoDataOutput的委托取得的CMSampleBuffers?

我想用AVSampleBufferDisplayLayer显示一些CMSampleBuffer,但是在显示第一个样本后它会冻结。 我从AVCaptureVideoDataOutputSampleBuffer委托中获取样本缓冲区: -(void)captureOutput:(AVCaptureOutput *)captureOutput didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer fromConnection:(AVCaptureConnection *)connection { CFRetain(sampleBuffer); [self imageToBuffer:sampleBuffer]; CFRelease(sampleBuffer); } 把他们变成一个载体 -(void) imageToBuffer: (CMSampleBufferRef )source{ //buffers is defined as: std::vector<CMSampleBufferRef> buffers; CMSampleBufferRef newRef; CMSampleBufferCreateCopy(kCFAllocatorDefault, source, &newRef); buffers.push_back(newRef); } 然后尝试通过AVSampleBufferDisplayLayer(在另一个ViewController中)显示它们 AVSampleBufferDisplayLayer * displayLayer = [[AVSampleBufferDisplayLayer alloc] init]; displayLayer.bounds = self.view.bounds; displayLayer.position = CGPointMake(CGRectGetMidX(self.displayOnMe.bounds), CGRectGetMidY(self.displayOnMe.bounds)); displayLayer.videoGravity = AVLayerVideoGravityResizeAspectFill; displayLayer.backgroundColor = [[UIColor greenColor] CGColor]; [self.view.layer […]

内存泄漏在CMSampleBufferGetImageBuffer

我得到一个CMSampleBufferRefvideo缓冲区每N个video帧的UIImage ,如: – (void)imageFromVideoBuffer:(void(^)(UIImage* image))completion { CMSampleBufferRef sampleBuffer = _myLastSampleBuffer; if (sampleBuffer != nil) { CFRetain(sampleBuffer); CIImage *ciImage = [CIImage imageWithCVPixelBuffer:CMSampleBufferGetImageBuffer(sampleBuffer)]; _lastAppendedVideoBuffer.sampleBuffer = nil; if (_context == nil) { _context = [CIContext contextWithOptions:nil]; } CVPixelBufferRef buffer = CMSampleBufferGetImageBuffer(sampleBuffer); CGImageRef cgImage = [_context createCGImage:ciImage fromRect: CGRectMake(0, 0, CVPixelBufferGetWidth(buffer), CVPixelBufferGetHeight(buffer))]; __block UIImage *image = [UIImage imageWithCGImage:cgImage]; CGImageRelease(cgImage); […]

audioCMSampleBuffer的深度副本

我正在尝试创build一个由CaptureOutput在AVCaptureAudioDataOutputSampleBufferDelegate返回的CMSampleBuffer的副本。 我遇到的问题是,我的框架来自委托方法captureOutput:didOutputSampleBuffer:fromConnection:在我长时间保留在CFArray后被删除。 显然,我需要创build传入缓冲区的深层副本进行进一步处理。 我也知道CMSampleBufferCreateCopy只创build浅拷贝。 SO上提出的相关问题很less: 从CMSampleBuffer提取数据以创build深层副本 在Swift中创buildCMSampleBuffer的副本将返回OSStatus -12743(无效的媒体格式) CMImageBuffer或CVImageBuffer的深度拷贝 但是他们都没有帮我正确使用具有12个参数的CMSampleBufferCreate函数: CMSampleBufferRef copyBuffer; CMBlockBufferRef data = CMSampleBufferGetDataBuffer(sampleBuffer); CMFormatDescriptionRef formatDescription = CMSampleBufferGetFormatDescription(sampleBuffer); CMItemCount itemCount = CMSampleBufferGetNumSamples(sampleBuffer); CMTime duration = CMSampleBufferGetDuration(sampleBuffer); CMTime presentationStamp = CMSampleBufferGetPresentationTimeStamp(sampleBuffer); CMSampleTimingInfo timingInfo; timingInfo.duration = duration; timingInfo.presentationTimeStamp = presentationStamp; timingInfo.decodeTimeStamp = CMSampleBufferGetDecodeTimeStamp(sampleBuffer); size_t sampleSize = CMBlockBufferGetDataLength(data); CMBlockBufferRef sampleData; if (CMBlockBufferCopyDataBytes(data, 0, sampleSize, &sampleData) != […]

设置AVSampleBufferDisplayLayer呈现样本缓冲区的速率

我正在使用AVSampleBufferDisplayLayer来显示通过h.264格式的networking连接来的CMSampleBuffers。 video播放是顺利和正常工作,但我似乎无法控制帧速率。 特别是,如果我在AVSampleBufferDisplayLayer中每秒排列60帧,即使video以30 FPSlogging,它也会显示这60帧。 创build样本缓冲区时,可以通过向CMSampleBufferCreate传递一个时间信息数组来设置表示时间戳(时间信息不在h.264stream中,但可以通过容器格式进行计算或传递)。 我设置的演示时间戳大约相隔0.033秒,持续时间为0.033,但显示层仍然每秒显示尽可能多的帧数。 有两种方法可以在AVSampleBufferDisplayLayer上排队缓冲区:通过在缓冲区就绪时调用[AVSampleBufferDisplayLayer enqueueSampleBuffer:],或通过调用[AVSampleBufferDisplayLayer requestMediaDataWhenReadyOnQueue:usingBlock:]并使该块中的缓冲区排入队列,来“约束”缓冲区。 我已经尝试了两个,但即使第二个方法尽可能快地显示缓冲区 – 例如,如果我有300帧在接收端排队,那么上面的方法中的块第一次执行readyForMoreMediaData保持真实无论多less缓冲区会被排队,并且它们都会在很短的时间内显示出来。 如果在CMSampleBuffer上设置了kCMSampleAttachmentKey_DisplayImmediately附件,则此行为与预期的行为类似,但目前未设置(默认值为false)。 我试图设置图层controlTimeBase,但它似乎没有任何效果。 我在其他东西的损失尝试,无法find网上的例子。 有谁知道如何控制AVSampleBufferDisplayLayer显示帧的帧率?

如何将CMSampleBufferRef转换为NSData

你如何将CMSampleBufferRef转换为NSData? 我已经成功地获得了一个MPMediaItem的数据,通过在这个线程上的Erik Aigner的回答,但是数据的types是CMSampleBufferRef 。 我知道CMSampleBufferRef是一个结构,并在iOS开发库中的CMSampleBuffer参考中定义,但我不认为我完全理解它是什么。 没有一个CMSampleBuffer函数似乎是一个明显的解决scheme。

iOS – 缩放和裁剪CMSampleBufferRef / CVImageBufferRef

我正在使用AVFoundation并从AVCaptureVideoDataOutput获取示例缓冲区,我可以直接写入到videoWriter使用: – (void)writeBufferFrame:(CMSampleBufferRef)sampleBuffer { CMTime lastSampleTime = CMSampleBufferGetPresentationTimeStamp(sampleBuffer); if(self.videoWriter.status != AVAssetWriterStatusWriting) { [self.videoWriter startWriting]; [self.videoWriter startSessionAtSourceTime:lastSampleTime]; } [self.videoWriterInput appendSampleBuffer:sampleBuffer]; } 我现在要做的是在CMSampleBufferRef中裁剪和缩放图像,而不将其转换为UIImage或CGImageRef,因为这会降低性能。