diff options
author | Christophe Fergeau <cfergeau@redhat.com> | 2014-11-21 11:01:17 +0100 |
---|---|---|
committer | Christophe Fergeau <cfergeau@redhat.com> | 2014-12-03 11:31:17 +0100 |
commit | 1876971442ef808b5dcdaa5dc12df617f2179cb5 (patch) | |
tree | 54cdeb35593396e8319ae079f900a18808fb201a /client/playback_channel.cpp | |
parent | b532ef0866cefe260ad0f08550f7c40d3580d0d7 (diff) | |
download | spice-1876971442ef808b5dcdaa5dc12df617f2179cb5.tar.gz spice-1876971442ef808b5dcdaa5dc12df617f2179cb5.tar.xz spice-1876971442ef808b5dcdaa5dc12df617f2179cb5.zip |
client: Remove client code
The client has been superseded by virt-viewer (
http://virt-manager.org/download/sources/virt-viewer/ ) and is no longer
being maintained.
Diffstat (limited to 'client/playback_channel.cpp')
-rw-r--r-- | client/playback_channel.cpp | 364 |
1 files changed, 0 insertions, 364 deletions
diff --git a/client/playback_channel.cpp b/client/playback_channel.cpp deleted file mode 100644 index 9f8c334c..00000000 --- a/client/playback_channel.cpp +++ /dev/null @@ -1,364 +0,0 @@ -/* - Copyright (C) 2009 Red Hat, Inc. - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, see <http://www.gnu.org/licenses/>. -*/ -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include "common.h" -#include "red_client.h" -#include "audio_channels.h" -#include "audio_devices.h" - -//#define WAVE_CAPTURE -#ifdef WAVE_CAPTURE - -#include <fcntl.h> - -#define WAVE_BUF_SIZE (1024 * 1024 * 20) - -typedef struct __attribute__ ((__packed__)) ChunkHeader { - uint32_t id; - uint32_t size; -} ChunkHeader; - -typedef struct __attribute__ ((__packed__)) FormatInfo { - uint16_t compression_code; - uint16_t num_channels; - uint32_t sample_rate; - uint32_t average_bytes_per_second; - uint16_t block_align; - uint16_t bits_per_sample; - //uint16_t extra_format_bytes; - //uint8_t extra[0]; -} FormatInfo; - -static uint8_t* wave_buf = NULL; -static uint8_t* wave_now = NULL; -static uint8_t* wave_end = NULL; -static bool wave_blocked = false; - -static void write_all(int fd, uint8_t* data, uint32_t size) -{ - while (size) { - int n = write(fd, data, size); - if (n == -1) { - if (errno != EINTR) { - throw Exception(fmt("%s: failed") % __FUNCTION__); - } - } else { - data += n; - size -= n; - } - } -} - -static void write_wave() -{ - static uint32_t file_id = 0; - char file_name[100]; - ChunkHeader header; - FormatInfo format; - - if (wave_buf == wave_now) { - return; - } - - sprintf(file_name, "/tmp/%u.wav", ++file_id); - int fd = open(file_name, O_CREAT | O_TRUNC | O_WRONLY, 0644); - if (fd == -1) { - DBG(0, fmt("open file %s failed") % file_name); - return; - } - - memcpy((char *)&header.id, "RIFF", 4); - header.size = 4; - write_all(fd, (uint8_t *)&header, sizeof(header)); - write_all(fd, (uint8_t *)"WAVE", 4); - - memcpy((char *)&header.id, "fmt ", 4); - header.size = sizeof(format); - write_all(fd, (uint8_t *)&header, sizeof(header)); - - format.compression_code = 1; - format.num_channels = 2; - format.sample_rate = 44100; - format.average_bytes_per_second = format.sample_rate * 4; - format.block_align = 4; - format.bits_per_sample = 16; - write_all(fd, (uint8_t *)&format, sizeof(format)); - - memcpy((char *)&header.id, "data", 4); - header.size = wave_now - wave_buf; - write_all(fd, (uint8_t *)&header, sizeof(header)); - write_all(fd, wave_buf, header.size); - close(fd); -} - -static void init_wave() -{ - if (!wave_buf) { - wave_buf = new uint8_t[WAVE_BUF_SIZE]; - } - wave_now = wave_buf; - wave_end = wave_buf + WAVE_BUF_SIZE; -} - -static void start_wave() -{ - wave_blocked = false; - wave_now = wave_buf; -} - -static void put_wave_data(uint8_t *data, uint32_t size) -{ - if (wave_blocked || size > wave_end - wave_now) { - wave_blocked = true; - return; - } - memcpy((void *)wave_now, (void *)data, size); - wave_now += size; -} - -static void end_wave() -{ - write_wave(); -} - -#endif - -class PlaybackHandler: public MessageHandlerImp<PlaybackChannel, SPICE_CHANNEL_PLAYBACK> { -public: - PlaybackHandler(PlaybackChannel& channel) - : MessageHandlerImp<PlaybackChannel, SPICE_CHANNEL_PLAYBACK>(channel) {} -}; - -PlaybackChannel::PlaybackChannel(RedClient& client, uint32_t id) - : RedChannel(client, SPICE_CHANNEL_PLAYBACK, id, new PlaybackHandler(*this), - Platform::PRIORITY_HIGH) - , _wave_player (NULL) - , _mode (SPICE_AUDIO_DATA_MODE_INVALID) - , _codec(NULL) - , _playing (false) -{ -#ifdef WAVE_CAPTURE - init_wave(); -#endif - PlaybackHandler* handler = static_cast<PlaybackHandler*>(get_message_handler()); - - handler->set_handler(SPICE_MSG_MIGRATE, &PlaybackChannel::handle_migrate); - handler->set_handler(SPICE_MSG_SET_ACK, &PlaybackChannel::handle_set_ack); - handler->set_handler(SPICE_MSG_PING, &PlaybackChannel::handle_ping); - handler->set_handler(SPICE_MSG_WAIT_FOR_CHANNELS, &PlaybackChannel::handle_wait_for_channels); - handler->set_handler(SPICE_MSG_DISCONNECTING, &PlaybackChannel::handle_disconnect); - handler->set_handler(SPICE_MSG_NOTIFY, &PlaybackChannel::handle_notify); - - handler->set_handler(SPICE_MSG_PLAYBACK_MODE, &PlaybackChannel::handle_mode); - - if (snd_codec_is_capable(SPICE_AUDIO_DATA_MODE_CELT_0_5_1, SND_CODEC_ANY_FREQUENCY)) - set_capability(SPICE_PLAYBACK_CAP_CELT_0_5_1); - if (snd_codec_is_capable(SPICE_AUDIO_DATA_MODE_OPUS, SND_CODEC_ANY_FREQUENCY)) - set_capability(SPICE_PLAYBACK_CAP_OPUS); -} - -void PlaybackChannel::clear() -{ - if (_wave_player) { - _playing = false; - _wave_player->stop(); - delete _wave_player; - _wave_player = NULL; - } - _mode = SPICE_AUDIO_DATA_MODE_INVALID; - - snd_codec_destroy(&_codec); -} - -void PlaybackChannel::on_disconnect() -{ - clear(); -} - -PlaybackChannel::~PlaybackChannel(void) -{ - clear(); -} - -bool PlaybackChannel::abort(void) -{ - return (!_wave_player || _wave_player->abort()) && RedChannel::abort(); -} - -void PlaybackChannel::set_data_handler() -{ - PlaybackHandler* handler = static_cast<PlaybackHandler*>(get_message_handler()); - - if (_mode == SPICE_AUDIO_DATA_MODE_RAW) { - handler->set_handler(SPICE_MSG_PLAYBACK_DATA, &PlaybackChannel::handle_raw_data); - } else if (snd_codec_is_capable(_mode, SND_CODEC_ANY_FREQUENCY)) { - handler->set_handler(SPICE_MSG_PLAYBACK_DATA, &PlaybackChannel::handle_compressed_data); - } else { - THROW("invalid mode"); - } - -} - -void PlaybackChannel::handle_mode(RedPeer::InMessage* message) -{ - SpiceMsgPlaybackMode* playback_mode = (SpiceMsgPlaybackMode*)message->data(); - if (playback_mode->mode != SPICE_AUDIO_DATA_MODE_RAW - && !snd_codec_is_capable(playback_mode->mode, SND_CODEC_ANY_FREQUENCY) ) { - THROW("invalid mode"); - } - - _mode = playback_mode->mode; - if (_playing) { - set_data_handler(); - return; - } - - PlaybackHandler* handler = static_cast<PlaybackHandler*>(get_message_handler()); - handler->set_handler(SPICE_MSG_PLAYBACK_START, &PlaybackChannel::handle_start); -} - -void PlaybackChannel::null_handler(RedPeer::InMessage* message) -{ -} - -void PlaybackChannel::disable() -{ - PlaybackHandler* handler = static_cast<PlaybackHandler*>(get_message_handler()); - - handler->set_handler(SPICE_MSG_PLAYBACK_START, &PlaybackChannel::null_handler); - handler->set_handler(SPICE_MSG_PLAYBACK_STOP, &PlaybackChannel::null_handler); - handler->set_handler(SPICE_MSG_PLAYBACK_MODE, &PlaybackChannel::null_handler); - handler->set_handler(SPICE_MSG_PLAYBACK_DATA, &PlaybackChannel::null_handler); -} - -void PlaybackChannel::handle_start(RedPeer::InMessage* message) -{ - PlaybackHandler* handler = static_cast<PlaybackHandler*>(get_message_handler()); - SpiceMsgPlaybackStart* start = (SpiceMsgPlaybackStart*)message->data(); - - handler->set_handler(SPICE_MSG_PLAYBACK_START, NULL); - handler->set_handler(SPICE_MSG_PLAYBACK_STOP, &PlaybackChannel::handle_stop); - -#ifdef WAVE_CAPTURE - start_wave(); -#endif - if (!_wave_player) { - if (start->format != SPICE_AUDIO_FMT_S16) { - THROW("unexpected format"); - } - if (start->channels != 2) { - THROW("unexpected number of channels"); - } - int bits_per_sample = 16; - int frame_size = SND_CODEC_MAX_FRAME_SIZE; - - if (_mode != SPICE_AUDIO_DATA_MODE_RAW) { - if (snd_codec_create(&_codec, _mode, start->frequency, SND_CODEC_DECODE) != SND_CODEC_OK) - THROW("create decoder"); - frame_size = snd_codec_frame_size(_codec); - } - - try { - _wave_player = Platform::create_player(start->frequency, bits_per_sample, - start->channels, frame_size); - } catch (...) { - LOG_WARN("create player failed"); - //todo: support disconnecting single channel - disable(); - return; - } - - _frame_bytes = frame_size * start->channels * bits_per_sample / 8; - } - _playing = true; - _frame_count = 0; - set_data_handler(); -} - -void PlaybackChannel::handle_stop(RedPeer::InMessage* message) -{ - PlaybackHandler* handler = static_cast<PlaybackHandler*>(get_message_handler()); - - handler->set_handler(SPICE_MSG_PLAYBACK_STOP, NULL); - handler->set_handler(SPICE_MSG_PLAYBACK_DATA, NULL); - handler->set_handler(SPICE_MSG_PLAYBACK_START, &PlaybackChannel::handle_start); - -#ifdef WAVE_CAPTURE - end_wave(); -#endif - _wave_player->stop(); - _playing = false; -} - -void PlaybackChannel::handle_raw_data(RedPeer::InMessage* message) -{ - SpiceMsgPlaybackPacket* packet = (SpiceMsgPlaybackPacket*)message->data(); - uint8_t* data = packet->data; - uint32_t size = packet->data_size; -#ifdef WAVE_CAPTURE - put_wave_data(data, size); - return; -#endif - if (size != _frame_bytes) { - //for now throw on unexpected size (based on current server imp). - // will probably be replaced by supporting flexible data size in the player imp - THROW("unexpected frame size"); - } - if ((_frame_count++ % 1000) == 0) { - get_client().set_mm_time(packet->time - _wave_player->get_delay_ms()); - } - _wave_player->write(data); -} - -void PlaybackChannel::handle_compressed_data(RedPeer::InMessage* message) -{ - SpiceMsgPlaybackPacket* packet = (SpiceMsgPlaybackPacket*)message->data(); - uint8_t* data = packet->data; - uint32_t size = packet->data_size; - int pcm_size = _frame_bytes; - uint8_t pcm[_frame_bytes]; - - if (snd_codec_decode(_codec, data, size, pcm, &pcm_size) != SND_CODEC_OK) - THROW("decode failed"); -#ifdef WAVE_CAPTURE - put_wave_data(pcm, _frame_bytes); - return; -#endif - if ((_frame_count++ % 1000) == 0) { - get_client().set_mm_time(packet->time - _wave_player->get_delay_ms()); - } - _wave_player->write((uint8_t *)pcm); -} - -class PlaybackFactory: public ChannelFactory { -public: - PlaybackFactory() : ChannelFactory(SPICE_CHANNEL_PLAYBACK) {} - virtual RedChannel* construct(RedClient& client, uint32_t id) - { - return new PlaybackChannel(client, id); - } -}; - -static PlaybackFactory factory; - -ChannelFactory& PlaybackChannel::Factory() -{ - return factory; -} |