channels: refactoring of channel subsystems
This commit is contained in:
parent
83473d11d1
commit
2e1a7447a1
@ -77,7 +77,7 @@ macro(define_channel_client_subsystem _channel_name _subsystem _type)
|
||||
if(_type_length GREATER 0)
|
||||
set(SUBSYSTEM_TYPE ${_type})
|
||||
set(MODULE_NAME "${CHANNEL_NAME}-client-${CHANNEL_SUBSYSTEM}-${SUBSYSTEM_TYPE}")
|
||||
string(TOUPPER "CHANNEL_${CHANNEL_NAME}_CLIENT_${CHANNEL_SUBSYSTEM}-${SUBSYSTEM_TYPE}" MODULE_PREFIX)
|
||||
string(TOUPPER "CHANNEL_${CHANNEL_NAME}_CLIENT_${CHANNEL_SUBSYSTEM}_${SUBSYSTEM_TYPE}" MODULE_PREFIX)
|
||||
else()
|
||||
set(MODULE_NAME "${CHANNEL_NAME}-client-${CHANNEL_SUBSYSTEM}")
|
||||
string(TOUPPER "CHANNEL_${CHANNEL_NAME}_CLIENT_${CHANNEL_SUBSYSTEM}" MODULE_PREFIX)
|
||||
@ -116,10 +116,19 @@ endmacro(add_channel_server)
|
||||
macro(add_channel_client_subsystem _channel_prefix _channel_name _subsystem _type)
|
||||
add_subdirectory(${_subsystem})
|
||||
set(_channel_module_name "${_channel_name}-client")
|
||||
string(LENGTH "${_type}" _type_length)
|
||||
if(_type_length GREATER 0)
|
||||
string(TOUPPER "CHANNEL_${_channel_name}_CLIENT_${_subsystem}_${_type}" _subsystem_prefix)
|
||||
else()
|
||||
string(TOUPPER "CHANNEL_${_channel_name}_CLIENT_${_subsystem}" _subsystem_prefix)
|
||||
endif()
|
||||
if(${${_subsystem_prefix}_STATIC})
|
||||
get_target_property(CHANNEL_SUBSYSTEMS ${_channel_module_name} SUBSYSTEMS)
|
||||
if(_type_length GREATER 0)
|
||||
set(SUBSYSTEMS ${SUBSYSTEMS} "${_subsystem}-${_type}")
|
||||
else()
|
||||
set(SUBSYSTEMS ${SUBSYSTEMS} ${_subsystem})
|
||||
endif()
|
||||
set_target_properties(${_channel_module_name} PROPERTIES SUBSYSTEMS "${SUBSYSTEMS}")
|
||||
endif()
|
||||
endmacro(add_channel_client_subsystem)
|
||||
@ -139,7 +148,7 @@ macro(add_channel_client_library _module_prefix _module_name _channel_name _dyna
|
||||
endif()
|
||||
endmacro(add_channel_client_library)
|
||||
|
||||
macro(add_channel_client_subsystem_library _module_prefix _module_name _channel_name _dynamic _entry)
|
||||
macro(add_channel_client_subsystem_library _module_prefix _module_name _channel_name _type _dynamic _entry)
|
||||
if(${_dynamic} AND MSVC AND (NOT STATIC_CHANNELS))
|
||||
set(${_module_prefix}_SRCS ${${_module_prefix}_SRCS} module.def)
|
||||
endif()
|
||||
@ -148,6 +157,7 @@ macro(add_channel_client_subsystem_library _module_prefix _module_name _channel_
|
||||
else()
|
||||
set(${_module_prefix}_STATIC ON PARENT_SCOPE)
|
||||
set(${_module_prefix}_NAME ${_module_name} PARENT_SCOPE)
|
||||
set(${_module_prefix}_TYPE ${_type} PARENT_SCOPE)
|
||||
add_library(${_module_name} STATIC ${${_module_prefix}_SRCS})
|
||||
endif()
|
||||
endmacro(add_channel_client_subsystem_library)
|
||||
|
@ -23,7 +23,7 @@ set(${MODULE_PREFIX}_SRCS
|
||||
include_directories(..)
|
||||
include_directories(${ALSA_INCLUDE_DIRS})
|
||||
|
||||
add_channel_client_subsystem_library(${MODULE_PREFIX} ${MODULE_NAME} ${CHANNEL_NAME} TRUE "")
|
||||
add_channel_client_subsystem_library(${MODULE_PREFIX} ${MODULE_NAME} ${CHANNEL_NAME} "" TRUE "")
|
||||
|
||||
set_target_properties(${MODULE_NAME} PROPERTIES PREFIX "")
|
||||
|
||||
|
@ -25,7 +25,12 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <winpr/crt.h>
|
||||
#include <winpr/cmdline.h>
|
||||
|
||||
#include <alsa/asoundlib.h>
|
||||
|
||||
#include <freerdp/addin.h>
|
||||
#include <freerdp/utils/memory.h>
|
||||
#include <freerdp/utils/thread.h>
|
||||
#include <freerdp/utils/dsp.h>
|
||||
@ -36,7 +41,7 @@ typedef struct _AudinALSADevice
|
||||
{
|
||||
IAudinDevice iface;
|
||||
|
||||
char device_name[32];
|
||||
char* device_name;
|
||||
UINT32 frames_per_packet;
|
||||
UINT32 target_rate;
|
||||
UINT32 actual_rate;
|
||||
@ -236,6 +241,9 @@ static void audin_alsa_free(IAudinDevice* device)
|
||||
|
||||
freerdp_thread_free(alsa->thread);
|
||||
freerdp_dsp_context_free(alsa->dsp_context);
|
||||
|
||||
free(alsa->device_name);
|
||||
|
||||
free(alsa);
|
||||
}
|
||||
|
||||
@ -328,40 +336,66 @@ static void audin_alsa_close(IAudinDevice* device)
|
||||
alsa->user_data = NULL;
|
||||
}
|
||||
|
||||
COMMAND_LINE_ARGUMENT_A audin_alsa_args[] =
|
||||
{
|
||||
{ "audio-dev", COMMAND_LINE_VALUE_REQUIRED, "<device>", NULL, NULL, -1, NULL, "audio device name" },
|
||||
{ NULL, 0, NULL, NULL, NULL, -1, NULL, NULL }
|
||||
};
|
||||
|
||||
static void audin_alsa_parse_addin_args(AudinALSADevice* device, ADDIN_ARGV* args)
|
||||
{
|
||||
int status;
|
||||
DWORD flags;
|
||||
COMMAND_LINE_ARGUMENT_A* arg;
|
||||
AudinALSADevice* alsa = (AudinALSADevice*) device;
|
||||
|
||||
flags = COMMAND_LINE_SIGIL_NONE | COMMAND_LINE_SEPARATOR_COLON;
|
||||
|
||||
status = CommandLineParseArgumentsA(args->argc, (const char**) args->argv, audin_alsa_args, flags, alsa, NULL, NULL);
|
||||
|
||||
arg = audin_alsa_args;
|
||||
|
||||
do
|
||||
{
|
||||
if (!(arg->Flags & COMMAND_LINE_VALUE_PRESENT))
|
||||
continue;
|
||||
|
||||
CommandLineSwitchStart(arg)
|
||||
|
||||
CommandLineSwitchCase(arg, "audio-dev")
|
||||
{
|
||||
alsa->device_name = _strdup(arg->Value);
|
||||
}
|
||||
|
||||
CommandLineSwitchEnd(arg)
|
||||
}
|
||||
while ((arg = CommandLineFindNextArgumentA(arg)) != NULL);
|
||||
}
|
||||
|
||||
#ifdef STATIC_CHANNELS
|
||||
#define freerdp_audin_client_subsystem_entry alsa_freerdp_audin_client_subsystem_entry
|
||||
#endif
|
||||
|
||||
int freerdp_audin_client_subsystem_entry(PFREERDP_AUDIN_DEVICE_ENTRY_POINTS pEntryPoints)
|
||||
{
|
||||
ADDIN_ARGV* args;
|
||||
AudinALSADevice* alsa;
|
||||
RDP_PLUGIN_DATA* data;
|
||||
|
||||
alsa = xnew(AudinALSADevice);
|
||||
alsa = (AudinALSADevice*) malloc(sizeof(AudinALSADevice));
|
||||
ZeroMemory(alsa, sizeof(AudinALSADevice));
|
||||
|
||||
alsa->iface.Open = audin_alsa_open;
|
||||
alsa->iface.FormatSupported = audin_alsa_format_supported;
|
||||
alsa->iface.SetFormat = audin_alsa_set_format;
|
||||
alsa->iface.Close = audin_alsa_close;
|
||||
alsa->iface.Free = audin_alsa_free;
|
||||
alsa->device_name[0] = '\0';
|
||||
|
||||
data = pEntryPoints->plugin_data;
|
||||
if (data)
|
||||
{
|
||||
char *data2 = (char *) (data->data[2]);
|
||||
if (data->data[0] && (strcmp(data->data[0], "audin") == 0) &&
|
||||
data->data[1] && (strcmp(data->data[1], "alsa") == 0) &&
|
||||
data2 && (*data2 != '\0'))
|
||||
{
|
||||
strncpy(alsa->device_name, data2, sizeof(alsa->device_name));
|
||||
}
|
||||
}
|
||||
args = pEntryPoints->args;
|
||||
|
||||
if (alsa->device_name[0] == '\0')
|
||||
{
|
||||
strcpy(alsa->device_name, "default");
|
||||
}
|
||||
audin_alsa_parse_addin_args(alsa, args);
|
||||
|
||||
if (!alsa->device_name)
|
||||
alsa->device_name = _strdup("default");
|
||||
|
||||
alsa->frames_per_packet = 128;
|
||||
alsa->target_rate = 22050;
|
||||
@ -378,4 +412,3 @@ int freerdp_audin_client_subsystem_entry(PFREERDP_AUDIN_DEVICE_ENTRY_POINTS pEnt
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -25,6 +25,9 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <winpr/crt.h>
|
||||
#include <winpr/cmdline.h>
|
||||
|
||||
#include <freerdp/addin.h>
|
||||
|
||||
#include <freerdp/utils/memory.h>
|
||||
@ -78,6 +81,8 @@ struct _AUDIN_PLUGIN
|
||||
UINT16 fixed_format;
|
||||
UINT16 fixed_channel;
|
||||
UINT32 fixed_rate;
|
||||
char* subsystem;
|
||||
char* device_name;
|
||||
|
||||
/* Device interface */
|
||||
IAudinDevice* device;
|
||||
@ -437,7 +442,7 @@ static void audin_register_device_plugin(IWTSPlugin* pPlugin, IAudinDevice* devi
|
||||
audin->device = device;
|
||||
}
|
||||
|
||||
static BOOL audin_load_device_plugin(IWTSPlugin* pPlugin, const char* name, RDP_PLUGIN_DATA* data)
|
||||
static BOOL audin_load_device_plugin(IWTSPlugin* pPlugin, const char* name, ADDIN_ARGV* args)
|
||||
{
|
||||
PFREERDP_AUDIN_DEVICE_ENTRY entry;
|
||||
FREERDP_AUDIN_DEVICE_ENTRY_POINTS entryPoints;
|
||||
@ -449,7 +454,7 @@ static BOOL audin_load_device_plugin(IWTSPlugin* pPlugin, const char* name, RDP_
|
||||
|
||||
entryPoints.plugin = pPlugin;
|
||||
entryPoints.pRegisterAudinDevice = audin_register_device_plugin;
|
||||
entryPoints.plugin_data = data;
|
||||
entryPoints.args = args;
|
||||
|
||||
if (entry(&entryPoints) != 0)
|
||||
{
|
||||
@ -460,54 +465,81 @@ static BOOL audin_load_device_plugin(IWTSPlugin* pPlugin, const char* name, RDP_
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static BOOL audin_process_plugin_data(IWTSPlugin* pPlugin, RDP_PLUGIN_DATA* data)
|
||||
void audin_set_subsystem(AUDIN_PLUGIN* audin, char* subsystem)
|
||||
{
|
||||
BOOL ret;
|
||||
if (audin->subsystem)
|
||||
free(audin->subsystem);
|
||||
|
||||
audin->subsystem = _strdup(subsystem);
|
||||
}
|
||||
|
||||
void audin_set_device_name(AUDIN_PLUGIN* audin, char* device_name)
|
||||
{
|
||||
if (audin->device_name)
|
||||
free(audin->device_name);
|
||||
|
||||
audin->device_name = _strdup(device_name);
|
||||
}
|
||||
|
||||
COMMAND_LINE_ARGUMENT_A audin_args[] =
|
||||
{
|
||||
{ "sys", COMMAND_LINE_VALUE_REQUIRED, "<subsystem>", NULL, NULL, -1, NULL, "subsystem" },
|
||||
{ "dev", COMMAND_LINE_VALUE_REQUIRED, "<device>", NULL, NULL, -1, NULL, "device" },
|
||||
{ "format", COMMAND_LINE_VALUE_REQUIRED, "<format>", NULL, NULL, -1, NULL, "format" },
|
||||
{ "rate", COMMAND_LINE_VALUE_REQUIRED, "<rate>", NULL, NULL, -1, NULL, "rate" },
|
||||
{ "channel", COMMAND_LINE_VALUE_REQUIRED, "<channel>", NULL, NULL, -1, NULL, "channel" },
|
||||
{ NULL, 0, NULL, NULL, NULL, -1, NULL, NULL }
|
||||
};
|
||||
|
||||
static BOOL audin_process_addin_args(IWTSPlugin* pPlugin, ADDIN_ARGV* args)
|
||||
{
|
||||
int status;
|
||||
DWORD flags;
|
||||
COMMAND_LINE_ARGUMENT_A* arg;
|
||||
AUDIN_PLUGIN* audin = (AUDIN_PLUGIN*) pPlugin;
|
||||
RDP_PLUGIN_DATA default_data[2] = { { 0 }, { 0 } };
|
||||
|
||||
if (data->data[0] && (strcmp((char*)data->data[0], "audin") == 0 || strstr((char*) data->data[0], "/audin.") != NULL))
|
||||
{
|
||||
if (data->data[1] && strcmp((char*)data->data[1], "format") == 0)
|
||||
{
|
||||
audin->fixed_format = atoi(data->data[2]);
|
||||
return TRUE;
|
||||
}
|
||||
else if (data->data[1] && strcmp((char*)data->data[1], "rate") == 0)
|
||||
{
|
||||
audin->fixed_rate = atoi(data->data[2]);
|
||||
return TRUE;
|
||||
}
|
||||
else if (data->data[1] && strcmp((char*)data->data[1], "channel") == 0)
|
||||
{
|
||||
audin->fixed_channel = atoi(data->data[2]);
|
||||
return TRUE;
|
||||
}
|
||||
else if (data->data[1] && ((char*)data->data[1])[0])
|
||||
{
|
||||
return audin_load_device_plugin(pPlugin, (char*) data->data[1], data);
|
||||
}
|
||||
else
|
||||
{
|
||||
default_data[0].size = sizeof(RDP_PLUGIN_DATA);
|
||||
default_data[0].data[0] = "audin";
|
||||
default_data[0].data[1] = "pulse";
|
||||
default_data[0].data[2] = "";
|
||||
flags = COMMAND_LINE_SIGIL_NONE | COMMAND_LINE_SEPARATOR_COLON;
|
||||
|
||||
ret = audin_load_device_plugin(pPlugin, "pulse", default_data);
|
||||
status = CommandLineParseArgumentsA(args->argc, (const char**) args->argv,
|
||||
audin_args, flags, audin, NULL, NULL);
|
||||
|
||||
if (!ret)
|
||||
arg = audin_args;
|
||||
|
||||
do
|
||||
{
|
||||
default_data[0].size = sizeof(RDP_PLUGIN_DATA);
|
||||
default_data[0].data[0] = "audin";
|
||||
default_data[0].data[1] = "alsa";
|
||||
default_data[0].data[2] = "default";
|
||||
ret = audin_load_device_plugin(pPlugin, "alsa", default_data);
|
||||
if (!(arg->Flags & COMMAND_LINE_VALUE_PRESENT))
|
||||
continue;
|
||||
|
||||
CommandLineSwitchStart(arg)
|
||||
|
||||
CommandLineSwitchCase(arg, "sys")
|
||||
{
|
||||
audin_set_subsystem(audin, arg->Value);
|
||||
}
|
||||
CommandLineSwitchCase(arg, "dev")
|
||||
{
|
||||
audin_set_device_name(audin, arg->Value);
|
||||
}
|
||||
CommandLineSwitchCase(arg, "format")
|
||||
{
|
||||
audin->fixed_format = atoi(arg->Value);
|
||||
}
|
||||
CommandLineSwitchCase(arg, "rate")
|
||||
{
|
||||
audin->fixed_rate = atoi(arg->Value);
|
||||
}
|
||||
CommandLineSwitchCase(arg, "channel")
|
||||
{
|
||||
audin->fixed_channel = atoi(arg->Value);
|
||||
}
|
||||
CommandLineSwitchDefault(arg)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
CommandLineSwitchEnd(arg)
|
||||
}
|
||||
while ((arg = CommandLineFindNextArgumentA(arg)) != NULL);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
@ -519,23 +551,50 @@ static BOOL audin_process_plugin_data(IWTSPlugin* pPlugin, RDP_PLUGIN_DATA* data
|
||||
int DVCPluginEntry(IDRDYNVC_ENTRY_POINTS* pEntryPoints)
|
||||
{
|
||||
int error = 0;
|
||||
ADDIN_ARGV* args;
|
||||
AUDIN_PLUGIN* audin;
|
||||
|
||||
audin = (AUDIN_PLUGIN*) pEntryPoints->GetPlugin(pEntryPoints, "audin");
|
||||
|
||||
if (audin == NULL)
|
||||
{
|
||||
audin = xnew(AUDIN_PLUGIN);
|
||||
audin = (AUDIN_PLUGIN*) malloc(sizeof(AUDIN_PLUGIN));
|
||||
ZeroMemory(audin, sizeof(AUDIN_PLUGIN));
|
||||
|
||||
audin->iface.Initialize = audin_plugin_initialize;
|
||||
audin->iface.Connected = NULL;
|
||||
audin->iface.Disconnected = NULL;
|
||||
audin->iface.Terminated = audin_plugin_terminated;
|
||||
|
||||
error = pEntryPoints->RegisterPlugin(pEntryPoints, "audin", (IWTSPlugin*) audin);
|
||||
}
|
||||
|
||||
args = pEntryPoints->GetPluginData(pEntryPoints);
|
||||
|
||||
if (error == 0)
|
||||
audin_process_plugin_data((IWTSPlugin*) audin, pEntryPoints->GetPluginData(pEntryPoints));
|
||||
audin_process_addin_args((IWTSPlugin*) audin, args);
|
||||
|
||||
if (audin->subsystem)
|
||||
audin_load_device_plugin((IWTSPlugin*) audin, audin->subsystem, args);
|
||||
|
||||
if (!audin->device)
|
||||
{
|
||||
audin_set_subsystem(audin, "pulse");
|
||||
audin_set_device_name(audin, "");
|
||||
audin_load_device_plugin((IWTSPlugin*) audin, audin->subsystem, args);
|
||||
}
|
||||
|
||||
if (!audin->device)
|
||||
{
|
||||
audin_set_subsystem(audin, "alsa");
|
||||
audin_set_device_name(audin, "default");
|
||||
audin_load_device_plugin((IWTSPlugin*) audin, audin->subsystem, args);
|
||||
}
|
||||
|
||||
if (audin->device == NULL)
|
||||
{
|
||||
DEBUG_WARN("no sound device.");
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
@ -26,6 +26,7 @@
|
||||
|
||||
#include <freerdp/dvc.h>
|
||||
#include <freerdp/types.h>
|
||||
#include <freerdp/addin.h>
|
||||
#include <freerdp/utils/debug.h>
|
||||
|
||||
#ifdef WITH_DEBUG_DVC
|
||||
@ -66,7 +67,7 @@ struct _FREERDP_AUDIN_DEVICE_ENTRY_POINTS
|
||||
{
|
||||
IWTSPlugin* plugin;
|
||||
PREGISTERAUDINDEVICE pRegisterAudinDevice;
|
||||
RDP_PLUGIN_DATA* plugin_data;
|
||||
ADDIN_ARGV* args;
|
||||
};
|
||||
typedef struct _FREERDP_AUDIN_DEVICE_ENTRY_POINTS FREERDP_AUDIN_DEVICE_ENTRY_POINTS;
|
||||
typedef FREERDP_AUDIN_DEVICE_ENTRY_POINTS* PFREERDP_AUDIN_DEVICE_ENTRY_POINTS;
|
||||
|
@ -23,7 +23,7 @@ set(${MODULE_PREFIX}_SRCS
|
||||
include_directories(..)
|
||||
include_directories(${PULSE_INCLUDE_DIR})
|
||||
|
||||
add_channel_client_subsystem_library(${MODULE_PREFIX} ${MODULE_NAME} ${CHANNEL_NAME} TRUE "")
|
||||
add_channel_client_subsystem_library(${MODULE_PREFIX} ${MODULE_NAME} ${CHANNEL_NAME} "" TRUE "")
|
||||
|
||||
set_target_properties(${MODULE_NAME} PROPERTIES PREFIX "")
|
||||
|
||||
|
@ -25,8 +25,13 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <winpr/crt.h>
|
||||
#include <winpr/cmdline.h>
|
||||
|
||||
#include <pulse/pulseaudio.h>
|
||||
|
||||
#include <freerdp/types.h>
|
||||
#include <freerdp/addin.h>
|
||||
#include <freerdp/utils/memory.h>
|
||||
#include <freerdp/utils/dsp.h>
|
||||
|
||||
@ -36,7 +41,7 @@ typedef struct _AudinPulseDevice
|
||||
{
|
||||
IAudinDevice iface;
|
||||
|
||||
char device_name[32];
|
||||
char* device_name;
|
||||
UINT32 frames_per_packet;
|
||||
pa_threaded_mainloop* mainloop;
|
||||
pa_context* context;
|
||||
@ -430,16 +435,53 @@ static void audin_pulse_open(IAudinDevice* device, AudinReceive receive, void* u
|
||||
}
|
||||
}
|
||||
|
||||
COMMAND_LINE_ARGUMENT_A audin_pulse_args[] =
|
||||
{
|
||||
{ "audio-dev", COMMAND_LINE_VALUE_REQUIRED, "<device>", NULL, NULL, -1, NULL, "audio device name" },
|
||||
{ NULL, 0, NULL, NULL, NULL, -1, NULL, NULL }
|
||||
};
|
||||
|
||||
static void audin_pulse_parse_addin_args(AudinPulseDevice* device, ADDIN_ARGV* args)
|
||||
{
|
||||
int status;
|
||||
DWORD flags;
|
||||
COMMAND_LINE_ARGUMENT_A* arg;
|
||||
AudinPulseDevice* pulse = (AudinPulseDevice*) device;
|
||||
|
||||
flags = COMMAND_LINE_SIGIL_NONE | COMMAND_LINE_SEPARATOR_COLON;
|
||||
|
||||
status = CommandLineParseArgumentsA(args->argc, (const char**) args->argv, audin_pulse_args, flags, pulse, NULL, NULL);
|
||||
|
||||
arg = audin_pulse_args;
|
||||
|
||||
do
|
||||
{
|
||||
if (!(arg->Flags & COMMAND_LINE_VALUE_PRESENT))
|
||||
continue;
|
||||
|
||||
CommandLineSwitchStart(arg)
|
||||
|
||||
CommandLineSwitchCase(arg, "audio-dev")
|
||||
{
|
||||
pulse->device_name = _strdup(arg->Value);
|
||||
}
|
||||
|
||||
CommandLineSwitchEnd(arg)
|
||||
}
|
||||
while ((arg = CommandLineFindNextArgumentA(arg)) != NULL);
|
||||
}
|
||||
|
||||
#ifdef STATIC_CHANNELS
|
||||
#define freerdp_audin_client_subsystem_entry pulse_freerdp_audin_client_subsystem_entry
|
||||
#endif
|
||||
|
||||
int freerdp_audin_client_subsystem_entry(PFREERDP_AUDIN_DEVICE_ENTRY_POINTS pEntryPoints)
|
||||
{
|
||||
ADDIN_ARGV* args;
|
||||
AudinPulseDevice* pulse;
|
||||
RDP_PLUGIN_DATA * data;
|
||||
|
||||
pulse = xnew(AudinPulseDevice);
|
||||
pulse = (AudinPulseDevice*) malloc(sizeof(AudinPulseDevice));
|
||||
ZeroMemory(pulse, sizeof(AudinPulseDevice));
|
||||
|
||||
pulse->iface.Open = audin_pulse_open;
|
||||
pulse->iface.FormatSupported = audin_pulse_format_supported;
|
||||
@ -447,30 +489,35 @@ int freerdp_audin_client_subsystem_entry(PFREERDP_AUDIN_DEVICE_ENTRY_POINTS pEnt
|
||||
pulse->iface.Close = audin_pulse_close;
|
||||
pulse->iface.Free = audin_pulse_free;
|
||||
|
||||
data = pEntryPoints->plugin_data;
|
||||
if (data && data->data[0] && strcmp(data->data[0], "audin") == 0 &&
|
||||
data->data[1] && strcmp(data->data[1], "pulse") == 0)
|
||||
{
|
||||
strncpy(pulse->device_name, (char*)data->data[2], sizeof(pulse->device_name));
|
||||
}
|
||||
args = pEntryPoints->args;
|
||||
|
||||
audin_pulse_parse_addin_args(pulse, args);
|
||||
|
||||
if (!pulse->device_name)
|
||||
pulse->device_name = _strdup("default");
|
||||
|
||||
pulse->dsp_context = freerdp_dsp_context_new();
|
||||
|
||||
pulse->mainloop = pa_threaded_mainloop_new();
|
||||
|
||||
if (!pulse->mainloop)
|
||||
{
|
||||
DEBUG_WARN("pa_threaded_mainloop_new failed");
|
||||
audin_pulse_free((IAudinDevice*) pulse);
|
||||
return 1;
|
||||
}
|
||||
|
||||
pulse->context = pa_context_new(pa_threaded_mainloop_get_api(pulse->mainloop), "freerdp");
|
||||
|
||||
if (!pulse->context)
|
||||
{
|
||||
DEBUG_WARN("pa_context_new failed");
|
||||
audin_pulse_free((IAudinDevice*) pulse);
|
||||
return 1;
|
||||
}
|
||||
|
||||
pa_context_set_state_callback(pulse->context, audin_pulse_context_state_callback, pulse);
|
||||
|
||||
if (!audin_pulse_connect((IAudinDevice*) pulse))
|
||||
{
|
||||
audin_pulse_free((IAudinDevice*) pulse);
|
||||
@ -481,4 +528,3 @@ int freerdp_audin_client_subsystem_entry(PFREERDP_AUDIN_DEVICE_ENTRY_POINTS pEnt
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -62,12 +62,24 @@ foreach(STATIC_MODULE ${CHANNEL_STATIC_CLIENT_MODULES})
|
||||
if(CHANNEL_SUBSYSTEMS MATCHES "NOTFOUND")
|
||||
set(CHANNEL_SUBSYSTEMS "")
|
||||
endif()
|
||||
message(STATUS "Channel: ${STATIC_MODULE_CHANNEL} Subsystems: ${CHANNEL_SUBSYSTEMS}")
|
||||
foreach(STATIC_SUBSYSTEM ${CHANNEL_SUBSYSTEMS})
|
||||
string(TOUPPER "${STATIC_MODULE}_CLIENT_${STATIC_SUBSYSTEM}" SUBSYSTEM_PREFIX)
|
||||
if(${STATIC_SUBSYSTEM} MATCHES "^([^-]*)-(.*)")
|
||||
string(REGEX REPLACE "^([^-]*)-(.*)" "\\1" STATIC_SUBSYSTEM_NAME ${STATIC_SUBSYSTEM})
|
||||
string(REGEX REPLACE "^([^-]*)-(.*)" "\\2" STATIC_SUBSYSTEM_TYPE ${STATIC_SUBSYSTEM})
|
||||
else()
|
||||
set(STATIC_SUBSYSTEM_NAME "${STATIC_SUBSYSTEM}")
|
||||
set(STATIC_SUBSYSTEM_TYPE "")
|
||||
endif()
|
||||
string(LENGTH "${STATIC_SUBSYSTEM_TYPE}" _type_length)
|
||||
set(SUBSYSTEM_MODULE_NAME "${STATIC_MODULE_NAME}-${STATIC_SUBSYSTEM}")
|
||||
set(${MODULE_PREFIX}_LIBS ${${MODULE_PREFIX}_LIBS} ${SUBSYSTEM_MODULE_NAME})
|
||||
set(STATIC_SUBSYSTEM_ENTRY "${STATIC_SUBSYSTEM}_freerdp_${STATIC_MODULE_CHANNEL}_client_subsystem_entry")
|
||||
set(SUBSYSTEM_TABLE "${SUBSYSTEM_TABLE}\n\t{ \"${STATIC_SUBSYSTEM}\", \"\", ${STATIC_SUBSYSTEM_ENTRY} },")
|
||||
if(_type_length GREATER 0)
|
||||
set(STATIC_SUBSYSTEM_ENTRY "${STATIC_SUBSYSTEM_NAME}_freerdp_${STATIC_MODULE_CHANNEL}_client_${STATIC_SUBSYSTEM_TYPE}_subsystem_entry")
|
||||
else()
|
||||
set(STATIC_SUBSYSTEM_ENTRY "${STATIC_SUBSYSTEM_NAME}_freerdp_${STATIC_MODULE_CHANNEL}_client_subsystem_entry")
|
||||
endif()
|
||||
set(SUBSYSTEM_TABLE "${SUBSYSTEM_TABLE}\n\t{ \"${STATIC_SUBSYSTEM_NAME}\", \"${STATIC_SUBSYSTEM_TYPE}\", ${STATIC_SUBSYSTEM_ENTRY} },")
|
||||
set(SUBSYSTEM_IMPORT "extern void ${STATIC_SUBSYSTEM_ENTRY}();")
|
||||
set(CLIENT_STATIC_SUBSYSTEM_IMPORTS "${CLIENT_STATIC_SUBSYSTEM_IMPORTS}\n${SUBSYSTEM_IMPORT}")
|
||||
endforeach()
|
||||
|
@ -360,10 +360,13 @@ void* freerdp_channels_load_static_addin_entry(LPCSTR pszName, LPSTR pszSubsyste
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (strcmp(CLIENT_STATIC_ADDIN_TABLE[i].name, pszName) == 0)
|
||||
{
|
||||
return (void*) CLIENT_STATIC_ADDIN_TABLE[i].entry;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
@ -990,7 +993,7 @@ int freerdp_channels_client_load(rdpChannels* channels, rdpSettings* settings, v
|
||||
|
||||
if (channels->num_libs_data + 1 >= CHANNEL_MAX_COUNT)
|
||||
{
|
||||
DEBUG_CHANNELS("too many channels");
|
||||
printf("error: too many channels\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -1024,7 +1027,7 @@ int freerdp_channels_client_load(rdpChannels* channels, rdpSettings* settings, v
|
||||
|
||||
if (!status)
|
||||
{
|
||||
DEBUG_CHANNELS("export function call failed");
|
||||
printf("error: channel export function call failed\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -76,6 +76,7 @@ static int drdynvc_write_variable_uint(STREAM* stream, UINT32 val)
|
||||
cb = 2;
|
||||
stream_write_UINT32(stream, val);
|
||||
}
|
||||
|
||||
return cb;
|
||||
}
|
||||
|
||||
@ -148,12 +149,14 @@ int drdynvc_write_data(drdynvcPlugin* drdynvc, UINT32 ChannelId, BYTE* data, UIN
|
||||
error = svc_plugin_send((rdpSvcPlugin*)drdynvc, data_out);
|
||||
}
|
||||
}
|
||||
|
||||
if (error != CHANNEL_RC_OK)
|
||||
{
|
||||
drdynvc->channel_error = error;
|
||||
DEBUG_WARN("VirtualChannelWrite failed %d", error);
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -162,11 +165,13 @@ int drdynvc_push_event(drdynvcPlugin* drdynvc, RDP_EVENT* event)
|
||||
int error;
|
||||
|
||||
error = svc_plugin_send_event((rdpSvcPlugin*) drdynvc, event);
|
||||
|
||||
if (error != CHANNEL_RC_OK)
|
||||
{
|
||||
DEBUG_WARN("pVirtualChannelEventPush failed %d", error);
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -178,6 +183,7 @@ static int drdynvc_process_capability_request(drdynvcPlugin* drdynvc, int Sp, in
|
||||
DEBUG_DVC("Sp=%d cbChId=%d", Sp, cbChId);
|
||||
stream_seek(s, 1); /* pad */
|
||||
stream_read_UINT16(s, drdynvc->version);
|
||||
|
||||
if (drdynvc->version == 2)
|
||||
{
|
||||
stream_read_UINT16(s, drdynvc->PriorityCharge0);
|
||||
@ -185,15 +191,18 @@ static int drdynvc_process_capability_request(drdynvcPlugin* drdynvc, int Sp, in
|
||||
stream_read_UINT16(s, drdynvc->PriorityCharge2);
|
||||
stream_read_UINT16(s, drdynvc->PriorityCharge3);
|
||||
}
|
||||
|
||||
data_out = stream_new(4);
|
||||
stream_write_UINT16(data_out, 0x0050); /* Cmd+Sp+cbChId+Pad. Note: MSTSC sends 0x005c */
|
||||
stream_write_UINT16(data_out, drdynvc->version);
|
||||
error = svc_plugin_send((rdpSvcPlugin*) drdynvc, data_out);
|
||||
|
||||
if (error != CHANNEL_RC_OK)
|
||||
{
|
||||
DEBUG_WARN("VirtualChannelWrite failed %d", error);
|
||||
return 1;
|
||||
}
|
||||
|
||||
drdynvc->channel_error = error;
|
||||
|
||||
return 0;
|
||||
@ -208,22 +217,25 @@ static UINT32 drdynvc_read_variable_uint(STREAM* stream, int cbLen)
|
||||
case 0:
|
||||
stream_read_BYTE(stream, val);
|
||||
break;
|
||||
|
||||
case 1:
|
||||
stream_read_UINT16(stream, val);
|
||||
break;
|
||||
|
||||
default:
|
||||
stream_read_UINT32(stream, val);
|
||||
break;
|
||||
}
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
static int drdynvc_process_create_request(drdynvcPlugin* drdynvc, int Sp, int cbChId, STREAM* s)
|
||||
{
|
||||
STREAM* data_out;
|
||||
int pos;
|
||||
int error;
|
||||
UINT32 ChannelId;
|
||||
STREAM* data_out;
|
||||
|
||||
ChannelId = drdynvc_read_variable_uint(s, cbChId);
|
||||
pos = stream_get_pos(s);
|
||||
@ -248,25 +260,28 @@ static int drdynvc_process_create_request(drdynvcPlugin* drdynvc, int Sp, int cb
|
||||
}
|
||||
|
||||
error = svc_plugin_send((rdpSvcPlugin*) drdynvc, data_out);
|
||||
|
||||
if (error != CHANNEL_RC_OK)
|
||||
{
|
||||
DEBUG_WARN("VirtualChannelWrite failed %d", error);
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int drdynvc_process_data_first(drdynvcPlugin* drdynvc, int Sp, int cbChId, STREAM* s)
|
||||
{
|
||||
UINT32 ChannelId;
|
||||
UINT32 Length;
|
||||
int error;
|
||||
UINT32 Length;
|
||||
UINT32 ChannelId;
|
||||
|
||||
ChannelId = drdynvc_read_variable_uint(s, cbChId);
|
||||
Length = drdynvc_read_variable_uint(s, Sp);
|
||||
DEBUG_DVC("ChannelId=%d Length=%d", ChannelId, Length);
|
||||
|
||||
error = dvcman_receive_channel_data_first(drdynvc->channel_mgr, ChannelId, Length);
|
||||
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
@ -298,11 +313,11 @@ static int drdynvc_process_close_request(drdynvcPlugin* drdynvc, int Sp, int cbC
|
||||
|
||||
static void drdynvc_process_receive(rdpSvcPlugin* plugin, STREAM* s)
|
||||
{
|
||||
drdynvcPlugin* drdynvc = (drdynvcPlugin*)plugin;
|
||||
int value;
|
||||
int Cmd;
|
||||
int Sp;
|
||||
int cbChId;
|
||||
drdynvcPlugin* drdynvc = (drdynvcPlugin*) plugin;
|
||||
|
||||
stream_read_BYTE(s, value);
|
||||
Cmd = (value & 0xf0) >> 4;
|
||||
@ -338,13 +353,24 @@ static void drdynvc_process_receive(rdpSvcPlugin* plugin, STREAM* s)
|
||||
|
||||
static void drdynvc_process_connect(rdpSvcPlugin* plugin)
|
||||
{
|
||||
int index;
|
||||
ADDIN_ARGV* args;
|
||||
rdpSettings* settings;
|
||||
drdynvcPlugin* drdynvc = (drdynvcPlugin*)plugin;
|
||||
|
||||
DEBUG_DVC("connecting");
|
||||
|
||||
drdynvc->channel_mgr = dvcman_new(drdynvc);
|
||||
drdynvc->channel_error = 0;
|
||||
dvcman_load_plugin(drdynvc->channel_mgr, svc_plugin_get_data(plugin));
|
||||
|
||||
settings = (rdpSettings*) ((rdpSvcPlugin*) plugin)->channel_entry_points.pExtendedData;
|
||||
|
||||
for (index = 0; index < settings->DynamicChannelCount; index++)
|
||||
{
|
||||
args = settings->DynamicChannelArray[index];
|
||||
dvcman_load_addin(drdynvc->channel_mgr, args);
|
||||
}
|
||||
|
||||
dvcman_init(drdynvc->channel_mgr);
|
||||
}
|
||||
|
||||
@ -391,4 +417,3 @@ int VirtualChannelEntry(PCHANNEL_ENTRY_POINTS pEntryPoints)
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -74,7 +74,7 @@ struct _DVCMAN_ENTRY_POINTS
|
||||
IDRDYNVC_ENTRY_POINTS iface;
|
||||
|
||||
DVCMAN* dvcman;
|
||||
RDP_PLUGIN_DATA* plugin_data;
|
||||
ADDIN_ARGV* args;
|
||||
};
|
||||
|
||||
typedef struct _DVCMAN_CHANNEL DVCMAN_CHANNEL;
|
||||
@ -183,9 +183,9 @@ IWTSPlugin* dvcman_get_plugin(IDRDYNVC_ENTRY_POINTS* pEntryPoints, const char* n
|
||||
return NULL;
|
||||
}
|
||||
|
||||
RDP_PLUGIN_DATA* dvcman_get_plugin_data(IDRDYNVC_ENTRY_POINTS* pEntryPoints)
|
||||
ADDIN_ARGV* dvcman_get_plugin_data(IDRDYNVC_ENTRY_POINTS* pEntryPoints)
|
||||
{
|
||||
return ((DVCMAN_ENTRY_POINTS*) pEntryPoints)->plugin_data;
|
||||
return ((DVCMAN_ENTRY_POINTS*) pEntryPoints)->args;
|
||||
}
|
||||
|
||||
UINT32 dvcman_get_channel_id(IWTSVirtualChannel * channel)
|
||||
@ -224,16 +224,14 @@ IWTSVirtualChannelManager* dvcman_new(drdynvcPlugin* plugin)
|
||||
return (IWTSVirtualChannelManager*) dvcman;
|
||||
}
|
||||
|
||||
int dvcman_load_plugin(IWTSVirtualChannelManager* pChannelMgr, RDP_PLUGIN_DATA* data)
|
||||
int dvcman_load_addin(IWTSVirtualChannelManager* pChannelMgr, ADDIN_ARGV* args)
|
||||
{
|
||||
DVCMAN_ENTRY_POINTS entryPoints;
|
||||
PDVC_PLUGIN_ENTRY pDVCPluginEntry = NULL;
|
||||
|
||||
while (data && data->size > 0)
|
||||
{
|
||||
printf("Loading Dynamic Virtual Channel %s\n", data->data[0]);
|
||||
printf("Loading Dynamic Virtual Channel %s\n", args->argv[0]);
|
||||
|
||||
pDVCPluginEntry = (PDVC_PLUGIN_ENTRY) freerdp_load_channel_addin_entry((char*) data->data[0],
|
||||
pDVCPluginEntry = (PDVC_PLUGIN_ENTRY) freerdp_load_channel_addin_entry(args->argv[0],
|
||||
NULL, NULL, FREERDP_ADDIN_CHANNEL_DYNAMIC);
|
||||
|
||||
if (pDVCPluginEntry != NULL)
|
||||
@ -242,13 +240,10 @@ int dvcman_load_plugin(IWTSVirtualChannelManager* pChannelMgr, RDP_PLUGIN_DATA*
|
||||
entryPoints.iface.GetPlugin = dvcman_get_plugin;
|
||||
entryPoints.iface.GetPluginData = dvcman_get_plugin_data;
|
||||
entryPoints.dvcman = (DVCMAN*) pChannelMgr;
|
||||
entryPoints.plugin_data = data;
|
||||
entryPoints.args = args;
|
||||
pDVCPluginEntry((IDRDYNVC_ENTRY_POINTS*) &entryPoints);
|
||||
}
|
||||
|
||||
data = (RDP_PLUGIN_DATA*)(((BYTE*) data) + data->size);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -382,7 +377,6 @@ int dvcman_create_channel(IWTSVirtualChannelManager* pChannelMgr, UINT32 Channel
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
int dvcman_close_channel(IWTSVirtualChannelManager* pChannelMgr, UINT32 ChannelId)
|
||||
{
|
||||
DVCMAN_CHANNEL* channel;
|
||||
|
@ -21,10 +21,12 @@
|
||||
#define __DVCMAN_H
|
||||
|
||||
#include <freerdp/dvc.h>
|
||||
#include <freerdp/addin.h>
|
||||
|
||||
#include "drdynvc_main.h"
|
||||
|
||||
IWTSVirtualChannelManager* dvcman_new(drdynvcPlugin* plugin);
|
||||
int dvcman_load_plugin(IWTSVirtualChannelManager* pChannelMgr, RDP_PLUGIN_DATA* data);
|
||||
int dvcman_load_addin(IWTSVirtualChannelManager* pChannelMgr, ADDIN_ARGV* args);
|
||||
void dvcman_free(IWTSVirtualChannelManager* pChannelMgr);
|
||||
int dvcman_init(IWTSVirtualChannelManager* pChannelMgr);
|
||||
int dvcman_create_channel(IWTSVirtualChannelManager* pChannelMgr, UINT32 ChannelId, const char* ChannelName);
|
||||
|
@ -23,7 +23,7 @@ set(${MODULE_PREFIX}_SRCS
|
||||
include_directories(..)
|
||||
include_directories(${ALSA_INCLUDE_DIRS})
|
||||
|
||||
add_channel_client_subsystem_library(${MODULE_PREFIX} ${MODULE_NAME} ${CHANNEL_NAME} TRUE "")
|
||||
add_channel_client_subsystem_library(${MODULE_PREFIX} ${MODULE_NAME} ${CHANNEL_NAME} "" TRUE "")
|
||||
|
||||
set_target_properties(${MODULE_NAME} PROPERTIES PREFIX "")
|
||||
|
||||
|
@ -462,7 +462,8 @@ int freerdp_rdpsnd_client_subsystem_entry(PFREERDP_RDPSND_DEVICE_ENTRY_POINTS pE
|
||||
ADDIN_ARGV* args;
|
||||
rdpsndAlsaPlugin* alsa;
|
||||
|
||||
alsa = xnew(rdpsndAlsaPlugin);
|
||||
alsa = (rdpsndAlsaPlugin*) malloc(sizeof(rdpsndAlsaPlugin));
|
||||
ZeroMemory(alsa, sizeof(rdpsndAlsaPlugin));
|
||||
|
||||
alsa->device.Open = rdpsnd_alsa_open;
|
||||
alsa->device.FormatSupported = rdpsnd_alsa_format_supported;
|
||||
|
@ -24,7 +24,7 @@ set(${MODULE_PREFIX}_SRCS
|
||||
include_directories(..)
|
||||
include_directories(${MACAUDIO_INCLUDE_DIRS})
|
||||
|
||||
add_channel_client_subsystem_library(${MODULE_PREFIX} ${MODULE_NAME} ${CHANNEL_NAME} TRUE "")
|
||||
add_channel_client_subsystem_library(${MODULE_PREFIX} ${MODULE_NAME} ${CHANNEL_NAME} "" TRUE "")
|
||||
|
||||
set_target_properties(${MODULE_NAME} PROPERTIES PREFIX "")
|
||||
|
||||
|
@ -23,7 +23,7 @@ set(${MODULE_PREFIX}_SRCS
|
||||
include_directories(..)
|
||||
include_directories(${PULSE_INCLUDE_DIR})
|
||||
|
||||
add_channel_client_subsystem_library(${MODULE_PREFIX} ${MODULE_NAME} ${CHANNEL_NAME} TRUE "")
|
||||
add_channel_client_subsystem_library(${MODULE_PREFIX} ${MODULE_NAME} ${CHANNEL_NAME} "" TRUE "")
|
||||
|
||||
set_target_properties(${MODULE_NAME} PROPERTIES PREFIX "")
|
||||
|
||||
|
@ -20,5 +20,3 @@ define_channel("tsmf")
|
||||
if(WITH_CLIENT_CHANNELS)
|
||||
add_channel_client(${MODULE_PREFIX} ${CHANNEL_NAME})
|
||||
endif()
|
||||
|
||||
|
||||
|
@ -43,7 +43,7 @@ set_target_properties(${MODULE_NAME} PROPERTIES PREFIX "")
|
||||
set_complex_link_libraries(VARIABLE ${MODULE_PREFIX}_LIBS
|
||||
MONOLITHIC ${MONOLITHIC_BUILD}
|
||||
MODULE freerdp
|
||||
MODULES freerdp-utils)
|
||||
MODULES freerdp-utils freerdp-common)
|
||||
|
||||
target_link_libraries(${MODULE_NAME} ${${MODULE_PREFIX}_LIBS})
|
||||
|
||||
@ -54,19 +54,19 @@ endif()
|
||||
set_property(TARGET ${MODULE_NAME} PROPERTY FOLDER "Channels/${CHANNEL_NAME}/Client")
|
||||
|
||||
if(WITH_FFMPEG)
|
||||
add_subdirectory(ffmpeg)
|
||||
add_channel_client_subsystem(${MODULE_PREFIX} ${CHANNEL_NAME} "ffmpeg" "decoder")
|
||||
endif()
|
||||
|
||||
if(WITH_XRANDR)
|
||||
if(GSTREAMER_FOUND)
|
||||
add_subdirectory(gstreamer)
|
||||
add_channel_client_subsystem(${MODULE_PREFIX} ${CHANNEL_NAME} "gstreamer" "decoder")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(WITH_ALSA)
|
||||
add_subdirectory(alsa)
|
||||
add_channel_client_subsystem(${MODULE_PREFIX} ${CHANNEL_NAME} "alsa" "audio")
|
||||
endif()
|
||||
|
||||
if(WITH_PULSE)
|
||||
add_subdirectory(pulse)
|
||||
add_channel_client_subsystem(${MODULE_PREFIX} ${CHANNEL_NAME} "pulse" "audio")
|
||||
endif()
|
||||
|
@ -23,7 +23,7 @@ set(${MODULE_PREFIX}_SRCS
|
||||
include_directories(..)
|
||||
include_directories(${ALSA_INCLUDE_DIRS})
|
||||
|
||||
add_library(${MODULE_NAME} ${${MODULE_PREFIX}_SRCS})
|
||||
add_channel_client_subsystem_library(${MODULE_PREFIX} ${MODULE_NAME} ${CHANNEL_NAME} "" TRUE "")
|
||||
|
||||
set_target_properties(${MODULE_NAME} PROPERTIES PREFIX "")
|
||||
|
||||
@ -36,6 +36,6 @@ set(${MODULE_PREFIX}_LIBS ${${MODULE_PREFIX}_LIBS} ${ALSA_LIBRARIES})
|
||||
|
||||
target_link_libraries(${MODULE_NAME} ${${MODULE_PREFIX}_LIBS})
|
||||
|
||||
install(TARGETS ${MODULE_NAME} DESTINATION ${FREERDP_PLUGIN_PATH})
|
||||
|
||||
|
||||
if(NOT STATIC_CHANNELS)
|
||||
install(TARGETS ${MODULE_NAME} DESTINATION ${FREERDP_ADDIN_PATH})
|
||||
endif()
|
||||
|
@ -26,7 +26,11 @@
|
||||
#include <string.h>
|
||||
#include <pthread.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <winpr/crt.h>
|
||||
|
||||
#include <alsa/asoundlib.h>
|
||||
|
||||
#include <freerdp/types.h>
|
||||
#include <freerdp/utils/memory.h>
|
||||
#include <freerdp/utils/dsp.h>
|
||||
@ -248,11 +252,16 @@ static void tsmf_alsa_free(ITSMFAudioDevice* audio)
|
||||
free(alsa);
|
||||
}
|
||||
|
||||
ITSMFAudioDevice* TSMFAudioDeviceEntry(void)
|
||||
#ifdef STATIC_CHANNELS
|
||||
#define freerdp_tsmf_client_audio_subsystem_entry alsa_freerdp_tsmf_client_audio_subsystem_entry
|
||||
#endif
|
||||
|
||||
ITSMFAudioDevice* freerdp_tsmf_client_audio_subsystem_entry(void)
|
||||
{
|
||||
TSMFALSAAudioDevice* alsa;
|
||||
|
||||
alsa = xnew(TSMFALSAAudioDevice);
|
||||
alsa = (TSMFALSAAudioDevice*) malloc(sizeof(TSMFALSAAudioDevice));
|
||||
ZeroMemory(alsa, sizeof(TSMFALSAAudioDevice));
|
||||
|
||||
alsa->iface.Open = tsmf_alsa_open;
|
||||
alsa->iface.SetFormat = tsmf_alsa_set_format;
|
||||
@ -265,4 +274,3 @@ ITSMFAudioDevice* TSMFAudioDeviceEntry(void)
|
||||
|
||||
return (ITSMFAudioDevice*) alsa;
|
||||
}
|
||||
|
||||
|
@ -15,7 +15,7 @@
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
define_channel_client_subsystem("tsmf" "ffmpeg" "video")
|
||||
define_channel_client_subsystem("tsmf" "ffmpeg" "decoder")
|
||||
|
||||
set(${MODULE_PREFIX}_SRCS
|
||||
tsmf_ffmpeg.c)
|
||||
@ -23,7 +23,7 @@ set(${MODULE_PREFIX}_SRCS
|
||||
include_directories(..)
|
||||
include_directories(${FFMPEG_INCLUDE_DIRS})
|
||||
|
||||
add_library(${MODULE_NAME} ${${MODULE_PREFIX}_SRCS})
|
||||
add_channel_client_subsystem_library(${MODULE_PREFIX} ${MODULE_NAME} ${CHANNEL_NAME} "" TRUE "")
|
||||
|
||||
set_target_properties(${MODULE_NAME} PROPERTIES PREFIX "")
|
||||
|
||||
@ -36,4 +36,6 @@ set(${MODULE_PREFIX}_LIBS ${${MODULE_PREFIX}_LIBS} ${FFMPEG_LIBRARIES})
|
||||
|
||||
target_link_libraries(${MODULE_NAME} ${${MODULE_PREFIX}_LIBS})
|
||||
|
||||
install(TARGETS ${MODULE_NAME} DESTINATION ${FREERDP_PLUGIN_PATH})
|
||||
if(NOT STATIC_CHANNELS)
|
||||
install(TARGETS ${MODULE_NAME} DESTINATION ${FREERDP_ADDIN_PATH})
|
||||
endif()
|
||||
|
@ -25,6 +25,8 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <winpr/crt.h>
|
||||
|
||||
#include <freerdp/utils/memory.h>
|
||||
#include <freerdp/utils/event.h>
|
||||
#include <freerdp/client/tsmf.h>
|
||||
@ -60,6 +62,7 @@ static BOOL tsmf_ffmpeg_init_context(ITSMFDecoder* decoder)
|
||||
TSMFFFmpegDecoder* mdecoder = (TSMFFFmpegDecoder*) decoder;
|
||||
|
||||
mdecoder->codec_context = avcodec_alloc_context3(NULL);
|
||||
|
||||
if (!mdecoder->codec_context)
|
||||
{
|
||||
DEBUG_WARN("avcodec_alloc_context failed.");
|
||||
@ -108,12 +111,13 @@ static BOOL tsmf_ffmpeg_init_audio_stream(ITSMFDecoder* decoder, const TS_AM_MED
|
||||
|
||||
static BOOL tsmf_ffmpeg_init_stream(ITSMFDecoder* decoder, const TS_AM_MEDIA_TYPE* media_type)
|
||||
{
|
||||
TSMFFFmpegDecoder* mdecoder = (TSMFFFmpegDecoder*) decoder;
|
||||
BYTE* p;
|
||||
UINT32 size;
|
||||
const BYTE* s;
|
||||
BYTE* p;
|
||||
TSMFFFmpegDecoder* mdecoder = (TSMFFFmpegDecoder*) decoder;
|
||||
|
||||
mdecoder->codec = avcodec_find_decoder(mdecoder->codec_id);
|
||||
|
||||
if (!mdecoder->codec)
|
||||
{
|
||||
DEBUG_WARN("avcodec_find_decoder failed.");
|
||||
@ -396,6 +400,7 @@ static BOOL tsmf_ffmpeg_decode_audio(ITSMFDecoder* decoder, const BYTE* data, UI
|
||||
DEBUG_WARN("error decoding");
|
||||
break;
|
||||
}
|
||||
|
||||
src += len;
|
||||
src_size -= len;
|
||||
mdecoder->decoded_size += frame_size;
|
||||
@ -444,13 +449,14 @@ static BOOL tsmf_ffmpeg_decode(ITSMFDecoder* decoder, const BYTE* data, UINT32 d
|
||||
|
||||
static BYTE* tsmf_ffmpeg_get_decoded_data(ITSMFDecoder* decoder, UINT32* size)
|
||||
{
|
||||
TSMFFFmpegDecoder* mdecoder = (TSMFFFmpegDecoder*) decoder;
|
||||
BYTE* buf;
|
||||
TSMFFFmpegDecoder* mdecoder = (TSMFFFmpegDecoder*) decoder;
|
||||
|
||||
*size = mdecoder->decoded_size;
|
||||
buf = mdecoder->decoded_data;
|
||||
mdecoder->decoded_data = NULL;
|
||||
mdecoder->decoded_size = 0;
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
@ -492,8 +498,10 @@ static void tsmf_ffmpeg_free(ITSMFDecoder* decoder)
|
||||
|
||||
if (mdecoder->frame)
|
||||
av_free(mdecoder->frame);
|
||||
|
||||
if (mdecoder->decoded_data)
|
||||
free(mdecoder->decoded_data);
|
||||
|
||||
if (mdecoder->codec_context)
|
||||
{
|
||||
if (mdecoder->prepared)
|
||||
@ -502,12 +510,17 @@ static void tsmf_ffmpeg_free(ITSMFDecoder* decoder)
|
||||
free(mdecoder->codec_context->extradata);
|
||||
av_free(mdecoder->codec_context);
|
||||
}
|
||||
|
||||
free(decoder);
|
||||
}
|
||||
|
||||
static BOOL initialized = FALSE;
|
||||
|
||||
ITSMFDecoder* TSMFDecoderEntry(void)
|
||||
#ifdef STATIC_CHANNELS
|
||||
#define freerdp_tsmf_client_decoder_subsystem_entry ffmpeg_freerdp_tsmf_client_decoder_subsystem_entry
|
||||
#endif
|
||||
|
||||
ITSMFDecoder* freerdp_tsmf_client_decoder_subsystem_entry(void)
|
||||
{
|
||||
TSMFFFmpegDecoder* decoder;
|
||||
|
||||
@ -517,7 +530,10 @@ ITSMFDecoder* TSMFDecoderEntry(void)
|
||||
initialized = TRUE;
|
||||
}
|
||||
|
||||
decoder = xnew(TSMFFFmpegDecoder);
|
||||
printf("TSMFDecoderEntry FFMPEG\n");
|
||||
|
||||
decoder = (TSMFFFmpegDecoder*) malloc(sizeof(TSMFFFmpegDecoder));
|
||||
ZeroMemory(decoder, sizeof(TSMFFFmpegDecoder));
|
||||
|
||||
decoder->iface.SetFormat = tsmf_ffmpeg_set_format;
|
||||
decoder->iface.Decode = tsmf_ffmpeg_decode;
|
||||
@ -528,4 +544,3 @@ ITSMFDecoder* TSMFDecoderEntry(void)
|
||||
|
||||
return (ITSMFDecoder*) decoder;
|
||||
}
|
||||
|
||||
|
@ -15,7 +15,7 @@
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
define_channel_client_subsystem("tsmf" "gstreamer" "video")
|
||||
define_channel_client_subsystem("tsmf" "gstreamer" "decoder")
|
||||
|
||||
set(${MODULE_PREFIX}_SRCS
|
||||
tsmf_gstreamer.c)
|
||||
@ -23,7 +23,7 @@ set(${MODULE_PREFIX}_SRCS
|
||||
include_directories(..)
|
||||
include_directories(${GSTREAMER_INCLUDE_DIRS})
|
||||
|
||||
add_library(${MODULE_NAME} ${${MODULE_PREFIX}_SRCS})
|
||||
add_channel_client_subsystem_library(${MODULE_PREFIX} ${MODULE_NAME} ${CHANNEL_NAME} "" TRUE "")
|
||||
|
||||
set_target_properties(${MODULE_NAME} PROPERTIES PREFIX "")
|
||||
|
||||
@ -40,4 +40,6 @@ set(${MODULE_PREFIX}_LIBS ${${MODULE_PREFIX}_LIBS}
|
||||
|
||||
target_link_libraries(${MODULE_NAME} ${${MODULE_PREFIX}_LIBS})
|
||||
|
||||
install(TARGETS ${MODULE_NAME} DESTINATION ${FREERDP_PLUGIN_PATH})
|
||||
if(NOT STATIC_CHANNELS)
|
||||
install(TARGETS ${MODULE_NAME} DESTINATION ${FREERDP_ADDIN_PATH})
|
||||
endif()
|
||||
|
@ -1565,8 +1565,11 @@ static void tsmf_gstreamer_update_rendering_area(ITSMFDecoder * decoder, int new
|
||||
|
||||
static int initialized = 0;
|
||||
|
||||
ITSMFDecoder *
|
||||
TSMFDecoderEntry(void)
|
||||
#ifdef STATIC_CHANNELS
|
||||
#define freerdp_tsmf_client_decoder_subsystem_entry gstreamer_freerdp_tsmf_client_decoder_subsystem_entry
|
||||
#endif
|
||||
|
||||
ITSMFDecoder* freerdp_tsmf_client_decoder_subsystem_entry(void)
|
||||
{
|
||||
TSMFGstreamerDecoder* decoder;
|
||||
|
||||
|
@ -23,7 +23,7 @@ set(${MODULE_PREFIX}_SRCS
|
||||
include_directories(..)
|
||||
include_directories(${PULSE_INCLUDE_DIR})
|
||||
|
||||
add_library(${MODULE_NAME} ${${MODULE_PREFIX}_SRCS})
|
||||
add_channel_client_subsystem_library(${MODULE_PREFIX} ${MODULE_NAME} ${CHANNEL_NAME} "" TRUE "")
|
||||
|
||||
set_target_properties(${MODULE_NAME} PROPERTIES PREFIX "")
|
||||
|
||||
@ -36,4 +36,7 @@ set(${MODULE_PREFIX}_LIBS ${${MODULE_PREFIX}_LIBS} ${PULSE_LIBRARY})
|
||||
|
||||
target_link_libraries(${MODULE_NAME} ${${MODULE_PREFIX}_LIBS})
|
||||
|
||||
install(TARGETS ${MODULE_NAME} DESTINATION ${FREERDP_PLUGIN_PATH})
|
||||
if(NOT STATIC_CHANNELS)
|
||||
install(TARGETS ${MODULE_NAME} DESTINATION ${FREERDP_ADDIN_PATH})
|
||||
endif()
|
||||
|
||||
|
@ -26,7 +26,10 @@
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <winpr/crt.h>
|
||||
|
||||
#include <pulse/pulseaudio.h>
|
||||
|
||||
#include <freerdp/utils/memory.h>
|
||||
|
||||
#include "tsmf_audio.h"
|
||||
@ -389,11 +392,16 @@ static void tsmf_pulse_free(ITSMFAudioDevice* audio)
|
||||
free(pulse);
|
||||
}
|
||||
|
||||
ITSMFAudioDevice* TSMFAudioDeviceEntry(void)
|
||||
#ifdef STATIC_CHANNELS
|
||||
#define freerdp_tsmf_client_audio_subsystem_entry pulse_freerdp_tsmf_client_audio_subsystem_entry
|
||||
#endif
|
||||
|
||||
ITSMFAudioDevice* freerdp_tsmf_client_audio_subsystem_entry(void)
|
||||
{
|
||||
TSMFPulseAudioDevice* pulse;
|
||||
|
||||
pulse = xnew(TSMFPulseAudioDevice);
|
||||
pulse = (TSMFPulseAudioDevice*) malloc(sizeof(TSMFPulseAudioDevice));
|
||||
ZeroMemory(pulse, sizeof(TSMFPulseAudioDevice));
|
||||
|
||||
pulse->iface.Open = tsmf_pulse_open;
|
||||
pulse->iface.SetFormat = tsmf_pulse_set_format;
|
||||
|
@ -34,34 +34,26 @@ static ITSMFAudioDevice* tsmf_load_audio_device_by_name(const char* name, const
|
||||
{
|
||||
ITSMFAudioDevice* audio;
|
||||
TSMF_AUDIO_DEVICE_ENTRY entry;
|
||||
char* fullname;
|
||||
|
||||
if (strrchr(name, '.') != NULL)
|
||||
entry = (TSMF_AUDIO_DEVICE_ENTRY) freerdp_load_plugin(name, TSMF_AUDIO_DEVICE_EXPORT_FUNC_NAME);
|
||||
else
|
||||
{
|
||||
fullname = xzalloc(strlen(name) + 6);
|
||||
strcpy(fullname, "tsmf_");
|
||||
strcat(fullname, name);
|
||||
entry = (TSMF_AUDIO_DEVICE_ENTRY) freerdp_load_plugin(fullname, TSMF_AUDIO_DEVICE_EXPORT_FUNC_NAME);
|
||||
free(fullname);
|
||||
}
|
||||
entry = (TSMF_AUDIO_DEVICE_ENTRY) freerdp_load_channel_addin_entry("tsmf", (LPSTR) name, "audio", 0);
|
||||
|
||||
if (entry == NULL)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
audio = entry();
|
||||
|
||||
if (audio == NULL)
|
||||
{
|
||||
DEBUG_WARN("failed to call export function in %s", name);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!audio->Open(audio, device))
|
||||
{
|
||||
audio->Free(audio);
|
||||
audio = NULL;
|
||||
}
|
||||
|
||||
return audio;
|
||||
}
|
||||
|
||||
@ -76,6 +68,7 @@ ITSMFAudioDevice* tsmf_load_audio_device(const char* name, const char* device)
|
||||
else
|
||||
{
|
||||
audio = tsmf_load_audio_device_by_name("pulse", device);
|
||||
|
||||
if (!audio)
|
||||
audio = tsmf_load_audio_device_by_name("alsa", device);
|
||||
}
|
||||
|
@ -25,31 +25,22 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <freerdp/addin.h>
|
||||
#include <freerdp/client/channels.h>
|
||||
|
||||
#include <freerdp/utils/memory.h>
|
||||
#include <freerdp/utils/load_plugin.h>
|
||||
|
||||
#include <freerdp/client/channels.h>
|
||||
|
||||
#include "tsmf_types.h"
|
||||
#include "tsmf_constants.h"
|
||||
#include "tsmf_decoder.h"
|
||||
|
||||
static ITSMFDecoder* tsmf_load_decoder_by_name(const char* name, TS_AM_MEDIA_TYPE* media_type)
|
||||
{
|
||||
char* fullname;
|
||||
ITSMFDecoder* decoder;
|
||||
TSMF_DECODER_ENTRY entry;
|
||||
|
||||
if (strrchr(name, '.') != NULL)
|
||||
entry = (TSMF_DECODER_ENTRY) freerdp_load_plugin(name, TSMF_DECODER_EXPORT_FUNC_NAME);
|
||||
else
|
||||
{
|
||||
fullname = xzalloc(strlen(name) + 6);
|
||||
strcpy(fullname, "tsmf_");
|
||||
strcat(fullname, name);
|
||||
entry = (TSMF_DECODER_ENTRY) freerdp_load_plugin(fullname, TSMF_DECODER_EXPORT_FUNC_NAME);
|
||||
free(fullname);
|
||||
}
|
||||
entry = (TSMF_DECODER_ENTRY) freerdp_load_channel_addin_entry("tsmf", (LPSTR) name, "decoder", 0);
|
||||
|
||||
if (entry == NULL)
|
||||
return NULL;
|
||||
@ -86,4 +77,3 @@ ITSMFDecoder* tsmf_load_decoder(const char* name, TS_AM_MEDIA_TYPE* media_type)
|
||||
|
||||
return decoder;
|
||||
}
|
||||
|
||||
|
@ -25,7 +25,9 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <freerdp/utils/memory.h>
|
||||
#include <winpr/crt.h>
|
||||
#include <winpr/cmdline.h>
|
||||
|
||||
#include <freerdp/utils/stream.h>
|
||||
|
||||
#include "tsmf_types.h"
|
||||
@ -76,7 +78,7 @@ void tsmf_playback_ack(IWTSVirtualChannelCallback* pChannelCallback,
|
||||
UINT32 message_id, UINT64 duration, UINT32 data_size)
|
||||
{
|
||||
STREAM* s;
|
||||
int error;
|
||||
int status;
|
||||
TSMF_CHANNEL_CALLBACK* callback = (TSMF_CHANNEL_CALLBACK*) pChannelCallback;
|
||||
|
||||
s = stream_new(32);
|
||||
@ -88,26 +90,29 @@ void tsmf_playback_ack(IWTSVirtualChannelCallback* pChannelCallback,
|
||||
stream_write_UINT64(s, data_size); /* cbData */
|
||||
|
||||
DEBUG_DVC("response size %d", (int) stream_get_length(s));
|
||||
error = callback->channel->Write(callback->channel, stream_get_length(s), stream_get_head(s), NULL);
|
||||
if (error)
|
||||
status = callback->channel->Write(callback->channel, stream_get_length(s), stream_get_head(s), NULL);
|
||||
|
||||
if (status)
|
||||
{
|
||||
DEBUG_WARN("response error %d", error);
|
||||
DEBUG_WARN("response error %d", status);
|
||||
}
|
||||
|
||||
stream_free(s);
|
||||
}
|
||||
|
||||
BOOL tsmf_push_event(IWTSVirtualChannelCallback* pChannelCallback,
|
||||
RDP_EVENT* event)
|
||||
BOOL tsmf_push_event(IWTSVirtualChannelCallback* pChannelCallback, RDP_EVENT* event)
|
||||
{
|
||||
int error;
|
||||
int status;
|
||||
TSMF_CHANNEL_CALLBACK* callback = (TSMF_CHANNEL_CALLBACK*) pChannelCallback;
|
||||
|
||||
error = callback->channel_mgr->PushEvent(callback->channel_mgr, event);
|
||||
if (error)
|
||||
status = callback->channel_mgr->PushEvent(callback->channel_mgr, event);
|
||||
|
||||
if (status)
|
||||
{
|
||||
DEBUG_WARN("response error %d", error);
|
||||
DEBUG_WARN("response error %d", status);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@ -118,7 +123,7 @@ static int tsmf_on_data_received(IWTSVirtualChannelCallback* pChannelCallback,
|
||||
int length;
|
||||
STREAM* input;
|
||||
STREAM* output;
|
||||
int error = -1;
|
||||
int status = -1;
|
||||
TSMF_IFMAN ifman;
|
||||
UINT32 MessageId;
|
||||
UINT32 FunctionId;
|
||||
@ -163,7 +168,7 @@ static int tsmf_on_data_received(IWTSVirtualChannelCallback* pChannelCallback,
|
||||
switch (FunctionId)
|
||||
{
|
||||
case RIM_EXCHANGE_CAPABILITY_REQUEST:
|
||||
error = tsmf_ifman_rim_exchange_capability_request(&ifman);
|
||||
status = tsmf_ifman_rim_exchange_capability_request(&ifman);
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -181,91 +186,91 @@ static int tsmf_on_data_received(IWTSVirtualChannelCallback* pChannelCallback,
|
||||
stream_read_UINT32(input, callback->stream_id);
|
||||
DEBUG_DVC("SET_CHANNEL_PARAMS StreamId=%d", callback->stream_id);
|
||||
ifman.output_pending = TRUE;
|
||||
error = 0;
|
||||
status = 0;
|
||||
break;
|
||||
|
||||
case EXCHANGE_CAPABILITIES_REQ:
|
||||
error = tsmf_ifman_exchange_capability_request(&ifman);
|
||||
status = tsmf_ifman_exchange_capability_request(&ifman);
|
||||
break;
|
||||
|
||||
case CHECK_FORMAT_SUPPORT_REQ:
|
||||
error = tsmf_ifman_check_format_support_request(&ifman);
|
||||
status = tsmf_ifman_check_format_support_request(&ifman);
|
||||
break;
|
||||
|
||||
case ON_NEW_PRESENTATION:
|
||||
error = tsmf_ifman_on_new_presentation(&ifman);
|
||||
status = tsmf_ifman_on_new_presentation(&ifman);
|
||||
break;
|
||||
|
||||
case ADD_STREAM:
|
||||
error = tsmf_ifman_add_stream(&ifman);
|
||||
status = tsmf_ifman_add_stream(&ifman);
|
||||
break;
|
||||
|
||||
case SET_TOPOLOGY_REQ:
|
||||
error = tsmf_ifman_set_topology_request(&ifman);
|
||||
status = tsmf_ifman_set_topology_request(&ifman);
|
||||
break;
|
||||
|
||||
case REMOVE_STREAM:
|
||||
error = tsmf_ifman_remove_stream(&ifman);
|
||||
status = tsmf_ifman_remove_stream(&ifman);
|
||||
break;
|
||||
|
||||
case SHUTDOWN_PRESENTATION_REQ:
|
||||
error = tsmf_ifman_shutdown_presentation(&ifman);
|
||||
status = tsmf_ifman_shutdown_presentation(&ifman);
|
||||
break;
|
||||
|
||||
case ON_STREAM_VOLUME:
|
||||
error = tsmf_ifman_on_stream_volume(&ifman);
|
||||
status = tsmf_ifman_on_stream_volume(&ifman);
|
||||
break;
|
||||
|
||||
case ON_CHANNEL_VOLUME:
|
||||
error = tsmf_ifman_on_channel_volume(&ifman);
|
||||
status = tsmf_ifman_on_channel_volume(&ifman);
|
||||
break;
|
||||
|
||||
case SET_VIDEO_WINDOW:
|
||||
error = tsmf_ifman_set_video_window(&ifman);
|
||||
status = tsmf_ifman_set_video_window(&ifman);
|
||||
break;
|
||||
|
||||
case UPDATE_GEOMETRY_INFO:
|
||||
error = tsmf_ifman_update_geometry_info(&ifman);
|
||||
status = tsmf_ifman_update_geometry_info(&ifman);
|
||||
break;
|
||||
|
||||
case SET_ALLOCATOR:
|
||||
error = tsmf_ifman_set_allocator(&ifman);
|
||||
status = tsmf_ifman_set_allocator(&ifman);
|
||||
break;
|
||||
|
||||
case NOTIFY_PREROLL:
|
||||
error = tsmf_ifman_notify_preroll(&ifman);
|
||||
status = tsmf_ifman_notify_preroll(&ifman);
|
||||
break;
|
||||
|
||||
case ON_SAMPLE:
|
||||
error = tsmf_ifman_on_sample(&ifman);
|
||||
status = tsmf_ifman_on_sample(&ifman);
|
||||
break;
|
||||
|
||||
case ON_FLUSH:
|
||||
error = tsmf_ifman_on_flush(&ifman);
|
||||
status = tsmf_ifman_on_flush(&ifman);
|
||||
break;
|
||||
|
||||
case ON_END_OF_STREAM:
|
||||
error = tsmf_ifman_on_end_of_stream(&ifman);
|
||||
status = tsmf_ifman_on_end_of_stream(&ifman);
|
||||
break;
|
||||
|
||||
case ON_PLAYBACK_STARTED:
|
||||
error = tsmf_ifman_on_playback_started(&ifman);
|
||||
status = tsmf_ifman_on_playback_started(&ifman);
|
||||
break;
|
||||
|
||||
case ON_PLAYBACK_PAUSED:
|
||||
error = tsmf_ifman_on_playback_paused(&ifman);
|
||||
status = tsmf_ifman_on_playback_paused(&ifman);
|
||||
break;
|
||||
|
||||
case ON_PLAYBACK_RESTARTED:
|
||||
error = tsmf_ifman_on_playback_restarted(&ifman);
|
||||
status = tsmf_ifman_on_playback_restarted(&ifman);
|
||||
break;
|
||||
|
||||
case ON_PLAYBACK_STOPPED:
|
||||
error = tsmf_ifman_on_playback_stopped(&ifman);
|
||||
status = tsmf_ifman_on_playback_stopped(&ifman);
|
||||
break;
|
||||
|
||||
case ON_PLAYBACK_RATE_CHANGED:
|
||||
error = tsmf_ifman_on_playback_rate_changed(&ifman);
|
||||
status = tsmf_ifman_on_playback_rate_changed(&ifman);
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -282,34 +287,34 @@ static int tsmf_on_data_received(IWTSVirtualChannelCallback* pChannelCallback,
|
||||
input = NULL;
|
||||
ifman.input = NULL;
|
||||
|
||||
if (error == -1)
|
||||
if (status == -1)
|
||||
{
|
||||
switch (FunctionId)
|
||||
{
|
||||
case RIMCALL_RELEASE:
|
||||
/* [MS-RDPEXPS] 2.2.2.2 Interface Release (IFACE_RELEASE)
|
||||
This message does not require a reply. */
|
||||
error = 0;
|
||||
status = 0;
|
||||
ifman.output_pending = 1;
|
||||
break;
|
||||
|
||||
case RIMCALL_QUERYINTERFACE:
|
||||
/* [MS-RDPEXPS] 2.2.2.1.2 Query Interface Response (QI_RSP)
|
||||
This message is not supported in this channel. */
|
||||
error = 0;
|
||||
status = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
if (error == -1)
|
||||
if (status == -1)
|
||||
{
|
||||
DEBUG_WARN("InterfaceId 0x%X FunctionId 0x%X not processed.",
|
||||
InterfaceId, FunctionId);
|
||||
/* When a request is not implemented we return empty response indicating error */
|
||||
}
|
||||
error = 0;
|
||||
status = 0;
|
||||
}
|
||||
|
||||
if (error == 0 && !ifman.output_pending)
|
||||
if (status == 0 && !ifman.output_pending)
|
||||
{
|
||||
/* Response packet does not have FunctionId */
|
||||
length = stream_get_length(output);
|
||||
@ -318,16 +323,16 @@ static int tsmf_on_data_received(IWTSVirtualChannelCallback* pChannelCallback,
|
||||
stream_write_UINT32(output, MessageId);
|
||||
|
||||
DEBUG_DVC("response size %d", length);
|
||||
error = callback->channel->Write(callback->channel, length, stream_get_head(output), NULL);
|
||||
if (error)
|
||||
status = callback->channel->Write(callback->channel, length, stream_get_head(output), NULL);
|
||||
if (status)
|
||||
{
|
||||
DEBUG_WARN("response error %d", error);
|
||||
DEBUG_WARN("response error %d", status);
|
||||
}
|
||||
}
|
||||
|
||||
stream_free(output);
|
||||
|
||||
return error;
|
||||
return status;
|
||||
}
|
||||
|
||||
static int tsmf_on_close(IWTSVirtualChannelCallback* pChannelCallback)
|
||||
@ -341,13 +346,16 @@ static int tsmf_on_close(IWTSVirtualChannelCallback* pChannelCallback)
|
||||
if (callback->stream_id)
|
||||
{
|
||||
presentation = tsmf_presentation_find_by_id(callback->presentation_id);
|
||||
|
||||
if (presentation)
|
||||
{
|
||||
stream = tsmf_stream_find_by_id(presentation, callback->stream_id);
|
||||
|
||||
if (stream)
|
||||
tsmf_stream_free(stream);
|
||||
}
|
||||
}
|
||||
|
||||
free(pChannelCallback);
|
||||
|
||||
return 0;
|
||||
@ -364,7 +372,9 @@ static int tsmf_on_new_channel_connection(IWTSListenerCallback* pListenerCallbac
|
||||
|
||||
DEBUG_DVC("");
|
||||
|
||||
callback = xnew(TSMF_CHANNEL_CALLBACK);
|
||||
callback = (TSMF_CHANNEL_CALLBACK*) malloc(sizeof(TSMF_CHANNEL_CALLBACK));
|
||||
ZeroMemory(callback, sizeof(TSMF_CHANNEL_CALLBACK));
|
||||
|
||||
callback->iface.OnDataReceived = tsmf_on_data_received;
|
||||
callback->iface.OnClose = tsmf_on_close;
|
||||
callback->plugin = listener_callback->plugin;
|
||||
@ -381,10 +391,13 @@ static int tsmf_plugin_initialize(IWTSPlugin* pPlugin, IWTSVirtualChannelManager
|
||||
|
||||
DEBUG_DVC("");
|
||||
|
||||
tsmf->listener_callback = xnew(TSMF_LISTENER_CALLBACK);
|
||||
tsmf->listener_callback = (TSMF_LISTENER_CALLBACK*) malloc(sizeof(TSMF_LISTENER_CALLBACK));
|
||||
ZeroMemory(tsmf->listener_callback, sizeof(TSMF_LISTENER_CALLBACK));
|
||||
|
||||
tsmf->listener_callback->iface.OnNewChannelConnection = tsmf_on_new_channel_connection;
|
||||
tsmf->listener_callback->plugin = pPlugin;
|
||||
tsmf->listener_callback->channel_mgr = pChannelMgr;
|
||||
|
||||
return pChannelMgr->CreateListener(pChannelMgr, "TSMF", 0,
|
||||
(IWTSListenerCallback*) tsmf->listener_callback, NULL);
|
||||
}
|
||||
@ -402,27 +415,55 @@ static int tsmf_plugin_terminated(IWTSPlugin* pPlugin)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void tsmf_process_plugin_data(IWTSPlugin* pPlugin, RDP_PLUGIN_DATA* data)
|
||||
COMMAND_LINE_ARGUMENT_A tsmf_args[] =
|
||||
{
|
||||
{ "audio", COMMAND_LINE_VALUE_REQUIRED, "<subsystem>", NULL, NULL, -1, NULL, "audio subsystem" },
|
||||
{ "audio-dev", COMMAND_LINE_VALUE_REQUIRED, "<device>", NULL, NULL, -1, NULL, "audio device name" },
|
||||
{ "decoder", COMMAND_LINE_VALUE_REQUIRED, "<subsystem>", NULL, NULL, -1, NULL, "decoder subsystem" },
|
||||
{ NULL, 0, NULL, NULL, NULL, -1, NULL, NULL }
|
||||
};
|
||||
|
||||
static void tsmf_process_addin_args(IWTSPlugin* pPlugin, ADDIN_ARGV* args)
|
||||
{
|
||||
int status;
|
||||
DWORD flags;
|
||||
COMMAND_LINE_ARGUMENT_A* arg;
|
||||
TSMF_PLUGIN* tsmf = (TSMF_PLUGIN*) pPlugin;
|
||||
|
||||
while (data && data->size > 0)
|
||||
flags = COMMAND_LINE_SIGIL_NONE | COMMAND_LINE_SEPARATOR_COLON;
|
||||
|
||||
status = CommandLineParseArgumentsA(args->argc, (const char**) args->argv,
|
||||
tsmf_args, flags, tsmf, NULL, NULL);
|
||||
|
||||
arg = tsmf_args;
|
||||
|
||||
do
|
||||
{
|
||||
if (data->data[0] && ( strcmp((char*)data->data[0], "tsmf") == 0 || strstr((char*)data->data[0], "/tsmf.") != NULL) )
|
||||
if (!(arg->Flags & COMMAND_LINE_VALUE_PRESENT))
|
||||
continue;
|
||||
|
||||
CommandLineSwitchStart(arg)
|
||||
|
||||
CommandLineSwitchCase(arg, "audio")
|
||||
{
|
||||
if (data->data[1] && strcmp((char*)data->data[1], "decoder") == 0)
|
||||
{
|
||||
tsmf->decoder_name = data->data[2];
|
||||
tsmf->audio_name = _strdup(arg->Value);
|
||||
}
|
||||
else if (data->data[1] && strcmp((char*)data->data[1], "audio") == 0)
|
||||
CommandLineSwitchCase(arg, "audio-dev")
|
||||
{
|
||||
tsmf->audio_name = data->data[2];
|
||||
tsmf->audio_device = data->data[3];
|
||||
tsmf->audio_device = _strdup(arg->Value);
|
||||
}
|
||||
CommandLineSwitchCase(arg, "decoder")
|
||||
{
|
||||
tsmf->decoder_name = _strdup(arg->Value);
|
||||
}
|
||||
CommandLineSwitchDefault(arg)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
data = (RDP_PLUGIN_DATA*)(((BYTE*)data) + data->size);
|
||||
CommandLineSwitchEnd(arg)
|
||||
}
|
||||
while ((arg = CommandLineFindNextArgumentA(arg)) != NULL);
|
||||
}
|
||||
|
||||
#ifdef STATIC_CHANNELS
|
||||
@ -431,29 +472,29 @@ static void tsmf_process_plugin_data(IWTSPlugin* pPlugin, RDP_PLUGIN_DATA* data)
|
||||
|
||||
int DVCPluginEntry(IDRDYNVC_ENTRY_POINTS* pEntryPoints)
|
||||
{
|
||||
int error = 0;
|
||||
int status = 0;
|
||||
TSMF_PLUGIN* tsmf;
|
||||
|
||||
tsmf = (TSMF_PLUGIN*) pEntryPoints->GetPlugin(pEntryPoints, "tsmf");
|
||||
|
||||
if (tsmf == NULL)
|
||||
{
|
||||
tsmf = xnew(TSMF_PLUGIN);
|
||||
tsmf = (TSMF_PLUGIN*) malloc(sizeof(TSMF_PLUGIN));
|
||||
ZeroMemory(tsmf, sizeof(TSMF_PLUGIN));
|
||||
|
||||
tsmf->iface.Initialize = tsmf_plugin_initialize;
|
||||
tsmf->iface.Connected = NULL;
|
||||
tsmf->iface.Disconnected = NULL;
|
||||
tsmf->iface.Terminated = tsmf_plugin_terminated;
|
||||
error = pEntryPoints->RegisterPlugin(pEntryPoints, "tsmf", (IWTSPlugin*) tsmf);
|
||||
status = pEntryPoints->RegisterPlugin(pEntryPoints, "tsmf", (IWTSPlugin*) tsmf);
|
||||
|
||||
tsmf_media_init();
|
||||
}
|
||||
if (error == 0)
|
||||
|
||||
if (status == 0)
|
||||
{
|
||||
tsmf_process_plugin_data((IWTSPlugin*) tsmf,
|
||||
pEntryPoints->GetPluginData(pEntryPoints));
|
||||
tsmf_process_addin_args((IWTSPlugin*) tsmf, pEntryPoints->GetPluginData(pEntryPoints));
|
||||
}
|
||||
|
||||
return error;
|
||||
return status;
|
||||
}
|
||||
|
||||
|
@ -837,7 +837,7 @@ int freerdp_client_load_addins(rdpChannels* channels, rdpSettings* settings)
|
||||
|
||||
args = settings->StaticChannelArray[index];
|
||||
|
||||
entry = freerdp_load_channel_addin_entry(args->argv[0], NULL, NULL, FREERDP_ADDIN_CHANNEL_STATIC);
|
||||
entry = freerdp_load_channel_addin_entry(args->argv[0], NULL, NULL, 0);
|
||||
|
||||
if (entry)
|
||||
{
|
||||
@ -848,7 +848,7 @@ int freerdp_client_load_addins(rdpChannels* channels, rdpSettings* settings)
|
||||
|
||||
if (settings->DeviceRedirection)
|
||||
{
|
||||
entry = freerdp_load_channel_addin_entry("rdpdr", NULL, NULL, FREERDP_ADDIN_CHANNEL_STATIC);
|
||||
entry = freerdp_load_channel_addin_entry("rdpdr", NULL, NULL, 0);
|
||||
|
||||
if (entry)
|
||||
{
|
||||
@ -859,7 +859,7 @@ int freerdp_client_load_addins(rdpChannels* channels, rdpSettings* settings)
|
||||
|
||||
if (settings->RemoteApplicationMode)
|
||||
{
|
||||
entry = freerdp_load_channel_addin_entry("rail", NULL, NULL, FREERDP_ADDIN_CHANNEL_STATIC);
|
||||
entry = freerdp_load_channel_addin_entry("rail", NULL, NULL, 0);
|
||||
|
||||
if (entry)
|
||||
{
|
||||
@ -870,7 +870,7 @@ int freerdp_client_load_addins(rdpChannels* channels, rdpSettings* settings)
|
||||
|
||||
if (settings->DynamicChannelCount)
|
||||
{
|
||||
entry = freerdp_load_channel_addin_entry("drdynvc", NULL, NULL, FREERDP_ADDIN_CHANNEL_STATIC);
|
||||
entry = freerdp_load_channel_addin_entry("drdynvc", NULL, NULL, 0);
|
||||
|
||||
if (entry)
|
||||
{
|
||||
|
@ -52,6 +52,7 @@
|
||||
#define __FREERDP_DVC_H
|
||||
|
||||
#include <freerdp/types.h>
|
||||
#include <freerdp/addin.h>
|
||||
|
||||
typedef struct _IWTSVirtualChannelManager IWTSVirtualChannelManager;
|
||||
typedef struct _IWTSListener IWTSListener;
|
||||
@ -145,7 +146,7 @@ struct _IDRDYNVC_ENTRY_POINTS
|
||||
const char* name, IWTSPlugin* pPlugin);
|
||||
IWTSPlugin* (*GetPlugin) (IDRDYNVC_ENTRY_POINTS* pEntryPoints,
|
||||
const char* name);
|
||||
RDP_PLUGIN_DATA* (*GetPluginData) (IDRDYNVC_ENTRY_POINTS* pEntryPoints);
|
||||
ADDIN_ARGV* (*GetPluginData) (IDRDYNVC_ENTRY_POINTS* pEntryPoints);
|
||||
};
|
||||
|
||||
typedef int (*PDVC_PLUGIN_ENTRY) (IDRDYNVC_ENTRY_POINTS*);
|
||||
|
@ -25,6 +25,7 @@
|
||||
|
||||
#include <freerdp/api.h>
|
||||
#include <freerdp/svc.h>
|
||||
#include <freerdp/addin.h>
|
||||
#include <freerdp/utils/stream.h>
|
||||
#include <freerdp/utils/event.h>
|
||||
#include <freerdp/utils/debug.h>
|
||||
@ -52,8 +53,6 @@ FREERDP_API void svc_plugin_init(rdpSvcPlugin* plugin, CHANNEL_ENTRY_POINTS* pEn
|
||||
FREERDP_API int svc_plugin_send(rdpSvcPlugin* plugin, STREAM* data_out);
|
||||
FREERDP_API int svc_plugin_send_event(rdpSvcPlugin* plugin, RDP_EVENT* event);
|
||||
|
||||
#define svc_plugin_get_data(_p) (RDP_PLUGIN_DATA*)(((rdpSvcPlugin*)_p)->channel_entry_points.pExtendedData)
|
||||
|
||||
#ifdef WITH_DEBUG_SVC
|
||||
#define DEBUG_SVC(fmt, ...) DEBUG_CLASS(SVC, fmt, ## __VA_ARGS__)
|
||||
#else
|
||||
|
@ -30,7 +30,7 @@ set_target_properties(${MODULE_NAME} PROPERTIES VERSION ${FREERDP_VERSION_FULL}
|
||||
|
||||
set_complex_link_libraries(VARIABLE ${MODULE_PREFIX}_LIBS MONOLITHIC ${MONOLITHIC_BUILD}
|
||||
MODULE winpr
|
||||
MODULES winpr-crt winpr-path winpr-file winpr-utils)
|
||||
MODULES winpr-crt winpr-path winpr-file winpr-library winpr-utils)
|
||||
|
||||
if(MONOLITHIC_BUILD)
|
||||
set(FREERDP_LIBS ${FREERDP_LIBS} ${${MODULE_PREFIX}_LIBS} PARENT_SCOPE)
|
||||
|
@ -111,37 +111,6 @@ void* freerdp_load_library_symbol(const char* file, const char* name)
|
||||
*/
|
||||
void* freerdp_load_plugin(const char* name, const char* entry_name)
|
||||
{
|
||||
#if 0
|
||||
char* path;
|
||||
void* entry;
|
||||
char* suffixed_name;
|
||||
|
||||
suffixed_name = freerdp_append_shared_library_suffix((char*) name);
|
||||
|
||||
if (!freerdp_path_contains_separator(suffixed_name))
|
||||
{
|
||||
/* no explicit path given, use default path */
|
||||
path = freerdp_construct_path(FREERDP_PLUGIN_PATH, suffixed_name);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* explicit path given, use it instead of default path */
|
||||
path = _strdup(suffixed_name);
|
||||
}
|
||||
|
||||
entry = freerdp_load_library_symbol(path, entry_name);
|
||||
|
||||
free(suffixed_name);
|
||||
free(path);
|
||||
|
||||
if (entry == NULL)
|
||||
{
|
||||
printf("freerdp_load_plugin: failed to load %s/%s\n", name, entry_name);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return entry;
|
||||
#endif
|
||||
return freerdp_load_dynamic_addin(name, NULL, entry_name);
|
||||
}
|
||||
|
||||
|
@ -166,10 +166,12 @@ static void svc_plugin_process_received(rdpSvcPlugin* plugin, void* pData, UINT3
|
||||
|
||||
if ((dataFlags & CHANNEL_FLAG_SUSPEND) || (dataFlags & CHANNEL_FLAG_RESUME))
|
||||
{
|
||||
/* According to MS-RDPBCGR 2.2.6.1, "All virtual channel traffic MUST be suspended.
|
||||
This flag is only valid in server-to-client virtual channel traffic. It MUST be
|
||||
ignored in client-to-server data." Thus it would be best practice to cease data
|
||||
transmission. However, simply returning here avoids a crash. */
|
||||
/*
|
||||
* According to MS-RDPBCGR 2.2.6.1, "All virtual channel traffic MUST be suspended.
|
||||
* This flag is only valid in server-to-client virtual channel traffic. It MUST be
|
||||
* ignored in client-to-server data." Thus it would be best practice to cease data
|
||||
* transmission. However, simply returning here avoids a crash.
|
||||
*/
|
||||
return;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user