static void* tsmf_stream_ack_func(void *arg) { HANDLE hdl[2]; TSMF_STREAM* stream = (TSMF_STREAM*) arg; DEBUG_TSMF("in %d", stream->stream_id); hdl[0] = stream->stopEvent; hdl[1] = Queue_Event(stream->sample_ack_list); while (1) { DWORD ev = WaitForMultipleObjects(2, hdl, FALSE, INFINITE); if (ev == WAIT_OBJECT_0) break; if (!stream->decoder) continue; if (stream->decoder->SetAckFunc) continue; if (tsmf_stream_process_ack(stream, FALSE)) break; } DEBUG_TSMF("out %d", stream->stream_id); ExitThread(0); return NULL; }
static void* tsmf_stream_playback_func(void* arg) { TSMF_SAMPLE* sample; TSMF_STREAM* stream = (TSMF_STREAM*) arg; TSMF_PRESENTATION* presentation = stream->presentation; DEBUG_DVC("in %d", stream->stream_id); if (stream->major_type == TSMF_MAJOR_TYPE_AUDIO && stream->sample_rate && stream->channels && stream->bits_per_sample) { if (stream->decoder) { if (stream->decoder->GetDecodedData) { stream->audio = tsmf_load_audio_device( presentation->audio_name && presentation->audio_name[0] ? presentation->audio_name : NULL, presentation->audio_device && presentation->audio_device[0] ? presentation->audio_device : NULL); if (stream->audio) { stream->audio->SetFormat(stream->audio, stream->sample_rate, stream->channels, stream->bits_per_sample); } } } } while (!(WaitForSingleObject(stream->stopEvent, 0) == WAIT_OBJECT_0)) { tsmf_stream_process_ack(stream); sample = tsmf_stream_pop_sample(stream, 1); if (sample) tsmf_sample_playback(sample); else USleep(5000); } if (stream->eos || presentation->eos) { while ((sample = tsmf_stream_pop_sample(stream, 1)) != NULL) tsmf_sample_playback(sample); } if (stream->audio) { stream->audio->Free(stream->audio); stream->audio = NULL; } SetEvent(stream->stopEvent); DEBUG_DVC("out %d", stream->stream_id); return NULL; }
static void* tsmf_stream_ack_func(void *arg) { HANDLE hdl[2]; TSMF_STREAM* stream = (TSMF_STREAM*) arg; UINT error = CHANNEL_RC_OK; DEBUG_TSMF("in %d", stream->stream_id); hdl[0] = stream->stopEvent; hdl[1] = Queue_Event(stream->sample_ack_list); while (1) { DWORD ev = WaitForMultipleObjects(2, hdl, FALSE, INFINITE); if (ev == WAIT_FAILED) { error = GetLastError(); WLog_ERR(TAG, "WaitForMultipleObjects failed with error %lu!", error); break; } if (ev == WAIT_OBJECT_0) break; if (!stream->decoder) continue; if (stream->decoder->SetAckFunc) continue; if (tsmf_stream_process_ack(stream, FALSE)) { error = ERROR_INTERNAL_ERROR; WLog_ERR(TAG, "tsmf_stream_process_ack failed!"); break; } } if (error && stream->rdpcontext) setChannelError(stream->rdpcontext, error, "tsmf_stream_ack_func reported an error"); DEBUG_TSMF("out %d", stream->stream_id); ExitThread(0); return NULL; }
static void* tsmf_stream_ack_func(void *arg) { HANDLE hdl[2]; TSMF_STREAM* stream = (TSMF_STREAM*) arg; UINT error = CHANNEL_RC_OK; DEBUG_TSMF("in %d", stream->stream_id); hdl[0] = stream->stopEvent; hdl[1] = Queue_Event(stream->sample_ack_list); while (1) { DWORD ev = WaitForMultipleObjects(2, hdl, FALSE, 1000); if (ev == WAIT_FAILED) { error = GetLastError(); WLog_ERR(TAG, "WaitForMultipleObjects failed with error %lu!", error); break; } if (stream->decoder) if (stream->decoder->BufferLevel) stream->currentBufferLevel = stream->decoder->BufferLevel(stream->decoder); if (stream->eos) { while ((stream->currentBufferLevel > 0) || !(tsmf_stream_process_ack(stream, TRUE))) { DEBUG_TSMF("END OF STREAM PROCESSING!"); if (stream->decoder->BufferLevel) stream->currentBufferLevel = stream->decoder->BufferLevel(stream->decoder); else stream->currentBufferLevel = 1; USleep(1000); } tsmf_send_eos_response(stream->eos_channel_callback, stream->eos_message_id); stream->eos = 0; if (stream->delayed_stop) { DEBUG_TSMF("Finishing delayed stream stop, now that eos has processed."); tsmf_stream_flush(stream); if (stream->decoder->Control) stream->decoder->Control(stream->decoder, Control_Stop, NULL); } } /* Stream stopped force all of the acks to happen */ if (ev == WAIT_OBJECT_0) { DEBUG_TSMF("ack: Stream stopped!"); while(1) { if (tsmf_stream_process_ack(stream, TRUE)) break; USleep(1000); } break; } if (tsmf_stream_process_ack(stream, FALSE)) continue; if (stream->currentBufferLevel > stream->minBufferLevel) USleep(1000); } if (error && stream->rdpcontext) setChannelError(stream->rdpcontext, error, "tsmf_stream_ack_func reported an error"); DEBUG_TSMF("out %d", stream->stream_id); ExitThread(0); return NULL; }