2012-03-07 13 views
0

は私がMonoTouchでに次のコードを変換しようとしている:このOpenGLコードをxcodeからMonotouchに移植するにはどうすればいいですか?

if (videoTextureCache == NULL) { 
    // Create a new CVOpenGLESTexture cache 
    CVReturn err = CVOpenGLESTextureCacheCreate(kCFAllocatorDefault, NULL, self.context, NULL, &videoTextureCache); 
    if (err) { 
     NSLog(@"Error at CVOpenGLESTextureCacheCreate %d", err); 
    } 
} 

if (videoTextureCache) { 
    CMSampleBufferRef sampleBuffer = self.videoFrameReader.sampleBuffer; 
    CVImageBufferRef imageBuffer = CMSampleBufferGetImageBuffer(sampleBuffer); 
    CVPixelBufferLockBaseAddress(imageBuffer, 0); 

    // Create a CVOpenGLESTexture from the CVImageBuffer 
    size_t frameWidth = CVPixelBufferGetWidth(imageBuffer); 
    size_t frameHeight = CVPixelBufferGetHeight(imageBuffer); 
    CVOpenGLESTextureRef texture = NULL; 
    CVReturn err = CVOpenGLESTextureCacheCreateTextureFromImage(kCFAllocatorDefault, 
                   videoTextureCache, 
                   imageBuffer, 
                   NULL, 
                   GL_TEXTURE_2D, 
                   GL_RGBA, 
                   frameWidth, 
                   frameHeight, 
                   GL_BGRA, 
                   GL_UNSIGNED_BYTE, 
                   0, 
                   &texture); 
    if (!texture || err) { 
     NSLog(@"CVOpenGLESTextureCacheCreateTextureFromImage failed (error: %d)", err); 
     return; 
    } else { 
     self.cubeTextureName = CVOpenGLESTextureGetName(texture); 
    } 

    // Flush the CVOpenGLESTexture cache and release the texture 
    CVOpenGLESTextureCacheFlush(videoTextureCache, 0); 
    CFRelease(texture); 

    CVPixelBufferUnlockBaseAddress(imageBuffer, 0); 

それは速いOpenGLのテクスチャにビデオのレンダリングに関連しています。優れたパフォーマンスでxCodeがうまく動作しますが、今はMonotouch関連のプロジェクトで動作させる必要があります。

しかし、CVOpenGLESTextureCacheCreateTextureFromImageやCVOpenGLESTextureCacheCreateのように、上記のキーメソッドについて必要なMonotouchバインディングやMonoTouch関連のドキュメントが見つからないので、このコードを移植する方法がかなり失われています。彼らはモノトゥッチから逃していますか?

私はそれらを呼び出す方法はありますか?

答えて

2

私はOpenGLと非常に精通していないですので、私はサンプル間違っを得ますが、ここでの出発点であるかもしれません。

using System; 
using System.Collections.Generic; 
using System.Linq; 

using MonoTouch.Foundation; 
using MonoTouch.UIKit; 
using MonoTouch.CoreVideo; 
using MonoTouch.CoreMedia; 
using System.Runtime.InteropServices; 
using MonoTouch.OpenGLES; 
using OpenTK.Platform.iPhoneOS; 
using OpenTK.Graphics.ES20; 
using OpenTK; 

namespace cv1 
{ 
    [Register ("AppDelegate")] 
    public partial class AppDelegate : UIApplicationDelegate 
    { 
     UIWindow window; 

     [DllImport (MonoTouch.Constants.CoreVideoLibrary)] 
     extern static int CVOpenGLESTextureCacheCreate (IntPtr alloc, IntPtr cache, IntPtr eaglContext, IntPtr textureAttr, out IntPtr cache); 

     [DllImport (MonoTouch.Constants.CoreVideoLibrary)] 
     extern static int CVOpenGLESTextureCacheCreateTextureFromImage (IntPtr alloc, IntPtr textureCache, IntPtr sourceImage, IntPtr textureAttr, EnableCap target, PixelFormat internalFormat, int width, int height, int format, DataType type, int planeIndex, out IntPtr texture); 
     [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); 

     IntPtr videoTextureCache; 

     void Stuff (EAGLContext context) 
     { 
      int err; 
      if (videoTextureCache == IntPtr.Zero) { 
       err = CVOpenGLESTextureCacheCreate (IntPtr.Zero, IntPtr.Zero, context.Handle, IntPtr.Zero, out videoTextureCache); 
       if (err != 0){ 
        Console.WriteLine ("Error at CVOpenGLESTextureCacheCreate {0}", err); 
        return; 
       } 
      } 
      CMSampleBuffer sampleBuffer = null; //videoFrameReader.SampleBuffer; 
      CVPixelBuffer imageBuffer = (CVPixelBuffer) sampleBuffer.GetImageBuffer(); 
      imageBuffer.Lock (CVOptionFlags.None); 
      int frameWidth = imageBuffer.Width; 
      int frameHeight = imageBuffer.Height; 

      IntPtr texture = IntPtr.Zero; 
      err = CVOpenGLESTextureCacheCreateTextureFromImage(IntPtr.Zero, 
                   videoTextureCache, 
                   imageBuffer.Handle, 
                   IntPtr.Zero, 
                   EnableCap.Texture2D, 
                   PixelFormat.Rgba, 
                   frameWidth, 
                   frameHeight, 
                   0x10B6, 
                   DataType.UnsignedByte, 
                   0, 
                   out 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); 

      imageBuffer.Unlock (CVOptionFlags.None); 
     } 

     public override bool FinishedLaunching (UIApplication app, NSDictionary options) 
     { 
      window = new UIWindow (UIScreen.MainScreen.Bounds); 
      window.MakeKeyAndVisible(); 


      return true; 
     } 
    } 
} 

あなたはデータポイントのカップルを提供しなかったので、私はちょうどに持っていましたヌル値のままにしておくか、値に何も割り当てずに値を出力します。

+0

これはsize_t(intに、私が疑ったように)をバインドする方法の無関係な質問に答えるので、ありがとう!:-) – Dermot

0

ありがとう、あなたが提供したサンプルはうまくいかなかったが、それは私をそこに連れて行くのに大いに役立った。 :)

これは私が(私は明確にするため、ややそれを編集した)になってしまったコードです:

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

    } 

私はまだかかわらず、いくつかの奇妙な問題を抱えています。ビデオを再生し、上記の方法に個々のフレームを送信するとき、フレームは実際にはそのメソッドに正しい順序で来るが、ビデオはちらつきを作って、ややランダムな順序で描画されます。

は、基本的にはプログラムの流れは、このようなものです:

  1. 抽出ビデオフレーム上記の方法に
  2. フィードフレームを(私は彼らが実際に正しい順序で来るのか知っている)、およびテクスチャを作成
  3. テクスチャを描く(現在のフレームから+/- 5フレームのフレームが実際に描画されます)

非常にシンプルですが、モノトゥッチはうまくいきません。

上記のコードは、xCodeバージョンの正確なレプリカであり、正常に動作するので、これは奇妙です。何が起こっているのかは分かりませんが、Monotouchの自動メモリ管理に関係していると思われます。

ビデオが2の累乗である解像度でない場合、私は黒いテクスチャを取得します... Objective Cを使用する場合は問題ありません。ここでもモノトゥーで何が起こっているのかわかりません。 。:(

関連する問題