gpt4 book ai didi

c# - 将 Unity texture2d 转换为 ffmpeg 的 YUV420P

转载 作者:塔克拉玛干 更新时间:2023-11-03 07:08:04 34 4
gpt4 key购买 nike

我正在尝试使用 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_getContextsws_scale 传递了不正确的源高度和宽度。您应该将维度传递给 Unity 中的方法或核心值。

此外,sws_scale 返回输出切片的高度,而不是错误。

关于c# - 将 Unity texture2d 转换为 ffmpeg 的 YUV420P,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46545422/

34 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com