简体   繁体   English

Monotouch AVAssetReader

[英]Monotouch AVAssetReader

I'm trying to convert a sample from objective C to Monotouch, and I have run into some difficulties. 我试图将样本从目标C转换为Monotouch,但遇到了一些困难。

Basically I want to read a video file, and decode the frames one by one to an opengl texture. 基本上,我想读取视频文件,并将帧一一解码为opengl纹理。

The key to doing this is to use the AVAssetReader, but I am not sure how to set this up properly in Monotouch. 这样做的关键是使用AVAssetReader,但是我不确定如何在Monotouch中正确设置它。

This is my code: 这是我的代码:

    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();

The program crashes on the line indicated above, with an invalid argument exception, indicating that the content of the NSDictionary is not in the right format? 程序在上面指出的行上崩溃,并带有无效的参数异常,这表明NSDictionary的内容格式不正确? I have checked the video file, and it loads well, "asset" contains valid information about the video. 我已经检查了视频文件,并且文件加载良好,“资产”包含有关视频的有效信息。

This is the original Objective C code: 这是原始的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];

I'm not that into Objective C, so any help is appreciated. 我对目标C的了解还不多,因此可以提供任何帮助。

EDIT: I used the code suggested below 编辑:我用下面建议的代码

var videoSettings = NSDictionary.FromObjectAndKey (
  new NSNumber ((int) MonoTouch.CoreVideo.CVPixelFormatType.CV32BGRA),
  MonoTouch.CoreVideo.CVPixelBuffer.PixelFormatTypeKey);

And the program no longer crashes. 并且程序不再崩溃。 By using the following code: 通过使用以下代码:

        CMSampleBuffer buffer=assetReader.Outputs[0].CopyNextSampleBuffer();
        CVImageBuffer imageBuffer = buffer.GetImageBuffer();

I get the image buffer which should contain the next frame in the video file. 我得到图像缓冲区,该缓冲区应包含视频文件中的下一帧。 By inspecting the imageBuffer object, I find it has valid data such as the width and height, matching that of the video file. 通过检查imageBuffer对象,我发现它具有有效的数据,例如宽度和高度,与视频文件的数据匹配。

However, the imageBuffer BaseAddress is always 0, which indicates the image has no data? 但是,imageBuffer BaseAddress始终为0,这表示图像没有数据吗? I tried to do this as a test: 我尝试将其作为测试:

        CVPixelBuffer buffer=(CVPixelBuffer)imageBuffer;
        CIImage image=CIImage.FromImageBuffer(buffer);

And image is always returned as null. 并且图像始终返回为null。 Does this mean the actual image data is not present, and my imageBuffer object only contains the frame header info? 这是否意味着不存在实际的图像数据,并且我的imageBuffer对象仅包含帧头信息?

And if so, is this a bug in Monotouch, or am I setting this up wrong? 如果是这样,这是Monotouch中的错误,还是我将其设置为错误?

I had an idea that I may need to wait for the image data to be ready, but in that case, I do not know how either. 我有一个想法,我可能需要等待图像数据准备就绪,但是在那种情况下,我也不知道该怎么办。 Pretty stuck now... 现在很卡住...

You need to create the NSDictionary like this: 您需要像这样创建NSDictionary:

var videoSettings = NSDictionary.FromObjectAndKey (
  new NSNumber ((int) MonoTouch.CoreVideo.CVPixelFormatType.CV32BGRA),
  MonoTouch.CoreVideo.CVPixelBuffer.PixelFormatTypeKey);

SetNativeField is something completely different (you're setting the field named CVPixelBuffer.PixelFormatTypeKey to 0x754b9d0 , not adding a key/value pair to the dictionary). SetNativeField是完全不同的东西(您将名为CVPixelBuffer.PixelFormatTypeKey的字段设置为0x754b9d0 ,未在字典中添加键/值对)。

[NSNumber numberWithUnsignedInt:kCVPixelFormatType_32BGRA]; [NSNumber numberWithUnsignedInt:kCVPixelFormatType_32BGRA]; - Had to hardcode constant as it is not defined in Monotouch? -是否必须对常量进行硬编码,因为它不是在Monotouch中定义的?

You should be able to replace this with: 您应该可以将其替换为:

CVPixelFormatType.CV32BGRA

Note that MonoTouch defines this value as 0x42475241 which differs from yours. 请注意,MonoTouch将此值定义为0x42475241 ,该值与您的不同。 That could be your error. 那可能是你的错误。 If not I suggest you to make a small, self contained, test case and attach it to a bug report on http://bugzilla.xamarin.com and we'll have a look at it. 如果不是,我建议您制作一个小的独立测试用例,并将其附加到http://bugzilla.xamarin.com上的错误报告中,我们将对其进行研究。

A link to the objective-c sample, if available, would be helpful too (here to an update to your question or on the bug report). 链接到Objective-C示例(如果可用)也将很有帮助(此处是您问题的更新或错误报告)。

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

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