2017-10-03 21 views
1

私はFFmpegを使ってUnityプレーヤー内にビデオレコーダーを作成しようとしています。ffmpegのUnity texture2dをYUV420Pに変換する

私は次のコードスニペットがあります。それは "sws_scale" をやっているとき

__declspec(dllexport) void AddFrame(uint8_t *data, int size, VideoCapture *vc) { 
    vc->AddFrame(data, size); 
} 

void VideoCapture::AddFrame(uint8_t *data, int size) { 
    Log("\nAdding frame\n"); 

    int err; 
    if (!videoFrame) { 
     Log("Allocating Video Frame\n"); 

     videoFrame = av_frame_alloc(); 
     videoFrame->format = AV_PIX_FMT_YUV420P; 
     videoFrame->width = cctx->width; 
     videoFrame->height = cctx->height; 

     if ((err = av_frame_get_buffer(videoFrame, 32)) < 0) { 
      Debug("Failed to allocate picture", err); 
      return; 
     } 
    } 

    if (!swsCtx) { 
     Log("Creating SWS context\n"); 
     swsCtx = sws_getContext(cctx->width, cctx->height, AV_PIX_FMT_RGB24, cctx->width, cctx->height, AV_PIX_FMT_YUV420P, 0, 0, 0, 0); 
    } 

    uint8_t * inData[1] = { data }; 
    int inLinesize[1] = { 3 * cctx->width }; 

    Log("Scaling data\n"); 
    // From RGB to YUV 
    if ((err = sws_scale(swsCtx, inData, inLinesize, 0, cctx->height, videoFrame->data, videoFrame->linesize)) < 0) { 
     Debug("Failed to scale img", err); 
     return; 
    } 
    ........... 

ユニティプレーヤーがクラッシュ:

ユニティ、C#:

Texture2D frameTexture = new Texture2D(frameWidth, frameHeight, TextureFormat.RGB24, false); 
//... 
frameTexture.ReadPixels(new Rect(0, 0, frameWidth, frameHeight), 0, 0, false); 
frameTexture.Apply(); 
//..... 
byte[] pixels = frameTexture.GetRawTextureData(); 
AddFrame(pixels, pixels.Length, libApi); 


//DLL Function Declaration 
[DllImport("VideoCapture", CallingConvention = CallingConvention.Cdecl)] 
static extern void AddFrame(byte[] data, int size, System.IntPtr api); 

C++のコードを。 Unityから

ログ:

ERROR: SymGetSymFromAddr64, GetLastError: 'Attempt to access invalid address.' (Address: 00007FF8437B49A6) 
0x00007FF8437B49A6 (swscale-4) 
    ERROR: SymGetSymFromAddr64, GetLastError: 'Attempt to access invalid address.' (Address: 00007FF8437B2982) 
0x00007FF8437B2982 (swscale-4) 
0x00007FF8437E78A6 (swscale-4) sws_get_class 
0x00007FF8437E8E47 (swscale-4) sws_scale 

私はそのために「sws_get_class」と思ったが、私はこの関数を直接呼び出す場合はそれが動作します。空のデータを 'sws_scale'に渡して、それがNULLだと不平を言う場合にも機能します。だから、その理由はデータそのものですが、私は何が間違っているのではありません。

また、JPGとPNGにテクスチャをエンコードしようとしましたが、メモリに固定されていましたが、結果は変わりませんでした。事前に

おかげ

UPD :::

変更DLL関数

unsafe void AddFrame(byte[] data) 
{ 
    fixed (byte* p = data) 
    { 
     AddFrame((IntPtr)p, data.Length, customLib); 
    } 
} 
//Function declaration 
static extern void AddFrame(IntPtr data, int size, System.IntPtr api); 

に呼び出したが、エラーがまだそこにあります。

+0

あなたのC# 'AddFrame'関数は3つのパラメータをとりますが、C++の' AddFrame'関数は2つのパラメータしか持ちません....また、配列を固定しません。あなたは基本的に私の[他の](https://stackoverflow.com/a/46527921/3785314)の答えで言ったことを無視します。 – Programmer

+0

@Programmer、メインの質問にすべての情報を追加しました。私はあなたがその答えで言ったようにすべてをしました。 –

+0

他の問題が発生しているにもかかわらず、後でこれを削除しないでください。それが必要でないなら、私はそれを書くのに時間を費やしません。あなたの問題については、私が心に留めていたほとんどの事柄が削除されているので、私は実際にはわかりませんが、問題は 'sws_scale'行からどういうことを知っていますか? – Programmer

答えて

0

sws_scaleが失敗したのは、sws_getContextsws_scaleのソースの高さと幅が正しくありません。 Unityでは、メソッドまたはハードコアの値に次元を渡す必要があります。

sws_scale出力スライスの高さを返します。エラーではありません。

関連する問題