我正试图通过MetalKit渲染I420(YCbCr规划器)
大多数例子都是使用来自Camera的CMSampleBuffer,
但我的目标是使用给定的I420字节.
我做这样的事情:
let data = NSMutableData(contentsOfURL: NSBundle.mainBundle().URLForResource("yuv_640_360", withExtension: "yuv")!)
// Cache for Y
CVMetalTextureCacheCreate(kCFAllocatorDefault, nil, self.device!, nil, &videoTextureCache)
var pixelBuffer: CVPixelBuffer?
CVPixelBufferCreateWithBytes(kCFAllocatorDefault, Int(size.width), Int(size.height), kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange, data.mutableBytes, Int(size.width), nil, nil, [
"kCVPixelBufferMetalCompatibilityKey": true,
"kCVPixelBufferOpenGLCompatibilityKey": true,
"kCVPixelBufferIOSurfacePropertiesKey": []
]
, &pixelBuffer)
// Y texture
var yTextureRef : Unmanaged<CVMetalTexture>?
let yWidth = CVPixelBufferGetWidthOfPlane(pixelBuffer, 0)
let yHeight = CVPixelBufferGetHeightOfPlane(pixelBuffer, 0)
let result = CVMetalTextureCacheCreateTextureFromImage(kCFAllocatorDefault, (videoTextureCache?.takeUnretainedValue())!, pixelBuffer, nil, MTLPixelFormat.R8Unorm, yWidth, yHeight, 0, &yTextureRef);
Run Code Online (Sandbox Code Playgroud)
基本上代码与其他示例几乎相同,但我自己创建自己的CVPixelBuffer.
我创建CVPixelBuffer和CVMetalTexture时没有出错,
但它总是为yTexture返回null.
如何创建正确的CVPixelBuffer并使用它进行渲染?
我有一个有趣的问题,我需要研究与非常低级别的视频流.
有没有人有过将原始字节流(分成每像素信息,但不是标准格式的视频)转换为低分辨率视频流的经验?我相信我可以将数据映射到每像素字节的RGB值,因为与原始数据中的值对应的颜色值将由我们确定.我不知道从那里去哪里,或者每个像素需要RGB格式.
我看过FFMPeg,但它的文档很大,我不知道从哪里开始.
我所包含的具体问题是,是否可以使用该像素数据创建CVPixelBuffer?如果我这样做,我需要转换为每像素数据的格式是什么?
另外,我是否应该更深入地研究OpenGL,如果是这样,哪里可以找到有关此主题的信息的最佳位置?
那么CGBitmapContextCreate呢?例如,如果我去了,我就是这样的,一个典型的像素字节需要看起来像什么?这是否足够快以保持帧速率高于20fps?
编辑:
我认为在你们的帮助下,以及我自己的一些研究,我已经制定了一个如何构建原始RGBA数据的计划,然后根据该数据构建CGImage,从而创建一个来自CGImage的CVPixelBuffer来自CGImage的CVPixelBuffer.
然而,为了在数据进入时播放,我不确定我会看到什么样的FPS.我是否将它们绘制到CALayer,或者是否有类似AVAssetWriter的类,我可以使用它来添加CVPixelBuffers.我的经验是使用AVAssetWriter将构建的CoreAnimation层次结构导出到视频,因此视频总是在开始播放之前构建,而不是显示为实时视频.
我收到了CMSampleBufferRef来自系统 API 的CVPixelBufferRefs,其中包含不是RGBA(线性像素)的s 。缓冲区包含平面像素(例如420faka kCVPixelFormatType_420YpCbCr8BiPlanarVideoRangeaka yCbCraka YUV)。
我想在将视频数据发送VideoToolkit到编码之前对其进行一些修改h264(绘制一些文本、覆盖徽标、旋转图像等),但我希望它高效且真实-时间。Buuuut 平面图像数据处理起来看起来很杂乱——有色度平面和亮度平面,它们的大小不同,而且……在字节级别上使用它似乎需要做很多工作。
我可能会使用 aCGContextRef并直接在像素顶部绘制,但据我所知,它仅支持 RGBA 像素。关于如何以尽可能少的数据复制和尽可能少的代码行来做到这一点的任何建议?
我有一个 CVImageBuffer,它的记录高度为 640 像素,宽度为 852 像素。每行的字节数为 3456。您会注意到 3456/852px != 4(类似于 4.05)。经过一些检查,864 将是使 bytesPerRow/width = 4.0 的宽度。因此,每行似乎都有一个额外的 12px(填充在右侧)。我假设这是因为这些缓冲区针对该图像没有的某些倍数进行了优化。
当我在 OpenGL 中渲染出这个缓冲区时,它看起来很糟糕(见下文)。我注意到该模式每 71 像素重复一次,这是有道理的,因为如果有额外的 12 像素,则 (852/12 像素 = 71)。因此,额外的 12 个像素似乎是导致问题的原因。
如何非常快速地摆脱这些额外的像素,然后使用这些数据读入 OpenGL ES?或者更确切地说,我如何通过跳过每一行上的这些额外像素来读入 OpenGL ES?

