Пример #1
0
void cliprdr_process_format_list_event(cliprdrPlugin* cliprdr, RDP_CB_FORMAT_LIST_EVENT* cb_event)
{
	int i;
	wStream* s;

	DEBUG_CLIPRDR("Sending Clipboard Format List");

	if (cb_event->raw_format_data)
	{
		s = cliprdr_packet_new(CB_FORMAT_LIST, 0, cb_event->raw_format_data_size);
		stream_write(s, cb_event->raw_format_data, cb_event->raw_format_data_size);
	}
	else
	{
		wStream* body = stream_new(0);
		
		for (i = 0; i < cb_event->num_formats; i++)
		{
			const char* name;
			int name_length;

			switch (cb_event->formats[i])
			{
				case CB_FORMAT_HTML:
					name = CFSTR_HTML; name_length = sizeof(CFSTR_HTML);
					break;
				case CB_FORMAT_PNG:
					name = CFSTR_PNG; name_length = sizeof(CFSTR_PNG);
					break;
				case CB_FORMAT_JPEG:
					name = CFSTR_JPEG; name_length = sizeof(CFSTR_JPEG);
					break;
				case CB_FORMAT_GIF:
					name = CFSTR_GIF; name_length = sizeof(CFSTR_GIF);
					break;
				default:
					name = "\0\0";
					name_length = 2;
					break;
			}
			
			if (!cliprdr->use_long_format_names)
				name_length = 32;
			
			stream_extend(body, stream_get_size(body) + 4 + name_length);

			stream_write_UINT32(body, cb_event->formats[i]);
			stream_write(body, name, name_length);
		}
				
		s = cliprdr_packet_new(CB_FORMAT_LIST, 0, stream_get_size(body));
		stream_write(s, stream_get_head(body), stream_get_size(body));
		stream_free(body);
	}

	cliprdr_packet_send(cliprdr, s);
}
Пример #2
0
static void* tf_debug_channel_thread_func(void* arg)
{
	void* fd;
	STREAM* s;
	void* buffer;
	UINT32 bytes_returned = 0;
	testPeerContext* context = (testPeerContext*) arg;
	freerdp_thread* thread = context->debug_channel_thread;

	if (WTSVirtualChannelQuery(context->debug_channel, WTSVirtualFileHandle, &buffer, &bytes_returned) == TRUE)
	{
		fd = *((void**) buffer);
		WTSFreeMemory(buffer);
		thread->signals[thread->num_signals++] = CreateFileDescriptorEvent(NULL, TRUE, FALSE, ((int) (long) fd));
	}

	s = stream_new(4096);

	WTSVirtualChannelWrite(context->debug_channel, (BYTE*) "test1", 5, NULL);

	while (1)
	{
		freerdp_thread_wait(thread);

		if (freerdp_thread_is_stopped(thread))
			break;

		stream_set_pos(s, 0);

		if (WTSVirtualChannelRead(context->debug_channel, 0, stream_get_head(s),
			stream_get_size(s), &bytes_returned) == FALSE)
		{
			if (bytes_returned == 0)
				break;

			stream_check_size(s, bytes_returned);

			if (WTSVirtualChannelRead(context->debug_channel, 0, stream_get_head(s),
				stream_get_size(s), &bytes_returned) == FALSE)
			{
				/* should not happen */
				break;
			}
		}

		stream_set_pos(s, bytes_returned);

		printf("got %d bytes\n", bytes_returned);
	}

	stream_free(s);
	freerdp_thread_quit(thread);

	return 0;
}
Пример #3
0
static void* tf_debug_channel_thread_func(void* arg)
{
	void* fd;
	STREAM* s;
	void* buffer;
	uint32 bytes_returned = 0;
	testPeerContext* context = (testPeerContext*) arg;
	freerdp_thread* thread = context->debug_channel_thread;

	if (WTSVirtualChannelQuery(context->debug_channel, WTSVirtualFileHandle, &buffer, &bytes_returned) == true)
	{
		fd = *((void**)buffer);
		WTSFreeMemory(buffer);
		thread->signals[thread->num_signals++] = wait_obj_new_with_fd(fd);
	}

	s = stream_new(4096);

	WTSVirtualChannelWrite(context->debug_channel, (uint8*) "test1", 5, NULL);

	while (1)
	{
		freerdp_thread_wait(thread);
		if (freerdp_thread_is_stopped(thread))
			break;

		stream_set_pos(s, 0);
		if (WTSVirtualChannelRead(context->debug_channel, 0, stream_get_head(s),
			stream_get_size(s), &bytes_returned) == false)
		{
			if (bytes_returned == 0)
				break;
			stream_check_size(s, bytes_returned);
			if (WTSVirtualChannelRead(context->debug_channel, 0, stream_get_head(s),
				stream_get_size(s), &bytes_returned) == false)
			{
				/* should not happen */
				break;
			}
		}
		stream_set_pos(s, bytes_returned);

		printf("got %d bytes\n", bytes_returned);
	}

	stream_free(s);
	freerdp_thread_quit(thread);

	return 0;
}
Пример #4
0
static void sample_process_receive(rdpSvcPlugin* plugin, STREAM* data_in)
{
	int bytes;
	STREAM* data_out;
	samplePlugin* sample = (samplePlugin*) plugin;

	printf("sample_process_receive:\n");

	if (!sample)
	{
		printf("sample_process_receive: sample is nil\n");
		return;
	}

	/* process data in (from server) here */
	/* here we just send the same data back */

	bytes = stream_get_size(data_in);
	printf("sample_process_receive: got bytes %d\n", bytes);

	if (bytes > 0)
	{
		data_out = stream_new(bytes);
		stream_copy(data_out, data_in, bytes);
		/* svc_plugin_send takes ownership of data_out, that is why
		   we do not free it */

		bytes = stream_get_length(data_in);
		printf("sample_process_receive: sending bytes %d\n", bytes);

		svc_plugin_send(plugin, data_out);
	}

	stream_free(data_in);
}
Пример #5
0
static void svc_plugin_process_received(rdpSvcPlugin* plugin, void* pData, uint32 dataLength,
	uint32 totalLength, uint32 dataFlags)
{
	STREAM* data_in;

	if (dataFlags & CHANNEL_FLAG_FIRST)
	{
		if (plugin->priv->data_in != NULL)
			stream_free(plugin->priv->data_in);
		plugin->priv->data_in = stream_new(totalLength);
	}

	data_in = plugin->priv->data_in;
	stream_check_size(data_in, dataLength);
	stream_write(data_in, pData, dataLength);

	if (dataFlags & CHANNEL_FLAG_LAST)
	{
		if (stream_get_size(data_in) != stream_get_length(data_in))
		{
			printf("svc_plugin_process_received: read error\n");
		}
		/* the stream ownership is passed to the callback who is responsible for freeing it. */
		plugin->priv->data_in = NULL;
		stream_set_pos(data_in, 0);
		plugin->receive_callback(plugin, data_in);
	}
}
Пример #6
0
void cdc_acmd_write(USBD* usbd, CDC_ACMD* cdc_acmd)
{
    if (!cdc_acmd->DTR || !cdc_acmd->tx_idle || cdc_acmd->suspended)
        return;

    unsigned int to_write;
    if (cdc_acmd->tx_size == 0)
        cdc_acmd->tx_size = stream_get_size(cdc_acmd->tx_stream);

    to_write = cdc_acmd->tx_size;
    if (to_write > cdc_acmd->data_ep_size)
        to_write = cdc_acmd->data_ep_size;
    if (to_write)
    {
        cdc_acmd->tx_size -= to_write;
        if (stream_read(cdc_acmd->tx_stream_handle, io_data(cdc_acmd->tx), to_write))
        {
            cdc_acmd->tx_idle = false;
            cdc_acmd->tx->data_size = to_write;
            usbd_usb_ep_write(usbd, cdc_acmd->data_ep, cdc_acmd->tx);
        }
        //just in case of driver failure
        else
            stream_listen(cdc_acmd->tx_stream, USBD_IFACE(cdc_acmd->data_iface, 0), HAL_USBD_IFACE);
    }
    else
        stream_listen(cdc_acmd->tx_stream, USBD_IFACE(cdc_acmd->data_iface, 0), HAL_USBD_IFACE);
}
Пример #7
0
static int open_file(struct demuxer *demuxer, enum demux_check check)
{
    if (stream_get_size(demuxer->stream) == 0)
        return -1;

    int flags = 0;
    if (check <= DEMUX_CHECK_REQUEST)
        flags |= MP_ARCHIVE_FLAG_UNSAFE;
    struct mp_archive *mpa = mp_archive_new(demuxer->log, demuxer->stream, flags);
    if (!mpa)
        return -1;

    struct playlist *pl = talloc_zero(demuxer, struct playlist);
    demuxer->playlist = pl;

    // make it load archive://
    pl->disable_safety = true;

    char *prefix = mp_url_escape(mpa, demuxer->stream->url, "~|");

    char **files = NULL;
    int num_files = 0;

    for (;;) {
        struct archive_entry *entry;
        int r = archive_read_next_header(mpa->arch, &entry);
        if (r == ARCHIVE_EOF)
            break;
        if (r < ARCHIVE_OK)
            MP_ERR(demuxer, "libarchive: %s\n", archive_error_string(mpa->arch));
        if (r < ARCHIVE_WARN)
            break;
        if (archive_entry_filetype(entry) != AE_IFREG)
            continue;
        const char *fn = archive_entry_pathname(entry);
        // Some archives may have no filenames.
        if (!fn)
            fn = talloc_asprintf(mpa, "mpv_unknown#%d\n", num_files);
        // stream_libarchive.c does the real work
        char *f = talloc_asprintf(mpa, "archive://%s|%s", prefix, fn);
        MP_TARRAY_APPEND(mpa, files, num_files, f);
    }

    if (files)
        qsort(files, num_files, sizeof(files[0]), cmp_filename);

    for (int n = 0; n < num_files; n++)
        playlist_add_file(pl, files[n]);

    demuxer->filetype = "archive";
    demuxer->fully_read = true;

    mp_archive_free(mpa);

    return 0;
}
Пример #8
0
static void rdpdbg_process_receive(rdpSvcPlugin* plugin, STREAM* data_in)
{
	STREAM* data_out;

	DEBUG_WARN("size %d", stream_get_size(data_in));
	stream_free(data_in);

	data_out = stream_new(8);
	stream_write(data_out, "senddata", 8);
	svc_plugin_send(plugin, data_out);
}
Пример #9
0
int dvcman_receive_channel_data(IWTSVirtualChannelManager* pChannelMgr, uint32 ChannelId, uint8* data, uint32 data_size)
{
	int error = 0;
	DVCMAN_CHANNEL* channel;

	channel = dvcman_find_channel_by_id(pChannelMgr, ChannelId);

	if (channel == NULL)
	{
		DEBUG_WARN("ChannelId %d not found!", ChannelId);
		return 1;
	}

	if (channel->dvc_data)
	{
		/* Fragmented data */
		if (stream_get_length(channel->dvc_data) + data_size > (uint32) stream_get_size(channel->dvc_data))
		{
			DEBUG_WARN("data exceeding declared length!");
			stream_free(channel->dvc_data);
			channel->dvc_data = NULL;
			return 1;
		}

		stream_write(channel->dvc_data, data, data_size);

		if (stream_get_length(channel->dvc_data) >= stream_get_size(channel->dvc_data))
		{
			error = channel->channel_callback->OnDataReceived(channel->channel_callback,
				stream_get_size(channel->dvc_data), stream_get_data(channel->dvc_data));
			stream_free(channel->dvc_data);
			channel->dvc_data = NULL;
		}
	}
	else
	{
		error = channel->channel_callback->OnDataReceived(channel->channel_callback, data_size, data);
	}

	return error;
}
Пример #10
0
/* header is not removed from data in this function */
static void rdpsnd_process_message_wave(rdpsndPlugin* rdpsnd, STREAM* data_in)
{
	uint16 wTimeStamp;
	uint32 delay_ms;
	uint32 process_ms;
	struct data_out_item* item;

	rdpsnd->expectingWave = 0;
	memcpy(stream_get_head(data_in), rdpsnd->waveData, 4);
	if (stream_get_size(data_in) != rdpsnd->waveDataSize)
	{
		DEBUG_WARN("size error");
		return;
	}
	if (rdpsnd->device)
		IFCALL(rdpsnd->device->Play, rdpsnd->device, stream_get_head(data_in), stream_get_size(data_in));

	process_ms = get_mstime() - rdpsnd->wave_timestamp;
	delay_ms = 250;
	wTimeStamp = rdpsnd->wTimeStamp + delay_ms;

	DEBUG_SVC("data_size %d delay_ms %u process_ms %u",
		stream_get_size(data_in), delay_ms, process_ms);

	item = xnew(struct data_out_item);
	item->data_out = stream_new(8);
	stream_write_uint8(item->data_out, SNDC_WAVECONFIRM);
	stream_write_uint8(item->data_out, 0);
	stream_write_uint16(item->data_out, 4);
	stream_write_uint16(item->data_out, wTimeStamp);
	stream_write_uint8(item->data_out, rdpsnd->cBlockNo); /* cConfirmedBlockNo */
	stream_write_uint8(item->data_out, 0); /* bPad */
	item->out_timestamp = rdpsnd->wave_timestamp + delay_ms;

	list_enqueue(rdpsnd->data_out_list, item);
	rdpsnd->plugin.interval_ms = 10;
}
Пример #11
0
static void svc_plugin_process_received(rdpSvcPlugin* plugin, void* pData, uint32 dataLength,
	uint32 totalLength, uint32 dataFlags)
{
	STREAM* data_in;
	svc_data_in_item* item;
	
	if ( (dataFlags & CHANNEL_FLAG_SUSPEND) || (dataFlags & CHANNEL_FLAG_RESUME))
	{
		/* According to MS-RDPBCGR 2.2.6.1, "All virtual channel traffic MUST be suspended.
		This flag is only valid in server-to-client virtual channel traffic. It MUST be
		ignored in client-to-server data." Thus it would be best practice to cease data
		transmission. However, simply returing here avoids a crash. */
		return;
	}

	if (dataFlags & CHANNEL_FLAG_FIRST)
	{
		if (plugin->priv->data_in != NULL)
			stream_free(plugin->priv->data_in);
		plugin->priv->data_in = stream_new(totalLength);
	}

	data_in = plugin->priv->data_in;
	stream_check_size(data_in, (int) dataLength);
	stream_write(data_in, pData, dataLength);

	if (dataFlags & CHANNEL_FLAG_LAST)
	{
		if (stream_get_size(data_in) != stream_get_length(data_in))
		{
			printf("svc_plugin_process_received: read error\n");
		}

		plugin->priv->data_in = NULL;
		stream_set_pos(data_in, 0);

		item = xnew(svc_data_in_item);
		item->data_in = data_in;

		freerdp_thread_lock(plugin->priv->thread);
		list_enqueue(plugin->priv->data_in_list, item);
		freerdp_thread_unlock(plugin->priv->thread);

		freerdp_thread_signal(plugin->priv->thread);
	}
}
Пример #12
0
static void update_cached_controls(struct priv *s)
{
    int64_t i64;
    double d;
    struct mp_tags *tags;
    s->stream_time_length = 0;
    if (stream_control(s->stream, STREAM_CTRL_GET_TIME_LENGTH, &d) == STREAM_OK)
        s->stream_time_length = d;
    if (stream_control(s->stream, STREAM_CTRL_GET_METADATA, &tags) == STREAM_OK) {
        talloc_free(s->stream_metadata);
        s->stream_metadata = talloc_steal(s, tags);
    }
    s->stream_size = s->eof_pos;
    i64 = stream_get_size(s->stream);
    if (i64 >= 0)
        s->stream_size = i64;
    s->has_avseek = stream_control(s->stream, STREAM_CTRL_HAS_AVSEEK, NULL) > 0;
}
Пример #13
0
static void svc_plugin_process_received(rdpSvcPlugin* plugin, void* pData, UINT32 dataLength,
	UINT32 totalLength, UINT32 dataFlags)
{
	wStream* data_in;
	
	if ((dataFlags & CHANNEL_FLAG_SUSPEND) || (dataFlags & CHANNEL_FLAG_RESUME))
	{
		/*
		 * According to MS-RDPBCGR 2.2.6.1, "All virtual channel traffic MUST be suspended.
		 * This flag is only valid in server-to-client virtual channel traffic. It MUST be
		 * ignored in client-to-server data." Thus it would be best practice to cease data
		 * transmission. However, simply returning here avoids a crash.
		 */
		return;
	}

	if (dataFlags & CHANNEL_FLAG_FIRST)
	{
		if (plugin->data_in != NULL)
			stream_free(plugin->data_in);

		plugin->data_in = stream_new(totalLength);
	}

	data_in = plugin->data_in;
	stream_check_size(data_in, (int) dataLength);
	stream_write(data_in, pData, dataLength);

	if (dataFlags & CHANNEL_FLAG_LAST)
	{
		if (stream_get_size(data_in) != stream_get_length(data_in))
		{
			fprintf(stderr, "svc_plugin_process_received: read error\n");
		}

		plugin->data_in = NULL;
		stream_set_pos(data_in, 0);

		MessageQueue_Post(plugin->MsgPipe->In, NULL, 0, (void*) data_in, NULL);
	}
}
Пример #14
0
static void svc_plugin_process_received(rdpSvcPlugin* plugin, void* pData, uint32 dataLength,
	uint32 totalLength, uint32 dataFlags)
{
	STREAM* data_in;
	svc_data_in_item* item;

	if (dataFlags & CHANNEL_FLAG_FIRST)
	{
		if (plugin->priv->data_in != NULL)
			stream_free(plugin->priv->data_in);
		plugin->priv->data_in = stream_new(totalLength);
	}

	data_in = plugin->priv->data_in;
	stream_check_size(data_in, (int) dataLength);
	stream_write(data_in, pData, dataLength);

	if (dataFlags & CHANNEL_FLAG_LAST)
	{
		if (stream_get_size(data_in) != stream_get_length(data_in))
		{
			printf("svc_plugin_process_received: read error\n");
		}

		plugin->priv->data_in = NULL;
		stream_set_pos(data_in, 0);

		item = xnew(svc_data_in_item);
		item->data_in = data_in;

		freerdp_thread_lock(plugin->priv->thread);
		list_enqueue(plugin->priv->data_in_list, item);
		freerdp_thread_unlock(plugin->priv->thread);

		freerdp_thread_signal(plugin->priv->thread);
	}
}
Пример #15
0
// lazy seek to avoid problems with end seeking over http
static int64_t seek_cb(struct archive *arch, void *priv,
                       int64_t offset, int whence)
{
    struct mp_archive_volume *vol = priv;
    switch (whence) {
    case SEEK_SET:
        vol->seek_to = offset;
        break;
    case SEEK_CUR:
        if (vol->seek_to < 0)
            vol->seek_to = stream_tell(vol->src);
        vol->seek_to += offset;
        break;
    case SEEK_END: ;
        int64_t size = stream_get_size(vol->src);
        if (size < 0)
            return -1;
        vol->seek_to = size + offset;
        break;
    default:
        return -1;
    }
    return vol->seek_to;
}
Пример #16
0
// return 1 on success, 0 if the cache is disabled/not needed, and -1 on error
// or if the cache is disabled
int stream_cache_init(stream_t *cache, stream_t *stream,
                      struct mp_cache_opts *opts)
{
    if (opts->size < 1)
        return 0;

