Большое вам спасибо, хотя предоставленный вами образец не сработал, он мне очень помог. :)
Это код, с которым я закончил (я немного отредактировал его для ясности):
[DllImport (MonoTouch.Constants.CoreVideoLibrary)]
extern static int CVOpenGLESTextureCacheCreateTextureFromImage (
IntPtr allocator,
IntPtr textureCache,
IntPtr sourceImage,
IntPtr textureAttributes,
int target,
int internalFormat,
int width,
int height,
int format,
int type,
int planeIndex,
ref IntPtr textureOut);
[DllImport (MonoTouch.Constants.CoreVideoLibrary)]
extern static int CVOpenGLESTextureCacheFlush (IntPtr texture, int v);
[DllImport (MonoTouch.Constants.CoreVideoLibrary)]
extern static int CVOpenGLESTextureGetName (IntPtr texture);
[DllImport (MonoTouch.Constants.CoreFoundationLibrary, CharSet=CharSet.Unicode)]
internal extern static IntPtr CFRelease (IntPtr obj);
private IntPtr videoTextureCache;
unsafe public void setTexture(CVImageBuffer sampleBuffer)
{
int err;
if (videoTextureCache == IntPtr.Zero) {
EAGLContext eaglContext=Global.localScreen.view.Context;
err = CVOpenGLESTextureCacheCreate (IntPtr.Zero, IntPtr.Zero, eaglContext.Handle, IntPtr.Zero, out videoTextureCache);
if (err != 0){
Console.WriteLine ("Error at CVOpenGLESTextureCacheCreate {0}", err);
return;
}
}
CVPixelBuffer pixelBuffer = (CVPixelBuffer) sampleBuffer;
pixelBuffer.Lock (CVOptionFlags.None);
int frameWidth = pixelBuffer.Width;
int frameHeight = pixelBuffer.Height;
IntPtr texture = IntPtr.Zero;
err = CVOpenGLESTextureCacheCreateTextureFromImage(IntPtr.Zero,
videoTextureCache,
pixelBuffer.Handle,
IntPtr.Zero,
(int)All.Texture2D,
(int)All.Rgba,
frameWidth,
frameHeight,
(int)All.Bgra,
(int)All.UnsignedByte,
0,
ref texture);
if (texture == IntPtr.Zero || err != 0) {
Console.WriteLine("CVOpenGLESTextureCacheCreateTextureFromImage failed (error: {0})", err);
return;
} else {
Console.WriteLine ("Texture name: {0}", CVOpenGLESTextureGetName(texture));
}
CVOpenGLESTextureCacheFlush(videoTextureCache, 0);
CFRelease(texture);
pixelBuffer.Unlock (CVOptionFlags.None);
}
У меня все еще есть странные проблемы. При воспроизведении видео и отправке отдельных кадров способом, описанным выше, кадры отрисовываются в несколько случайном порядке, заставляя видео мерцать, хотя кадры действительно приходят в правильном порядке в этот метод.
В основном поток программы выглядит так:
- Извлечение видеокадра (я знаю, что они действительно идут в правильном порядке)
- Подайте кадр вышеописанным способом и создайте текстуру
- Рисование текстуры (фактически рисуется кадр +/- 5 кадров из текущего кадра)
Очень просто, но, кажется, Monotouch плохо играет.
Это странно, поскольку приведенный выше код является точной копией версии xCode, которая работает нормально. Не уверен, что происходит, но я подозреваю, что это связано с автоматическим управлением памятью в Monotouch.
Кроме того, если видео имеет разрешение не в два раза больше, я получаю черную текстуру ... Не проблема при использовании Objective C. Опять же, не уверен, что здесь происходит с Monotouch ... (