RenderingPlugin.cpp 6.09 KB
Newer Older
Martin Finkel's avatar
Martin Finkel committed
1
2
3
#include "PlatformBase.h"
#include "RenderAPI.h"
#include "Log.h"
Martin Finkel's avatar
WIP-2    
Martin Finkel committed
4

Martin Finkel's avatar
Martin Finkel committed
5
#include <map>
6
#include <windows.h>
Martin Finkel's avatar
Martin Finkel committed
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

extern "C" {
#include <stdlib.h>
#include <unistd.h>
#include <vlc/vlc.h>
#include <string.h>
}

static UnityGfxRenderer s_DeviceType = kUnityGfxRendererNull;

static int   g_TextureWidth  = 0;
static int   g_TextureHeight = 0;
static int   g_TextureRowPitch = 0;

libvlc_instance_t * inst;
Martin Finkel's avatar
WIP-2    
Martin Finkel committed
22
libvlc_media_player_t * mp;
Martin Finkel's avatar
Martin Finkel committed
23
24
25
26
27

static IUnityGraphics* s_Graphics = NULL;
static std::map<libvlc_media_player_t*,RenderAPI*> contexts = {};
static IUnityInterfaces* s_UnityInterfaces = NULL;

28
29
static UINT Width;
static UINT Height;
30
31
static void* Hwnd;

Martin Finkel's avatar
Martin Finkel committed
32
33
34
35
36
37
38
39
40
41
/** LibVLC's API function exported to Unity
 *
 * Every following functions will be exported to. Unity We have to
 * redeclare the LibVLC's function for the keyword
 * UNITY_INTERFACE_EXPORT and UNITY_INTERFACE_API
 */

extern "C" libvlc_media_player_t* UNITY_INTERFACE_EXPORT UNITY_INTERFACE_API
CreateAndInitMediaPlayer(libvlc_instance_t* libvlc)
{
42
    if(libvlc == NULL)
Martin Finkel's avatar
Martin Finkel committed
43
44
45
46
47
48
49
50
51
52
53
54
55
56
    {
        DEBUG("libvlc is NULL, aborting...");
        return NULL;
    }

    inst = libvlc;

    DEBUG("LAUNCH");

    if (inst == NULL) {
        DEBUG("LibVLC is not instanciated");
        return NULL;
    }

57
    mp = libvlc_media_player_new(inst);
Martin Finkel's avatar
Martin Finkel committed
58
59
    RenderAPI* s_CurrentAPI;

60
    if (mp == NULL) {
Martin Finkel's avatar
Martin Finkel committed
61
62
        DEBUG("Error initializing media player");
        goto err;
63
    }
Martin Finkel's avatar
Martin Finkel committed
64

Martin Finkel's avatar
WIP    
Martin Finkel committed
65
    DEBUG("Calling... Initialize Render API \n");
Martin Finkel's avatar
Martin Finkel committed
66
67

    s_DeviceType = s_Graphics->GetRenderer();
Martin Finkel's avatar
WIP    
Martin Finkel committed
68
69
70

    DEBUG("Calling... CreateRenderAPI \n");

Martin Finkel's avatar
Martin Finkel committed
71
    s_CurrentAPI = CreateRenderAPI(s_DeviceType);
Martin Finkel's avatar
WIP    
Martin Finkel committed
72
73
74
75
    
    if(s_CurrentAPI == NULL)
    {
        DEBUG("s_CurrentAPI is NULL \n");    
76
    }    
Martin Finkel's avatar
WIP    
Martin Finkel committed
77
78
79
    
    DEBUG("Calling... ProcessDeviceEvent \n");
    
Martin Finkel's avatar
Martin Finkel committed
80
81
    s_CurrentAPI->ProcessDeviceEvent(kUnityGfxDeviceEventInitialize, s_UnityInterfaces);

Martin Finkel's avatar
WIP    
Martin Finkel committed
82
    DEBUG("Calling... setVlcContext s_CurrentAPI=%p mp=%p", s_CurrentAPI, mp);
83
    // s_CurrentAPI->setVlcContext(mp);
Martin Finkel's avatar
Martin Finkel committed
84

85
    contexts[mp] = s_CurrentAPI;
Martin Finkel's avatar
Martin Finkel committed
86

87
    return mp;
Martin Finkel's avatar
Martin Finkel committed
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
err:
    if ( mp ) {
        // Stop playing
        libvlc_media_player_stop_async (mp);

        // Free the media_player
        libvlc_media_player_release (mp);
        mp = NULL;
    }    
    return NULL;
}

extern "C" void* UNITY_INTERFACE_EXPORT UNITY_INTERFACE_API
getVideoFrameVLC (libvlc_media_player_t* mp, bool * updated)
{
103
104
105
106
    if(mp == NULL)
        return NULL;

    RenderAPI* s_CurrentAPI = contexts.find(mp)->second;
Martin Finkel's avatar
Martin Finkel committed
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135

    if (!s_CurrentAPI) {
        DEBUG("Error, no Render API");
        if (updated)
            *updated = false;
        return nullptr;
    }

    return s_CurrentAPI->getVideoFrame(updated);
}

static void UNITY_INTERFACE_API OnGraphicsDeviceEvent(UnityGfxDeviceEventType eventType);