    struct priv *s = talloc_zero(NULL, struct priv);
    s->log = cache->log;
    s->eof_pos = -1;

    cache_drop_contents(s);

    s->seek_limit = opts->seek_min * 1024ULL;
    s->back_size = opts->back_buffer * 1024ULL;

    int64_t cache_size = opts->size * 1024ULL;

    int64_t file_size = stream_get_size(stream);
    if (file_size >= 0)
        cache_size = MPMIN(cache_size, file_size);

    if (resize_cache(s, cache_size) != STREAM_OK) {
        MP_ERR(s, "Failed to allocate cache buffer.\n");
        talloc_free(s);
        return -1;
    }

    MP_VERBOSE(cache, "Cache size set to %lld KiB (%lld KiB backbuffer)\n",
               (long long)(s->buffer_size / 1024),
               (long long)(s->back_size / 1024));

    pthread_mutex_init(&s->mutex, NULL);
    pthread_cond_init(&s->wakeup, NULL);

    cache->priv = s;
    s->cache = cache;
    s->stream = stream;

    cache->seek = cache_seek;
    cache->fill_buffer = cache_fill_buffer;
    cache->control = cache_control;
    cache->close = cache_uninit;

    int64_t min = opts->initial * 1024ULL;
    if (min > s->buffer_size - FILL_LIMIT)
        min = s->buffer_size - FILL_LIMIT;

