diff --git a/channels/tsmf/client/gstreamer/tsmf_X11.c b/channels/tsmf/client/gstreamer/tsmf_X11.c index c32501301..7c026ee9e 100644 --- a/channels/tsmf/client/gstreamer/tsmf_X11.c +++ b/channels/tsmf/client/gstreamer/tsmf_X11.c @@ -313,11 +313,6 @@ int tsmf_window_resize(TSMFGstreamerDecoder* decoder, int x, int y, int width, return -3; } -#if GST_VERSION_MAJOR > 0 - GstVideoOverlay *overlay = GST_VIDEO_OVERLAY(decoder->outsink); -#else - GstXOverlay *overlay = GST_X_OVERLAY(decoder->outsink); -#endif if (!decoder) return -1; @@ -331,19 +326,19 @@ int tsmf_window_resize(TSMFGstreamerDecoder* decoder, int x, int y, int width, { #if GST_VERSION_MAJOR > 0 - if (!gst_video_overlay_set_render_rectangle(overlay, 0, 0, width, height)) + if (!gst_video_overlay_set_render_rectangle(hdl->overlay, 0, 0, width, height)) { WLog_ERR(TAG, "Could not resize overlay!"); } - gst_video_overlay_expose(overlay); + gst_video_overlay_expose(hdl->overlay); #else - if (!gst_x_overlay_set_render_rectangle(overlay, 0, 0, width, height)) + if (!gst_x_overlay_set_render_rectangle(hdl->overlay, 0, 0, width, height)) { WLog_ERR(TAG, "Could not resize overlay!"); } - gst_x_overlay_expose(overlay); + gst_x_overlay_expose(hdl->overlay); #endif } diff --git a/channels/tsmf/client/gstreamer/tsmf_gstreamer.c b/channels/tsmf/client/gstreamer/tsmf_gstreamer.c index 2458d6ec5..b283534ef 100644 --- a/channels/tsmf/client/gstreamer/tsmf_gstreamer.c +++ b/channels/tsmf/client/gstreamer/tsmf_gstreamer.c @@ -116,15 +116,15 @@ static gboolean tsmf_gstreamer_seek_data(GstAppSrc *src, guint64 offset, gpointe return TRUE; } -static void tsmf_gstreamer_change_volume(ITSMFDecoder* decoder, UINT32 newVolume, UINT32 muted) +static BOOL tsmf_gstreamer_change_volume(ITSMFDecoder* decoder, UINT32 newVolume, UINT32 muted) { TSMFGstreamerDecoder* mdecoder = (TSMFGstreamerDecoder *) decoder; if (!mdecoder || !mdecoder->pipe) - return; + return TRUE; if (mdecoder->media_type == TSMF_MAJOR_TYPE_VIDEO) - return; + return TRUE; mdecoder->gstMuted = (BOOL) muted; DEBUG_TSMF("mute=[%d]", mdecoder->gstMuted); @@ -132,13 +132,15 @@ static void tsmf_gstreamer_change_volume(ITSMFDecoder* decoder, UINT32 newVolume DEBUG_TSMF("gst_new_vol=[%f]", mdecoder->gstVolume); if (!mdecoder->volume) - return; + return TRUE; if (!G_IS_OBJECT(mdecoder->volume)) - return; + return TRUE; g_object_set(mdecoder->volume, "mute", mdecoder->gstMuted, NULL); g_object_set(mdecoder->volume, "volume", mdecoder->gstVolume, NULL); + + return TRUE; } #ifdef __OpenBSD__ @@ -843,7 +845,10 @@ static BOOL tsmf_gstreamer_control(ITSMFDecoder* decoder, ITSMFControlMsg contro TSMFGstreamerDecoder* mdecoder = (TSMFGstreamerDecoder *) decoder; if (!mdecoder) - return FALSE; + { + WLog_ERR(TAG, "Control called with no decoder!"); + return TRUE; + } if (control_msg == Control_Pause) { diff --git a/channels/tsmf/client/tsmf_ifman.c b/channels/tsmf/client/tsmf_ifman.c index 644bde57a..efdfe2021 100644 --- a/channels/tsmf/client/tsmf_ifman.c +++ b/channels/tsmf/client/tsmf_ifman.c @@ -224,6 +224,7 @@ UINT tsmf_ifman_add_stream(TSMF_IFMAN* ifman, rdpContext* rdpcontext) if (!presentation) { + WLog_ERR(TAG, "unknown presentation id"); status = ERROR_NOT_FOUND; } else @@ -232,10 +233,16 @@ UINT tsmf_ifman_add_stream(TSMF_IFMAN* ifman, rdpContext* rdpcontext) Stream_Seek_UINT32(ifman->input); /* numMediaType */ stream = tsmf_stream_new(presentation, StreamId, rdpcontext); if (!stream) + { + WLog_ERR(TAG, "failed to create stream"); return ERROR_OUTOFMEMORY; + } if (!tsmf_stream_set_format(stream, ifman->decoder_name, ifman->input)) + { + WLog_ERR(TAG, "failed to set stream format"); return ERROR_OUTOFMEMORY; + } } ifman->output_pending = TRUE; @@ -660,8 +667,10 @@ UINT tsmf_ifman_on_flush(TSMF_IFMAN* ifman) */ stream = tsmf_stream_find_by_id(presentation, StreamId); if (stream) + { if (!tsmf_stream_flush(stream)) return ERROR_INVALID_OPERATION; + } else WLog_ERR(TAG, "unknown stream id"); diff --git a/channels/tsmf/client/tsmf_main.c b/channels/tsmf/client/tsmf_main.c index 7957e97c4..d4a590086 100644 --- a/channels/tsmf/client/tsmf_main.c +++ b/channels/tsmf/client/tsmf_main.c @@ -36,7 +36,7 @@ #include "tsmf_main.h" -void tsmf_send_eos_response(IWTSVirtualChannelCallback* pChannelCallback, UINT32 message_id) +BOOL tsmf_send_eos_response(IWTSVirtualChannelCallback* pChannelCallback, UINT32 message_id) { wStream* s = NULL; int status; @@ -49,21 +49,21 @@ void tsmf_send_eos_response(IWTSVirtualChannelCallback* pChannelCallback, UINT32 if (!callback) { DEBUG_TSMF("No callback reference - unable to send eos response!"); - return; + return FALSE; } if (callback && callback->stream_id && callback->channel && callback->channel->Write) { s = Stream_New(NULL, 24); if (!s) - return FALSE; + return FALSE; Stream_Write_UINT32(s, TSMF_INTERFACE_CLIENT_NOTIFICATIONS | STREAM_ID_PROXY); - Stream_Write_UINT32(s, message_id); - Stream_Write_UINT32(s, CLIENT_EVENT_NOTIFICATION); /* FunctionId */ - Stream_Write_UINT32(s, callback->stream_id); /* StreamId */ - Stream_Write_UINT32(s, TSMM_CLIENT_EVENT_ENDOFSTREAM); /* EventId */ - Stream_Write_UINT32(s, 0); /* cbData */ - DEBUG_TSMF("response size %i", Stream_GetPosition(s)); + Stream_Write_UINT32(s, message_id); + Stream_Write_UINT32(s, CLIENT_EVENT_NOTIFICATION); /* FunctionId */ + Stream_Write_UINT32(s, callback->stream_id); /* StreamId */ + Stream_Write_UINT32(s, TSMM_CLIENT_EVENT_ENDOFSTREAM); /* EventId */ + Stream_Write_UINT32(s, 0); /* cbData */ + DEBUG_TSMF("EOS response size %i", Stream_GetPosition(s)); status = callback->channel->Write(callback->channel, Stream_GetPosition(s), Stream_Buffer(s), NULL); if (status) @@ -76,7 +76,7 @@ void tsmf_send_eos_response(IWTSVirtualChannelCallback* pChannelCallback, UINT32 return (status == 0); } -void tsmf_playback_ack(IWTSVirtualChannelCallback *pChannelCallback, +BOOL tsmf_playback_ack(IWTSVirtualChannelCallback *pChannelCallback, UINT32 message_id, UINT64 duration, UINT32 data_size) { wStream *s = NULL; @@ -87,12 +87,6 @@ void tsmf_playback_ack(IWTSVirtualChannelCallback *pChannelCallback, if (!s) return FALSE; - if (s == NULL) - { - WLog_ERR(TAG, "Stream creation error!"); - return; - } - Stream_Write_UINT32(s, TSMF_INTERFACE_CLIENT_NOTIFICATIONS | STREAM_ID_PROXY); Stream_Write_UINT32(s, message_id); Stream_Write_UINT32(s, PLAYBACK_ACK); /* FunctionId */ @@ -100,7 +94,7 @@ void tsmf_playback_ack(IWTSVirtualChannelCallback *pChannelCallback, Stream_Write_UINT64(s, duration); /* DataDuration */ Stream_Write_UINT64(s, data_size); /* cbData */ - DEBUG_TSMF("response size %d", (int) Stream_GetPosition(s)); + DEBUG_TSMF("ACK response size %d", (int) Stream_GetPosition(s)); if (!callback || !callback->channel || !callback->channel->Write) { @@ -313,6 +307,11 @@ static UINT tsmf_on_data_received(IWTSVirtualChannelCallback* pChannelCallback, input = NULL; ifman.input = NULL; + if (error) + { + WLog_ERR(TAG, "ifman data received processing error %d", error); + } + if (!processed) { switch (FunctionId) diff --git a/channels/tsmf/client/tsmf_main.h b/channels/tsmf/client/tsmf_main.h index c9489f33a..db3c94582 100644 --- a/channels/tsmf/client/tsmf_main.h +++ b/channels/tsmf/client/tsmf_main.h @@ -64,8 +64,8 @@ struct _TSMF_PLUGIN rdpContext* rdpcontext; }; -void tsmf_send_eos_response(IWTSVirtualChannelCallback* pChannelCallback, UINT32 message_id); -void tsmf_playback_ack(IWTSVirtualChannelCallback* pChannelCallback, +BOOL tsmf_send_eos_response(IWTSVirtualChannelCallback* pChannelCallback, UINT32 message_id); +BOOL tsmf_playback_ack(IWTSVirtualChannelCallback* pChannelCallback, UINT32 message_id, UINT64 duration, UINT32 data_size); #endif diff --git a/channels/tsmf/client/tsmf_media.c b/channels/tsmf/client/tsmf_media.c index 3414d1f18..78b8c78eb 100644 --- a/channels/tsmf/client/tsmf_media.c +++ b/channels/tsmf/client/tsmf_media.c @@ -327,7 +327,7 @@ dequeue: sample = Queue_Dequeue(stream->sample_ack_list); if (sample) { - rc = tsmf_sample_ack(sample); + tsmf_sample_ack(sample); tsmf_sample_free(sample); } @@ -572,9 +572,12 @@ static BOOL tsmf_sample_playback(TSMF_SAMPLE* sample) if (!ret) { - WLog_ERR(TAG, "decode error"); + WLog_ERR(TAG, "decode error, queue ack anyways"); if (!tsmf_sample_queue_ack(sample)) + { + WLog_ERR(TAG, "error queuing sample for ack"); return FALSE; + } return TRUE; } @@ -593,7 +596,7 @@ static BOOL tsmf_sample_playback(TSMF_SAMPLE* sample) WLog_ERR(TAG, "unable to decode video format"); if (!tsmf_sample_queue_ack(sample)) { - WLog_ERR(TAG, "error acking sample"); + WLog_ERR(TAG, "error queuing sample for ack"); } return FALSE; } @@ -601,8 +604,6 @@ static BOOL tsmf_sample_playback(TSMF_SAMPLE* sample) sample->pixfmt = pixfmt; } - ret = FALSE; - if (stream->decoder->GetDecodedDimension) { ret = stream->decoder->GetDecodedDimension(stream->decoder, &width, &height); @@ -658,18 +659,22 @@ static BOOL tsmf_sample_playback(TSMF_SAMPLE* sample) switch (sample->stream->major_type) { case TSMF_MAJOR_TYPE_VIDEO: - { - break; - } + { + break; + } case TSMF_MAJOR_TYPE_AUDIO: - { - break; - } + { + break; + } } sample->ack_time = ack_anticipation_time; - ret = tsmf_sample_queue_ack(sample); + if (!tsmf_sample_queue_ack(sample)) + { + WLog_ERR(TAG, "error queuing sample for ack"); + ret = FALSE; + } } return ret; @@ -761,7 +766,7 @@ static void* tsmf_stream_playback_func(void *arg) TSMF_STREAM* stream = (TSMF_STREAM *) arg; TSMF_PRESENTATION* presentation = stream->presentation; UINT error = CHANNEL_RC_OK; - DWORD status; + DWORD status; DEBUG_TSMF("in %d", stream->stream_id); @@ -798,7 +803,6 @@ static void* tsmf_stream_playback_func(void *arg) break; } - status = WaitForSingleObject(stream->stopEvent, 0); if (status == WAIT_FAILED) @@ -1004,7 +1008,7 @@ UINT tsmf_presentation_sync(TSMF_PRESENTATION* presentation) { UINT32 index; UINT32 count; - UINT error; + UINT error; ArrayList_Lock(presentation->stream_list); count = ArrayList_Count(presentation->stream_list); @@ -1013,15 +1017,15 @@ UINT tsmf_presentation_sync(TSMF_PRESENTATION* presentation) { TSMF_STREAM* stream = (TSMF_STREAM *) ArrayList_GetItem(presentation->stream_list, index); if (WaitForSingleObject(stream->ready, 500) == WAIT_FAILED) - { - error = GetLastError(); - WLog_ERR(TAG, "WaitForSingleObject failed with error %lu!", error); - return error; - } + { + error = GetLastError(); + WLog_ERR(TAG, "WaitForSingleObject failed with error %lu!", error); + return error; + } } ArrayList_Unlock(presentation->stream_list); - return CHANNEL_RC_OK; + return CHANNEL_RC_OK; } BOOL tsmf_presentation_stop(TSMF_PRESENTATION* presentation) @@ -1031,8 +1035,6 @@ BOOL tsmf_presentation_stop(TSMF_PRESENTATION* presentation) TSMF_STREAM* stream; BOOL ret = TRUE; - ret &= tsmf_presentation_flush(presentation); - ArrayList_Lock(presentation->stream_list); count = ArrayList_Count(presentation->stream_list); @@ -1067,17 +1069,8 @@ BOOL tsmf_presentation_set_geometry_info(TSMF_PRESENTATION* presentation, return TRUE; /* Streams can be added/removed from the presentation and the server will resend geometry info when a new stream is - * added to the presentation. + * added to the presentation. So, always process a valid message. */ - /* - if ((width == presentation->width) && (height == presentation->height) && - (x == presentation->x) && (y == presentation->y) && - (num_rects == presentation->nr_rects) && - (0 == memcmp(rects, presentation->rects, num_rects * sizeof(RDP_RECT)))) - { - return TRUE; - } - */ presentation->x = x; presentation->y = y; @@ -1142,30 +1135,6 @@ BOOL tsmf_stream_flush(TSMF_STREAM* stream) return TRUE; } -BOOL tsmf_presentation_flush(TSMF_PRESENTATION* presentation) -{ - UINT32 index; - UINT32 count; - TSMF_STREAM* stream; - BOOL ret = TRUE; - - ArrayList_Lock(presentation->stream_list); - count = ArrayList_Count(presentation->stream_list); - - for (index = 0; index < count; index++) - { - stream = (TSMF_STREAM*) ArrayList_GetItem(presentation->stream_list, index); - ret &= tsmf_stream_flush(stream); - } - - ArrayList_Unlock(presentation->stream_list); - presentation->eos = 0; - presentation->audio_start_time = 0; - presentation->audio_end_time = 0; - - return ret; -} - void _tsmf_presentation_free(TSMF_PRESENTATION* presentation) { tsmf_presentation_stop(presentation); @@ -1304,7 +1273,10 @@ BOOL tsmf_stream_set_format(TSMF_STREAM* stream, const char *name, wStream *s) } if (!tsmf_codec_parse_media_type(&mediatype, s)) + { + WLog_ERR(TAG, "unable to parse media type"); return FALSE; + } if (mediatype.MajorType == TSMF_MAJOR_TYPE_VIDEO) { @@ -1370,10 +1342,10 @@ void _tsmf_stream_free(TSMF_STREAM* stream) if (stream->play_thread) { if (WaitForSingleObject(stream->play_thread, INFINITE) == WAIT_FAILED) - { - WLog_ERR(TAG, "WaitForSingleObject failed with error %lu!", GetLastError()); - return; - } + { + WLog_ERR(TAG, "WaitForSingleObject failed with error %lu!", GetLastError()); + return; + } CloseHandle(stream->play_thread); stream->play_thread = NULL; @@ -1382,10 +1354,10 @@ void _tsmf_stream_free(TSMF_STREAM* stream) if (stream->ack_thread) { if (WaitForSingleObject(stream->ack_thread, INFINITE) == WAIT_FAILED) - { - WLog_ERR(TAG, "WaitForSingleObject failed with error %lu!", GetLastError()); - return; - } + { + WLog_ERR(TAG, "WaitForSingleObject failed with error %lu!", GetLastError()); + return; + } CloseHandle(stream->ack_thread); stream->ack_thread = NULL; } diff --git a/channels/tsmf/client/tsmf_media.h b/channels/tsmf/client/tsmf_media.h index 47f189f5d..1760fe05a 100644 --- a/channels/tsmf/client/tsmf_media.h +++ b/channels/tsmf/client/tsmf_media.h @@ -49,7 +49,6 @@ BOOL tsmf_presentation_set_geometry_info(TSMF_PRESENTATION *presentation, int num_rects, RDP_RECT *rects); void tsmf_presentation_set_audio_device(TSMF_PRESENTATION *presentation, const char *name, const char *device); -BOOL tsmf_presentation_flush(TSMF_PRESENTATION *presentation); void tsmf_presentation_free(TSMF_PRESENTATION *presentation); TSMF_STREAM *tsmf_stream_new(TSMF_PRESENTATION *presentation, UINT32 stream_id, rdpContext* rdpcontext); @@ -57,7 +56,7 @@ TSMF_STREAM *tsmf_stream_find_by_id(TSMF_PRESENTATION *presentation, UINT32 stre BOOL tsmf_stream_set_format(TSMF_STREAM *stream, const char *name, wStream *s); void tsmf_stream_end(TSMF_STREAM *stream, UINT32 message_id, IWTSVirtualChannelCallback* pChannelCallback); void tsmf_stream_free(TSMF_STREAM *stream); -void tsmf_stream_flush(TSMF_STREAM* stream); +BOOL tsmf_stream_flush(TSMF_STREAM* stream); BOOL tsmf_stream_push_sample(TSMF_STREAM *stream, IWTSVirtualChannelCallback *pChannelCallback, UINT32 sample_id, UINT64 start_time, UINT64 end_time, UINT64 duration, UINT32 extensions,