我正在尝试将样本从 Objective C 转换为 Monotouch,但遇到了一些困难。
基本上我想读取一个视频文件,并将帧一一解码为opengl纹理。
这样做的关键是使用 AVAssetReader,但我不确定如何在 Monotouch 中正确设置它。
这是我的代码:
AVUrlAsset asset=new AVUrlAsset(NSUrl.FromFilename(videoFileName),null);
assetReader=new AVAssetReader(asset,System.IntPtr.Zero);
AVAssetTrack videoTrack=asset.Tracks[0];
NSDictionary videoSettings=new NSDictionary();
NSString key = CVPixelBuffer.PixelFormatTypeKey;
NSNumber val=0x754b9d0; //NSNumber* value = [NSNumber numberWithUnsignedInt:kCVPixelFormatType_32BGRA]; - Had to hardcode constant as it is not defined in Monotouch?
videoSettings.SetNativeField(key,val);
//**The program crashes here:
AVAssetReaderTrackOutput trackOutput=new AVAssetReaderTrackOutput(videoTrack,videoSettings);
assetReader.AddOutput(trackOutput);
assetReader.StartReading();
程序在上面指出的那一行崩溃,出现无效参数异常,说明 NSDictionary 的内容格式不正确?我检查了视频文件,它加载良好,“资产”包含有关视频的有效信息。
这是原始的 Objective C 代码:
NSString* key = (NSString*)kCVPixelBufferPixelFormatTypeKey;
NSNumber* value = [NSNumber numberWithUnsignedInt:kCVPixelFormatType_32BGRA];
NSDictionary* videoSettings = [NSDictionary dictionaryWithObject:value forKey:key];
AVAssetReaderTrackOutput *trackOutput = [AVAssetReaderTrackOutput assetReaderTrackOutputWithTrack:videoTrack outputSettings:videoSettings];
[_assetReader addOutput:trackOutput];
[_assetReader startReading];
我不是那么喜欢Objective C,所以感谢您的帮助。
编辑:我使用了下面建议的代码
var videoSettings = NSDictionary.FromObjectAndKey (
new NSNumber ((int) MonoTouch.CoreVideo.CVPixelFormatType.CV32BGRA),
MonoTouch.CoreVideo.CVPixelBuffer.PixelFormatTypeKey);
并且程序不再崩溃。通过使用以下代码:
CMSampleBuffer buffer=assetReader.Outputs[0].CopyNextSampleBuffer();
CVImageBuffer imageBuffer = buffer.GetImageBuffer();
我得到了应该包含视频文件中下一帧的图像缓冲区。通过检查 imageBuffer 对象,我发现它具有与视频文件匹配的宽度和高度等有效数据。
但是,imageBuffer BaseAddress 始终为 0,表示图像没有数据?我试图这样做作为一个测试:
CVPixelBuffer buffer=(CVPixelBuffer)imageBuffer;
CIImage image=CIImage.FromImageBuffer(buffer);
并且图像始终返回为空。这是否意味着实际的图像数据不存在,而我的 imageBuffer 对象仅包含帧头信息?
如果是这样,这是 Monotouch 中的错误,还是我设置错误?
我有一个想法,我可能需要等待图像数据准备好,但在这种情况下,我也不知道怎么做。现在很卡...