    s->seekable = stream->seekable;

    if (pthread_create(&s->cache_thread, NULL, cache_thread, s) != 0) {
        MP_ERR(s, "Starting cache thread failed.\n");
        return -1;
    }
    s->cache_thread_running = true;

    // wait until cache is filled with at least min bytes
    if (min < 1)
        return 1;
    for (;;) {
        if (mp_cancel_test(cache->cancel))
            return -1;
        int64_t fill;
        int idle;
        if (stream_control(s->cache, STREAM_CTRL_GET_CACHE_FILL, &fill) < 0)
            break;
        if (stream_control(s->cache, STREAM_CTRL_GET_CACHE_IDLE, &idle) < 0)
            break;
        MP_INFO(s, "\rCache fill: %5.2f%% "
                "(%" PRId64 " bytes)   ", 100.0 * fill / s->buffer_size, fill);
        if (fill >= min)
            break;
        if (idle)
            break;    // file is smaller than prefill size
        // Wake up if the cache is done reading some data (or on timeout/abort)
        pthread_mutex_lock(&s->mutex);
        s->control = CACHE_CTRL_PING;
        pthread_cond_signal(&s->wakeup);
        cache_wakeup_and_wait(s, &(double){0});
        pthread_mutex_unlock(&s->mutex);
    }
Пример #17
0
Файл: misc.c Проект: Ionic/mpv
void update_vo_playback_state(struct MPContext *mpctx)
{
    if (mpctx->video_out && mpctx->video_out->config_ok) {
        struct voctrl_playback_state oldstate = mpctx->vo_playback_state;
        struct voctrl_playback_state newstate = {
            .taskbar_progress = mpctx->opts->vo->taskbar_progress,
            .playing = mpctx->playing,
            .paused = mpctx->paused,
            .percent_pos = get_percent_pos(mpctx),
        };

        if (oldstate.taskbar_progress != newstate.taskbar_progress ||
            oldstate.playing != newstate.playing ||
            oldstate.paused != newstate.paused ||
            oldstate.percent_pos != newstate.percent_pos)
        {
            // Don't update progress bar if it was and still is hidden
            if ((oldstate.playing && oldstate.taskbar_progress) ||
                (newstate.playing && newstate.taskbar_progress))
            {
                vo_control_async(mpctx->video_out,
                                 VOCTRL_UPDATE_PLAYBACK_STATE, &newstate);
            }
            mpctx->vo_playback_state = newstate;
        }
    } else {
        mpctx->vo_playback_state = (struct voctrl_playback_state){ 0 };
    }
}

void update_window_title(struct MPContext *mpctx, bool force)
{
    if (!mpctx->video_out && !mpctx->ao) {
        talloc_free(mpctx->last_window_title);
        mpctx->last_window_title = NULL;
        return;
    }
    char *title = mp_property_expand_string(mpctx, mpctx->opts->wintitle);
    if (!mpctx->last_window_title || force ||
        strcmp(title, mpctx->last_window_title) != 0)
    {
        talloc_free(mpctx->last_window_title);
        mpctx->last_window_title = talloc_steal(mpctx, title);

        if (mpctx->video_out)
            vo_control(mpctx->video_out, VOCTRL_UPDATE_WINDOW_TITLE, title);

        if (mpctx->ao) {
            ao_control(mpctx->ao, AOCONTROL_UPDATE_STREAM_TITLE, title);
        }
    } else {
        talloc_free(title);
    }
}

void error_on_track(struct MPContext *mpctx, struct track *track)
{
    if (!track || !track->selected)
        return;
    mp_deselect_track(mpctx, track);
    if (track->type == STREAM_AUDIO)
        MP_INFO(mpctx, "Audio: no audio\n");
    if (track->type == STREAM_VIDEO)
        MP_INFO(mpctx, "Video: no video\n");
    if (mpctx->opts->stop_playback_on_init_failure ||
        !(mpctx->vo_chain || mpctx->ao_chain))
    {
        if (!mpctx->stop_play)
            mpctx->stop_play = PT_ERROR;
        if (mpctx->error_playing >= 0)
            mpctx->error_playing = MPV_ERROR_NOTHING_TO_PLAY;
    }
    mp_wakeup_core(mpctx);
}

int stream_dump(struct MPContext *mpctx, const char *source_filename)
{
    struct MPOpts *opts = mpctx->opts;
    stream_t *stream = stream_open(source_filename, mpctx->global);
    if (!stream)
        return -1;

    int64_t size = stream_get_size(stream);

    FILE *dest = fopen(opts->stream_dump, "wb");
    if (!dest) {
        MP_ERR(mpctx, "Error opening dump file: %s\n", mp_strerror(errno));
        return -1;
    }

    bool ok = true;

    while (mpctx->stop_play == KEEP_PLAYING && ok) {
        if (!opts->quiet && ((stream->pos / (1024 * 1024)) % 2) == 1) {
            uint64_t pos = stream->pos;
            MP_MSG(mpctx, MSGL_STATUS, "Dumping %lld/%lld...",
                   (long long int)pos, (long long int)size);
        }
        bstr data = stream_peek(stream, STREAM_MAX_BUFFER_SIZE);
        if (data.len == 0) {
            ok &= stream->eof;
            break;
        }
        ok &= fwrite(data.start, data.len, 1, dest) == 1;
        stream_skip(stream, data.len);
        mp_wakeup_core(mpctx); // don't actually sleep
        mp_idle(mpctx); // but process input
    }

    ok &= fclose(dest) == 0;
    free_stream(stream);
    return ok ? 0 : -1;
}

void merge_playlist_files(struct playlist *pl)
{
    if (!pl->first)
        return;
    char *edl = talloc_strdup(NULL, "edl://");
    for (struct playlist_entry *e = pl->first; e; e = e->next) {
        if (e != pl->first)
            edl = talloc_strdup_append_buffer(edl, ";");
        // Escape if needed
        if (e->filename[strcspn(e->filename, "=%,;\n")] ||
            bstr_strip(bstr0(e->filename)).len != strlen(e->filename))
        {
            // %length%
            edl = talloc_asprintf_append_buffer(edl, "%%%zd%%", strlen(e->filename));
        }
        edl = talloc_strdup_append_buffer(edl, e->filename);
    }
    playlist_clear(pl);
    playlist_add_file(pl, edl);
    talloc_free(edl);
}
Пример #18
0
void
bgp_zebra_announce (struct prefix *p, struct bgp_info *info, struct bgp *bgp, safi_t safi)
{
  int flags;
  u_char distance;
  struct peer *peer;
  struct bgp_info *mpinfo;
  size_t oldsize, newsize;

  if (zclient->sock < 0)
    return;

  if (! zclient->redist[ZEBRA_ROUTE_BGP])
    return;

  flags = 0;
  peer = info->peer;

  if (peer->sort == BGP_PEER_IBGP || peer->sort == BGP_PEER_CONFED)
    {
      SET_FLAG (flags, ZEBRA_FLAG_IBGP);
      SET_FLAG (flags, ZEBRA_FLAG_INTERNAL);
    }

  if ((peer->sort == BGP_PEER_EBGP && peer->ttl != 1)
      || CHECK_FLAG (peer->flags, PEER_FLAG_DISABLE_CONNECTED_CHECK))
    SET_FLAG (flags, ZEBRA_FLAG_INTERNAL);

  /* resize nexthop buffer size if necessary */
  if ((oldsize = stream_get_size (bgp_nexthop_buf)) <
      (sizeof (struct in_addr *) * (bgp_info_mpath_count (info) + 1)))
    {
      newsize = (sizeof (struct in_addr *) * (bgp_info_mpath_count (info) + 1));
      newsize = stream_resize (bgp_nexthop_buf, newsize);
      if (newsize == oldsize)
	{
	  zlog_err ("can't resize nexthop buffer");
	  return;
	}
    }

  stream_reset (bgp_nexthop_buf);

  if (p->family == AF_INET)
    {
      struct zapi_ipv4 api;
      struct in_addr *nexthop;

      api.flags = flags;
      nexthop = &info->attr->nexthop;
      stream_put (bgp_nexthop_buf, &nexthop, sizeof (struct in_addr *));
      for (mpinfo = bgp_info_mpath_first (info); mpinfo;
	   mpinfo = bgp_info_mpath_next (mpinfo))
	{
	  nexthop = &mpinfo->attr->nexthop;
	  stream_put (bgp_nexthop_buf, &nexthop, sizeof (struct in_addr *));
	}

      api.type = ZEBRA_ROUTE_BGP;
      api.message = 0;
      api.safi = safi;
      SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP);
      api.nexthop_num = 1 + bgp_info_mpath_count (info);
      api.nexthop = (struct in_addr **)STREAM_DATA (bgp_nexthop_buf);
      api.ifindex_num = 0;
      SET_FLAG (api.message, ZAPI_MESSAGE_METRIC);
      api.metric = info->attr->med;

      distance = bgp_distance_apply (p, info, bgp);

      if (distance)
	{
	  SET_FLAG (api.message, ZAPI_MESSAGE_DISTANCE);
	  api.distance = distance;
	}

      if (BGP_DEBUG(zebra, ZEBRA))
	{
	  int i;
	  char buf[2][INET_ADDRSTRLEN];
	  zlog_debug("Zebra send: IPv4 route add %s/%d nexthop %s metric %u"
		     " count %d",
		     inet_ntop(AF_INET, &p->u.prefix4, buf[0], sizeof(buf[0])),
		     p->prefixlen,
		     inet_ntop(AF_INET, api.nexthop[0], buf[1], sizeof(buf[1])),
		     api.metric, api.nexthop_num);
	  for (i = 1; i < api.nexthop_num; i++)
	    zlog_debug("Zebra send: IPv4 route add [nexthop %d] %s",
		       i, inet_ntop(AF_INET, api.nexthop[i], buf[1],
				    sizeof(buf[1])));
	}

      zapi_ipv4_route (ZEBRA_IPV4_ROUTE_ADD, zclient, 
                       (struct prefix_ipv4 *) p, &api);
    }
#ifdef HAVE_IPV6
  /* We have to think about a IPv6 link-local address curse. */
  if (p->family == AF_INET6)
    {
      unsigned int ifindex;
      struct in6_addr *nexthop;
      struct zapi_ipv6 api;

      ifindex = 0;
      nexthop = NULL;
      
      assert (info->attr->extra);
      
      /* Only global address nexthop exists. */
      if (info->attr->extra->mp_nexthop_len == 16)
	nexthop = &info->attr->extra->mp_nexthop_global;
      
      /* If both global and link-local address present. */
      if (info->attr->extra->mp_nexthop_len == 32)
	{
	  /* Workaround for Cisco's nexthop bug.  */
	  if (IN6_IS_ADDR_UNSPECIFIED (&info->attr->extra->mp_nexthop_global)
	      && peer->su_remote->sa.sa_family == AF_INET6)
	    nexthop = &peer->su_remote->sin6.sin6_addr;
	  else
	    nexthop = &info->attr->extra->mp_nexthop_local;

	  if (info->peer->nexthop.ifp)
	    ifindex = info->peer->nexthop.ifp->ifindex;
	}

      if (nexthop == NULL)
	return;

      if (IN6_IS_ADDR_LINKLOCAL (nexthop) && ! ifindex)
	{
	  if (info->peer->ifname)
	    ifindex = if_nametoindex (info->peer->ifname);
	  else if (info->peer->nexthop.ifp)
	    ifindex = info->peer->nexthop.ifp->ifindex;
	}

      /* Make Zebra API structure. */
      api.flags = flags;
      api.type = ZEBRA_ROUTE_BGP;
      api.message = 0;
      api.safi = safi;
      SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP);
      api.nexthop_num = 1;
      api.nexthop = &nexthop;
      SET_FLAG (api.message, ZAPI_MESSAGE_IFINDEX);
      api.ifindex_num = 1;
      api.ifindex = &ifindex;
      SET_FLAG (api.message, ZAPI_MESSAGE_METRIC);
      api.metric = info->attr->med;

