Merge pull request #942 from C-o-r-E/master
mfreerdp-server: Added output sound redirection
This commit is contained in:
commit
2efb4637d4
@ -410,13 +410,28 @@ endif()
|
||||
|
||||
# Packaging
|
||||
|
||||
SET(CPACK_BINARY_ZIP "ON")
|
||||
|
||||
set(CPACK_SOURCE_IGNORE_FILES "/\\\\.git/;/\\\\.gitignore;/CMakeCache.txt")
|
||||
|
||||
if(NOT WIN32)
|
||||
set(CPACK_PACKAGE_EXECUTABLES "xfreerdp")
|
||||
if(WITH_SERVER)
|
||||
set(CPACK_PACKAGE_EXECUTABLES ${CPACK_PACKAGE_EXECUTABLES} "xfreerdp-server")
|
||||
if(APPLE AND (NOT IOS))
|
||||
#set(CPACK_PACKAGE_EXECUTABLES "mfreerdp")
|
||||
|
||||
if(WITH_SERVER)
|
||||
set(CPACK_PACKAGE_EXECUTABLES ${CPACK_PACKAGE_EXECUTABLES} "mfreerdp-server")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(WITH_X11)
|
||||
set(CPACK_PACKAGE_EXECUTABLES "xfreerdp")
|
||||
|
||||
if(WITH_SERVER)
|
||||
set(CPACK_PACKAGE_EXECUTABLES ${CPACK_PACKAGE_EXECUTABLES} "xfreerdp-server")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
|
||||
endif()
|
||||
|
||||
set(CPACK_SYSTEM_NAME "${CMAKE_SYSTEM_NAME}-${CMAKE_SYSTEM_PROCESSOR}")
|
||||
@ -447,6 +462,8 @@ set(CPACK_PACKAGE_ICON "${CMAKE_SOURCE_DIR}/resources\\\\FreeRDP_Install.bmp")
|
||||
set(CPACK_NSIS_MUI_ICON "${CMAKE_SOURCE_DIR}/resources\\\\FreeRDP_Icon_96px.ico")
|
||||
set(CPACK_NSIS_MUI_UNICON "${CMAKE_SOURCE_DIR}/resource\\\\FreeRDP_Icon_96px.ico")
|
||||
|
||||
set(CPACK_COMPONENTS_ALL client server libraries headers)
|
||||
|
||||
if(MSVC)
|
||||
if(MSVC_RUNTIME STREQUAL "dynamic")
|
||||
set(CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS_SKIP TRUE)
|
||||
@ -454,26 +471,24 @@ if(MSVC)
|
||||
install(PROGRAMS ${CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS}
|
||||
DESTINATION ${CMAKE_INSTALL_BINDIR}
|
||||
COMPONENT libraries)
|
||||
endif()
|
||||
|
||||
set(EXTRA_DATA_DIR "extra/")
|
||||
file(GLOB EXTRA_FILES "${CMAKE_SOURCE_DIR}/extra/*")
|
||||
install(FILES ${EXTRA_FILES}
|
||||
DESTINATION ${EXTRA_DATA_DIR}
|
||||
COMPONENT extra)
|
||||
|
||||
set(EXTRA_DATA_DIR "pre-requisites/")
|
||||
file(GLOB EXTRA_FILES "${CMAKE_SOURCE_DIR}/extra/*")
|
||||
install(FILES ${EXTRA_FILES}
|
||||
DESTINATION ${EXTRA_DATA_DIR}
|
||||
COMPONENT extra)
|
||||
|
||||
set(REV_DATA_DIR "REV/")
|
||||
file(GLOB REV_FILES "${CMAKE_SOURCE_DIR}/REV/*")
|
||||
install(FILES ${REV_FILES}
|
||||
DESTINATION ${REV_DATA_DIR}
|
||||
COMPONENT rev)
|
||||
endif()
|
||||
set(REV_DATA_DIR "REV/")
|
||||
file(GLOB REV_FILES "${CMAKE_SOURCE_DIR}/REV/*")
|
||||
install(FILES ${REV_FILES}
|
||||
DESTINATION ${REV_DATA_DIR}
|
||||
COMPONENT rev)
|
||||
|
||||
set(CPACK_COMPONENTS_AL ${CPACK_COMPONENTS_ALL} extra rev)
|
||||
endif()
|
||||
|
||||
|
||||
set(CPACK_COMPONENTS_ALL client server libraries headers extra rev)
|
||||
|
||||
|
||||
set(CPACK_COMPONENT_CLIENT_DISPLAY_NAME "Client")
|
||||
set(CPACK_COMPONENT_CLIENT_GROUP "Applications")
|
||||
|
||||
|
@ -33,6 +33,7 @@
|
||||
#include <winpr/tchar.h>
|
||||
#include <winpr/sysinfo.h>
|
||||
#include <winpr/registry.h>
|
||||
#include <winpr/tchar.h>
|
||||
|
||||
#include <freerdp/codec/rfx.h>
|
||||
#include <freerdp/constants.h>
|
||||
|
@ -189,7 +189,7 @@ int rpc_client_on_fragment_received_event(rdpRpc* rpc)
|
||||
* combined stub data length of all remaining fragment PDUs.
|
||||
*/
|
||||
|
||||
if ((header->response.alloc_hint == StubLength))
|
||||
if (header->response.alloc_hint == StubLength)
|
||||
{
|
||||
rpc->StubCallId = 0;
|
||||
rpc->StubFragCount = 0;
|
||||
|
@ -18,6 +18,8 @@
|
||||
set(MODULE_NAME "mfreerdp-server")
|
||||
set(MODULE_PREFIX "FREERDP_SERVER_MAC")
|
||||
|
||||
FIND_LIBRARY(AUDIO_TOOL AudioToolbox)
|
||||
FIND_LIBRARY(CORE_AUDIO CoreAudio)
|
||||
FIND_LIBRARY(CORE_VIDEO CoreVideo)
|
||||
FIND_LIBRARY(CORE_GRAPHICS CoreGraphics)
|
||||
FIND_LIBRARY(APP_SERVICES ApplicationServices)
|
||||
@ -55,7 +57,9 @@ add_executable(${MODULE_NAME} ${${MODULE_PREFIX}_SRCS})
|
||||
|
||||
set(${MODULE_PREFIX}_LIBS ${${MODULE_PREFIX}_LIBS}
|
||||
freerdp-server
|
||||
${CORE_VIDEO}
|
||||
${AUDIO_TOOL}
|
||||
${CORE_AUDIO}
|
||||
${CORE_VIDEO}
|
||||
${CORE_GRAPHICS}
|
||||
${APP_SERVICES}
|
||||
${IOKIT}
|
||||
|
@ -3,6 +3,7 @@
|
||||
* FreeRDP Mac OS X Server (Audio Input)
|
||||
*
|
||||
* Copyright 2012 Marc-Andre Moreau <marcandre.moreau@gmail.com>
|
||||
* Copyright 2013 Corey Clayton <can.of.tuna@gmail.com>
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@ -22,10 +23,11 @@
|
||||
|
||||
#include <freerdp/freerdp.h>
|
||||
#include <freerdp/listener.h>
|
||||
#include <freerdp/server/audin.h>
|
||||
|
||||
#include "mf_interface.h"
|
||||
#include "mfreerdp.h"
|
||||
|
||||
|
||||
void mf_peer_audin_init(mfPeerContext* context);
|
||||
|
||||
#endif /* MF_AUDIN_H */
|
||||
|
@ -26,7 +26,7 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <freerdp/utils/memory.h>
|
||||
//#include <util.h>
|
||||
|
||||
#include "mf_event.h"
|
||||
|
||||
@ -144,7 +144,7 @@ mfEvent* mf_event_pop(mfEventQueue* event_queue)
|
||||
|
||||
mfEventRegion* mf_event_region_new(int x, int y, int width, int height)
|
||||
{
|
||||
mfEventRegion* event_region = xnew(mfEventRegion);
|
||||
mfEventRegion* event_region = malloc(sizeof(mfEventRegion));
|
||||
|
||||
if (event_region != NULL)
|
||||
{
|
||||
@ -164,7 +164,7 @@ void mf_event_region_free(mfEventRegion* event_region)
|
||||
|
||||
mfEvent* mf_event_new(int type)
|
||||
{
|
||||
mfEvent* event = xnew(mfEvent);
|
||||
mfEvent* event = malloc(sizeof(mfEvent));
|
||||
event->type = type;
|
||||
return event;
|
||||
}
|
||||
@ -176,7 +176,7 @@ void mf_event_free(mfEvent* event)
|
||||
|
||||
mfEventQueue* mf_event_queue_new()
|
||||
{
|
||||
mfEventQueue* event_queue = xnew(mfEventQueue);
|
||||
mfEventQueue* event_queue = malloc(sizeof(mfEventQueue));
|
||||
|
||||
if (event_queue != NULL)
|
||||
{
|
||||
@ -185,7 +185,7 @@ mfEventQueue* mf_event_queue_new()
|
||||
|
||||
event_queue->size = 16;
|
||||
event_queue->count = 0;
|
||||
event_queue->events = (mfEvent**) xzalloc(sizeof(mfEvent*) * event_queue->size);
|
||||
event_queue->events = (mfEvent**) malloc(sizeof(mfEvent*) * event_queue->size);
|
||||
|
||||
if (pipe(event_queue->pipe_fd) < 0)
|
||||
printf("mf_event_queue_new: pipe failed\n");
|
||||
|
@ -23,22 +23,24 @@
|
||||
|
||||
#include <pthread.h>
|
||||
|
||||
#include <freerdp/codec/rfx.h>
|
||||
#include <freerdp/codec/nsc.h>
|
||||
#include <freerdp/listener.h>
|
||||
#include <freerdp/utils/stream.h>
|
||||
|
||||
#ifdef WITH_SERVER_CHANNELS
|
||||
//#ifdef WITH_SERVER_CHANNELS
|
||||
#include <freerdp/channels/wtsvc.h>
|
||||
#endif
|
||||
//#endif
|
||||
|
||||
#ifdef CHANNEL_RDPSND_SERVER
|
||||
//#ifdef CHANNEL_RDPSND_SERVER
|
||||
#include <freerdp/server/rdpsnd.h>
|
||||
#include "mf_rdpsnd.h"
|
||||
#endif
|
||||
//#include "mf_rdpsnd.h"
|
||||
//#endif
|
||||
|
||||
#ifdef CHANNEL_AUDIN_SERVER
|
||||
#include "mf_audin.h"
|
||||
#endif
|
||||
//#ifdef CHANNEL_AUDIN_SERVER
|
||||
#include <freerdp/server/audin.h>
|
||||
//#include "mf_audin.h"
|
||||
//#endif
|
||||
|
||||
typedef struct mf_info mfInfo;
|
||||
typedef struct mf_peer_context mfPeerContext;
|
||||
@ -55,16 +57,16 @@ struct mf_peer_context
|
||||
RFX_CONTEXT* rfx_context;
|
||||
NSC_CONTEXT* nsc_context;
|
||||
|
||||
#ifdef WITH_SERVER_CHANNELS
|
||||
//#ifdef WITH_SERVER_CHANNELS
|
||||
WTSVirtualChannelManager* vcm;
|
||||
#endif
|
||||
#ifdef CHANNEL_AUDIN_SERVER
|
||||
//#endif
|
||||
//#ifdef CHANNEL_AUDIN_SERVER
|
||||
audin_server_context* audin;
|
||||
#endif
|
||||
//#endif
|
||||
|
||||
#ifdef CHANNEL_RDPSND_SERVER
|
||||
//#ifdef CHANNEL_RDPSND_SERVER
|
||||
rdpsnd_server_context* rdpsnd;
|
||||
#endif
|
||||
//#endif
|
||||
};
|
||||
|
||||
|
||||
|
@ -22,7 +22,6 @@
|
||||
#endif
|
||||
|
||||
#include <freerdp/listener.h>
|
||||
#include <freerdp/utils/sleep.h>
|
||||
#include <freerdp/codec/rfx.h>
|
||||
#include <freerdp/utils/stream.h>
|
||||
|
||||
@ -31,6 +30,7 @@
|
||||
#include "mf_peer.h"
|
||||
#include "mf_info.h"
|
||||
#include "mf_event.h"
|
||||
#include "mf_rdpsnd.h"
|
||||
|
||||
#include <mach/clock.h>
|
||||
#include <mach/mach.h>
|
||||
@ -147,6 +147,9 @@ void mf_peer_rfx_update(freerdp_peer* client)
|
||||
rect.width = width;
|
||||
rect.height = height;
|
||||
|
||||
mfp->rfx_context->width = mfi->servscreen_width;
|
||||
mfp->rfx_context->height = mfi->servscreen_height;
|
||||
|
||||
rfx_compose_message(mfp->rfx_context, s, &rect, 1,
|
||||
(BYTE*) dataBits, rect.width, rect.height, pitch);
|
||||
|
||||
@ -165,7 +168,7 @@ void mf_peer_rfx_update(freerdp_peer* client)
|
||||
|
||||
//send
|
||||
|
||||
update->SurfaceBits(update->context, cmd);
|
||||
update->SurfaceBits(update->context, cmd);
|
||||
|
||||
//clean up
|
||||
|
||||
@ -198,9 +201,9 @@ void mf_peer_context_new(freerdp_peer* client, mfPeerContext* context)
|
||||
|
||||
context->s = stream_new(0xFFFF);
|
||||
|
||||
#ifdef WITH_SERVER_CHANNELS
|
||||
//#ifdef WITH_SERVER_CHANNELS
|
||||
context->vcm = WTSCreateVirtualChannelManager(client);
|
||||
#endif
|
||||
//#endif
|
||||
|
||||
mf_info_peer_register(context->info, context);
|
||||
}
|
||||
@ -225,14 +228,15 @@ void mf_peer_context_free(freerdp_peer* client, mfPeerContext* context)
|
||||
audin_server_context_free(context->audin);
|
||||
#endif
|
||||
|
||||
#ifdef CHANNEL_RDPSND_SERVER
|
||||
//#ifdef CHANNEL_RDPSND_SERVER
|
||||
mf_peer_rdpsnd_stop();
|
||||
if (context->rdpsnd)
|
||||
rdpsnd_server_context_free(context->rdpsnd);
|
||||
#endif
|
||||
//#endif
|
||||
|
||||
#ifdef WITH_SERVER_CHANNELS
|
||||
//#ifdef WITH_SERVER_CHANNELS
|
||||
WTSDestroyVirtualChannelManager(context->vcm);
|
||||
#endif
|
||||
//#endif
|
||||
}
|
||||
}
|
||||
|
||||
@ -252,7 +256,7 @@ void mf_peer_init(freerdp_peer* client)
|
||||
if(info_timer)
|
||||
{
|
||||
//printf("created timer\n");
|
||||
dispatch_source_set_timer(info_timer, DISPATCH_TIME_NOW, 33ull * NSEC_PER_MSEC, 100ull * NSEC_PER_MSEC);
|
||||
dispatch_source_set_timer(info_timer, DISPATCH_TIME_NOW, 42ull * NSEC_PER_MSEC, 100ull * NSEC_PER_MSEC);
|
||||
dispatch_source_set_event_handler(info_timer, ^{
|
||||
//printf("dispatch\n");
|
||||
mfEvent* event = mf_event_new(MF_EVENT_TYPE_FRAME_TICK);
|
||||
@ -265,10 +269,10 @@ void mf_peer_init(freerdp_peer* client)
|
||||
|
||||
BOOL mf_peer_post_connect(freerdp_peer* client)
|
||||
{
|
||||
//mfPeerContext* context = (mfPeerContext*) client->context;
|
||||
mfPeerContext* context = (mfPeerContext*) client->context;
|
||||
rdpSettings* settings = client->settings;
|
||||
|
||||
printf("Client %s is activated\n", client->hostname);
|
||||
printf("Client %s post connect\n", client->hostname);
|
||||
|
||||
if (client->settings->AutoLogonEnabled)
|
||||
{
|
||||
@ -300,27 +304,24 @@ BOOL mf_peer_post_connect(freerdp_peer* client)
|
||||
client->update->DesktopResize(client->update->context);
|
||||
|
||||
|
||||
/*printf("Client requested desktop: %dx%dx%d\n",
|
||||
client->settings->DesktopWidth, client->settings->DesktopHeight, client->settings->ColorDepth);
|
||||
*/
|
||||
#ifdef WITH_SERVER_CHANNELS
|
||||
//#ifdef WITH_SERVER_CHANNELS
|
||||
/* Iterate all channel names requested by the client and activate those supported by the server */
|
||||
int i;
|
||||
for (i = 0; i < client->settings->ChannelCount; i++)
|
||||
{
|
||||
if (client->settings->ChannelDefArray[i].joined)
|
||||
{
|
||||
#ifdef CHANNEL_RDPSND_SERVER
|
||||
//#ifdef CHANNEL_RDPSND_SERVER
|
||||
if (strncmp(client->settings->ChannelDefArray[i].Name, "rdpsnd", 6) == 0)
|
||||
{
|
||||
mf_peer_rdpsnd_init(context); /* Audio Output */
|
||||
}
|
||||
#endif
|
||||
//#endif
|
||||
}
|
||||
}
|
||||
|
||||
/* Dynamic Virtual Channels */
|
||||
#endif
|
||||
//#endif
|
||||
|
||||
#ifdef CHANNEL_AUDIN_SERVER
|
||||
mf_peer_audin_init(context); /* Audio Input */
|
||||
@ -333,7 +334,7 @@ BOOL mf_peer_post_connect(freerdp_peer* client)
|
||||
BOOL mf_peer_activate(freerdp_peer* client)
|
||||
{
|
||||
mfPeerContext* context = (mfPeerContext*) client->context;
|
||||
|
||||
|
||||
rfx_context_reset(context->rfx_context);
|
||||
context->activated = TRUE;
|
||||
|
||||
@ -374,10 +375,12 @@ void mf_peer_keyboard_event(rdpInput* input, UINT16 flags, UINT16 code)
|
||||
state_down = TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
CGEventRef event;
|
||||
event = CGEventCreateKeyboardEvent(NULL, (CGKeyCode)code, state_down);
|
||||
CGEventPost(kCGHIDEventTap, event);
|
||||
CFRelease(event);
|
||||
*/
|
||||
}
|
||||
|
||||
void mf_peer_unicode_keyboard_event(rdpInput* input, UINT16 flags, UINT16 code)
|
||||
@ -511,6 +514,7 @@ void* mf_peer_main_loop(void* arg)
|
||||
client->settings->PrivateKeyFile = _strdup("server.key");
|
||||
client->settings->NlaSecurity = FALSE;
|
||||
client->settings->RemoteFxCodec = TRUE;
|
||||
client->settings->ColorDepth = 32;
|
||||
client->settings->SuppressOutput = TRUE;
|
||||
client->settings->RefreshRect = FALSE;
|
||||
|
||||
@ -546,9 +550,9 @@ void* mf_peer_main_loop(void* arg)
|
||||
break;
|
||||
}
|
||||
|
||||
#ifdef WITH_SERVER_CHANNELS
|
||||
//#ifdef WITH_SERVER_CHANNELS
|
||||
WTSVirtualChannelManagerGetFileDescriptor(context->vcm, rfds, &rcount);
|
||||
#endif
|
||||
//#endif
|
||||
|
||||
max_fds = 0;
|
||||
FD_ZERO(&rfds_set);
|
||||
@ -591,10 +595,10 @@ void* mf_peer_main_loop(void* arg)
|
||||
}
|
||||
|
||||
|
||||
#ifdef WITH_SERVER_CHANNELS
|
||||
//#ifdef WITH_SERVER_CHANNELS
|
||||
if (WTSVirtualChannelManagerCheckFileDescriptor(context->vcm) != TRUE)
|
||||
break;
|
||||
#endif
|
||||
//#endif
|
||||
|
||||
}
|
||||
|
||||
|
@ -23,8 +23,11 @@
|
||||
|
||||
#include <freerdp/server/audin.h>
|
||||
|
||||
#include "mf_info.h"
|
||||
#include "mf_rdpsnd.h"
|
||||
|
||||
AQRecorderState recorderState;
|
||||
|
||||
static const rdpsndFormat audio_formats[] =
|
||||
{
|
||||
{ 0x11, 2, 22050, 1024, 4, 0, NULL }, /* IMA ADPCM, 22050 Hz, 2 channels */
|
||||
@ -42,10 +45,82 @@ static const rdpsndFormat audio_formats[] =
|
||||
static void mf_peer_rdpsnd_activated(rdpsnd_server_context* context)
|
||||
{
|
||||
printf("RDPSND Activated\n");
|
||||
|
||||
|
||||
|
||||
printf("Let's create an audio queue for input!\n");
|
||||
|
||||
OSStatus status;
|
||||
|
||||
recorderState.dataFormat.mSampleRate = 44100.0;
|
||||
recorderState.dataFormat.mFormatID = kAudioFormatLinearPCM;
|
||||
recorderState.dataFormat.mFormatFlags = kAudioFormatFlagIsSignedInteger | kAudioFormatFlagsNativeEndian | kAudioFormatFlagIsPacked;
|
||||
recorderState.dataFormat.mBytesPerPacket = 4;
|
||||
recorderState.dataFormat.mFramesPerPacket = 1;
|
||||
recorderState.dataFormat.mBytesPerFrame = 4;
|
||||
recorderState.dataFormat.mChannelsPerFrame = 2;
|
||||
recorderState.dataFormat.mBitsPerChannel = 16;
|
||||
|
||||
recorderState.snd_context = context;
|
||||
|
||||
status = AudioQueueNewInput(&recorderState.dataFormat,
|
||||
mf_peer_rdpsnd_input_callback,
|
||||
&recorderState,
|
||||
NULL,
|
||||
kCFRunLoopCommonModes,
|
||||
0,
|
||||
&recorderState.queue);
|
||||
|
||||
if (status != noErr)
|
||||
{
|
||||
printf("Failed to create a new Audio Queue. Status code: %d\n", status);
|
||||
}
|
||||
|
||||
|
||||
UInt32 dataFormatSize = sizeof (recorderState.dataFormat);
|
||||
|
||||
AudioQueueGetProperty(recorderState.queue,
|
||||
kAudioConverterCurrentInputStreamDescription,
|
||||
&recorderState.dataFormat,
|
||||
&dataFormatSize);
|
||||
|
||||
|
||||
mf_rdpsnd_derive_buffer_size(recorderState.queue, &recorderState.dataFormat, 0.05, &recorderState.bufferByteSize);
|
||||
|
||||
|
||||
printf("Preparing a set of buffers...");
|
||||
|
||||
for (int i = 0; i < snd_numBuffers; ++i)
|
||||
{
|
||||
AudioQueueAllocateBuffer(recorderState.queue,
|
||||
recorderState.bufferByteSize,
|
||||
&recorderState.buffers[i]);
|
||||
|
||||
AudioQueueEnqueueBuffer(recorderState.queue,
|
||||
recorderState.buffers[i],
|
||||
0,
|
||||
NULL);
|
||||
}
|
||||
|
||||
printf("done\n");
|
||||
|
||||
printf("recording...\n");
|
||||
|
||||
|
||||
|
||||
recorderState.currentPacket = 0;
|
||||
recorderState.isRunning = true;
|
||||
|
||||
context->SelectFormat(context, 4);
|
||||
context->SetVolume(context, 0x7FFF, 0x7FFF);
|
||||
|
||||
AudioQueueStart (recorderState.queue, NULL);
|
||||
|
||||
}
|
||||
|
||||
BOOL mf_peer_rdpsnd_init(mfPeerContext* context)
|
||||
{
|
||||
//printf("RDPSND INIT\n");
|
||||
context->rdpsnd = rdpsnd_server_context_new(context->vcm);
|
||||
context->rdpsnd->data = context;
|
||||
|
||||
@ -63,3 +138,75 @@ BOOL mf_peer_rdpsnd_init(mfPeerContext* context)
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL mf_peer_rdpsnd_stop()
|
||||
{
|
||||
recorderState.isRunning = false;
|
||||
AudioQueueStop(recorderState.queue, true);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void mf_peer_rdpsnd_input_callback (void *inUserData,
|
||||
AudioQueueRef inAQ,
|
||||
AudioQueueBufferRef inBuffer,
|
||||
const AudioTimeStamp *inStartTime,
|
||||
UInt32 inNumberPacketDescriptions,
|
||||
const AudioStreamPacketDescription *inPacketDescs)
|
||||
{
|
||||
OSStatus status;
|
||||
AQRecorderState * rState;
|
||||
rState = inUserData;
|
||||
|
||||
|
||||
if (inNumberPacketDescriptions == 0 && rState->dataFormat.mBytesPerPacket != 0)
|
||||
{
|
||||
inNumberPacketDescriptions = inBuffer->mAudioDataByteSize / rState->dataFormat.mBytesPerPacket;
|
||||
}
|
||||
|
||||
|
||||
if (rState->isRunning == 0)
|
||||
{
|
||||
return ;
|
||||
}
|
||||
|
||||
rState->snd_context->SendSamples(rState->snd_context, inBuffer->mAudioData, inBuffer->mAudioDataByteSize/4);
|
||||
|
||||
status = AudioQueueEnqueueBuffer(
|
||||
rState->queue,
|
||||
inBuffer,
|
||||
0,
|
||||
NULL);
|
||||
|
||||
if (status != noErr)
|
||||
{
|
||||
printf("AudioQueueEnqueueBuffer() returned status = %d\n", status);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void mf_rdpsnd_derive_buffer_size (AudioQueueRef audioQueue,
|
||||
AudioStreamBasicDescription *ASBDescription,
|
||||
Float64 seconds,
|
||||
UInt32 *outBufferSize)
|
||||
{
|
||||
static const int maxBufferSize = 0x50000;
|
||||
|
||||
int maxPacketSize = ASBDescription->mBytesPerPacket;
|
||||
if (maxPacketSize == 0)
|
||||
{
|
||||
UInt32 maxVBRPacketSize = sizeof(maxPacketSize);
|
||||
AudioQueueGetProperty (audioQueue,
|
||||
kAudioQueueProperty_MaximumOutputPacketSize,
|
||||
// in Mac OS X v10.5, instead use
|
||||
// kAudioConverterPropertyMaximumOutputPacketSize
|
||||
&maxPacketSize,
|
||||
&maxVBRPacketSize
|
||||
);
|
||||
}
|
||||
|
||||
Float64 numBytesForTime =
|
||||
ASBDescription->mSampleRate * maxPacketSize * seconds;
|
||||
*outBufferSize = (UInt32) (numBytesForTime < maxBufferSize ? numBytesForTime : maxBufferSize);
|
||||
}
|
||||
|
||||
|
@ -20,13 +20,47 @@
|
||||
#ifndef MF_RDPSND_H
|
||||
#define MF_RDPSND_H
|
||||
|
||||
#include <CoreAudio/CoreAudio.h>
|
||||
#include <AudioToolbox/AudioToolbox.h>
|
||||
|
||||
#include <freerdp/freerdp.h>
|
||||
#include <freerdp/listener.h>
|
||||
#include <freerdp/server/rdpsnd.h>
|
||||
|
||||
#include "mf_interface.h"
|
||||
#include "mfreerdp.h"
|
||||
|
||||
void mf_rdpsnd_derive_buffer_size (AudioQueueRef audioQueue,
|
||||
AudioStreamBasicDescription *ASBDescription,
|
||||
Float64 seconds,
|
||||
UInt32 *outBufferSize);
|
||||
|
||||
void mf_peer_rdpsnd_input_callback (void *inUserData,
|
||||
AudioQueueRef inAQ,
|
||||
AudioQueueBufferRef inBuffer,
|
||||
const AudioTimeStamp *inStartTime,
|
||||
UInt32 inNumberPacketDescriptions,
|
||||
const AudioStreamPacketDescription *inPacketDescs);
|
||||
|
||||
|
||||
static const int snd_numBuffers = 3;
|
||||
struct _AQRecorderState
|
||||
{
|
||||
AudioStreamBasicDescription dataFormat;
|
||||
AudioQueueRef queue;
|
||||
AudioQueueBufferRef buffers[snd_numBuffers];
|
||||
AudioFileID audioFile;
|
||||
UInt32 bufferByteSize;
|
||||
SInt64 currentPacket;
|
||||
bool isRunning;
|
||||
rdpsnd_server_context* snd_context;
|
||||
|
||||
};
|
||||
|
||||
typedef struct _AQRecorderState AQRecorderState;
|
||||
|
||||
BOOL mf_peer_rdpsnd_init(mfPeerContext* context);
|
||||
BOOL mf_peer_rdpsnd_stop();
|
||||
|
||||
#endif /* MF_RDPSND_H */
|
||||
|
||||
|
@ -35,8 +35,8 @@
|
||||
#include <winpr/crt.h>
|
||||
|
||||
#include <freerdp/constants.h>
|
||||
#include <freerdp/utils/sleep.h>
|
||||
#include <freerdp/utils/memory.h>
|
||||
//#include <freerdp/utils/sleep.h>
|
||||
//#include <freerdp/utils/memory.h>
|
||||
|
||||
#include "mfreerdp.h"
|
||||
#include "mf_peer.h"
|
||||
|
@ -202,6 +202,7 @@ void wf_update_encoder_reset(wfInfo* wfi)
|
||||
wfi->rfx_context->width = wfi->servscreen_width;
|
||||
wfi->rfx_context->height = wfi->servscreen_height;
|
||||
rfx_context_set_pixel_format(wfi->rfx_context, RDP_PIXEL_FORMAT_B8G8R8A8);
|
||||
rfx_context_set_cpu_opt(wfi->rfx_context, CPU_SSE2);
|
||||
wfi->s = stream_new(0xFFFF);
|
||||
}
|
||||
|
||||
|
@ -29,7 +29,8 @@
|
||||
#include <winpr/synch.h>
|
||||
|
||||
#include "synch.h"
|
||||
#include "thread.h"
|
||||
#include "../thread/thread.h"
|
||||
#include <winpr/thread.h>
|
||||
|
||||
/**
|
||||
* WaitForSingleObject
|
||||
|
Loading…
Reference in New Issue
Block a user