私は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);
に呼び出したが、エラーがまだそこにあります。
あなたのC# 'AddFrame'関数は3つのパラメータをとりますが、C++の' AddFrame'関数は2つのパラメータしか持ちません....また、配列を固定しません。あなたは基本的に私の[他の](https://stackoverflow.com/a/46527921/3785314)の答えで言ったことを無視します。 – Programmer
@Programmer、メインの質問にすべての情報を追加しました。私はあなたがその答えで言ったようにすべてをしました。 –
他の問題が発生しているにもかかわらず、後でこれを削除しないでください。それが必要でないなら、私はそれを書くのに時間を費やしません。あなたの問題については、私が心に留めていたほとんどの事柄が削除されているので、私は実際にはわかりませんが、問題は 'sws_scale'行からどういうことを知っていますか? – Programmer