      if (BGP_DEBUG(zebra, ZEBRA))
	{
	  char buf[2][INET6_ADDRSTRLEN];
	  zlog_debug("Zebra send: IPv6 route add %s/%d nexthop %s metric %u",
		     inet_ntop(AF_INET6, &p->u.prefix6, buf[0], sizeof(buf[0])),
		     p->prefixlen,
		     inet_ntop(AF_INET6, nexthop, buf[1], sizeof(buf[1])),
		     api.metric);
	}

      zapi_ipv6_route (ZEBRA_IPV6_ROUTE_ADD, zclient, 
                       (struct prefix_ipv6 *) p, &api);
    }
#endif /* HAVE_IPV6 */
}
Пример #19
0
static void* rdpsnd_server_thread_func(void* arg)
{
	void* fd;
	STREAM* s;
	void* buffer;
	BYTE msgType;
	UINT16 BodySize;
	UINT32 bytes_returned = 0;
	rdpsnd_server* rdpsnd = (rdpsnd_server*) arg;
	freerdp_thread* thread = rdpsnd->rdpsnd_channel_thread;

	if (WTSVirtualChannelQuery(rdpsnd->rdpsnd_channel, WTSVirtualFileHandle, &buffer, &bytes_returned) == TRUE)
	{
		fd = *((void**)buffer);
		WTSFreeMemory(buffer);
		thread->signals[thread->num_signals++] = wait_obj_new_with_fd(fd);
	}

	s = stream_new(4096);

	rdpsnd_server_send_formats(rdpsnd, s);

	while (1)
	{
		freerdp_thread_wait(thread);
		
		if (freerdp_thread_is_stopped(thread))
			break;

		stream_set_pos(s, 0);

		if (WTSVirtualChannelRead(rdpsnd->rdpsnd_channel, 0, stream_get_head(s),
			stream_get_size(s), &bytes_returned) == FALSE)
		{
			if (bytes_returned == 0)
				break;
			
			stream_check_size(s, (int) bytes_returned);

			if (WTSVirtualChannelRead(rdpsnd->rdpsnd_channel, 0, stream_get_head(s),
				stream_get_size(s), &bytes_returned) == FALSE)
				break;
		}

		stream_read_BYTE(s, msgType);
		stream_seek_BYTE(s); /* bPad */
		stream_read_UINT16(s, BodySize);

		if (BodySize + 4 > (int) bytes_returned)
			continue;

		switch (msgType)
		{
			case SNDC_FORMATS:
				if (rdpsnd_server_recv_formats(rdpsnd, s))
				{
					IFCALL(rdpsnd->context.Activated, &rdpsnd->context);
				}
				break;
			default:
				break;
		}
	}

	stream_free(s);
	freerdp_thread_quit(thread);

	return 0;
}
Пример #20
0
static void* audin_server_thread_func(void* arg)
{
	void* fd;
	STREAM* s;
	void* buffer;
	BYTE MessageId;
	BOOL ready = FALSE;
	UINT32 bytes_returned = 0;
	audin_server* audin = (audin_server*) arg;
	freerdp_thread* thread = audin->audin_channel_thread;

	if (WTSVirtualChannelQuery(audin->audin_channel, WTSVirtualFileHandle, &buffer, &bytes_returned) == TRUE)
	{
		fd = *((void**)buffer);
		WTSFreeMemory(buffer);
		thread->signals[thread->num_signals++] = wait_obj_new_with_fd(fd);
	}

	/* Wait for the client to confirm that the Audio Input dynamic channel is ready */
	while (1)
	{
		freerdp_thread_wait(thread);
		if (freerdp_thread_is_stopped(thread))
			break;

		if (WTSVirtualChannelQuery(audin->audin_channel, WTSVirtualChannelReady, &buffer, &bytes_returned) == FALSE)
			break;
		ready = *((BOOL*)buffer);
		WTSFreeMemory(buffer);
		if (ready)
			break;
	}

	s = stream_new(4096);

	if (ready)
	{
		audin_server_send_version(audin, s);
	}

	while (ready)
	{
		freerdp_thread_wait(thread);
		
		if (freerdp_thread_is_stopped(thread))
			break;

		stream_set_pos(s, 0);

		if (WTSVirtualChannelRead(audin->audin_channel, 0, stream_get_head(s),
			stream_get_size(s), &bytes_returned) == FALSE)
		{
			if (bytes_returned == 0)
				break;
			
			stream_check_size(s, (int) bytes_returned);

			if (WTSVirtualChannelRead(audin->audin_channel, 0, stream_get_head(s),
				stream_get_size(s), &bytes_returned) == FALSE)
				break;
		}
		if (bytes_returned < 1)
			continue;

		stream_read_BYTE(s, MessageId);
		bytes_returned--;
		switch (MessageId)
		{
			case MSG_SNDIN_VERSION:
				if (audin_server_recv_version(audin, s, bytes_returned))
					audin_server_send_formats(audin, s);
				break;

			case MSG_SNDIN_FORMATS:
				if (audin_server_recv_formats(audin, s, bytes_returned))
					audin_server_send_open(audin, s);
				break;

			case MSG_SNDIN_OPEN_REPLY:
				audin_server_recv_open_reply(audin, s, bytes_returned);
				break;

			case MSG_SNDIN_DATA_INCOMING:
				break;

			case MSG_SNDIN_DATA:
				audin_server_recv_data(audin, s, bytes_returned);
				break;

			case MSG_SNDIN_FORMATCHANGE:
				break;

			default:
				printf("audin_server_thread_func: unknown MessageId %d\n", MessageId);
				break;
		}
	}

	stream_free(s);
	WTSVirtualChannelClose(audin->audin_channel);
	audin->audin_channel = NULL;
	freerdp_thread_quit(thread);

	return NULL;
}
Пример #21
0
int demux_mp4_open(struct demux **demux, struct stream_handle *stream,
		   unsigned long *samplerate, unsigned char *channels)
{
	struct demux *d;
	const unsigned char *buffer;
	unsigned long mdat_pos = 0;
	unsigned long moov_pos = 0;
	unsigned long count = 0;
	unsigned long size;

	if(stream == NULL)
		return -1;

	/* Get stream buffer */
	buffer = stream_get_buffer(stream);

	/* Read 8 first bytes for first atom header */
	if(stream_read(stream, 8) != 8)
		return -1;

	/* Check "ftyp" atom */
	if(ATOM_CHECK(buffer, "ftyp") != 0)
		return -1;
	size = ATOM_LEN(buffer);
	count = size;

	/* Allocate demux data structure */
	*demux = malloc(sizeof(struct demux));
	if(*demux == NULL)
		return -1;
	d = *demux;

	/* Init demux structure */
	memset(d, 0, sizeof(struct demux));
	d->stream = stream;
	d->buffer = buffer;
	d->buffer_size = stream_get_buffer_size(stream);
	d->size = stream_get_size(stream);

	/* Seek to next atom and get next atom header */
	stream_seek(d->stream, size, SEEK_CUR);

	/* Read all atom until "mdat" */
	while(count < d->size)
	{
		/* Get size of sub-atom */
		stream_read(d->stream, 8);
		size = ATOM_LEN(d->buffer);

		/* Process sub-atom */
		if(ATOM_CHECK(d->buffer, "moov") == 0)
		{
			/* Process "moov" */
			demux_mp4_parse_moov(d);
			moov_pos = count;
		}
		else
		{
			if(ATOM_CHECK(d->buffer, "mdat") == 0)
			{
				mdat_pos = count;
				if(moov_pos > 0)
					break;
			}

			/* Go to next atom */
			stream_seek(d->stream, size, SEEK_CUR);
		}
		/* Update read bytes count */
		count += size;
	}

	/* Check if a valid mp4 file and have found a mp4a track */
	if(mdat_pos == 0 || d->track_found == 0)
		return -1;

	/* Go to first frame */
	if(d->stsz_sample_size != 0)
		d->cur_sample_size = d->stsz_sample_size;
	else
		d->cur_sample_size = d->stsz_table[0];
	d->cur_sample = 0;
	d->cur_chunk_sample = 0;
	d->cur_chunk_idx = 0;
	d->cur_chunk = 0;
	d->cur_offset = d->stco_chunk_offset[0];

	/* Fill format */
	d->format.samplerate = d->mp4a_samplerate;
	d->format.channels = d->mp4a_channel_count;
	d->format.bitrate = d->esds_avg_bitrate / 1000;
	d->format.title = d->title;
	d->format.artist = d->artist;
	d->format.album = d->album;
	d->format.comment = d->comment;
	d->format.genre = d->genre;
	d->format.track = d->track;
	d->format.total_track = d->total_track;
	if(d->year != NULL)
		d->format.year = strtol(d->year, NULL, 10);
	d->format.picture.data = d->pic;
	d->format.picture.mime = d->pic_mime;
	d->format.picture.size = d->pic_len;

	/* Calculate stream duration */
	if(d->mdhd_time_scale != 0)
		d->format.length = d->mdhd_duration / d->mdhd_time_scale;

	/* Update samplerate and channels */
	*samplerate = d->mp4a_samplerate;
	*channels = d->mp4a_channel_count;

	return 0;
}