在 Unity 项目中使用 OpenGL ES 在 iOS 上进行纹理渲染
Texture rendering on iOS using OpenGL ES in Unity project
我正在做一个项目,其中一部分是将视频流式传输到我的 iPhone。我使用我的笔记本电脑通过 ffmpeg 为我的 iPhone 创建视频流。
shell中的流代码如下:
ffmpeg \
-f avfoundation -i "1" -s 1280*720 -r 29.97 \
-c:v mpeg2video -q:v 20 -pix_fmt yuv420p -g 1 -threads 4\
-f mpegts udp://192.168.1.102:6666
至此,我成功创建了视频流。
在 Unity 中,我想解码视频流以创建纹理。在完成一些 ffmpeg 教程和 Unity 教程后,我创建了 link 库。下面是其中一些代码(问我是否需要更多):
在我的图书馆中:
缓冲区分配:
uint8_t *buffer;
int buffer_size;
buffer_size = avpicture_get_size(AV_PIX_FMT_RGBA, VIEW_WIDTH, VIEW_HEIGHT);
buffer = (uint8_t *) av_malloc(buffer_size*sizeof(uint8_t));
avpicture_fill((AVPicture *) pFrameRGB, buffer, AV_PIX_FMT_RGBA,
VIEW_WIDTH, VIEW_HEIGHT);
获取上下文:
is->sws_ctx = sws_getContext
(
is->video_st->codec->width,
is->video_st->codec->height,
is->video_st->codec->pix_fmt,
VIEW_WIDTH,
VIEW_HEIGHT,
AV_PIX_FMT_RGBA,
SWS_BILINEAR,
NULL,
NULL,
NULL
);
sws_scale:
sws_scale(
is->sws_ctx,
(uint8_t const * const *)pFrame->data,
pFrame->linesize,
0,
is->video_st->codec->height,
pFrameRGB->data,
pFrameRGB->linesize
);
纹理渲染:
static void UNITY_INTERFACE_API OnRenderEvent(int texID)
{
GLuint gltex = (GLuint)(size_t)(texID);
glBindTexture(GL_TEXTURE_2D, gltex);
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, VIEW_WIDTH, VIEW_HEIGHT,
GL_RGBA, GL_UNSIGNED_BYTE, pFrameRGB->data[0]);
glGetError();
return;
}
extern "C" UnityRenderingEvent UNITY_INTERFACE_EXPORT UNITY_INTERFACE_API GetRenderEventFunc()
{
return OnRenderEvent;
}
在 Unity 中:
纹理创建:
private Texture2D texture;
private int texID;
texture = new Texture2D (width, height, TextureFormat.RGBA32, false);
texture.filterMode = FilterMode.Point;
texture.Apply ();
GetComponent<Renderer> ().material.mainTexture = texture;
texID = texture.GetNativeTexturePtr ().ToInt32();
更新功能:
void Update ()
{
GL.IssuePluginEvent(GetRenderEventFunc(), texID);
}
视频流信息:
Input #0, mpegts, from 'udp://0.0.0.0:6666':
Duration: N/A, start: 2.534467, bitrate: N/A
Program 1
Metadata:
service_name : Service01
service_provider: FFmpeg
Stream #0:0[0x100]: Video: mpeg2video (Main) ([2][0][0][0] / 0x0002), yuv420p(tv), 1280x720 [SAR 1:1 DAR 16:9], max. 104857 kb/s, 29.97 fps, 29.97 tbr, 90k tbn, 59.94 tbc
留下其他细节,我的库在 Unity 模拟器上运行良好,但是当我为 arm64 编译我的所有库并使用 Unity 创建的 xcode 项目来构建我的应用程序并 运行 它,我无法在我的 iPhone 中渲染任何纹理,我检查了我的网络,我确定数据已发送到我的 iPhone 并且调试日志显示该帧已成功解码OnRenderEvent
函数也被调用了。
仅供参考:
Unity 5.3.2f1 个人版
Xcode7.2.1
iOS 9.2.1
ffmpeg 3.0
嗯,我自己想出来了。
原来Unity 5.3.2f1中iOS 9的Graphics APIs默认是Auto Graphics API
,以后会是Metal
,所以在我的app 我无法使用 OpenGL ES
API 来操纵我的框架。
我把Graphics API
设置成OpenGL ES 3
后,一切顺利
我正在做一个项目,其中一部分是将视频流式传输到我的 iPhone。我使用我的笔记本电脑通过 ffmpeg 为我的 iPhone 创建视频流。
shell中的流代码如下:
ffmpeg \
-f avfoundation -i "1" -s 1280*720 -r 29.97 \
-c:v mpeg2video -q:v 20 -pix_fmt yuv420p -g 1 -threads 4\
-f mpegts udp://192.168.1.102:6666
至此,我成功创建了视频流。
在 Unity 中,我想解码视频流以创建纹理。在完成一些 ffmpeg 教程和 Unity 教程后,我创建了 link 库。下面是其中一些代码(问我是否需要更多):
在我的图书馆中:
缓冲区分配:
uint8_t *buffer;
int buffer_size;
buffer_size = avpicture_get_size(AV_PIX_FMT_RGBA, VIEW_WIDTH, VIEW_HEIGHT);
buffer = (uint8_t *) av_malloc(buffer_size*sizeof(uint8_t));
avpicture_fill((AVPicture *) pFrameRGB, buffer, AV_PIX_FMT_RGBA,
VIEW_WIDTH, VIEW_HEIGHT);
获取上下文:
is->sws_ctx = sws_getContext
(
is->video_st->codec->width,
is->video_st->codec->height,
is->video_st->codec->pix_fmt,
VIEW_WIDTH,
VIEW_HEIGHT,
AV_PIX_FMT_RGBA,
SWS_BILINEAR,
NULL,
NULL,
NULL
);
sws_scale:
sws_scale(
is->sws_ctx,
(uint8_t const * const *)pFrame->data,
pFrame->linesize,
0,
is->video_st->codec->height,
pFrameRGB->data,
pFrameRGB->linesize
);
纹理渲染:
static void UNITY_INTERFACE_API OnRenderEvent(int texID)
{
GLuint gltex = (GLuint)(size_t)(texID);
glBindTexture(GL_TEXTURE_2D, gltex);
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, VIEW_WIDTH, VIEW_HEIGHT,
GL_RGBA, GL_UNSIGNED_BYTE, pFrameRGB->data[0]);
glGetError();
return;
}
extern "C" UnityRenderingEvent UNITY_INTERFACE_EXPORT UNITY_INTERFACE_API GetRenderEventFunc()
{
return OnRenderEvent;
}
在 Unity 中:
纹理创建:
private Texture2D texture;
private int texID;
texture = new Texture2D (width, height, TextureFormat.RGBA32, false);
texture.filterMode = FilterMode.Point;
texture.Apply ();
GetComponent<Renderer> ().material.mainTexture = texture;
texID = texture.GetNativeTexturePtr ().ToInt32();
更新功能:
void Update ()
{
GL.IssuePluginEvent(GetRenderEventFunc(), texID);
}
视频流信息:
Input #0, mpegts, from 'udp://0.0.0.0:6666':
Duration: N/A, start: 2.534467, bitrate: N/A
Program 1
Metadata:
service_name : Service01
service_provider: FFmpeg
Stream #0:0[0x100]: Video: mpeg2video (Main) ([2][0][0][0] / 0x0002), yuv420p(tv), 1280x720 [SAR 1:1 DAR 16:9], max. 104857 kb/s, 29.97 fps, 29.97 tbr, 90k tbn, 59.94 tbc
留下其他细节,我的库在 Unity 模拟器上运行良好,但是当我为 arm64 编译我的所有库并使用 Unity 创建的 xcode 项目来构建我的应用程序并 运行 它,我无法在我的 iPhone 中渲染任何纹理,我检查了我的网络,我确定数据已发送到我的 iPhone 并且调试日志显示该帧已成功解码OnRenderEvent
函数也被调用了。
仅供参考:
Unity 5.3.2f1 个人版
Xcode7.2.1
iOS 9.2.1
ffmpeg 3.0
嗯,我自己想出来了。
原来Unity 5.3.2f1中iOS 9的Graphics APIs默认是Auto Graphics API
,以后会是Metal
,所以在我的app 我无法使用 OpenGL ES
API 来操纵我的框架。
我把Graphics API
设置成OpenGL ES 3
后,一切顺利