我正在编写一个自定义的Movie Recording应用程序,并已实现了AVAssetWriter和AVAssetWriterInputPixelBufferAdaptor,用于将帧写入文件.在DataOutputDelegate回调中,我尝试将CIFilter应用于sampleBuffer.首先,我得到一个CVPixelBufferRef,然后创建一个CIImage.然后我应用CIIFilter并获取生成的CIImage:
CVPixelBufferRef pixelBuffer = (CVPixelBufferRef)CMSampleBufferGetImageBuffer(sampleBuffer);
CIImage *image = [CIImage imageWithCVPixelBuffer:pixelBuffer];
CIFilter *hueAdjust = [CIFilter filterWithName:@"CIHueAdjust"];
[hueAdjust setDefaults];
[hueAdjust setValue: image forKey: @"inputImage"];
[hueAdjust setValue: [NSNumber numberWithFloat: 2.094]
forKey: @"inputAngle"];
CIImage *result = [hueAdjust valueForKey: @"outputImage"];
CVPixelBufferRef newBuffer = //Convert CIImage...
Run Code Online (Sandbox Code Playgroud)
我将如何转换CIImage以便我可以:
[self.filteredImageWriter appendPixelBuffer:newBuffer withPresentationTime:lastSampleTime];
Run Code Online (Sandbox Code Playgroud) 得到这个代码:
videoSize = [[AVPlayerItem playerItemWithAsset:asset] presentationSize];
Run Code Online (Sandbox Code Playgroud)
// nslogs - > height:000 width 000
这个已被弃用:
videoSize = [asset naturalSize];
Run Code Online (Sandbox Code Playgroud)
// nslogs - > height:360 width 480
为什么会这样?我不明白.
我在这里使用代码将 aCGImageRef转换为CVPixelBufferRefOS X 上的 a 。
将 UIImage 转换为 CVImageBufferRef
但是,我需要在 YUV(kCVPixelFormatType_420YpCbCr8Planar)而不是像现在这样的 RBG 中绘制图像。
反正有没有直接CGImage在YUV色彩空间中绘制一个?如果没有,没有任何人有去了解转换的最佳途径例如CVPixedBufferRef从RBG到YUV?
我了解转换的公式,但在 CPU 上进行转换非常缓慢。
我有一个视频播放器,需要播放来自网络的一系列视频.这些视频的URL不是事先知道的,因为它们来自其他HTTP请求的XML或JSON响应.
随着视频网址的出现,我创建AVPlayerItems并添加它们AVQueuePlayer.我观察玩家状态和项目状态以确定正在播放的项目等.
问题是玩家似乎进入各种奇怪的状态, AVFoundationErrorDomain error -11800然后玩家就会拒绝玩任何东西.即使在取消分配AVQueuePlayer和开始新的视频之后,之前播放的视频也拒绝播放.
是AVPlayerItems在播放AVQueuePlayer支持的操作时添加新内容,还是应该以另一种方式执行此操作?如果它受支持,我应该注意/做什么(例如.线程问题?KVO问题?)使这项工作?
我一直在研究gstreamer applemedia编码器插件,并改进了基于VideoToolbox的视频编码.运行gstreamer管道,如:
$ gst-launch-1.0 filesrc location=source.avi ! decodebin ! vtenc_h264 ! h264parse ! qtmux name=mux ! filesink location=sink.mp4
Run Code Online (Sandbox Code Playgroud)
VTCompressionSession在Mac OS系统上编码h264视频时,我期待看到非常低的CPU使用率.然而,在我测试过的系统上:2009年中期Macbook Pro配备GeForce 9600M和2011年中期Mac mini和Radeon HD 6630M,编码仍然消耗80%到130%的CPU - 这表明它不是硬件加速的.
在哪些硬件配置上,或给定哪些压缩参数(例如哪些kVTCompressionPropertyKey_ProfileLevel)确实VTCompressionSession使用硬件加速编码?
macos video-encoding gstreamer hardware-acceleration core-video
请告诉我这段代码泄漏的地方......
//这里我用文档目录中的图像制作了视频
- (void) testCompressionSession:(NSString *)path
{
if ([[NSFileManager defaultManager] fileExistsAtPath:path]) {
[[NSFileManager defaultManager] removeItemAtPath:path error:nil];
}
NSArray *array = [dictInfo objectForKey:@"sortedKeys"];
NSString *betaCompressionDirectory = path;
NSError *error = nil;
unlink([betaCompressionDirectory UTF8String]);
NSLog(@"array = %@",array);
NSData *imgDataTmp = [NSData dataWithContentsOfFile:[projectPath stringByAppendingPathComponent:[array objectAtIndex:0]]];
NSLog(@"link : %@",[projectPath stringByAppendingPathComponent:[array objectAtIndex:0]]);
CGSize size = CGSizeMake([UIImage imageWithData:imgDataTmp].size.width, [UIImage imageWithData:imgDataTmp].size.height);
//----initialize compression engine
NSLog(@"size : w : %f, h : %f",size.width,size.height);
AVAssetWriter *videoWriter = [[AVAssetWriter alloc] initWithURL:[NSURL fileURLWithPath:betaCompressionDirectory]
fileType:AVFileTypeQuickTimeMovie
error:&error];
NSParameterAssert(videoWriter);
if(error)
NSLog(@"error = %@", [error …Run Code Online (Sandbox Code Playgroud) 我正在开发AR应用程序.我有一个SceneKit场景被渲染到SCNView(使用OpenGL ES作为渲染API).在此下方是另一个显示相机实时预览的视图.我想创建一个包含视频和3D场景的电影.
我正在使用基于Apple的RosyWriter示例代码的代码来处理带有OpenGL着色器的视频帧像素缓冲区.我认为我不太了解这些概念,因为我不确定如何在视频帧上叠加SceneKit渲染.我可以从SCNView/SCNSceneRenderer获取像素缓冲区,还是需要使用SCNRenderer将场景重新渲染到OpenGL捕获管道用于处理视频帧的屏幕外缓冲区中的纹理?
根据Apple文档,它是存储在主存储器中的图像,但这些图像如何用于制作电影?
在我的 iOS 应用程序的 UI 中,我显示了一个复杂的CALayers层次结构。这些层之一是AVPlayerLayer显示视频并CIFilter实时应用 s(使用AVVideoComposition(asset:, applyingCIFiltersWithHandler:))。
现在我想将此图层合成导出到视频文件。有两个工具AVFoundation似乎很有帮助:
A:AVVideoCompositionCoreAnimationTool允许在(可能是动画的)CALayer层次结构中渲染视频
B : AVVideoComposition(asset:, applyingCIFiltersWithHandler:),我也在 UI 中使用,将CIFilters 应用于视频资产。
但是,这两个工具不能同时使用:如果我启动AVAssetExportSession结合了这些工具的一个,则AVFoundation抛出一个NSInvalidArgumentException:
期望视频合成仅包含
AVCoreImageFilterVideoCompositionInstruction
我尝试解决此限制,如下所示:
解决方法 1
1) 使用AVAssetReader和设置导出AVAssetWriter
2) 从资产读取器获取样本缓冲区并应用CIFilter,将结果保存在CGImage.
3) 将 设置CGImage为content图层层次结构中视频图层的 。现在图层层次结构“看起来像”最终视频的一帧。
4)CVPixelBuffer使用资产编写器获取每个帧的数据,CVPixelBufferGetBaseAddress并CGContext使用该数据创建一个。
5) 使用CALayer.render(in ctx: CGContext).
此设置有效,但速度极慢 - …
core-video ×13
ios ×10
iphone ×3
objective-c ×3
opengl-es ×3
core-image ×2
macos ×2
avasset ×1
avfoundation ×1
cifilter ×1
core-media ×1
deprecated ×1
encoding ×1
gstreamer ×1
ios6 ×1
metal ×1
metalkit ×1
replaykit ×1
rgb ×1
scenekit ×1
video ×1
yuv ×1