mirror of
https://github.com/gnif/LookingGlass.git
synced 2026-08-22 15:11:31 +00:00
[client] transport: split video provider operations
This commit is contained in:
@@ -236,31 +236,9 @@ LG_TransportControl;
|
||||
|
||||
typedef uint64_t LG_TransportControlToken;
|
||||
|
||||
typedef struct LG_TransportOps
|
||||
typedef struct LG_FrameOps
|
||||
{
|
||||
const char * name;
|
||||
void (*setup)(void);
|
||||
bool (*create)(LG_Transport ** transport);
|
||||
void (*destroy)(LG_Transport ** transport);
|
||||
|
||||
LG_TransportStatus (*connect)(LG_Transport * transport,
|
||||
LG_TransportSession * session);
|
||||
void (*disconnect)(LG_Transport * transport);
|
||||
bool (*sessionValid)(LG_Transport * transport);
|
||||
bool (*supportsDMA)(LG_Transport * transport);
|
||||
/* Queried after connect. The returned operations and opaque value remain
|
||||
* valid until disconnect; NULL indicates that this session has no input. */
|
||||
const LG_InputOps *(*getInputOps)(LG_Transport * transport,
|
||||
void ** opaque);
|
||||
/* Queried after connect. The returned operations and opaque value remain
|
||||
* valid until disconnect; NULL indicates that this session has no audio. */
|
||||
const LG_AudioOps *(*getAudioOps)(LG_Transport * transport,
|
||||
void ** opaque);
|
||||
/* Queried after connect. The returned operations and opaque value remain
|
||||
* valid until disconnect; NULL indicates that this session has no
|
||||
* clipboard. */
|
||||
const LG_ClipboardOps *(*getClipboardOps)(LG_Transport * transport,
|
||||
void ** opaque);
|
||||
bool (*attachRenderer)(LG_Transport * transport,
|
||||
const LG_RendererInterop * interop);
|
||||
void (*detachRenderer)(LG_Transport * transport);
|
||||
@@ -274,16 +252,62 @@ typedef struct LG_TransportOps
|
||||
const LG_TransportFrame * frame, LG_TransportFrameTiming * timing);
|
||||
void (*releaseFrame)(LG_Transport * transport, LG_TransportFrame * frame);
|
||||
/* Called by the frame consumer as it exits. A backend may release transient
|
||||
* stream resources; nextFrame must reacquire them when the consumer restarts. */
|
||||
* stream resources; nextFrame must reacquire them when the consumer
|
||||
* restarts. */
|
||||
void (*stopFrame)(LG_Transport * transport);
|
||||
|
||||
LG_TransportStatus (*nextPointer)(LG_Transport * transport,
|
||||
LG_TransportPointer * pointer);
|
||||
void (*releasePointer)(LG_Transport * transport,
|
||||
LG_TransportPointer * pointer);
|
||||
/* Called by the pointer consumer as it exits. A backend may release transient
|
||||
* stream resources; nextPointer must reacquire them when the consumer restarts. */
|
||||
/* Called by the pointer consumer as it exits. A backend may release
|
||||
* transient stream resources; nextPointer must reacquire them when the
|
||||
* consumer restarts. */
|
||||
void (*stopPointer)(LG_Transport * transport);
|
||||
}
|
||||
LG_FrameOps;
|
||||
|
||||
typedef enum LG_VideoType
|
||||
{
|
||||
LG_VIDEO_TYPE_FRAME,
|
||||
}
|
||||
LG_VideoType;
|
||||
|
||||
typedef struct LG_VideoOps
|
||||
{
|
||||
const char * name;
|
||||
LG_VideoType type;
|
||||
const LG_FrameOps * frame;
|
||||
}
|
||||
LG_VideoOps;
|
||||
|
||||
typedef struct LG_TransportOps
|
||||
{
|
||||
const char * name;
|
||||
void (*setup)(void);
|
||||
bool (*create)(LG_Transport ** transport);
|
||||
void (*destroy)(LG_Transport ** transport);
|
||||
|
||||
LG_TransportStatus (*connect)(LG_Transport * transport,
|
||||
LG_TransportSession * session);
|
||||
void (*disconnect)(LG_Transport * transport);
|
||||
bool (*sessionValid)(LG_Transport * transport);
|
||||
/* Queried after create. The returned operations remain valid until the
|
||||
* transport is destroyed. NULL indicates that this transport has no video. */
|
||||
const LG_VideoOps *(*getVideoOps)(LG_Transport * transport);
|
||||
/* Queried after connect. The returned operations and opaque value remain
|
||||
* valid until disconnect; NULL indicates that this session has no input. */
|
||||
const LG_InputOps *(*getInputOps)(LG_Transport * transport,
|
||||
void ** opaque);
|
||||
/* Queried after connect. The returned operations and opaque value remain
|
||||
* valid until disconnect; NULL indicates that this session has no audio. */
|
||||
const LG_AudioOps *(*getAudioOps)(LG_Transport * transport,
|
||||
void ** opaque);
|
||||
/* Queried after connect. The returned operations and opaque value remain
|
||||
* valid until disconnect; NULL indicates that this session has no
|
||||
* clipboard. */
|
||||
const LG_ClipboardOps *(*getClipboardOps)(LG_Transport * transport,
|
||||
void ** opaque);
|
||||
|
||||
LG_TransportStatus (*sendControl)(LG_Transport * transport,
|
||||
const LG_TransportControl * control, LG_TransportControlToken * token);
|
||||
|
||||
@@ -1044,8 +1044,8 @@ static int renderThread(void * unused)
|
||||
core_stopCursorThread();
|
||||
core_stopFrameThread();
|
||||
|
||||
if (g_state.transport.ops && g_state.transport.ops->detachRenderer)
|
||||
g_state.transport.ops->detachRenderer(g_state.transport.handle);
|
||||
if (g_state.videoOps && g_state.videoOps->frame->detachRenderer)
|
||||
g_state.videoOps->frame->detachRenderer(g_state.transport.handle);
|
||||
|
||||
RENDERER(deinitialize);
|
||||
g_state.lgr = NULL;
|
||||
@@ -1066,7 +1066,7 @@ int main_cursorThread(void * unused)
|
||||
while(app_getState() == APP_STATE_RUNNING && !g_state.stopVideo)
|
||||
{
|
||||
LG_TransportPointer pointer;
|
||||
const LG_TransportStatus status = g_state.transport.ops->nextPointer(
|
||||
const LG_TransportStatus status = g_state.videoOps->frame->nextPointer(
|
||||
g_state.transport.handle, &pointer);
|
||||
if (status != LG_TRANSPORT_OK)
|
||||
{
|
||||
@@ -1119,7 +1119,7 @@ int main_cursorThread(void * unused)
|
||||
case CURSOR_TYPE_MASKED_COLOR: cursorType = LG_CURSOR_MASKED_COLOR; break;
|
||||
default:
|
||||
DEBUG_ERROR("Invalid cursor type");
|
||||
g_state.transport.ops->releasePointer(
|
||||
g_state.videoOps->frame->releasePointer(
|
||||
g_state.transport.handle, &pointer);
|
||||
continue;
|
||||
}
|
||||
@@ -1130,7 +1130,7 @@ int main_cursorThread(void * unused)
|
||||
pointer.pitch, pointer.shape))
|
||||
{
|
||||
DEBUG_ERROR("Failed to update mouse shape");
|
||||
g_state.transport.ops->releasePointer(
|
||||
g_state.videoOps->frame->releasePointer(
|
||||
g_state.transport.handle, &pointer);
|
||||
continue;
|
||||
}
|
||||
@@ -1192,11 +1192,12 @@ int main_cursorThread(void * unused)
|
||||
(g_params.mouseRedraw || contentChanged))))
|
||||
cursorRepaintRequest();
|
||||
|
||||
g_state.transport.ops->releasePointer(g_state.transport.handle, &pointer);
|
||||
g_state.videoOps->frame->releasePointer(
|
||||
g_state.transport.handle, &pointer);
|
||||
}
|
||||
|
||||
if (g_state.transport.ops->stopPointer)
|
||||
g_state.transport.ops->stopPointer(g_state.transport.handle);
|
||||
if (g_state.videoOps->frame->stopPointer)
|
||||
g_state.videoOps->frame->stopPointer(g_state.transport.handle);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1213,15 +1214,15 @@ int main_frameThread(void * unused)
|
||||
lgWaitEvent(e_startup, TIMEOUT_INFINITE);
|
||||
if (app_getState() != APP_STATE_RUNNING)
|
||||
{
|
||||
if (g_state.transport.ops->stopFrame)
|
||||
g_state.transport.ops->stopFrame(g_state.transport.handle);
|
||||
if (g_state.videoOps->frame->stopFrame)
|
||||
g_state.videoOps->frame->stopFrame(g_state.transport.handle);
|
||||
return 0;
|
||||
}
|
||||
|
||||
while(app_getState() == APP_STATE_RUNNING && !g_state.stopVideo)
|
||||
{
|
||||
LG_TransportFrame frame;
|
||||
const LG_TransportStatus status = g_state.transport.ops->nextFrame(
|
||||
const LG_TransportStatus status = g_state.videoOps->frame->nextFrame(
|
||||
g_state.transport.handle, g_state.useDMA, &frame);
|
||||
if (status != LG_TRANSPORT_OK)
|
||||
{
|
||||
@@ -1251,7 +1252,7 @@ int main_frameThread(void * unused)
|
||||
if (frame.serial == frameSerial && g_state.formatValid &&
|
||||
!frame.scheduleOwner)
|
||||
{
|
||||
g_state.transport.ops->releaseFrame(g_state.transport.handle, &frame);
|
||||
g_state.videoOps->frame->releaseFrame(g_state.transport.handle, &frame);
|
||||
continue;
|
||||
}
|
||||
frameSerial = frame.serial;
|
||||
@@ -1261,7 +1262,7 @@ int main_frameThread(void * unused)
|
||||
if (!format)
|
||||
{
|
||||
DEBUG_ERROR("Transport returned a frame without format metadata");
|
||||
g_state.transport.ops->releaseFrame(g_state.transport.handle, &frame);
|
||||
g_state.videoOps->frame->releaseFrame(g_state.transport.handle, &frame);
|
||||
app_setState(APP_STATE_SHUTDOWN);
|
||||
break;
|
||||
}
|
||||
@@ -1343,7 +1344,8 @@ int main_frameThread(void * unused)
|
||||
if (invalid)
|
||||
{
|
||||
DEBUG_ERROR("Unsupported frame type");
|
||||
g_state.transport.ops->releaseFrame(g_state.transport.handle, &frame);
|
||||
g_state.videoOps->frame->releaseFrame(
|
||||
g_state.transport.handle, &frame);
|
||||
app_setState(APP_STATE_SHUTDOWN);
|
||||
break;
|
||||
}
|
||||
@@ -1365,7 +1367,8 @@ int main_frameThread(void * unused)
|
||||
{
|
||||
LG_UNLOCK(g_state.lgrLock);
|
||||
DEBUG_ERROR("Renderer failed to configure format");
|
||||
g_state.transport.ops->releaseFrame(g_state.transport.handle, &frame);
|
||||
g_state.videoOps->frame->releaseFrame(
|
||||
g_state.transport.handle, &frame);
|
||||
app_setState(APP_STATE_SHUTDOWN);
|
||||
break;
|
||||
}
|
||||
@@ -1418,7 +1421,7 @@ int main_frameThread(void * unused)
|
||||
rendererOwnsFrame ? frame.releaseHandle : 0))
|
||||
{
|
||||
frameTimingCancel(frameToken);
|
||||
g_state.transport.ops->releaseFrame(g_state.transport.handle, &frame);
|
||||
g_state.videoOps->frame->releaseFrame(g_state.transport.handle, &frame);
|
||||
DEBUG_ERROR("Renderer onFrame returned failure");
|
||||
app_setState(APP_STATE_SHUTDOWN);
|
||||
break;
|
||||
@@ -1428,8 +1431,8 @@ int main_frameThread(void * unused)
|
||||
* is signalled below, so sample producer timing while this lease is still
|
||||
* unambiguously owned by the frame thread. */
|
||||
LG_TransportFrameTiming timing = {};
|
||||
if (g_state.transport.ops->getFrameTiming)
|
||||
g_state.transport.ops->getFrameTiming(
|
||||
if (g_state.videoOps->frame->getFrameTiming)
|
||||
g_state.videoOps->frame->getFrameTiming(
|
||||
g_state.transport.handle, &frame, &timing);
|
||||
|
||||
const uint64_t queueStart = nanotime();
|
||||
@@ -1474,7 +1477,7 @@ int main_frameThread(void * unused)
|
||||
frameTimingFinishFrame(frameToken, &timing);
|
||||
|
||||
if (!rendererOwnsFrame)
|
||||
g_state.transport.ops->releaseFrame(g_state.transport.handle, &frame);
|
||||
g_state.videoOps->frame->releaseFrame(g_state.transport.handle, &frame);
|
||||
app_useSpiceDisplay(false);
|
||||
}
|
||||
|
||||
@@ -1491,8 +1494,8 @@ int main_frameThread(void * unused)
|
||||
|
||||
/* Renderer reset requests release for every asynchronous DMA snapshot.
|
||||
* Drain those requests before the transport unsubscribes or reconnects. */
|
||||
if (g_state.transport.ops->stopFrame)
|
||||
g_state.transport.ops->stopFrame(g_state.transport.handle);
|
||||
if (g_state.videoOps->frame->stopFrame)
|
||||
g_state.videoOps->frame->stopFrame(g_state.transport.handle);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -2126,6 +2129,16 @@ static int lg_run(void)
|
||||
}
|
||||
DEBUG_INFO("Using Transport: %s", g_state.transport.ops->name);
|
||||
|
||||
g_state.videoOps =
|
||||
g_state.transport.ops->getVideoOps(g_state.transport.handle);
|
||||
if (!g_state.videoOps || g_state.videoOps->type != LG_VIDEO_TYPE_FRAME ||
|
||||
!g_state.videoOps->frame)
|
||||
{
|
||||
DEBUG_ERROR("Transport does not provide a frame source");
|
||||
return -1;
|
||||
}
|
||||
DEBUG_INFO("Using Video: %s", g_state.videoOps->name);
|
||||
|
||||
// setup the spice startup condition
|
||||
if (!(e_spice = lgCreateEvent(false, 0)))
|
||||
{
|
||||
@@ -2207,7 +2220,8 @@ static int lg_run(void)
|
||||
return -1;
|
||||
}
|
||||
|
||||
g_state.useDMA = g_state.transport.ops->supportsDMA(g_state.transport.handle);
|
||||
g_state.useDMA =
|
||||
g_state.videoOps->frame->supportsDMA(g_state.transport.handle);
|
||||
|
||||
// initialize the window dimensions at init for renderers
|
||||
g_state.windowW = g_params.w;
|
||||
@@ -2305,8 +2319,8 @@ static int lg_run(void)
|
||||
if (g_state.lgr->ops.getInterop &&
|
||||
g_state.lgr->ops.getInterop(g_state.lgr, &interop))
|
||||
interopPtr = &interop;
|
||||
if (g_state.transport.ops->attachRenderer &&
|
||||
!g_state.transport.ops->attachRenderer(
|
||||
if (g_state.videoOps->frame->attachRenderer &&
|
||||
!g_state.videoOps->frame->attachRenderer(
|
||||
g_state.transport.handle, interopPtr))
|
||||
{
|
||||
DEBUG_ERROR("Failed to attach the renderer to the transport");
|
||||
|
||||
@@ -124,6 +124,7 @@ struct AppState
|
||||
bool useDMA;
|
||||
|
||||
LG_TransportInstance transport;
|
||||
const LG_VideoOps * videoOps;
|
||||
LG_TransportFeatureFlags transportFeatures;
|
||||
|
||||
LGThread * cursorThread;
|
||||
|
||||
@@ -82,6 +82,7 @@ int main(void)
|
||||
PLGMPMemory frameMemory = NULL;
|
||||
PLGMPMemory pointerMemory = NULL;
|
||||
LG_Transport * transport = NULL;
|
||||
const LG_FrameOps * frameOps = NULL;
|
||||
|
||||
debug_init();
|
||||
|
||||
@@ -155,6 +156,11 @@ int main(void)
|
||||
option_set_int("lgmp", "framePollInterval", 0);
|
||||
option_set_int("lgmp", "cursorPollInterval", 0);
|
||||
CHECK(LGT_LGMP.create(&transport));
|
||||
const LG_VideoOps * videoOps = LGT_LGMP.getVideoOps(transport);
|
||||
CHECK(videoOps);
|
||||
CHECK(videoOps->type == LG_VIDEO_TYPE_FRAME);
|
||||
CHECK(videoOps->frame);
|
||||
frameOps = videoOps->frame;
|
||||
|
||||
CHECK(unlink(path) == 0);
|
||||
pathExists = false;
|
||||
@@ -167,8 +173,8 @@ int main(void)
|
||||
|
||||
LG_TransportFrame frame;
|
||||
LG_TransportPointer pointer;
|
||||
CHECK(LGT_LGMP.nextFrame(transport, false, &frame) == LG_TRANSPORT_TIMEOUT);
|
||||
CHECK(LGT_LGMP.nextPointer(transport, &pointer) == LG_TRANSPORT_TIMEOUT);
|
||||
CHECK(frameOps->nextFrame(transport, false, &frame) == LG_TRANSPORT_TIMEOUT);
|
||||
CHECK(frameOps->nextPointer(transport, &pointer) == LG_TRANSPORT_TIMEOUT);
|
||||
CHECK(lgmpHostQueueHasSubs(frameQueue));
|
||||
CHECK(lgmpHostQueueHasSubs(pointerQueue));
|
||||
CHECK(lgmpHostQueueNewSubs(frameQueue) == 1);
|
||||
@@ -177,16 +183,16 @@ int main(void)
|
||||
CHECK(lgmpHostQueuePost(frameQueue, 0, frameMemory) == LGMP_OK);
|
||||
CHECK(lgmpHostQueuePost(pointerQueue, CURSOR_FLAG_POSITION,
|
||||
pointerMemory) == LGMP_OK);
|
||||
CHECK(LGT_LGMP.nextFrame(transport, false, &frame) == LG_TRANSPORT_OK);
|
||||
CHECK(frameOps->nextFrame(transport, false, &frame) == LG_TRANSPORT_OK);
|
||||
LG_TransportFrameTiming timing;
|
||||
LGT_LGMP.getFrameTiming(transport, &frame, &timing);
|
||||
frameOps->getFrameTiming(transport, &frame, &timing);
|
||||
CHECK(timing.captureTime == wireFrame->captureTime);
|
||||
CHECK(timing.postProcessTime == wireFrame->postProcessTime);
|
||||
CHECK(timing.copyTime == wireFrame->copyTime);
|
||||
CHECK(timing.readyTime == wireFrame->readyTime);
|
||||
LGT_LGMP.releaseFrame(transport, &frame);
|
||||
CHECK(LGT_LGMP.nextPointer(transport, &pointer) == LG_TRANSPORT_OK);
|
||||
LGT_LGMP.releasePointer(transport, &pointer);
|
||||
frameOps->releaseFrame(transport, &frame);
|
||||
CHECK(frameOps->nextPointer(transport, &pointer) == LG_TRANSPORT_OK);
|
||||
frameOps->releasePointer(transport, &pointer);
|
||||
|
||||
/*
|
||||
* Stop with messages pending. Unsubscribing before the host timeout is the
|
||||
@@ -195,10 +201,10 @@ int main(void)
|
||||
CHECK(lgmpHostQueuePost(frameQueue, 0, frameMemory) == LGMP_OK);
|
||||
CHECK(lgmpHostQueuePost(pointerQueue, CURSOR_FLAG_POSITION,
|
||||
pointerMemory) == LGMP_OK);
|
||||
CHECK(LGT_LGMP.stopFrame);
|
||||
CHECK(LGT_LGMP.stopPointer);
|
||||
LGT_LGMP.stopFrame(transport);
|
||||
LGT_LGMP.stopPointer(transport);
|
||||
CHECK(frameOps->stopFrame);
|
||||
CHECK(frameOps->stopPointer);
|
||||
frameOps->stopFrame(transport);
|
||||
frameOps->stopPointer(transport);
|
||||
CHECK(!lgmpHostQueueHasSubs(frameQueue));
|
||||
CHECK(!lgmpHostQueueHasSubs(pointerQueue));
|
||||
|
||||
@@ -206,8 +212,8 @@ int main(void)
|
||||
CHECK(lgmpHostQueuePending(frameQueue) == 0);
|
||||
CHECK(lgmpHostQueuePending(pointerQueue) == 0);
|
||||
|
||||
CHECK(LGT_LGMP.nextFrame(transport, false, &frame) == LG_TRANSPORT_TIMEOUT);
|
||||
CHECK(LGT_LGMP.nextPointer(transport, &pointer) == LG_TRANSPORT_TIMEOUT);
|
||||
CHECK(frameOps->nextFrame(transport, false, &frame) == LG_TRANSPORT_TIMEOUT);
|
||||
CHECK(frameOps->nextPointer(transport, &pointer) == LG_TRANSPORT_TIMEOUT);
|
||||
CHECK(lgmpHostQueueNewSubs(frameQueue) == 1);
|
||||
CHECK(lgmpHostQueueNewSubs(pointerQueue) == 1);
|
||||
|
||||
@@ -215,10 +221,10 @@ int main(void)
|
||||
CHECK(lgmpHostQueuePost(frameQueue, 0, frameMemory) == LGMP_OK);
|
||||
CHECK(lgmpHostQueuePost(pointerQueue, CURSOR_FLAG_POSITION,
|
||||
pointerMemory) == LGMP_OK);
|
||||
CHECK(LGT_LGMP.nextFrame(transport, false, &frame) == LG_TRANSPORT_OK);
|
||||
LGT_LGMP.releaseFrame(transport, &frame);
|
||||
CHECK(LGT_LGMP.nextPointer(transport, &pointer) == LG_TRANSPORT_OK);
|
||||
LGT_LGMP.releasePointer(transport, &pointer);
|
||||
CHECK(frameOps->nextFrame(transport, false, &frame) == LG_TRANSPORT_OK);
|
||||
frameOps->releaseFrame(transport, &frame);
|
||||
CHECK(frameOps->nextPointer(transport, &pointer) == LG_TRANSPORT_OK);
|
||||
frameOps->releasePointer(transport, &pointer);
|
||||
|
||||
/*
|
||||
* Also recover when the host has already marked the cached handles bad.
|
||||
@@ -229,15 +235,15 @@ int main(void)
|
||||
CHECK(lgmpHostQueuePost(frameQueue, 0, frameMemory) == LGMP_OK);
|
||||
CHECK(lgmpHostQueuePost(pointerQueue, CURSOR_FLAG_POSITION,
|
||||
pointerMemory) == LGMP_OK);
|
||||
CHECK(LGT_LGMP.nextFrame(transport, false, &frame) == LG_TRANSPORT_OK);
|
||||
CHECK(frameOps->nextFrame(transport, false, &frame) == LG_TRANSPORT_OK);
|
||||
CHECK(waitForQueuesEmpty(host, frameQueue, pointerQueue));
|
||||
CHECK(lgmpHostQueueHasSubs(frameQueue));
|
||||
CHECK(lgmpHostQueueHasSubs(pointerQueue));
|
||||
|
||||
LGT_LGMP.stopFrame(transport);
|
||||
LGT_LGMP.stopPointer(transport);
|
||||
CHECK(LGT_LGMP.nextFrame(transport, false, &frame) == LG_TRANSPORT_TIMEOUT);
|
||||
CHECK(LGT_LGMP.nextPointer(transport, &pointer) == LG_TRANSPORT_TIMEOUT);
|
||||
frameOps->stopFrame(transport);
|
||||
frameOps->stopPointer(transport);
|
||||
CHECK(frameOps->nextFrame(transport, false, &frame) == LG_TRANSPORT_TIMEOUT);
|
||||
CHECK(frameOps->nextPointer(transport, &pointer) == LG_TRANSPORT_TIMEOUT);
|
||||
CHECK(lgmpHostQueueNewSubs(frameQueue) == 1);
|
||||
CHECK(lgmpHostQueueNewSubs(pointerQueue) == 1);
|
||||
|
||||
@@ -245,10 +251,10 @@ int main(void)
|
||||
CHECK(lgmpHostQueuePost(frameQueue, 0, frameMemory) == LGMP_OK);
|
||||
CHECK(lgmpHostQueuePost(pointerQueue, CURSOR_FLAG_POSITION,
|
||||
pointerMemory) == LGMP_OK);
|
||||
CHECK(LGT_LGMP.nextFrame(transport, false, &frame) == LG_TRANSPORT_OK);
|
||||
LGT_LGMP.releaseFrame(transport, &frame);
|
||||
CHECK(LGT_LGMP.nextPointer(transport, &pointer) == LG_TRANSPORT_OK);
|
||||
LGT_LGMP.releasePointer(transport, &pointer);
|
||||
CHECK(frameOps->nextFrame(transport, false, &frame) == LG_TRANSPORT_OK);
|
||||
frameOps->releaseFrame(transport, &frame);
|
||||
CHECK(frameOps->nextPointer(transport, &pointer) == LG_TRANSPORT_OK);
|
||||
frameOps->releasePointer(transport, &pointer);
|
||||
|
||||
result = 0;
|
||||
|
||||
|
||||
@@ -1360,17 +1360,9 @@ static const LG_InputOps * lgmp_getInputOps(LG_Transport * this,
|
||||
return lgmpInput_getOps();
|
||||
}
|
||||
|
||||
const LG_TransportOps LGT_LGMP =
|
||||
static const LG_FrameOps lgmpFrameOps =
|
||||
{
|
||||
.name = "lgmp",
|
||||
.setup = lgmp_setup,
|
||||
.create = lgmp_create,
|
||||
.destroy = lgmp_destroy,
|
||||
.connect = lgmp_connect,
|
||||
.disconnect = lgmp_disconnect,
|
||||
.sessionValid = lgmp_sessionValid,
|
||||
.supportsDMA = lgmp_supportsDMA,
|
||||
.getInputOps = lgmp_getInputOps,
|
||||
.attachRenderer = lgmp_attachRenderer,
|
||||
.detachRenderer = lgmp_detachRenderer,
|
||||
.nextFrame = lgmp_nextFrame,
|
||||
@@ -1380,6 +1372,31 @@ const LG_TransportOps LGT_LGMP =
|
||||
.nextPointer = lgmp_nextPointer,
|
||||
.releasePointer = lgmp_releasePointer,
|
||||
.stopPointer = lgmp_stopPointer,
|
||||
.sendControl = lgmp_sendControl,
|
||||
.controlStatus = lgmp_controlStatus,
|
||||
};
|
||||
|
||||
static const LG_VideoOps lgmpVideoOps =
|
||||
{
|
||||
.name = "LGMP",
|
||||
.type = LG_VIDEO_TYPE_FRAME,
|
||||
.frame = &lgmpFrameOps,
|
||||
};
|
||||
|
||||
static const LG_VideoOps * lgmp_getVideoOps(LG_Transport * this)
|
||||
{
|
||||
return &lgmpVideoOps;
|
||||
}
|
||||
|
||||
const LG_TransportOps LGT_LGMP =
|
||||
{
|
||||
.name = "lgmp",
|
||||
.setup = lgmp_setup,
|
||||
.create = lgmp_create,
|
||||
.destroy = lgmp_destroy,
|
||||
.connect = lgmp_connect,
|
||||
.disconnect = lgmp_disconnect,
|
||||
.sessionValid = lgmp_sessionValid,
|
||||
.getVideoOps = lgmp_getVideoOps,
|
||||
.getInputOps = lgmp_getInputOps,
|
||||
.sendControl = lgmp_sendControl,
|
||||
.controlStatus = lgmp_controlStatus,
|
||||
};
|
||||
|
||||
@@ -734,23 +734,40 @@ static const LG_InputOps * test_getInputOps(LG_Transport * this,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const LG_TransportOps LGT_Test =
|
||||
static const LG_FrameOps testFrameOps =
|
||||
{
|
||||
.name = "test",
|
||||
.setup = test_setup,
|
||||
.create = test_create,
|
||||
.destroy = test_destroy,
|
||||
.connect = test_connect,
|
||||
.disconnect = test_disconnect,
|
||||
.sessionValid = test_sessionValid,
|
||||
.supportsDMA = test_supportsDMA,
|
||||
.getInputOps = test_getInputOps,
|
||||
.attachRenderer = test_attachRenderer,
|
||||
.detachRenderer = test_detachRenderer,
|
||||
.nextFrame = test_nextFrame,
|
||||
.releaseFrame = test_releaseFrame,
|
||||
.nextPointer = test_nextPointer,
|
||||
.releasePointer = test_releasePointer,
|
||||
.sendControl = test_sendControl,
|
||||
.controlStatus = test_controlStatus,
|
||||
};
|
||||
|
||||
static const LG_VideoOps testVideoOps =
|
||||
{
|
||||
.name = "test",
|
||||
.type = LG_VIDEO_TYPE_FRAME,
|
||||
.frame = &testFrameOps,
|
||||
};
|
||||
|
||||
static const LG_VideoOps * test_getVideoOps(LG_Transport * this)
|
||||
{
|
||||
return &testVideoOps;
|
||||
}
|
||||
|
||||
const LG_TransportOps LGT_Test =
|
||||
{
|
||||
.name = "test",
|
||||
.setup = test_setup,
|
||||
.create = test_create,
|
||||
.destroy = test_destroy,
|
||||
.connect = test_connect,
|
||||
.disconnect = test_disconnect,
|
||||
.sessionValid = test_sessionValid,
|
||||
.getVideoOps = test_getVideoOps,
|
||||
.getInputOps = test_getInputOps,
|
||||
.sendControl = test_sendControl,
|
||||
.controlStatus = test_controlStatus,
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user