Рендеринг данных видеотекстур из iOS в единство Texture2d при каждом обновлении - PullRequest
0 голосов
/ 07 мая 2020

Фон: я создаю приложение, в котором я использую Dji SDK для 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, предоставленном единством.

Проблема: I Я не могу преобразовать видеоданные, представленные в приведенном выше методе, и отправить их в формате, который единство может понять и отобразить в объекте Texture2d.

Я получил несколько предложений, связанных с _GetNativeTexturePtr и MTLTexture, но это не сработало для me.

Цель: передавать NSData * videoData из iOS в объект Unity Texture2d при каждом вызове функции update () и отображать его там.

Любая помощь приветствуется, спасибо!

Чтобы дать более четкое представление, я делюсь, как я сделал в 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);
        }
    }

}

Собственный Android код:

 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);
    }
}
...