diff options
author | Laxmikant Rashinkar <LK.Rashinkar@gmail.com> | 2012-12-09 04:55:58 +0400 |
---|---|---|
committer | Laxmikant Rashinkar <LK.Rashinkar@gmail.com> | 2012-12-09 04:55:58 +0400 |
commit | 9cfbd4611489eb37d518a547a5c92e2273339070 (patch) | |
tree | ad28fe284b6bfd2bea8685b6f4b6e6e9b3bffe42 | |
parent | 53357fabd181e15b16d474d25e3906e3458b1413 (diff) |
o development checkin with changes to video redirection
-rw-r--r-- | channels/xrdpvr/xrdpvr_main.c | 373 | ||||
-rw-r--r-- | channels/xrdpvr/xrdpvr_main.h | 1 | ||||
-rw-r--r-- | channels/xrdpvr/xrdpvr_player.c | 54 | ||||
-rw-r--r-- | channels/xrdpvr/xrdpvr_player.h | 1 |
4 files changed, 241 insertions, 188 deletions
diff --git a/channels/xrdpvr/xrdpvr_main.c b/channels/xrdpvr/xrdpvr_main.c index 10ce11e..1fc9fdf 100644 --- a/channels/xrdpvr/xrdpvr_main.c +++ b/channels/xrdpvr/xrdpvr_main.c @@ -45,6 +45,8 @@ #include "xrdpvr_audio.h" #include "xrdpvr_player.h" +#define DEBUG_XRDPVR(x...) //printf(x) + struct xrdpvr_plugin { rdpSvcPlugin plugin; @@ -59,6 +61,8 @@ struct xrdpvr_plugin void* g_psi = NULL; /* player state info */ int g_meta_data_fd; /* media meta data file */ +void xrdpvr_process_command(rdpSvcPlugin *plugin, STREAM *data_in); + #if 0 static void xrdpvr_process_interval(rdpSvcPlugin *plugin) { @@ -71,239 +75,262 @@ static void xrdpvr_process_interval(rdpSvcPlugin *plugin) static void xrdpvr_process_receive(rdpSvcPlugin *plugin, STREAM *data_in) { xrdpvrPlugin* xrdpvr = (xrdpvrPlugin *) plugin; - STREAM* s; - int rv; - int bytes_to_process; - int i; - uint32 cmd; - uint32 data_len; - uint32 tmp; - uint8* decoded_data; - uint32 uncompressed_size; + + int bytes_to_process; /* bytes to process */ + int cmd_len; /* # bytes required by current cmd */ + int i; if (xrdpvr == NULL) { + DEBUG_XRDPVR("xrdpvr_process_receive: returning coz xrdpvr is NULL\n"); stream_free(data_in); return; } - if (stream_get_size(data_in) <= 0) + if ((bytes_to_process = stream_get_size(data_in)) <= 0) { stream_free(data_in); return; } -start: - if (xrdpvr->got_partial_data) { - /* previous pkt was fragmented and could not be processed; */ - /* if we have enough data, process it now, else defer */ - /* processing till next pkt */ + /* handle pkt fragmentation */ - /* how much additional data did we get? */ - int data_in_len = data_in->size; + if (xrdpvr->bytes_needed < 0) + { + /* cannot compute cmd len bcoz xrdpvr->s contains */ + /* less than 4 bytes; copy required # of bytes to */ + /* xrdpvr->s so we have exactly 4 bytes in it */ + i = 4 - (xrdpvr->s->p - xrdpvr->s->data); + memcpy(xrdpvr->s->p, data_in->p, i); + xrdpvr->s->p += i; + data_in->p += i; + bytes_to_process -= i; + + /* now we can read cmd len from xrdpvr->s and process */ + /* the data from data_in */ + stream_read_uint32(xrdpvr->s, cmd_len); + xrdpvr->got_partial_data = 0; + xrdpvr->bytes_needed = 0; + goto label1; + } + else + { + if (bytes_to_process < xrdpvr->bytes_needed) + { + /* we still don't have enough data; save */ + /* current data and wait for next pkt */ + memcpy(xrdpvr->s->p, data_in->p, bytes_to_process); + xrdpvr->s->p += bytes_to_process; + xrdpvr->bytes_needed -= bytes_to_process; + stream_free(data_in); + return; + } -#ifdef DEBUG_FRAGMENTS - printf("### partial_pkt has %d bytes\n", data_in_len); -#endif - /* append new data to old */ - memcpy(xrdpvr->s->p, data_in->p, data_in_len); - xrdpvr->s->p += data_in_len; + /* we have enough data to process cmd */ + memcpy(xrdpvr->s->p, data_in->p, xrdpvr->bytes_needed); + xrdpvr->s->p = xrdpvr->s->data; + bytes_to_process -= xrdpvr->bytes_needed; + xrdpvr->bytes_needed = 0; + xrdpvr->got_partial_data = 0; + xrdpvr_process_command(plugin, xrdpvr->s); + } + } - if (data_in_len < xrdpvr->bytes_needed) + while (bytes_to_process > 0) + { + if (bytes_to_process < 4) { - /* we still don't have enough data */ - xrdpvr->bytes_needed -= data_in_len; + /* not enough data to determine cmd len */ + xrdpvr->bytes_needed = -1; + xrdpvr->got_partial_data = 1; + xrdpvr->s->p = xrdpvr->s->data; + memcpy(xrdpvr->s->p, data_in->p, bytes_to_process); + xrdpvr->s->p += bytes_to_process; stream_free(data_in); return; } - /* we have enough data */ - xrdpvr->bytes_needed = 0; - xrdpvr->got_partial_data = 0; - bytes_to_process = stream_get_length(xrdpvr->s); - stream_set_pos(xrdpvr->s, 4); /* point to cmd */ - s = xrdpvr->s; - -#ifdef DEBUG_FRAGMENTS - printf("### pkt complete; bytes_to_process=%d bytes\n", bytes_to_process); -#endif - } - else - { - stream_read_uint32(data_in, data_len); - - if ((data_in->size - 4) < data_len) + /* get # bytes required by current cmd */ + stream_read_uint32(data_in, cmd_len); + bytes_to_process -= 4; +label1: + if (bytes_to_process >= cmd_len) { -#ifdef DEBUG_FRAGMENTS - printf("### pkt is fragmented; this pkt has %d bytes\n", data_len); -#endif + /* we have enough data to process this cmd */ + xrdpvr_process_command(plugin, data_in); + bytes_to_process -= cmd_len; + } + else + { + /* we need more data to process this cmd */ + xrdpvr->bytes_needed = cmd_len - bytes_to_process; + xrdpvr->got_partial_data = 1; - /* got a fragmented pkt - save it for later processing */ + /* save residual data */ xrdpvr->s->p = xrdpvr->s->data; - memcpy(xrdpvr->s->p, data_in->data, data_in->size); - xrdpvr->s->p += data_in->size; - xrdpvr->got_partial_data = 1; - xrdpvr->bytes_needed = data_len - (data_in->size - 4); + memcpy(xrdpvr->s->p, data_in->p, bytes_to_process); + xrdpvr->s->p += bytes_to_process; stream_free(data_in); return; } - - /* got complete pkt */ -#ifdef DEBUG_FRAGMENTS - printf("### pkt is NOT fragmented and has %d bytes\n", data_len); -#endif - xrdpvr->got_partial_data = 0; - xrdpvr->bytes_needed = 0; - s = data_in; } + stream_free(data_in); +} + +void xrdpvr_process_command(rdpSvcPlugin *plugin, STREAM *s) +{ + xrdpvrPlugin* xrdpvr = (xrdpvrPlugin *) plugin; + uint32 cmd; + uint32 tmp; + uint32 xpos = 0; + uint32 ypos = 0; + uint32 data_len; + uint8* decoded_data; + uint32 uncompressed_size; + int width = 0; + int height = 0; + int rv; + stream_read_uint32(s, cmd); switch (cmd) { - case CMD_SEND_AUDIO_DATA: - stream_read_uint32(s, tmp); /* stream id */ - stream_read_uint32(s, data_len); - - /* send decoded data to ALSA */ - if (xrdpvr->audio_inited) - { - /* TODO check for return */ - process_audio(g_psi, s->p, data_len); - s->p += data_len; - - decoded_data = get_decoded_audio_data(g_psi, - &uncompressed_size); - - if ((decoded_data == NULL) || - (uncompressed_size == 0)) - { - break; - } - - (xrdpvr->audio_device->Play)(xrdpvr->audio_device, - decoded_data, - uncompressed_size); - } - - break; - - case CMD_SEND_VIDEO_DATA: - stream_read_uint32(s, tmp); /* stream id */ - stream_read_uint32(s, data_len); + case CMD_SEND_AUDIO_DATA: + DEBUG_XRDPVR("###### got CMD_SEND_AUDIO_DATA\n"); + stream_read_uint32(s, tmp); /* stream id */ + stream_read_uint32(s, data_len); + /* send decoded data to ALSA */ + if (xrdpvr->audio_inited) + { /* TODO check for return */ - process_video(g_psi, s->p, data_len); + process_audio(g_psi, s->p, data_len); s->p += data_len; - /* TODO do we need this: av_free_packet(&av_pkt); */ - break; - - case CMD_SET_VIDEO_FORMAT: - stream_read_uint32(s, tmp); /* stream id */ - g_psi = init_player((void *) plugin, META_DATA_FILEAME); + decoded_data = get_decoded_audio_data(g_psi, + &uncompressed_size); - if (g_psi == NULL) + if ((decoded_data == NULL) || + (uncompressed_size == 0)) { - printf("init_player() failed\n"); + break; } - break; - - case CMD_SET_AUDIO_FORMAT: - stream_read_uint32(s, tmp); /* stream id */ - - if (xrdpvr->audio_inited) - { - int samp_per_sec; - int num_channels; - int bits_per_samp; - - get_audio_config(g_psi, &samp_per_sec, - &num_channels, &bits_per_samp); - - rv = (xrdpvr->audio_device->SetFormat)(xrdpvr->audio_device, - samp_per_sec, - num_channels, - bits_per_samp); - - if (!rv) - { - DEBUG_WARN("ERROR setting audio format\n"); - } - } + (xrdpvr->audio_device->Play)(xrdpvr->audio_device, + decoded_data, + uncompressed_size); + } - break; + break; + + case CMD_SEND_VIDEO_DATA: + DEBUG_XRDPVR("###### got CMD_SEND_VIDEO_DATA\n"); + stream_read_uint32(s, tmp); /* stream id */ + stream_read_uint32(s, data_len); + + /* TODO check for return */ + process_video(g_psi, s->p, data_len); + s->p += data_len; + + /* TODO do we need this: av_free_packet(&av_pkt); */ + break; + + case CMD_SET_GEOMETRY: + DEBUG_XRDPVR("###### got CMD_SET_GEOMETRY\n"); + stream_read_uint32(s, tmp); /* stream id */ + stream_read_uint32(s, xpos); + stream_read_uint32(s, ypos); + stream_read_uint32(s, width); + stream_read_uint32(s, height); + set_geometry(g_psi, xpos, ypos, width, height); + break; + + case CMD_SET_VIDEO_FORMAT: + DEBUG_XRDPVR("###### got CMD_SET_VIDEO_FORMAT\n"); + stream_read_uint32(s, tmp); /* stream id */ + g_psi = init_player((void *) plugin, META_DATA_FILEAME); + if (g_psi == NULL) + { + printf("init_player() failed\n"); + } - case CMD_CREATE_META_DATA_FILE: + break; - if ((g_meta_data_fd = open(META_DATA_FILEAME, - O_RDWR | O_CREAT | O_TRUNC, - 0755)) < 0) - { - DEBUG_WARN("ERROR opening %s; " - "video redirection disabled!\n", - META_DATA_FILEAME); - } + case CMD_SET_AUDIO_FORMAT: + DEBUG_XRDPVR("###### got CMD_SET_AUDIO_FORMAT\n"); + stream_read_uint32(s, tmp); /* stream id */ - break; + if (xrdpvr->audio_inited) + { + int samp_per_sec; + int num_channels; + int bits_per_samp; - case CMD_CLOSE_META_DATA_FILE: - close(g_meta_data_fd); - break; + get_audio_config(g_psi, &samp_per_sec, + &num_channels, &bits_per_samp); - case CMD_WRITE_META_DATA: - stream_read_uint32(s, data_len); + rv = (xrdpvr->audio_device->SetFormat)(xrdpvr->audio_device, + samp_per_sec, + num_channels, + bits_per_samp); - if ((rv = write(g_meta_data_fd, s->p, data_len)) != data_len) + if (!rv) { - close(g_meta_data_fd); - g_meta_data_fd = -1; - DEBUG_WARN("ERROR writing to %s; " - "video redirection disabled!\n", - META_DATA_FILEAME); + DEBUG_WARN("ERROR setting audio format\n"); } + } - s->p += data_len; - break; + break; - case CMD_DEINIT_XRDPVR: - stream_read_uint32(s, tmp); /* stream id */ - deinit_player(g_psi); - break; + case CMD_CREATE_META_DATA_FILE: + DEBUG_XRDPVR("###### got CMD_CREATE_META_DATA_FILE\n"); + if ((g_meta_data_fd = open(META_DATA_FILEAME, + O_RDWR | O_CREAT | O_TRUNC, + 0755)) < 0) + { + DEBUG_WARN("ERROR opening %s; " + "video redirection disabled!\n", + META_DATA_FILEAME); + } - default: - printf("### got unknown command 0x%x %d(.)\n", cmd, cmd); - break; - } + break; - if (s == xrdpvr->s) - { - /* we just finished processing a fragmented pkt; */ - /* did we get part of the next command as well? */ + case CMD_CLOSE_META_DATA_FILE: + DEBUG_XRDPVR("###### got CMD_CLOSE_META_DATA_FILE\n"); + close(g_meta_data_fd); + break; - i = stream_get_length(xrdpvr->s); + case CMD_WRITE_META_DATA: + DEBUG_XRDPVR("###### got CMD_WRITE_META_DATA\n"); + stream_read_uint32(s, data_len); - if (bytes_to_process > i) + if ((rv = write(g_meta_data_fd, s->p, data_len)) != data_len) { - /* yes we did - copy this to data_in and start all over */ -#ifdef DEBUG_FRAGMENTS - printf("### xrdpvr_process_receive: got part of next command\n"); - printf("### xrdpvr_process_receive: bytes_to_process=%d diff=%d\n", - bytes_to_process, bytes_to_process - i); -#endif - memcpy(data_in->data, s->p, bytes_to_process - i); - data_in->p = data_in->data; - xrdpvr->got_partial_data = 0; - xrdpvr->bytes_needed = 0; - bytes_to_process = 0; - goto start; + close(g_meta_data_fd); + g_meta_data_fd = -1; + DEBUG_WARN("ERROR writing to %s; " + "video redirection disabled!\n", + META_DATA_FILEAME); } + + s->p += data_len; + break; + + case CMD_DEINIT_XRDPVR: + DEBUG_XRDPVR("###### got CMD_DEINIT_XRDPVR\n"); + stream_read_uint32(s, tmp); /* stream id */ + deinit_player(g_psi); + break; + + default: + // LK_TODO change to DEBUG_XRDPVR + printf("### got unknown command 0x%x %d(.)\n", cmd, cmd); + break; } - stream_free(data_in); } /* @@ -324,7 +351,7 @@ static void xrdpvr_process_connect(rdpSvcPlugin *plugin_p) #endif /* setup stream */ - plugin->s = stream_new(1024 * 1024); + plugin->s = stream_new(1024 * 1024 * 2); plugin->got_partial_data = 0; plugin->bytes_needed = 0; diff --git a/channels/xrdpvr/xrdpvr_main.h b/channels/xrdpvr/xrdpvr_main.h index 6251e97..bbcb7f5 100644 --- a/channels/xrdpvr/xrdpvr_main.h +++ b/channels/xrdpvr/xrdpvr_main.h @@ -30,6 +30,7 @@ typedef struct xrdpvr_plugin xrdpvrPlugin; #define CMD_CLOSE_META_DATA_FILE 6 #define CMD_WRITE_META_DATA 7 #define CMD_DEINIT_XRDPVR 8 +#define CMD_SET_GEOMETRY 9 /* TODO need to support Windows paths */ #define META_DATA_FILEAME "/tmp/xrdpvr_metadata.dat" diff --git a/channels/xrdpvr/xrdpvr_player.c b/channels/xrdpvr/xrdpvr_player.c index 5ddac40..a5990db 100644 --- a/channels/xrdpvr/xrdpvr_player.c +++ b/channels/xrdpvr/xrdpvr_player.c @@ -54,6 +54,10 @@ typedef struct player_state_info void *plugin; int player_inited; + int xpos; + int ypos; + int width; + int height; } PLAYER_STATE_INFO; /* forward declarations local to this file */ @@ -76,20 +80,18 @@ init_player(void *plugin, char *filename) int audio_index = -1; int i; + printf("############# init_player() entered\n"); + /* to hold player state information */ psi = (PLAYER_STATE_INFO *) calloc(1, sizeof(PLAYER_STATE_INFO)); if (psi == NULL) - { return NULL; - } psi->plugin = plugin; if ((g_meta_data_fd < 0) || (does_file_exist(filename) == 0)) - { return NULL; - } /* register all available fileformats and codecs */ av_register_all(); @@ -108,7 +110,8 @@ init_player(void *plugin, char *filename) goto bailout1; } -#if 0 +// LK_TODO +#if 1 /* display basic media info */ av_dump_format(psi->format_ctx, 0, filename, 0); #endif @@ -149,7 +152,6 @@ init_player(void *plugin, char *filename) /* find decoder for audio stream */ psi->audio_codec = avcodec_find_decoder(psi->audio_codec_ctx->codec_id); - if (psi->audio_codec == NULL) { DEBUG_WARN("xrdp_player.c:init_player: " @@ -159,7 +161,6 @@ init_player(void *plugin, char *filename) /* find decoder for video stream */ psi->video_codec = avcodec_find_decoder(psi->video_codec_ctx->codec_id); - if (psi->video_codec == NULL) { DEBUG_WARN("xrdp_player.c:init_player: " @@ -317,6 +318,24 @@ get_audio_config(void *vp, int *samp_per_sec, int *num_channels, int *bits_per_s } } +void +set_geometry(void *vp, int xpos, int ypos, int width, int height) +{ + PLAYER_STATE_INFO *psi = (PLAYER_STATE_INFO *) vp; + + printf("set_geometry: x=%d y=%d with=%d height=%d\n", xpos, ypos, width, height); + if ((psi == NULL) || (!psi->player_inited)) + { + DEBUG_WARN("xrdpvr player is NULL or not inited"); + return; + } + + psi->xpos = xpos; + psi->ypos = ypos; + psi->width = width; + psi->height = height; +} + /******************************************************************************* functions local to this file *******************************************************************************/ @@ -327,7 +346,7 @@ static int play_video(PLAYER_STATE_INFO *psi, AVPacket *av_pkt) { AVFrame *frame; - int len; + int len = -1; int got_frame; if ((psi == NULL) || (!psi->player_inited)) @@ -339,7 +358,6 @@ play_video(PLAYER_STATE_INFO *psi, AVPacket *av_pkt) /* TODO need to handle older versions - see Vic's code */ len = avcodec_decode_video2(psi->video_codec_ctx, psi->video_frame, &got_frame, av_pkt); - if (len < 0) { DEBUG_WARN("xrdp_player.c:play_video: frame decode error\n"); @@ -418,11 +436,17 @@ display_picture(PLAYER_STATE_INFO *psi) vevent->frame_width = width; vevent->frame_height = height; - /* TODO these hard coded values need to change */ - vevent->x = 0; - vevent->y = 0; + //printf("display: x=%d y=%d with=%d height=%d\n", psi->xpos, psi->ypos, psi->width, psi->height); + + vevent->x = psi->xpos; + vevent->y = psi->ypos; +#if 0 vevent->width = psi->video_codec_ctx->width; vevent->height = psi->video_codec_ctx->height; +#else + vevent->width = psi->width; + vevent->height = psi->height; +#endif vevent->num_visible_rects = 1; vevent->visible_rects = xmalloc(sizeof(RDP_RECT)); vevent->visible_rects->x = 0; @@ -487,7 +511,7 @@ get_decoded_video_format(PLAYER_STATE_INFO *psi) static int play_audio(PLAYER_STATE_INFO *psi, AVPacket *av_pkt) { - int len; + int len = 0; int frame_size; uint32_t src_size; int dst_offset; @@ -546,11 +570,11 @@ play_audio(PLAYER_STATE_INFO *psi, AVPacket *av_pkt) av_init_packet(&pkt); pkt.data = (uint8_t *) src; pkt.size = src_size; - +#if 1 len = avcodec_decode_audio4(psi->audio_codec_ctx, decoded_frame, &got_frame, &pkt); - +#endif if (len >= 0 && got_frame) { frame_size = av_samples_get_buffer_size(NULL, diff --git a/channels/xrdpvr/xrdpvr_player.h b/channels/xrdpvr/xrdpvr_player.h index 13df906..d9d965c 100644 --- a/channels/xrdpvr/xrdpvr_player.h +++ b/channels/xrdpvr/xrdpvr_player.h @@ -30,5 +30,6 @@ int process_video(void *vp, uint8 *data, int data_len); int process_audio(void *vp, uint8 *data, int data_len); uint8 *get_decoded_audio_data(void *vp, uint32 *size); void get_audio_config(void *vp, int *samp_per_sec, int *num_channels, int *bits_per_samp); +void set_geometry(void *g_psi, int xpos, int ypos, int width, int height); #endif |