[英]Converting Unity texture2d to YUV420P for ffmpeg
我正在嘗試使用 FFmpeg 在 Unity 播放器中創建錄像機。
我有下一個代碼片段:
統一,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++代碼:
__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;
}
...........
Unity 播放器在執行“sws_scale”時崩潰。
來自 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);
但是錯誤仍然存在。
sws_scale
失敗的原因是為sws_getContext
和sws_scale
傳遞了不正確的源高度和寬度。 您應該將維度傳遞給 Unity 中的方法或核心值。
此外sws_scale
返回輸出切片的高度,而不是錯誤。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.