mirror of
https://github.com/CTCaer/RetroArch.git
synced 2024-12-22 18:58:21 +00:00
Support different forms of compression from different clients.
This commit is contained in:
parent
84c33634a6
commit
677ffa9ebd
@ -610,6 +610,59 @@ void netplay_post_frame(netplay_t *netplay)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* netplay_send_savestate
|
||||
* @netplay : pointer to netplay object
|
||||
* @serial_info : the savestate being loaded
|
||||
* @cx : compression type
|
||||
* @z : compression backend to use
|
||||
*
|
||||
* Send a loaded savestate to those connected peers using the given compression
|
||||
* scheme.
|
||||
*/
|
||||
void netplay_send_savestate(netplay_t *netplay,
|
||||
retro_ctx_serialize_info_t *serial_info, uint32_t cx,
|
||||
struct compression_transcoder *z)
|
||||
{
|
||||
uint32_t header[4];
|
||||
uint32_t rd, wn;
|
||||
size_t i;
|
||||
|
||||
/* Compress it */
|
||||
z->compression_backend->set_in(z->compression_stream,
|
||||
(const uint8_t*)serial_info->data_const, serial_info->size);
|
||||
z->compression_backend->set_out(z->compression_stream,
|
||||
netplay->zbuffer, netplay->zbuffer_size);
|
||||
if (!z->compression_backend->trans(z->compression_stream, true, &rd,
|
||||
&wn, NULL))
|
||||
{
|
||||
/* Catastrophe! */
|
||||
for (i = 0; i < netplay->connections_size; i++)
|
||||
netplay_hangup(netplay, &netplay->connections[i]);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Send it to relevant peers */
|
||||
header[0] = htonl(NETPLAY_CMD_LOAD_SAVESTATE);
|
||||
header[1] = htonl(wn + 2*sizeof(uint32_t));
|
||||
header[2] = htonl(netplay->self_frame_count);
|
||||
header[3] = htonl(serial_info->size);
|
||||
|
||||
for (i = 0; i < netplay->connections_size; i++)
|
||||
{
|
||||
struct netplay_connection *connection = &netplay->connections[i];
|
||||
if (!connection->active ||
|
||||
connection->mode < NETPLAY_CONNECTION_CONNECTED ||
|
||||
connection->compression_supported != cx) continue;
|
||||
|
||||
if (!netplay_send(&connection->send_packet_buffer, connection->fd, header,
|
||||
sizeof(header)) ||
|
||||
!netplay_send(&connection->send_packet_buffer, connection->fd,
|
||||
netplay->zbuffer, wn))
|
||||
netplay_hangup(netplay, connection);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* netplay_load_savestate
|
||||
* @netplay : pointer to netplay object
|
||||
@ -623,10 +676,7 @@ void netplay_post_frame(netplay_t *netplay)
|
||||
void netplay_load_savestate(netplay_t *netplay,
|
||||
retro_ctx_serialize_info_t *serial_info, bool save)
|
||||
{
|
||||
uint32_t header[4];
|
||||
retro_ctx_serialize_info_t tmp_serial_info;
|
||||
uint32_t rd, wn;
|
||||
size_t i;
|
||||
|
||||
/* Record it in our own buffer */
|
||||
if (save || !serial_info)
|
||||
@ -693,39 +743,12 @@ void netplay_load_savestate(netplay_t *netplay,
|
||||
| NETPLAY_QUIRK_NO_TRANSMISSION))
|
||||
return;
|
||||
|
||||
/* Compress it */
|
||||
if (!netplay->compression_backend)
|
||||
return;
|
||||
netplay->compression_backend->set_in(netplay->compression_stream,
|
||||
(const uint8_t*)serial_info->data_const, serial_info->size);
|
||||
netplay->compression_backend->set_out(netplay->compression_stream,
|
||||
netplay->zbuffer, netplay->zbuffer_size);
|
||||
if (!netplay->compression_backend->trans(netplay->compression_stream,
|
||||
true, &rd, &wn, NULL))
|
||||
{
|
||||
/* Catastrophe! */
|
||||
for (i = 0; i < netplay->connections_size; i++)
|
||||
netplay_hangup(netplay, &netplay->connections[i]);
|
||||
return;
|
||||
}
|
||||
|
||||
/* And send it to the peers */
|
||||
header[0] = htonl(NETPLAY_CMD_LOAD_SAVESTATE);
|
||||
header[1] = htonl(wn + 2*sizeof(uint32_t));
|
||||
header[2] = htonl(netplay->self_frame_count);
|
||||
header[3] = htonl(serial_info->size);
|
||||
|
||||
for (i = 0; i < netplay->connections_size; i++)
|
||||
{
|
||||
struct netplay_connection *connection = &netplay->connections[i];
|
||||
if (!connection->active || connection->mode < NETPLAY_CONNECTION_CONNECTED) continue;
|
||||
|
||||
if (!netplay_send(&connection->send_packet_buffer, connection->fd, header,
|
||||
sizeof(header)) ||
|
||||
!netplay_send(&connection->send_packet_buffer, connection->fd,
|
||||
netplay->zbuffer, wn))
|
||||
netplay_hangup(netplay, connection);
|
||||
}
|
||||
/* Send this to every peer */
|
||||
if (netplay->compress_nil.compression_backend)
|
||||
netplay_send_savestate(netplay, serial_info, 0, &netplay->compress_nil);
|
||||
if (netplay->compress_zlib.compression_backend)
|
||||
netplay_send_savestate(netplay, serial_info, NETPLAY_COMPRESSION_ZLIB,
|
||||
&netplay->compress_zlib);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -301,6 +301,7 @@ bool netplay_handshake_init(netplay_t *netplay,
|
||||
struct nick_buf_s nick_buf;
|
||||
uint32_t local_pmagic, remote_pmagic;
|
||||
uint32_t compression;
|
||||
struct compression_transcoder *ctrans;
|
||||
|
||||
dmsg = NULL;
|
||||
|
||||
@ -334,31 +335,41 @@ bool netplay_handshake_init(netplay_t *netplay,
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* Clear any existing compression */
|
||||
if (netplay->compression_stream)
|
||||
netplay->compression_backend->stream_free(netplay->compression_stream);
|
||||
if (netplay->decompression_stream)
|
||||
netplay->decompression_backend->stream_free(netplay->decompression_stream);
|
||||
|
||||
/* Check what compression is supported */
|
||||
compression = ntohl(header[2]);
|
||||
compression &= NETPLAY_COMPRESSION_SUPPORTED;
|
||||
if (compression & NETPLAY_COMPRESSION_ZLIB)
|
||||
{
|
||||
netplay->compression_backend = trans_stream_get_zlib_deflate_backend();
|
||||
if (!netplay->compression_backend)
|
||||
netplay->compression_backend = trans_stream_get_pipe_backend();
|
||||
ctrans = &netplay->compress_zlib;
|
||||
if (!ctrans->compression_backend)
|
||||
{
|
||||
ctrans->compression_backend =
|
||||
trans_stream_get_zlib_deflate_backend();
|
||||
if (!ctrans->compression_backend)
|
||||
ctrans->compression_backend = trans_stream_get_pipe_backend();
|
||||
}
|
||||
connection->compression_supported = NETPLAY_COMPRESSION_ZLIB;
|
||||
}
|
||||
else
|
||||
{
|
||||
netplay->compression_backend = trans_stream_get_pipe_backend();
|
||||
ctrans = &netplay->compress_nil;
|
||||
if (!ctrans->compression_backend)
|
||||
{
|
||||
ctrans->compression_backend =
|
||||
trans_stream_get_pipe_backend();
|
||||
}
|
||||
connection->compression_supported = 0;
|
||||
}
|
||||
netplay->decompression_backend = netplay->compression_backend->reverse;
|
||||
if (!ctrans->decompression_backend)
|
||||
ctrans->decompression_backend = ctrans->compression_backend->reverse;
|
||||
|
||||
/* Allocate our compression stream */
|
||||
netplay->compression_stream = netplay->compression_backend->stream_new();
|
||||
netplay->decompression_stream = netplay->decompression_backend->stream_new();
|
||||
if (!netplay->compression_stream || !netplay->decompression_stream)
|
||||
if (!ctrans->compression_stream)
|
||||
{
|
||||
ctrans->compression_stream = ctrans->compression_backend->stream_new();
|
||||
ctrans->decompression_stream = ctrans->decompression_backend->stream_new();
|
||||
}
|
||||
if (!ctrans->compression_stream || !ctrans->decompression_stream)
|
||||
{
|
||||
RARCH_ERR("Failed to allocate compression transcoder!\n");
|
||||
return false;
|
||||
|
@ -540,8 +540,16 @@ void netplay_free(netplay_t *netplay)
|
||||
if (netplay->zbuffer)
|
||||
free(netplay->zbuffer);
|
||||
|
||||
if (netplay->compression_stream)
|
||||
netplay->compression_backend->stream_free(netplay->compression_stream);
|
||||
if (netplay->compress_nil.compression_stream)
|
||||
{
|
||||
netplay->compress_nil.compression_backend->stream_free(netplay->compress_nil.compression_stream);
|
||||
netplay->compress_nil.decompression_backend->stream_free(netplay->compress_nil.decompression_stream);
|
||||
}
|
||||
if (netplay->compress_zlib.compression_stream)
|
||||
{
|
||||
netplay->compress_zlib.compression_backend->stream_free(netplay->compress_zlib.compression_stream);
|
||||
netplay->compress_zlib.decompression_backend->stream_free(netplay->compress_zlib.decompression_stream);
|
||||
}
|
||||
|
||||
if (netplay->addr)
|
||||
freeaddrinfo_retro(netplay->addr);
|
||||
|
@ -1013,6 +1013,7 @@ static bool netplay_get_cmd(netplay_t *netplay,
|
||||
uint32_t isize;
|
||||
uint32_t rd, wn;
|
||||
uint32_t player;
|
||||
struct compression_transcoder *ctrans;
|
||||
|
||||
/* Make sure we're ready for it */
|
||||
if (netplay->quirks & NETPLAY_QUIRK_INITIALIZATION)
|
||||
@ -1101,12 +1102,20 @@ static bool netplay_get_cmd(netplay_t *netplay,
|
||||
}
|
||||
|
||||
/* And decompress it */
|
||||
netplay->decompression_backend->set_in(netplay->decompression_stream,
|
||||
switch (connection->compression_supported)
|
||||
{
|
||||
case NETPLAY_COMPRESSION_ZLIB:
|
||||
ctrans = &netplay->compress_zlib;
|
||||
break;
|
||||
default:
|
||||
ctrans = &netplay->compress_nil;
|
||||
}
|
||||
ctrans->decompression_backend->set_in(ctrans->decompression_stream,
|
||||
netplay->zbuffer, cmd_size - 2*sizeof(uint32_t));
|
||||
netplay->decompression_backend->set_out(netplay->decompression_stream,
|
||||
ctrans->decompression_backend->set_out(ctrans->decompression_stream,
|
||||
(uint8_t*)netplay->buffer[netplay->read_ptr[connection->player]].state,
|
||||
netplay->state_size);
|
||||
netplay->decompression_backend->trans(netplay->decompression_stream,
|
||||
ctrans->decompression_backend->trans(ctrans->decompression_stream,
|
||||
true, &rd, &wn, NULL);
|
||||
|
||||
/* Skip ahead if it's past where we are */
|
||||
|
@ -274,6 +274,9 @@ struct netplay_connection
|
||||
/* Player # of connected player */
|
||||
int player;
|
||||
|
||||
/* What compression does this peer support? */
|
||||
uint32_t compression_supported;
|
||||
|
||||
/* Is this player paused? */
|
||||
bool paused;
|
||||
|
||||
@ -282,6 +285,15 @@ struct netplay_connection
|
||||
retro_time_t stall_time;
|
||||
};
|
||||
|
||||
/* Compression transcoder */
|
||||
struct compression_transcoder
|
||||
{
|
||||
const struct trans_stream_backend *compression_backend;
|
||||
void *compression_stream;
|
||||
const struct trans_stream_backend *decompression_backend;
|
||||
void *decompression_stream;
|
||||
};
|
||||
|
||||
struct netplay
|
||||
{
|
||||
/* Are we the server? */
|
||||
@ -330,10 +342,8 @@ struct netplay
|
||||
size_t buffer_size;
|
||||
|
||||
/* Compression transcoder */
|
||||
const struct trans_stream_backend *compression_backend;
|
||||
void *compression_stream;
|
||||
const struct trans_stream_backend *decompression_backend;
|
||||
void *decompression_stream;
|
||||
struct compression_transcoder compress_nil,
|
||||
compress_zlib;
|
||||
|
||||
/* A buffer into which to compress frames for transfer */
|
||||
uint8_t *zbuffer;
|
||||
|
Loading…
Reference in New Issue
Block a user