From d50cddc1bd96e66a07eb166f9e51f3ab5f5656fd Mon Sep 17 00:00:00 2001 From: C-o-r-E Date: Thu, 7 Mar 2013 13:34:12 -0500 Subject: [PATCH] mfreerdp-server: begin reworking rdpsnd server channel --- channels/rdpsnd/server/rdpsnd.c | 89 +++++++++++++++++++++++++++++---- libfreerdp/codec/rfx_sse2.c | 1 + server/Mac/mf_rdpsnd.c | 27 +++++++++- 3 files changed, 104 insertions(+), 13 deletions(-) diff --git a/channels/rdpsnd/server/rdpsnd.c b/channels/rdpsnd/server/rdpsnd.c index fc83fe002..ba78b2fdc 100644 --- a/channels/rdpsnd/server/rdpsnd.c +++ b/channels/rdpsnd/server/rdpsnd.c @@ -26,6 +26,7 @@ #include #include +#include #include #include @@ -71,6 +72,24 @@ typedef struct _rdpsnd_server return _r; \ } +void rdpsnd_print_audio_format(AUDIO_FORMAT* format) +{ + /*printf("\t wFormatTag: 0x%04X nChannels: %d nSamplesPerSec: %d nAvgBytesPerSec: %d nBlockAlign: %d wBitsPerSample: %d cbSize: %d\n", + format->wFormatTag, + format->nChannels, format->nSamplesPerSec, format->nAvgBytesPerSec, + format->nBlockAlign, format->wBitsPerSample, format->cbSize); + */ + + printf("\nTag: %#0X\nChannels: %d\nSamples per sec: %d\nAvg bytes per sec: %d\nBlockAlign: %d\nBits per sample: %d\ncbSize: %0X\n", + format->wFormatTag, + format->nChannels, + format->nSamplesPerSec, + format->nAvgBytesPerSec, + format->nBlockAlign, + format->wBitsPerSample, + format->cbSize); +} + static BOOL rdpsnd_server_send_formats(rdpsnd_server* rdpsnd, STREAM* s) { UINT16 i; @@ -85,9 +104,11 @@ static BOOL rdpsnd_server_send_formats(rdpsnd_server* rdpsnd, STREAM* s) stream_write_BYTE(s, rdpsnd->context.block_no); /* cLastBlockConfirmed */ stream_write_UINT16(s, 0x06); /* wVersion */ stream_write_BYTE(s, 0); /* bPad */ - + + printf("Server supports the following formats:\n"); for (i = 0; i < rdpsnd->context.num_server_formats; i++) { + rdpsnd_print_audio_format(&rdpsnd->context.server_formats[i]); stream_write_UINT16(s, rdpsnd->context.server_formats[i].wFormatTag); /* wFormatTag (WAVE_FORMAT_PCM) */ stream_write_UINT16(s, rdpsnd->context.server_formats[i].nChannels); /* nChannels */ stream_write_UINT32(s, rdpsnd->context.server_formats[i].nSamplesPerSec); /* nSamplesPerSec */ @@ -111,40 +132,66 @@ static BOOL rdpsnd_server_send_formats(rdpsnd_server* rdpsnd, STREAM* s) return TRUE; } +static void rdpsnd_server_recv_quality_mode(rdpsnd_server* rdpsnd, STREAM* s) +{ + UINT16 quality; + + stream_read_UINT16(s, quality); + stream_seek_UINT16(s); // reserved + + printf("Client requested sound quality: %#0X\n", quality); +} + static BOOL rdpsnd_server_recv_formats(rdpsnd_server* rdpsnd, STREAM* s) { - int i; + int i, num_known_format; + UINT32 flags, vol, pitch; + UINT16 udpPort, version; + BYTE lastblock; if (stream_get_left(s) < 20) + { + printf("vic logic: < 20"); return FALSE; + } + - stream_seek_UINT32(s); /* dwFlags */ - stream_seek_UINT32(s); /* dwVolume */ - stream_seek_UINT32(s); /* dwPitch */ - stream_seek_UINT16(s); /* wDGramPort */ + stream_read_UINT32(s, flags); /* dwFlags */ + stream_read_UINT32(s, vol); /* dwVolume */ + stream_read_UINT32(s, pitch); /* dwPitch */ + stream_read_UINT16(s, udpPort); /* wDGramPort */ stream_read_UINT16(s, rdpsnd->context.num_client_formats); /* wNumberOfFormats */ - stream_seek_BYTE(s); /* cLastBlockConfirmed */ - stream_seek_UINT16(s); /* wVersion */ + stream_read_BYTE(s, lastblock); /* cLastBlockConfirmed */ + stream_read_UINT16(s, version); /* wVersion */ stream_seek_BYTE(s); /* bPad */ + printf("recv_formats header:\n\tFlags: %#0X\n\tVol: %#0X\n\tPitch: %#0X\n\tudpPort: %#0X\n\tnumFormats: %#0X\n\tlastBlock: %#0X\n\tVersion: %#0X\n\n", + flags, vol, pitch, udpPort, rdpsnd->context.num_client_formats, lastblock, version); + + //printf("client supports the following formats: \n"); if (rdpsnd->context.num_client_formats > 0) { rdpsnd->context.client_formats = (AUDIO_FORMAT*) malloc(rdpsnd->context.num_client_formats * sizeof(AUDIO_FORMAT)); ZeroMemory(rdpsnd->context.client_formats, sizeof(AUDIO_FORMAT)); + num_known_format = 0; for (i = 0; i < rdpsnd->context.num_client_formats; i++) { + if (stream_get_left(s) < 18) { + printf("%lu bytes left in stream. Cannot get client sound format!\n\n", stream_get_left(s)); free(rdpsnd->context.client_formats); rdpsnd->context.client_formats = NULL; return FALSE; } + + //winpr_HexDump(s->p, 18); stream_read_UINT16(s, rdpsnd->context.client_formats[i].wFormatTag); stream_read_UINT16(s, rdpsnd->context.client_formats[i].nChannels); stream_read_UINT32(s, rdpsnd->context.client_formats[i].nSamplesPerSec); - stream_seek_UINT32(s); /* nAvgBytesPerSec */ + stream_read_UINT32(s, rdpsnd->context.client_formats[i].nAvgBytesPerSec); /* nAvgBytesPerSec */ stream_read_UINT16(s, rdpsnd->context.client_formats[i].nBlockAlign); stream_read_UINT16(s, rdpsnd->context.client_formats[i].wBitsPerSample); stream_read_UINT16(s, rdpsnd->context.client_formats[i].cbSize); @@ -153,8 +200,22 @@ static BOOL rdpsnd_server_recv_formats(rdpsnd_server* rdpsnd, STREAM* s) { stream_seek(s, rdpsnd->context.client_formats[i].cbSize); } + //rdpsnd_print_audio_format(&rdpsnd->context.client_formats[i]); + + if (rdpsnd->context.client_formats[i].wFormatTag != 0) + { + //lets call this a known format + //TODO: actually look through our own list of known formats + num_known_format++; + } } } + + if (num_known_format == 0) + { + printf("Client doesnt support any known formats!\n"); + return FALSE; + } return TRUE; } @@ -204,16 +265,21 @@ static void* rdpsnd_server_thread_func(void* arg) stream_get_size(s), &bytes_returned) == FALSE) break; } + + //winpr_HexDump(s->data, stream_get_size(s)); stream_read_BYTE(s, msgType); stream_seek_BYTE(s); /* bPad */ stream_read_UINT16(s, BodySize); - if (BodySize + 4 > (int) bytes_returned) - continue; + //if (BodySize + 4 > (int) bytes_returned) + //continue; switch (msgType) { + case SNDC_QUALITYMODE: + rdpsnd_server_recv_quality_mode(rdpsnd, s); + break; case SNDC_FORMATS: if (rdpsnd_server_recv_formats(rdpsnd, s)) { @@ -221,6 +287,7 @@ static void* rdpsnd_server_thread_func(void* arg) } break; default: + printf("UNKOWN MESSAGE TYPE!! (%#0X)\n\n", msgType); break; } } diff --git a/libfreerdp/codec/rfx_sse2.c b/libfreerdp/codec/rfx_sse2.c index fccd1e866..6142aa84d 100644 --- a/libfreerdp/codec/rfx_sse2.c +++ b/libfreerdp/codec/rfx_sse2.c @@ -495,6 +495,7 @@ void rfx_init_sse2(RFX_CONTEXT* context) if (!IsProcessorFeaturePresent(PF_XMMI64_INSTRUCTIONS_AVAILABLE)) return; + printf("\n\nIs this causing crashes???\n\n"); DEBUG_RFX("Using SSE2 optimizations"); IF_PROFILER(context->priv->prof_rfx_quantization_decode->name = "rfx_quantization_decode_sse2"); diff --git a/server/Mac/mf_rdpsnd.c b/server/Mac/mf_rdpsnd.c index 0bd40d7ef..258b609c9 100644 --- a/server/Mac/mf_rdpsnd.c +++ b/server/Mac/mf_rdpsnd.c @@ -21,7 +21,7 @@ #include "config.h" #endif -#include +#include #include "mf_info.h" #include "mf_rdpsnd.h" @@ -42,10 +42,32 @@ static const AUDIO_FORMAT audio_formats[] = { 0x01, 1, 8000, 2, 16, 0, NULL } /* PCM, 8000 Hz, 1 channels, 16 bits */ }; +static const AUDIO_FORMAT supported_audio_formats[] = +{ + { 0x01, 2, 44100, 4, 16, 0, NULL }, /* PCM, 44100 Hz, 2 channels, 16 bits */ +}; + + static void mf_peer_rdpsnd_activated(rdpsnd_server_context* context) { - OSStatus status; + int i; + //we should actually loop through the list of client formats here + //and see if we can send the client something that it supports... + + printf("Client supports the following %d formats: \n", context->num_client_formats); + for(i = 0; i < context->num_client_formats; i++) + { + printf("\n%d)\nTag: %#0X\nChannels: %d\nSamples per sec: %d\nAvg bytes per sec: %d\nBlockAlign: %d\nBits per sample: %d\ncbSize: %0X\n", + i, + context->client_formats[i].wFormatTag, + context->client_formats[i].nChannels, + context->client_formats[i].nSamplesPerSec, + context->client_formats[i].nAvgBytesPerSec, + context->client_formats[i].nBlockAlign, + context->client_formats[i].wBitsPerSample, + context->client_formats[i].cbSize); + } recorderState.dataFormat.mSampleRate = 44100.0; recorderState.dataFormat.mFormatID = kAudioFormatLinearPCM; @@ -99,6 +121,7 @@ static void mf_peer_rdpsnd_activated(rdpsnd_server_context* context) recorderState.currentPacket = 0; recorderState.isRunning = true; + context->SelectFormat(context, 4); context->SetVolume(context, 0x7FFF, 0x7FFF);