/* globals */
PLAYER_STATE_INFO g_psi; int g_video_index = -1; int g_audio_index = -1;
/*****************************************************************************/ /* produce a hex dump */ void
hexdump(char *p, int len)
{ unsignedchar *line; int i; int thisline; int offset;
line = (unsignedchar *)p;
offset = 0;
while (offset < len)
{
printf("%04x ", offset);
thisline = len - offset;
if (thisline > 16)
{
thisline = 16;
}
for (i = 0; i < thisline; i++)
{
printf("%02x ", line[i]);
}
for (; i < 16; i++)
{
printf(" ");
}
for (i = 0; i < thisline; i++)
{
printf("%c", (line[i] >= 0x20 && line[i] < 0x7f) ? line[i] : '.');
}
printf("\n");
offset += thisline;
line += thisline;
}
}
/* register all available fileformats and codecs */
av_register_all();
/* open media file - this will read just the header */ //if (avformat_open_input(&g_psi.p_format_ctx, filename, NULL, NULL)) if (av_open_input_file(&g_psi.p_format_ctx, filename, NULL, 0, NULL))
{
printf("ERROR opening %s\n", filename); return -1;
}
/* now get the real stream info */ //if (avformat_find_stream_info(g_psi.p_format_ctx, NULL) < 0) if (av_find_stream_info(g_psi.p_format_ctx) < 0)
{
printf("ERROR reading stream info\n"); return -1;
}
#if1 /* print media info to standard out */
av_dump_format(g_psi.p_format_ctx, 0, filename, 0); #endif
if ((g_audio_index < 0) || (g_video_index < 0))
{ /* close file and return with error */
printf("ERROR: no audio/video stream found in %s\n", filename); //avformat_close_input(&g_psi.p_format_ctx);
av_close_input_file(g_psi.p_format_ctx); return -1;
}
/* get pointers to codex contexts for both streams */
g_psi.p_audio_codec_ctx = g_psi.p_format_ctx->streams[g_audio_index]->codec;
g_psi.p_video_codec_ctx = g_psi.p_format_ctx->streams[g_video_index]->codec;
/* find decoder for audio stream */
g_psi.p_audio_codec =
avcodec_find_decoder(g_psi.p_audio_codec_ctx->codec_id);
if (g_psi.p_audio_codec == NULL)
{
printf("ERROR: audio codec not supported\n");
}
/* find decoder for video stream */
g_psi.p_video_codec =
avcodec_find_decoder(g_psi.p_video_codec_ctx->codec_id);
if (g_psi.p_video_codec == NULL)
{
printf("ERROR: video codec not supported\n");
}
/* open decoder for audio stream */ //if (avcodec_open2(g_psi.p_audio_codec_ctx, g_psi.p_audio_codec, // NULL) < 0) if (avcodec_open(g_psi.p_audio_codec_ctx, g_psi.p_audio_codec) < 0)
{
printf("ERROR: could not open audio decoder\n"); return -1;
}
/* open decoder for video stream */ //if (avcodec_open2(g_psi.p_video_codec_ctx, g_psi.p_video_codec, // NULL) < 0) if (avcodec_open(g_psi.p_video_codec_ctx, g_psi.p_video_codec) < 0)
{
printf("ERROR: could not open video decoder\n"); return -1;
}
/******************************************************************************/ int
xrdpvr_get_frame(void **av_pkt_ret, int *is_video_frame, int *delay_in_us)
{
AVPacket *av_pkt; double dts; int error;
AVBitStreamFilterContext *bsfc;
AVPacket new_pkt;
//printf("xrdpvr_get_frame:\n"); /* alloc an AVPacket */ if ((av_pkt = (AVPacket *) malloc(sizeof(AVPacket))) == NULL)
{ return -1;
}
/* read one frame into AVPacket */ if (av_read_frame(g_psi.p_format_ctx, av_pkt) < 0)
{
free(av_pkt); return -1;
}
if (av_pkt->stream_index == g_audio_index)
{ /* got an audio packet */
dts = av_pkt->dts;
dts *= av_q2d(g_psi.p_format_ctx->streams[g_audio_index]->time_base);
/******************************************************************************/ int
xrdpvr_play_frame(void *channel, int stream_id, int *videoTimeout, int *audioTimeout)
{
AVPacket av_pkt; double dts; int delay_in_us; int error;
AVBitStreamFilterContext *bsfc;
AVPacket new_pkt;
/******************************************************************************/ int
xrdpvr_seek_media(int64_t pos, int backward)
{
int64_t seek_target; int seek_flag;
/******************************************************************************/ int
xrdpvr_set_geometry(void *channel, int stream_id, int xpos, int ypos, int width, int height)
{
STREAM *s; char *cptr; int rv; int len;
stream_ins_u32_le(s, 0); /* number of bytes to follow */
stream_ins_u32_le(s, CMD_SET_GEOMETRY);
stream_ins_u32_le(s, stream_id);
stream_ins_u32_le(s, xpos);
stream_ins_u32_le(s, ypos);
stream_ins_u32_le(s, width);
stream_ins_u32_le(s, height);
/* insert number of bytes in stream */
len = stream_length(s) - 4;
cptr = s->p;
s->p = s->data;
stream_ins_u32_le(s, len);
s->p = cptr;
/* write data to virtual channel */
rv = xrdpvr_write_to_client(channel, s);
stream_free(s); return rv;
}
/** *setvideoformat * *@paramchannelopaquehandlereturnedbyWTSVirtualChannelOpenEx *@paramstream_iduniqueidentificationnumberforthisstream * *@return0onsuccess,-1onerror
*****************************************************************************/ int
xrdpvr_set_video_format(void *channel, uint32_t stream_id, int format, int width, int height)
{
STREAM *s; char *cptr; int rv; int len;
width = (width + 15) & ~15;
stream_new(s, MAX_PDU_SIZE);
stream_ins_u32_le(s, 0); /* number of bytes to follow */
stream_ins_u32_le(s, CMD_SET_VIDEO_FORMAT);
stream_ins_u32_le(s, stream_id);
stream_ins_u32_le(s, format);
stream_ins_u32_le(s, width);
stream_ins_u32_le(s, height);
/* insert number of bytes in stream */
len = stream_length(s) - 4;
cptr = s->p;
s->p = s->data;
stream_ins_u32_le(s, len);
s->p = cptr;
/* write data to virtual channel */
rv = xrdpvr_write_to_client(channel, s);
stream_free(s); return rv;
}
/** *setaudioformat * *@paramchannelopaquehandlereturnedbyWTSVirtualChannelOpenEx *@paramstream_iduniqueidentificationnumberforthisstream * *@return0onsuccess,-1onerror
*****************************************************************************/ int
xrdpvr_set_audio_format(void *channel, uint32_t stream_id, int format, char *extradata, int extradata_size, int sample_rate, int bit_rate, int channels, int block_align)
{
STREAM *s; char *cptr; int rv; int len;
/* send CMD_CREATE_META_DATA_FILE */
stream_ins_u32_le(s, 4); /* number of bytes to follow */
stream_ins_u32_le(s, CMD_CREATE_META_DATA_FILE);
if (xrdpvr_write_to_client(channel, s))
{
close(fd); return -1;
}
/* read first 1MB of file and send to client */
s->p = s->data;
stream_ins_u32_le(s, 0); /* number of bytes to follow */
stream_ins_u32_le(s, CMD_WRITE_META_DATA);
stream_ins_u32_le(s, 0); /* number of bytes to follow */
/* insert number of bytes in stream */
len = stream_length(s) - 4;
cptr = s->p;
s->p = s->data;
stream_ins_u32_le(s, len); /* number of bytes in this cmd */
s->p += 4;
stream_ins_u32_le(s, rv); /* number of metadata bytes */
s->p = cptr;
/* write data to virtual channel */
rv = xrdpvr_write_to_client(channel, s);
/* send CMD_CLOSE_META_DATA_FILE */
s->p = s->data;
stream_ins_u32_le(s, 4); /* number of bytes to follow */
stream_ins_u32_le(s, CMD_CLOSE_META_DATA_FILE);
if (xrdpvr_write_to_client(channel, s))
{
close(fd); return -1;
}
stream_free(s); return rv;
}
/**
******************************************************************************/ staticint
xrdpvr_read_from_client(void *channel, STREAM *s, int bytes, int timeout)
{ unsignedint bytes_read; int total_read; int ok;
/** *writedatatoaxrdpvrclient * *@paramchannelopaquehandlereturnedbyWTSVirtualChannelOpenEx *@paramsstructurecontainingdatatowrite * *@return0onsuccess,-1onfailure
******************************************************************************/ staticint
xrdpvr_write_to_client(void *channel, STREAM *s)
{ int bytes_to_send; int bytes_written; int index = 0; int rv;
if ((channel == NULL) || (s == NULL))
{ return -1;
}
bytes_to_send = stream_length(s);
while (1)
{
rv = WTSVirtualChannelWrite(channel, &s->data[index], bytes_to_send,
&bytes_written);
if (rv == 0)
{ return -1;
}
index += bytes_written;
bytes_to_send -= bytes_written;
usleep(1000 * 3);
}
}
/** *writesetvolumetoaxrdpvrclient * *@paramchannelopaquehandlereturnedbyWTSVirtualChannelOpenEx *@paramvolumevolume0x0000to0xffff * *@return0onsuccess,-1onfailure
******************************************************************************/ int
xrdpvr_set_volume(void *channel, int volume)
{
STREAM *s; char *cptr; int rv; int len;
stream_new(s, MAX_BUFSIZE);
stream_ins_u32_le(s, 0); /* number of bytes to follow */
stream_ins_u32_le(s, CMD_SET_VOLUME);
stream_ins_u32_le(s, volume);
/* insert number of bytes in stream */
len = stream_length(s) - 4;
cptr = s->p;
s->p = s->data;
stream_ins_u32_le(s, len);
s->p = cptr;
/* write data to virtual channel */
rv = xrdpvr_write_to_client(channel, s);
stream_free(s); return rv;
}
int
xrdpvr_send_init(void *channel)
{
STREAM *s; char *cptr; int rv; int len;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.