23 #include <freerdp/config.h>
34 #include <winpr/crt.h>
35 #include <winpr/synch.h>
36 #include <winpr/string.h>
37 #include <winpr/thread.h>
38 #include <winpr/stream.h>
39 #include <winpr/collections.h>
41 #include <freerdp/freerdp.h>
42 #include <freerdp/client/tsmf.h>
44 #include "tsmf_constants.h"
45 #include "tsmf_types.h"
46 #include "tsmf_decoder.h"
47 #include "tsmf_audio.h"
48 #include "tsmf_main.h"
49 #include "tsmf_codec.h"
50 #include "tsmf_media.h"
52 #define AUDIO_TOLERANCE 10000000LL
55 #define VIDEO_ADJUST_MAX (10ULL * 1000ULL * 1000ULL)
57 #define MAX_ACK_TIME 666667
59 #define AUDIO_MIN_BUFFER_LEVEL 3
60 #define AUDIO_MAX_BUFFER_LEVEL 6
62 #define VIDEO_MIN_BUFFER_LEVEL 10
63 #define VIDEO_MAX_BUFFER_LEVEL 30
65 struct S_TSMF_PRESENTATION
67 BYTE presentation_id[GUID_SIZE];
69 const char* audio_name;
70 const char* audio_device;
72 IWTSVirtualChannelCallback* channel_callback;
74 UINT64 audio_start_time;
75 UINT64 audio_end_time;
80 wArrayList* stream_list;
92 TSMF_PRESENTATION* presentation;
94 ITSMFDecoder* decoder;
98 UINT32 eos_message_id;
99 IWTSVirtualChannelCallback* eos_channel_callback;
104 ITSMFAudioDevice* audio;
107 UINT32 bits_per_sample;
110 UINT64 last_start_time;
112 UINT64 last_end_time;
114 UINT64 next_start_time;
116 UINT32 minBufferLevel;
117 UINT32 maxBufferLevel;
118 UINT32 currentBufferLevel;
126 wQueue* sample_ack_list;
127 rdpContext* rdpcontext;
144 BOOL invalidTimestamps;
147 IWTSVirtualChannelCallback* channel_callback;
151 static wArrayList* presentation_list = NULL;
152 static int TERMINATING = 0;
154 static void s_tsmf_presentation_free(
void* obj);
155 static void s_tsmf_stream_free(
void* obj);
157 static UINT64 get_current_time(
void)
160 gettimeofday(&tp, 0);
161 return ((UINT64)tp.tv_sec) * 10000000LL + ((UINT64)tp.tv_usec) * 10LL;
164 static TSMF_SAMPLE* tsmf_stream_pop_sample(TSMF_STREAM* stream,
int sync)
166 TSMF_SAMPLE* sample = NULL;
167 BOOL pending = FALSE;
172 TSMF_PRESENTATION* presentation = stream->presentation;
174 if (Queue_Count(stream->sample_list) < 1)
181 if (stream->decoder->GetDecodedData)
183 if (stream->major_type == TSMF_MAJOR_TYPE_AUDIO)
190 if (stream->last_start_time > AUDIO_TOLERANCE)
192 ArrayList_Lock(presentation->stream_list);
193 const size_t count = ArrayList_Count(presentation->stream_list);
195 for (
size_t index = 0; index < count; index++)
198 (TSMF_STREAM*)ArrayList_GetItem(presentation->stream_list, index);
203 if (s != stream && !s->eos && s->last_start_time &&
204 s->last_start_time < stream->last_start_time - AUDIO_TOLERANCE)
206 DEBUG_TSMF(
"Pending due to audio tolerance");
212 ArrayList_Unlock(presentation->stream_list);
220 if (stream->last_start_time > presentation->audio_start_time)
222 DEBUG_TSMF(
"Pending due to stream start time > audio start time");
233 sample = (TSMF_SAMPLE*)Queue_Dequeue(stream->sample_list);
237 if (sample && (sample->end_time > stream->last_end_time) && (!sample->invalidTimestamps))
238 stream->last_end_time = sample->end_time;
242 if (sample && (sample->start_time > stream->last_start_time) && (!sample->invalidTimestamps))
243 stream->last_start_time = sample->start_time;
248 static void tsmf_sample_free(
void* arg)
250 TSMF_SAMPLE* sample = arg;
259 static BOOL tsmf_sample_ack(TSMF_SAMPLE* sample)
264 return tsmf_playback_ack(sample->channel_callback, sample->sample_id, sample->duration,
268 static BOOL tsmf_sample_queue_ack(TSMF_SAMPLE* sample)
276 return Queue_Enqueue(sample->stream->sample_ack_list, sample);
282 static BOOL tsmf_stream_process_ack(
void* arg, BOOL force)
284 TSMF_STREAM* stream = arg;
285 TSMF_SAMPLE* sample = NULL;
292 Queue_Lock(stream->sample_ack_list);
293 sample = (TSMF_SAMPLE*)Queue_Peek(stream->sample_ack_list);
304 if (stream->decoder && stream->decoder->BufferLevel)
307 if (stream->currentBufferLevel > stream->maxBufferLevel)
310 else if (stream->currentBufferLevel < stream->minBufferLevel)
315 ack_time = get_current_time();
317 if (sample->ack_time > ack_time)
322 sample = Queue_Dequeue(stream->sample_ack_list);
326 tsmf_sample_ack(sample);
327 tsmf_sample_free(sample);
331 Queue_Unlock(stream->sample_ack_list);
335 TSMF_PRESENTATION* tsmf_presentation_new(
const BYTE* guid,
336 IWTSVirtualChannelCallback* pChannelCallback)
339 TSMF_PRESENTATION* presentation = NULL;
341 if (!guid || !pChannelCallback)
344 presentation = (TSMF_PRESENTATION*)calloc(1,
sizeof(TSMF_PRESENTATION));
348 WLog_ERR(TAG,
"calloc failed");
352 CopyMemory(presentation->presentation_id, guid, GUID_SIZE);
353 presentation->channel_callback = pChannelCallback;
354 presentation->volume = 5000;
355 presentation->muted = 0;
357 if (!(presentation->stream_list = ArrayList_New(TRUE)))
358 goto error_stream_list;
360 obj = ArrayList_Object(presentation->stream_list);
363 obj->fnObjectFree = s_tsmf_stream_free;
365 if (!ArrayList_Append(presentation_list, presentation))
370 ArrayList_Free(presentation->stream_list);
376 static char* guid_to_string(
const BYTE* guid,
char* str,
size_t len)
381 for (
size_t i = 0; i < GUID_SIZE && (len > 2 * i); i++)
382 (
void)sprintf_s(str + (2 * i), len - 2 * i,
"%02" PRIX8
"", guid[i]);
387 TSMF_PRESENTATION* tsmf_presentation_find_by_id(
const BYTE* guid)
390 char guid_str[GUID_SIZE * 2 + 1] = { 0 };
391 TSMF_PRESENTATION* presentation = NULL;
392 ArrayList_Lock(presentation_list);
393 const size_t count = ArrayList_Count(presentation_list);
395 for (
size_t index = 0; index < count; index++)
397 presentation = (TSMF_PRESENTATION*)ArrayList_GetItem(presentation_list, index);
399 if (memcmp(presentation->presentation_id, guid, GUID_SIZE) == 0)
406 ArrayList_Unlock(presentation_list);
409 WLog_WARN(TAG,
"presentation id %s not found",
410 guid_to_string(guid, guid_str,
sizeof(guid_str)));
412 return (found) ? presentation : NULL;
415 static BOOL tsmf_sample_playback_video(TSMF_SAMPLE* sample)
417 WINPR_ASSERT(sample);
419 TSMF_STREAM* stream = sample->stream;
420 TSMF_PRESENTATION* presentation = stream->presentation;
422 TsmfClientContext* tsmf = (TsmfClientContext*)callback->plugin->pInterface;
423 DEBUG_TSMF(
"MessageId %" PRIu32
" EndTime %" PRIu64
" data_size %" PRIu32
" consumed.",
424 sample->sample_id, sample->end_time, sample->data_size);
428 const UINT64 t = get_current_time();
433 if (stream->next_start_time > t &&
434 ((sample->start_time >= presentation->audio_start_time) ||
435 ((sample->start_time < stream->last_start_time) && (!sample->invalidTimestamps))))
437 size_t delay = (stream->next_start_time - t) / 10;
440 const UINT32 d = (delay > UINT32_MAX) ? UINT32_MAX : (UINT32)delay;
446 if (sample->stream->width > INT16_MAX)
448 if (sample->stream->height > INT16_MAX)
450 if (presentation->rect.left > INT16_MAX)
452 if (presentation->rect.top > INT16_MAX)
454 if (presentation->rect.width > INT16_MAX)
456 if (presentation->rect.height > INT16_MAX)
458 if (presentation->nr_rects > UINT16_MAX)
461 stream->next_start_time = t + sample->duration - 50000;
464 event.frameData = sample->data;
465 event.frameSize = sample->decoded_size;
466 event.framePixFmt = sample->pixfmt;
467 event.frameWidth = (INT16)sample->stream->width;
468 event.frameHeight = (INT16)sample->stream->height;
469 event.x = (INT16)presentation->rect.left;
470 event.y = (INT16)presentation->rect.top;
471 event.width = (INT16)presentation->rect.width;
472 event.height = (INT16)presentation->rect.height;
474 if (presentation->nr_rects > 0)
476 event.numVisibleRects = (UINT16)presentation->nr_rects;
479 if (!event.visibleRects)
481 WLog_ERR(TAG,
"can't allocate memory for copy rectangles");
485 for (
size_t x = 0; x < presentation->nr_rects; x++)
489 if ((cur->left > UINT16_MAX) || (cur->top > UINT16_MAX) ||
490 (cur->width > UINT16_MAX) || (cur->height > UINT16_MAX))
492 free(event.visibleRects);
495 dst->right = dst->left = (UINT16)cur->left;
496 dst->bottom = dst->top = (UINT16)cur->top;
497 dst->right += (UINT16)cur->width;
498 dst->bottom += (UINT16)cur->height;
500 memcpy(event.visibleRects, presentation->rects,
502 presentation->nr_rects = 0;
508 sample->decoded_size = 0;
510 if (tsmf->FrameEvent)
511 tsmf->FrameEvent(tsmf, &event);
513 free(event.frameData);
514 free(event.visibleRects);
520 static BOOL tsmf_sample_playback_audio(TSMF_SAMPLE* sample)
523 TSMF_STREAM* stream = sample->stream;
525 DEBUG_TSMF(
"MessageId %" PRIu32
" EndTime %" PRIu64
" consumed.", sample->sample_id,
528 if (stream->audio && sample->data)
531 sample->stream->audio->Play(sample->stream->audio, sample->data, sample->decoded_size);
534 sample->decoded_size = 0;
536 if (stream->audio->GetLatency)
537 latency = stream->audio->GetLatency(stream->audio);
545 sample->ack_time = latency + get_current_time();
548 if (!sample->invalidTimestamps)
550 stream->last_start_time = sample->start_time + latency;
551 stream->last_end_time = sample->end_time + latency;
552 stream->presentation->audio_start_time = sample->start_time + latency;
553 stream->presentation->audio_end_time = sample->end_time + latency;
559 static BOOL tsmf_sample_playback(TSMF_SAMPLE* sample)
565 TSMF_STREAM* stream = sample->stream;
569 if (stream->decoder->DecodeEx)
576 if (stream->major_type == TSMF_MAJOR_TYPE_VIDEO)
578 TSMF_STREAM* temp_stream = NULL;
579 TSMF_PRESENTATION* presentation = stream->presentation;
580 ArrayList_Lock(presentation->stream_list);
581 const size_t count = ArrayList_Count(presentation->stream_list);
583 for (
size_t index = 0; index < count; index++)
585 UINT64 time_diff = 0;
586 temp_stream = (TSMF_STREAM*)ArrayList_GetItem(presentation->stream_list, index);
588 if (temp_stream->major_type == TSMF_MAJOR_TYPE_AUDIO)
590 UINT64 video_time = stream->decoder->GetRunningTime(stream->decoder);
592 temp_stream->decoder->GetRunningTime(temp_stream->decoder);
593 UINT64 max_adjust = VIDEO_ADJUST_MAX;
595 if (video_time < audio_time)
596 max_adjust = -VIDEO_ADJUST_MAX;
598 if (video_time > audio_time)
599 time_diff = video_time - audio_time;
601 time_diff = audio_time - video_time;
603 time_diff = time_diff < VIDEO_ADJUST_MAX ? time_diff : max_adjust;
604 sample->start_time += time_diff;
605 sample->end_time += time_diff;
610 ArrayList_Unlock(presentation->stream_list);
613 ret = stream->decoder->DecodeEx(stream->decoder, sample->data, sample->data_size,
614 sample->extensions, sample->start_time,
615 sample->end_time, sample->duration);
619 ret = stream->decoder->Decode(stream->decoder, sample->data, sample->data_size,
626 WLog_ERR(TAG,
"decode error, queue ack anyways");
628 if (!tsmf_sample_queue_ack(sample))
630 WLog_ERR(TAG,
"error queuing sample for ack");
640 if (stream->major_type == TSMF_MAJOR_TYPE_VIDEO)
642 if (stream->decoder->GetDecodedFormat)
644 pixfmt = stream->decoder->GetDecodedFormat(stream->decoder);
646 if (pixfmt == ((UINT32)-1))
648 WLog_ERR(TAG,
"unable to decode video format");
650 if (!tsmf_sample_queue_ack(sample))
652 WLog_ERR(TAG,
"error queuing sample for ack");
658 sample->pixfmt = pixfmt;
661 if (stream->decoder->GetDecodedDimension)
663 ret = stream->decoder->GetDecodedDimension(stream->decoder, &width, &height);
665 if (ret && (width != stream->width || height != stream->height))
667 DEBUG_TSMF(
"video dimension changed to %" PRIu32
" x %" PRIu32
"", width, height);
668 stream->width = width;
669 stream->height = height;
674 if (stream->decoder->GetDecodedData)
676 sample->data = stream->decoder->GetDecodedData(stream->decoder, &sample->decoded_size);
678 switch (sample->stream->major_type)
680 case TSMF_MAJOR_TYPE_VIDEO:
681 ret = tsmf_sample_playback_video(sample) && tsmf_sample_queue_ack(sample);
684 case TSMF_MAJOR_TYPE_AUDIO:
685 ret = tsmf_sample_playback_audio(sample) && tsmf_sample_queue_ack(sample);
693 UINT64 ack_anticipation_time = get_current_time();
694 BOOL buffer_filled = TRUE;
697 if (stream->decoder->BufferLevel)
699 if (stream->currentBufferLevel < stream->minBufferLevel)
700 buffer_filled = FALSE;
703 ack_anticipation_time +=
704 (sample->duration / 2 < MAX_ACK_TIME) ? sample->duration / 2 : MAX_ACK_TIME;
706 switch (sample->stream->major_type)
708 case TSMF_MAJOR_TYPE_VIDEO:
713 case TSMF_MAJOR_TYPE_AUDIO:
721 sample->ack_time = ack_anticipation_time;
723 if (!tsmf_sample_queue_ack(sample))
725 WLog_ERR(TAG,
"error queuing sample for ack");
733 static DWORD WINAPI tsmf_stream_ack_func(LPVOID arg)
736 TSMF_STREAM* stream = (TSMF_STREAM*)arg;
737 UINT error = CHANNEL_RC_OK;
738 DEBUG_TSMF(
"in %" PRIu32
"", stream->stream_id);
739 hdl[0] = stream->stopEvent;
740 hdl[1] = Queue_Event(stream->sample_ack_list);
744 DWORD ev = WaitForMultipleObjects(2, hdl, FALSE, 1000);
746 if (ev == WAIT_FAILED)
748 error = GetLastError();
749 WLog_ERR(TAG,
"WaitForMultipleObjects failed with error %" PRIu32
"!", error);
754 if (stream->decoder->BufferLevel)
755 stream->currentBufferLevel = stream->decoder->BufferLevel(stream->decoder);
759 while ((stream->currentBufferLevel > 0) && !(tsmf_stream_process_ack(stream, TRUE)))
761 DEBUG_TSMF(
"END OF STREAM PROCESSING!");
763 if (stream->decoder && stream->decoder->BufferLevel)
764 stream->currentBufferLevel = stream->decoder->BufferLevel(stream->decoder);
766 stream->currentBufferLevel = 1;
771 tsmf_send_eos_response(stream->eos_channel_callback, stream->eos_message_id);
774 if (stream->delayed_stop)
776 DEBUG_TSMF(
"Finishing delayed stream stop, now that eos has processed.");
777 tsmf_stream_flush(stream);
779 if (stream->decoder && stream->decoder->Control)
780 stream->decoder->Control(stream->decoder, Control_Stop, NULL);
785 if (ev == WAIT_OBJECT_0)
787 DEBUG_TSMF(
"ack: Stream stopped!");
791 if (tsmf_stream_process_ack(stream, TRUE))
800 if (tsmf_stream_process_ack(stream, FALSE))
803 if (stream->currentBufferLevel > stream->minBufferLevel)
807 if (error && stream->rdpcontext)
808 setChannelError(stream->rdpcontext, error,
"tsmf_stream_ack_func reported an error");
810 DEBUG_TSMF(
"out %" PRIu32
"", stream->stream_id);
815 static DWORD WINAPI tsmf_stream_playback_func(LPVOID arg)
818 TSMF_SAMPLE* sample = NULL;
819 TSMF_STREAM* stream = (TSMF_STREAM*)arg;
820 TSMF_PRESENTATION* presentation = stream->presentation;
821 UINT error = CHANNEL_RC_OK;
823 DEBUG_TSMF(
"in %" PRIu32
"", stream->stream_id);
825 if (stream->major_type == TSMF_MAJOR_TYPE_AUDIO && stream->sample_rate && stream->channels &&
826 stream->bits_per_sample)
830 if (stream->decoder->GetDecodedData)
832 stream->audio = tsmf_load_audio_device(
833 presentation->audio_name && presentation->audio_name[0]
834 ? presentation->audio_name
836 presentation->audio_device && presentation->audio_device[0]
837 ? presentation->audio_device
842 stream->audio->SetFormat(stream->audio, stream->sample_rate, stream->channels,
843 stream->bits_per_sample);
849 hdl[0] = stream->stopEvent;
850 hdl[1] = Queue_Event(stream->sample_list);
854 status = WaitForMultipleObjects(2, hdl, FALSE, 1000);
856 if (status == WAIT_FAILED)
858 error = GetLastError();
859 WLog_ERR(TAG,
"WaitForMultipleObjects failed with error %" PRIu32
"!", error);
863 status = WaitForSingleObject(stream->stopEvent, 0);
865 if (status == WAIT_FAILED)
867 error = GetLastError();
868 WLog_ERR(TAG,
"WaitForSingleObject failed with error %" PRIu32
"!", error);
872 if (status == WAIT_OBJECT_0)
876 if (stream->decoder->BufferLevel)
877 stream->currentBufferLevel = stream->decoder->BufferLevel(stream->decoder);
879 sample = tsmf_stream_pop_sample(stream, 0);
881 if (sample && !tsmf_sample_playback(sample))
883 WLog_ERR(TAG,
"error playing sample");
884 error = ERROR_INTERNAL_ERROR;
888 if (stream->currentBufferLevel > stream->minBufferLevel)
894 stream->audio->Free(stream->audio);
895 stream->audio = NULL;
898 if (error && stream->rdpcontext)
899 setChannelError(stream->rdpcontext, error,
"tsmf_stream_playback_func reported an error");
901 DEBUG_TSMF(
"out %" PRIu32
"", stream->stream_id);
906 static BOOL tsmf_stream_start(TSMF_STREAM* stream)
908 if (!stream || !stream->presentation || !stream->decoder || !stream->decoder->Control)
912 return stream->decoder->Control(stream->decoder, Control_Restart, NULL);
915 static BOOL tsmf_stream_stop(TSMF_STREAM* stream)
917 if (!stream || !stream->decoder || !stream->decoder->Control)
926 DEBUG_TSMF(
"Setting up a delayed stop for once the eos has been processed.");
927 stream->delayed_stop = 1;
933 DEBUG_TSMF(
"Stop with no pending eos response, so do it immediately.");
934 tsmf_stream_flush(stream);
935 return stream->decoder->Control(stream->decoder, Control_Stop, NULL);
939 static BOOL tsmf_stream_pause(TSMF_STREAM* stream)
941 if (!stream || !stream->decoder || !stream->decoder->Control)
944 return stream->decoder->Control(stream->decoder, Control_Pause, NULL);
947 static BOOL tsmf_stream_restart(TSMF_STREAM* stream)
949 if (!stream || !stream->decoder || !stream->decoder->Control)
953 return stream->decoder->Control(stream->decoder, Control_Restart, NULL);
956 static BOOL tsmf_stream_change_volume(TSMF_STREAM* stream, UINT32 newVolume, UINT32 muted)
958 if (!stream || !stream->decoder)
961 if (stream->decoder != NULL && stream->decoder->ChangeVolume)
963 return stream->decoder->ChangeVolume(stream->decoder, newVolume, muted);
965 else if (stream->audio != NULL && stream->audio->ChangeVolume)
967 return stream->audio->ChangeVolume(stream->audio, newVolume, muted);
973 BOOL tsmf_presentation_volume_changed(TSMF_PRESENTATION* presentation, UINT32 newVolume,
976 TSMF_STREAM* stream = NULL;
978 presentation->volume = newVolume;
979 presentation->muted = muted;
980 ArrayList_Lock(presentation->stream_list);
981 size_t count = ArrayList_Count(presentation->stream_list);
983 for (
size_t index = 0; index < count; index++)
985 stream = (TSMF_STREAM*)ArrayList_GetItem(presentation->stream_list, index);
986 ret &= tsmf_stream_change_volume(stream, newVolume, muted);
989 ArrayList_Unlock(presentation->stream_list);
993 BOOL tsmf_presentation_paused(TSMF_PRESENTATION* presentation)
995 TSMF_STREAM* stream = NULL;
997 ArrayList_Lock(presentation->stream_list);
998 size_t count = ArrayList_Count(presentation->stream_list);
1000 for (
size_t index = 0; index < count; index++)
1002 stream = (TSMF_STREAM*)ArrayList_GetItem(presentation->stream_list, index);
1003 ret &= tsmf_stream_pause(stream);
1006 ArrayList_Unlock(presentation->stream_list);
1010 BOOL tsmf_presentation_restarted(TSMF_PRESENTATION* presentation)
1012 TSMF_STREAM* stream = NULL;
1014 ArrayList_Lock(presentation->stream_list);
1015 size_t count = ArrayList_Count(presentation->stream_list);
1017 for (
size_t index = 0; index < count; index++)
1019 stream = (TSMF_STREAM*)ArrayList_GetItem(presentation->stream_list, index);
1020 ret &= tsmf_stream_restart(stream);
1023 ArrayList_Unlock(presentation->stream_list);
1027 BOOL tsmf_presentation_start(TSMF_PRESENTATION* presentation)
1029 TSMF_STREAM* stream = NULL;
1031 ArrayList_Lock(presentation->stream_list);
1032 size_t count = ArrayList_Count(presentation->stream_list);
1034 for (
size_t index = 0; index < count; index++)
1036 stream = (TSMF_STREAM*)ArrayList_GetItem(presentation->stream_list, index);
1037 ret &= tsmf_stream_start(stream);
1040 ArrayList_Unlock(presentation->stream_list);
1049 UINT tsmf_presentation_sync(TSMF_PRESENTATION* presentation)
1052 ArrayList_Lock(presentation->stream_list);
1053 size_t count = ArrayList_Count(presentation->stream_list);
1055 for (
size_t index = 0; index < count; index++)
1057 TSMF_STREAM* stream = (TSMF_STREAM*)ArrayList_GetItem(presentation->stream_list, index);
1059 if (WaitForSingleObject(stream->ready, 500) == WAIT_FAILED)
1061 error = GetLastError();
1062 WLog_ERR(TAG,
"WaitForSingleObject failed with error %" PRIu32
"!", error);
1067 ArrayList_Unlock(presentation->stream_list);
1068 return CHANNEL_RC_OK;
1071 BOOL tsmf_presentation_stop(TSMF_PRESENTATION* presentation)
1073 TSMF_STREAM* stream = NULL;
1075 ArrayList_Lock(presentation->stream_list);
1076 size_t count = ArrayList_Count(presentation->stream_list);
1078 for (
size_t index = 0; index < count; index++)
1080 stream = (TSMF_STREAM*)ArrayList_GetItem(presentation->stream_list, index);
1081 ret &= tsmf_stream_stop(stream);
1084 ArrayList_Unlock(presentation->stream_list);
1085 presentation->audio_start_time = 0;
1086 presentation->audio_end_time = 0;
1090 BOOL tsmf_presentation_set_geometry_info(TSMF_PRESENTATION* presentation, UINT32 x, UINT32 y,
1091 UINT32 width, UINT32 height, UINT32 num_rects,
1094 TSMF_STREAM* stream = NULL;
1099 if (!width || !height)
1107 presentation->rect.left = x;
1108 presentation->rect.top = y;
1109 presentation->rect.width = width;
1110 presentation->rect.height = height;
1111 void* tmp_rects = realloc(presentation->rects,
sizeof(
RECTANGLE_32) * num_rects);
1113 if (!tmp_rects && num_rects)
1116 presentation->nr_rects = num_rects;
1118 if (presentation->rects)
1119 CopyMemory(presentation->rects, rects,
sizeof(
RECTANGLE_32) * num_rects);
1120 ArrayList_Lock(presentation->stream_list);
1121 size_t count = ArrayList_Count(presentation->stream_list);
1123 for (
size_t index = 0; index < count; index++)
1125 stream = (TSMF_STREAM*)ArrayList_GetItem(presentation->stream_list, index);
1127 if (!stream->decoder)
1130 if (stream->decoder->UpdateRenderingArea)
1132 ret = stream->decoder->UpdateRenderingArea(stream->decoder, x, y, width, height,
1137 ArrayList_Unlock(presentation->stream_list);
1141 void tsmf_presentation_set_audio_device(TSMF_PRESENTATION* presentation,
const char* name,
1144 presentation->audio_name = name;
1145 presentation->audio_device = device;
1148 BOOL tsmf_stream_flush(TSMF_STREAM* stream)
1155 ret = stream->audio->Flush(stream->audio);
1158 stream->eos_message_id = 0;
1159 stream->eos_channel_callback = NULL;
1160 stream->delayed_stop = 0;
1161 stream->last_end_time = 0;
1162 stream->next_start_time = 0;
1164 if (stream->major_type == TSMF_MAJOR_TYPE_AUDIO)
1166 stream->presentation->audio_start_time = 0;
1167 stream->presentation->audio_end_time = 0;
1173 void s_tsmf_presentation_free(
void* obj)
1175 TSMF_PRESENTATION* presentation = (TSMF_PRESENTATION*)obj;
1179 tsmf_presentation_stop(presentation);
1180 ArrayList_Clear(presentation->stream_list);
1181 ArrayList_Free(presentation->stream_list);
1182 free(presentation->rects);
1183 ZeroMemory(presentation,
sizeof(TSMF_PRESENTATION));
1188 void tsmf_presentation_free(TSMF_PRESENTATION* presentation)
1190 ArrayList_Remove(presentation_list, presentation);
1193 TSMF_STREAM* tsmf_stream_new(TSMF_PRESENTATION* presentation, UINT32 stream_id,
1194 rdpContext* rdpcontext)
1197 TSMF_STREAM* stream = NULL;
1198 stream = tsmf_stream_find_by_id(presentation, stream_id);
1202 WLog_ERR(TAG,
"duplicated stream id %" PRIu32
"!", stream_id);
1206 stream = (TSMF_STREAM*)calloc(1,
sizeof(TSMF_STREAM));
1210 WLog_ERR(TAG,
"Calloc failed");
1214 stream->minBufferLevel = VIDEO_MIN_BUFFER_LEVEL;
1215 stream->maxBufferLevel = VIDEO_MAX_BUFFER_LEVEL;
1216 stream->currentBufferLevel = 1;
1217 stream->seeking = FALSE;
1219 stream->eos_message_id = 0;
1220 stream->eos_channel_callback = NULL;
1221 stream->stream_id = stream_id;
1222 stream->presentation = presentation;
1223 stream->stopEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
1225 if (!stream->stopEvent)
1226 goto error_stopEvent;
1228 stream->ready = CreateEvent(NULL, TRUE, TRUE, NULL);
1233 stream->sample_list = Queue_New(TRUE, -1, -1);
1235 if (!stream->sample_list)
1236 goto error_sample_list;
1238 obj = Queue_Object(stream->sample_list);
1240 goto error_sample_ack_list;
1241 obj->fnObjectFree = tsmf_sample_free;
1243 stream->sample_ack_list = Queue_New(TRUE, -1, -1);
1245 if (!stream->sample_ack_list)
1246 goto error_sample_ack_list;
1248 obj = Queue_Object(stream->sample_ack_list);
1250 goto error_play_thread;
1251 obj->fnObjectFree = tsmf_sample_free;
1253 stream->play_thread =
1254 CreateThread(NULL, 0, tsmf_stream_playback_func, stream, CREATE_SUSPENDED, NULL);
1256 if (!stream->play_thread)
1257 goto error_play_thread;
1259 stream->ack_thread =
1260 CreateThread(NULL, 0, tsmf_stream_ack_func, stream, CREATE_SUSPENDED, NULL);
1262 if (!stream->ack_thread)
1263 goto error_ack_thread;
1265 if (!ArrayList_Append(presentation->stream_list, stream))
1268 stream->rdpcontext = rdpcontext;
1271 (void)SetEvent(stream->stopEvent);
1273 if (WaitForSingleObject(stream->ack_thread, INFINITE) == WAIT_FAILED)
1274 WLog_ERR(TAG,
"WaitForSingleObject failed with error %" PRIu32
"!", GetLastError());
1277 (void)SetEvent(stream->stopEvent);
1279 if (WaitForSingleObject(stream->play_thread, INFINITE) == WAIT_FAILED)
1280 WLog_ERR(TAG,
"WaitForSingleObject failed with error %" PRIu32
"!", GetLastError());
1283 Queue_Free(stream->sample_ack_list);
1284 error_sample_ack_list:
1285 Queue_Free(stream->sample_list);
1287 (void)CloseHandle(stream->ready);
1289 (void)CloseHandle(stream->stopEvent);
1295 void tsmf_stream_start_threads(TSMF_STREAM* stream)
1297 ResumeThread(stream->play_thread);
1298 ResumeThread(stream->ack_thread);
1301 TSMF_STREAM* tsmf_stream_find_by_id(TSMF_PRESENTATION* presentation, UINT32 stream_id)
1304 TSMF_STREAM* stream = NULL;
1305 ArrayList_Lock(presentation->stream_list);
1306 size_t count = ArrayList_Count(presentation->stream_list);
1308 for (
size_t index = 0; index < count; index++)
1310 stream = (TSMF_STREAM*)ArrayList_GetItem(presentation->stream_list, index);
1312 if (stream->stream_id == stream_id)
1319 ArrayList_Unlock(presentation->stream_list);
1320 return (found) ? stream : NULL;
1323 static void tsmf_stream_resync(
void* arg)
1325 TSMF_STREAM* stream = arg;
1326 (void)ResetEvent(stream->ready);
1329 BOOL tsmf_stream_set_format(TSMF_STREAM* stream,
const char* name,
wStream* s)
1334 if (stream->decoder)
1336 WLog_ERR(TAG,
"duplicated call");
1340 if (!tsmf_codec_parse_media_type(&mediatype, s))
1342 WLog_ERR(TAG,
"unable to parse media type");
1346 if (mediatype.MajorType == TSMF_MAJOR_TYPE_VIDEO)
1348 DEBUG_TSMF(
"video width %" PRIu32
" height %" PRIu32
" bit_rate %" PRIu32
1349 " frame_rate %f codec_data %" PRIu32
"",
1350 mediatype.Width, mediatype.Height, mediatype.BitRate,
1351 (
double)mediatype.SamplesPerSecond.Numerator /
1352 (
double)mediatype.SamplesPerSecond.Denominator,
1353 mediatype.ExtraDataSize);
1354 stream->minBufferLevel = VIDEO_MIN_BUFFER_LEVEL;
1355 stream->maxBufferLevel = VIDEO_MAX_BUFFER_LEVEL;
1357 else if (mediatype.MajorType == TSMF_MAJOR_TYPE_AUDIO)
1359 DEBUG_TSMF(
"audio channel %" PRIu32
" sample_rate %" PRIu32
" bits_per_sample %" PRIu32
1360 " codec_data %" PRIu32
"",
1361 mediatype.Channels, mediatype.SamplesPerSecond.Numerator,
1362 mediatype.BitsPerSample, mediatype.ExtraDataSize);
1363 stream->sample_rate = mediatype.SamplesPerSecond.Numerator;
1364 stream->channels = mediatype.Channels;
1365 stream->bits_per_sample = mediatype.BitsPerSample;
1367 if (stream->bits_per_sample == 0)
1368 stream->bits_per_sample = 16;
1370 stream->minBufferLevel = AUDIO_MIN_BUFFER_LEVEL;
1371 stream->maxBufferLevel = AUDIO_MAX_BUFFER_LEVEL;
1374 stream->major_type = mediatype.MajorType;
1375 stream->width = mediatype.Width;
1376 stream->height = mediatype.Height;
1377 stream->decoder = tsmf_load_decoder(name, &mediatype);
1378 ret &= tsmf_stream_change_volume(stream, stream->presentation->volume,
1379 stream->presentation->muted);
1381 if (!stream->decoder)
1384 if (stream->decoder->SetAckFunc)
1385 ret &= stream->decoder->SetAckFunc(stream->decoder, tsmf_stream_process_ack, stream);
1387 if (stream->decoder->SetSyncFunc)
1388 ret &= stream->decoder->SetSyncFunc(stream->decoder, tsmf_stream_resync, stream);
1393 void tsmf_stream_end(TSMF_STREAM* stream, UINT32 message_id,
1394 IWTSVirtualChannelCallback* pChannelCallback)
1400 stream->eos_message_id = message_id;
1401 stream->eos_channel_callback = pChannelCallback;
1404 void s_tsmf_stream_free(
void* obj)
1406 TSMF_STREAM* stream = (TSMF_STREAM*)obj;
1411 tsmf_stream_stop(stream);
1412 (void)SetEvent(stream->stopEvent);
1414 if (stream->play_thread)
1416 if (WaitForSingleObject(stream->play_thread, INFINITE) == WAIT_FAILED)
1418 WLog_ERR(TAG,
"WaitForSingleObject failed with error %" PRIu32
"!", GetLastError());
1422 (void)CloseHandle(stream->play_thread);
1423 stream->play_thread = NULL;
1426 if (stream->ack_thread)
1428 if (WaitForSingleObject(stream->ack_thread, INFINITE) == WAIT_FAILED)
1430 WLog_ERR(TAG,
"WaitForSingleObject failed with error %" PRIu32
"!", GetLastError());
1434 (void)CloseHandle(stream->ack_thread);
1435 stream->ack_thread = NULL;
1438 Queue_Free(stream->sample_list);
1439 Queue_Free(stream->sample_ack_list);
1441 if (stream->decoder && stream->decoder->Free)
1443 stream->decoder->Free(stream->decoder);
1444 stream->decoder = NULL;
1447 (void)CloseHandle(stream->stopEvent);
1448 (void)CloseHandle(stream->ready);
1449 ZeroMemory(stream,
sizeof(TSMF_STREAM));
1453 void tsmf_stream_free(TSMF_STREAM* stream)
1455 TSMF_PRESENTATION* presentation = stream->presentation;
1456 ArrayList_Remove(presentation->stream_list, stream);
1459 BOOL tsmf_stream_push_sample(TSMF_STREAM* stream, IWTSVirtualChannelCallback* pChannelCallback,
1460 UINT32 sample_id, UINT64 start_time, UINT64 end_time, UINT64 duration,
1461 UINT32 extensions, UINT32 data_size, BYTE* data)
1463 TSMF_SAMPLE* sample = NULL;
1464 (void)SetEvent(stream->ready);
1469 sample = (TSMF_SAMPLE*)calloc(1,
sizeof(TSMF_SAMPLE));
1473 WLog_ERR(TAG,
"calloc sample failed!");
1477 sample->sample_id = sample_id;
1478 sample->start_time = start_time;
1479 sample->end_time = end_time;
1480 sample->duration = duration;
1481 sample->extensions = extensions;
1483 if ((sample->extensions & 0x00000080) || (sample->extensions & 0x00000040))
1484 sample->invalidTimestamps = TRUE;
1486 sample->invalidTimestamps = FALSE;
1488 sample->stream = stream;
1489 sample->channel_callback = pChannelCallback;
1490 sample->data_size = data_size;
1491 sample->data = calloc(1, data_size + TSMF_BUFFER_PADDING_SIZE);
1496 CopyMemory(sample->data, data, data_size);
1497 if (!Queue_Enqueue(stream->sample_list, sample))
1511 static void tsmf_signal_handler(
int s)
1514 ArrayList_Free(presentation_list);
1518 (void)signal(s, SIG_DFL);
1521 else if (s == SIGUSR1)
1523 (void)signal(s, SIG_DFL);
1529 BOOL tsmf_media_init(
void)
1533 struct sigaction sigtrap;
1534 sigtrap.sa_handler = tsmf_signal_handler;
1535 sigemptyset(&sigtrap.sa_mask);
1536 sigtrap.sa_flags = 0;
1537 sigaction(SIGINT, &sigtrap, 0);
1538 sigaction(SIGUSR1, &sigtrap, 0);
1541 if (!presentation_list)
1543 presentation_list = ArrayList_New(TRUE);
1545 if (!presentation_list)
1548 obj = ArrayList_Object(presentation_list);
1551 obj->fnObjectFree = s_tsmf_presentation_free;
This struct contains function pointer to initialize/free objects.