extern "C" void	UNITY_INTERFACE_EXPORT UNITY_INTERFACE_API UnityPluginLoad(IUnityInterfaces* unityInterfaces)
{
    DEBUG("UnityPluginLoad");
    s_UnityInterfaces = unityInterfaces;
    s_Graphics = s_UnityInterfaces->Get<IUnityGraphics>();
    s_Graphics->RegisterDeviceEventCallback(OnGraphicsDeviceEvent);

    // Run OnGraphicsDeviceEvent(initialize) manually on plugin load
    OnGraphicsDeviceEvent(kUnityGfxDeviceEventInitialize);
}

extern "C" void UNITY_INTERFACE_EXPORT UNITY_INTERFACE_API UnityPluginUnload()
{
  s_Graphics->UnregisterDeviceEventCallback(OnGraphicsDeviceEvent);
}

136

Martin Finkel's avatar
Martin Finkel committed
137
138
139
140
141
142
143
144
145
146
147
148
149
150
static RenderAPI* EarlyRenderAPI = NULL;

static void UNITY_INTERFACE_API OnGraphicsDeviceEvent(UnityGfxDeviceEventType eventType)
{
    // Create graphics API implementation upon initialization
       if (eventType == kUnityGfxDeviceEventInitialize) {
            DEBUG("Initialise Render API");
            if (EarlyRenderAPI != NULL) {
                DEBUG("*** EarlyRenderAPI != NULL while initialising ***");
                return;
            }

        s_DeviceType = s_Graphics->GetRenderer();
        EarlyRenderAPI = CreateRenderAPI(s_DeviceType);
151
        return;
Martin Finkel's avatar
Martin Finkel committed
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
    }

    if(EarlyRenderAPI){
        EarlyRenderAPI->ProcessDeviceEvent(eventType, s_UnityInterfaces);
    } else {
        DEBUG("Unable to process event, no Render API");
    }

    // Let the implementation process the device related events
    std::map<libvlc_media_player_t*, RenderAPI*>::iterator it;

    for(it = contexts.begin(); it != contexts.end(); it++)
    {
        RenderAPI* currentAPI = it->second;
        if(currentAPI) {
            currentAPI->ProcessDeviceEvent(eventType, s_UnityInterfaces);
        }
    }
}

static void UNITY_INTERFACE_API OnRenderEvent(int eventID)
{
}

Martin Finkel's avatar
Martin Finkel committed
176
177
178
179
// void TextureUpdateCallback(int eventID, void* data)
// {
//     DEBUG("Entering TextureUpdateCallback \n");
//     auto event = static_cast<UnityRenderingExtEventType>(eventID);
Martin Finkel's avatar
WIP-2    
Martin Finkel committed
180

Martin Finkel's avatar
Martin Finkel committed
181
182
183
//     if (event == kUnityRenderingExtEventUpdateTextureBeginV2)
//     {
//         DEBUG("event is kUnityRenderingExtEventUpdateTextureBeginV2 \n");
184

Martin Finkel's avatar
Martin Finkel committed
185
//         auto *pParams = reinterpret_cast<UnityRenderingExtTextureUpdateParamsV2*>(data);
Martin Finkel's avatar
WIP-2    
Martin Finkel committed
186

Martin Finkel's avatar
Martin Finkel committed
187
188
//         if(mp == NULL)
//             return;
Martin Finkel's avatar
WIP-2    
Martin Finkel committed
189

Martin Finkel's avatar
Martin Finkel committed
190
//         RenderAPI* s_CurrentAPI = contexts.find(mp)->second;
Martin Finkel's avatar
WIP-2    
Martin Finkel committed
191

Martin Finkel's avatar
Martin Finkel committed
192
//         bool* updated;
Martin Finkel's avatar
WIP-2    
Martin Finkel committed
193

Martin Finkel's avatar
Martin Finkel committed
194
195
196
197
198
199
//         if (!s_CurrentAPI) {
//             DEBUG("Error, no Render API \n");
//             if (updated)
//                 *updated = false;
//             return;
//         }
200

Martin Finkel's avatar
Martin Finkel committed
201
//         DEBUG("calling s_CurrentAPI->getVideoFrame(updated) \n");
202

Martin Finkel's avatar
Martin Finkel committed
203
//         void* tex = s_CurrentAPI->getVideoFrame(updated);
Martin Finkel's avatar
WIP-2    
Martin Finkel committed
204
        
Martin Finkel's avatar
Martin Finkel committed
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
//         DEBUG("SWAPPING -=================== \n");
//         pParams->format = kUnityRenderingExtFormatR8G8B8A8_UNorm;

//         std::swap(tex, pParams->texData); 
//     }
//     else if (event == kUnityRenderingExtEventUpdateTextureEndV2)
//     {     
//         DEBUG("event is kUnityRenderingExtEventUpdateTextureEndV2 \n");
//         auto *pParams = reinterpret_cast<UnityRenderingExtTextureUpdateParamsV2*>(data);
//         if(pParams->texData != nullptr)
//         {
//             pParams->texData = nullptr;
//         }
//     }
// }
Martin Finkel's avatar
WIP-2    
Martin Finkel committed
220

Martin Finkel's avatar
Martin Finkel committed
221
222
223
extern "C" UnityRenderingEvent UNITY_INTERFACE_EXPORT UNITY_INTERFACE_API GetRenderEventFunc()
{
    return OnRenderEvent;
Martin Finkel's avatar
WIP-2    
Martin Finkel committed
224
225
}

Martin Finkel's avatar
Martin Finkel committed
226
227
228
229
// extern "C" UnityRenderingEventAndData UNITY_INTERFACE_EXPORT UNITY_INTERFACE_API GetTextureUpdateCallback()
// {
//     return TextureUpdateCallback;
// }