unity3d - 在每次更新时将来自 iOS 的视频纹理数据渲染到统一的 Texture2d
问题描述
背景:我正在创建一个使用 Dji SDK for iOS 的应用程序。我已经集成了 SDK,并且可以注册 DJI 的应用程序。我能够获得无人机连接和型号名称。
接下来,我打算使用 sdk 在无人机上启动视频流并在移动屏幕上捕获相同的视频流。但是有一个转折点。
设置:我的应用程序是基于统一的,并打算使用统一的一些功能。因此,我通过这种方法从 dji sdk 获得的数据
-(void)videoFeed:(nonnull DJIVideoFeed *)videoFeed didUpdateVideoData:(nonnull NSData *)videoData{
[[DJIVideoPreviewer instance] push:(uint8_t *)videoData.bytes length:(int)videoData.length];
需要发送到统一,我将在 Texture2d 中渲染它,由统一提供。
问题:我无法转换上述方法中存在的 videoData 并将其以统一可以理解的格式发送并在 Texture2d 对象中呈现。
我得到了一些与 _GetNativeTexturePtr 和 MTLTexture 相关的建议,但它对我不起作用。
目标:在每个调用的 update() 函数上将 NSData * videoData 从 iOS 传输到统一的 Texture2d 对象并在那里渲染。
任何帮助表示赞赏,谢谢!
为了更清楚地理解,我分享了我在 Android 中的表现(它在 android 中工作):
static Texture2D videoStreamTexture;
protected override Texture2D StartVideoStream_Native() {
int width = droneNativeObject.Get<int>("width");
int height = droneNativeObject.Get<int>("height");
if (videoStreamTexture == null)
videoStreamTexture = new Texture2D(width, height, TextureFormat.RGBA32, false);
droneNativeObject.Call("StartStream", videoStreamTexture.GetNativeTexturePtr().ToInt32()/*, 1920, 1088*/);
return videoStreamTexture;
}
protected override void StopVideoStream_Native() {
droneNativeObject.Call("StopStream");
/* if (videoStreamTexture != null) {
UnityEngine.Object.DestroyImmediate(videoStreamTexture);
videoStreamTexture = null;
}*/
}
public override void Update() {
base.Update();
if (IsStreaming && droneNativeObject != null &&videoStreamTexture != null) {
var frame = droneNativeObject.Call<AndroidJavaObject>("GetCameraFrame");
if (frame == null)
return;
byte[] bytes = frame.Get<byte[]>("jpegFrame");
int width = frame.Get<int>("width");
int height = frame.Get<int>("height");
if (bytes != null && bytes.Length > 0) {
//Debug.Log("texture size: width " + videoStreamTexture.width + " height " + videoStreamTexture.height);
videoStreamTexture.LoadRawTextureData(bytes);
videoStreamTexture.Apply(false);
}
}
}
原生安卓代码:
public int width = 1280;
public int height = 720;
public void StartStream(int textureId/*,int textureWidth, int textureHeight*/){
if(isStreaming)
return;
isStreaming = true;
cameraFrameIndex = -1;
lastPublishedCameraFrameIndex = -1;
if(surfaceTexture == null)
surfaceTexture = new SurfaceTexture(textureId);
//surfaceTexture.setDefaultBufferSize(width, height);
SetCameraToRecordMode();
if(codecManager == null)
codecManager = new DJICodecManager(activity.getBaseContext(), surfaceTexture, width, height);
VideoFeeder.getInstance().provideTranscodedVideoFeed().addVideoDataListener(videoDataListener);
}
public final class CameraFrame{
public byte[] jpegFrame;
public int width;
public int height;
public CameraFrame(){
}
public CameraFrame(byte[] frameData, int width, int height){
this.jpegFrame = frameData;
this.width = width;
this.height = height;
}
}
CameraFrame jpegFrame;
public CameraFrame FGetCameraFrame(){
if(!isStreaming || lastPublishedCameraFrameIndex == cameraFrameIndex){
return null;
}
lastPublishedCameraFrameIndex = cameraFrameIndex;
byte[] bytes = codecManager.getRgbaData(width, height);
return new CameraFrame(bytes, width, height);
}
}
解决方案
推荐阅读
- javascript - 要求未在 .js 文件中的 socket.io 实现中定义
- python-3.x - TypeError:“NoneType”对象不可调用 Tensorflow
- c++ - 连接 LPCSTR 变量和文字?
- vb.net - 通过减少颜色来减小图像大小
- excel - 动态数组函数
- android - 为什么 Android GPS 定位返回已禁用,尽管已将其打开
- php - 我想在 api url 中发送订单 id 并在 json 中获得正确的响应?
- angular - 从 ngx-material-timepicker 获取选择时间
- java - 从 RecyclerView 中删除最后一项不起作用
- postgresql - 如何按索引名称查询“can_unique”?