Bug#603699: debian spice package
On 06.05.2012 08:21, Serge E. Hallyn wrote:
> Just saw http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=671627 (someone
> forwarded it to me). Glad it seems to have worked out :) If you want
> more help pls let me know, but if you're comfortable as is that's great.
Well, it hasn't worked out yet, as I wrote in #671627 I had no
good conditions to do the work before since spice didn't work
in 32bits, and while I had a patch for some time I had no idea
if it works or not.
Yesterday I did some testing, but again I've no idea if it works
or not -- I don't know how to test sound transmitted using spice!
The current version of the patch is attached, for anyone to
experiment. I'll try to do my best afer a short vacation we all
russians have these days due to the Victory Day (World Wide War II),
I'll be back in May-10.
Thank you!
/mjt
diff --git a/client/audio_channels.h b/client/audio_channels.h
index d38a79e..8f8a186 100644
--- a/client/audio_channels.h
+++ b/client/audio_channels.h
@@ -18,7 +18,9 @@
#ifndef _H_AUDIO_CHANNELS
#define _H_AUDIO_CHANNELS
+#if HAVE_CELT051
#include <celt051/celt.h>
+#endif
#include "red_channel.h"
#include "debug.h"
@@ -45,7 +47,9 @@ private:
void handle_start(RedPeer::InMessage* message);
void handle_stop(RedPeer::InMessage* message);
void handle_raw_data(RedPeer::InMessage* message);
+#if HAVE_CELT051
void handle_celt_data(RedPeer::InMessage* message);
+#endif
void null_handler(RedPeer::InMessage* message);
void disable();
@@ -57,8 +61,10 @@ private:
WavePlaybackAbstract* _wave_player;
uint32_t _mode;
uint32_t _frame_bytes;
+#if HAVE_CELT051
CELTMode *_celt_mode;
CELTDecoder *_celt_decoder;
+#endif
bool _playing;
uint32_t _frame_count;
};
@@ -96,8 +102,10 @@ private:
Mutex _messages_lock;
std::list<RecordSamplesMessage *> _messages;
int _mode;
+#if HAVE_CELT051
CELTMode *_celt_mode;
CELTEncoder *_celt_encoder;
+#endif
uint32_t _frame_bytes;
static int data_mode;
diff --git a/client/playback_channel.cpp b/client/playback_channel.cpp
index 802a4d3..caf6424 100644
--- a/client/playback_channel.cpp
+++ b/client/playback_channel.cpp
@@ -151,8 +151,10 @@ PlaybackChannel::PlaybackChannel(RedClient& client, uint32_t id)
Platform::PRIORITY_HIGH)
, _wave_player (NULL)
, _mode (SPICE_AUDIO_DATA_MODE_INVALID)
+#if HAVE_CELT051
, _celt_mode (NULL)
, _celt_decoder (NULL)
+#endif
, _playing (false)
{
#ifdef WAVE_CAPTURE
@@ -169,7 +171,9 @@ PlaybackChannel::PlaybackChannel(RedClient& client, uint32_t id)
handler->set_handler(SPICE_MSG_PLAYBACK_MODE, &PlaybackChannel::handle_mode);
+#if HAVE_CELT051
set_capability(SPICE_PLAYBACK_CAP_CELT_0_5_1);
+#endif
}
void PlaybackChannel::clear()
@@ -182,6 +186,7 @@ void PlaybackChannel::clear()
}
_mode = SPICE_AUDIO_DATA_MODE_INVALID;
+#if HAVE_CELT051
if (_celt_decoder) {
celt051_decoder_destroy(_celt_decoder);
_celt_decoder = NULL;
@@ -191,6 +196,7 @@ void PlaybackChannel::clear()
celt051_mode_destroy(_celt_mode);
_celt_mode = NULL;
}
+#endif
}
void PlaybackChannel::on_disconnect()
@@ -214,8 +220,10 @@ void PlaybackChannel::set_data_handler()
if (_mode == SPICE_AUDIO_DATA_MODE_RAW) {
handler->set_handler(SPICE_MSG_PLAYBACK_DATA, &PlaybackChannel::handle_raw_data);
+#if HAVE_CELT051
} else if (_mode == SPICE_AUDIO_DATA_MODE_CELT_0_5_1) {
handler->set_handler(SPICE_MSG_PLAYBACK_DATA, &PlaybackChannel::handle_celt_data);
+#endif
} else {
THROW("invalid mode");
}
@@ -224,8 +232,11 @@ void PlaybackChannel::set_data_handler()
void PlaybackChannel::handle_mode(RedPeer::InMessage* message)
{
SpiceMsgPlaybackMode* playbacke_mode = (SpiceMsgPlaybackMode*)message->data();
- if (playbacke_mode->mode != SPICE_AUDIO_DATA_MODE_RAW &&
- playbacke_mode->mode != SPICE_AUDIO_DATA_MODE_CELT_0_5_1) {
+ if (playbacke_mode->mode != SPICE_AUDIO_DATA_MODE_RAW
+#if HAVE_CELT051
+ && playbacke_mode->mode != SPICE_AUDIO_DATA_MODE_CELT_0_5_1
+#endif
+ ) {
THROW("invalid mode");
}
@@ -265,9 +276,6 @@ void PlaybackChannel::handle_start(RedPeer::InMessage* message)
start_wave();
#endif
if (!_wave_player) {
- // for now support only one setting
- int celt_mode_err;
-
if (start->format != SPICE_AUDIO_FMT_S16) {
THROW("unexpected format");
}
@@ -284,6 +292,10 @@ void PlaybackChannel::handle_start(RedPeer::InMessage* message)
return;
}
+#if HAVE_CELT051
+ // for now support only one setting
+ int celt_mode_err;
+
if (!(_celt_mode = celt051_mode_create(start->frequency, start->channels,
frame_size, &celt_mode_err))) {
THROW("create celt mode failed %d", celt_mode_err);
@@ -292,6 +304,7 @@ void PlaybackChannel::handle_start(RedPeer::InMessage* message)
if (!(_celt_decoder = celt051_decoder_create(_celt_mode))) {
THROW("create celt decoder");
}
+#endif
}
_playing = true;
_frame_count = 0;
@@ -333,6 +346,7 @@ void PlaybackChannel::handle_raw_data(RedPeer::InMessage* message)
_wave_player->write(data);
}
+#if HAVE_CELT051
void PlaybackChannel::handle_celt_data(RedPeer::InMessage* message)
{
SpiceMsgPlaybackPacket* packet = (SpiceMsgPlaybackPacket*)message->data();
@@ -352,6 +366,7 @@ void PlaybackChannel::handle_celt_data(RedPeer::InMessage* message)
}
_wave_player->write((uint8_t *)pcm);
}
+#endif
class PlaybackFactory: public ChannelFactory {
public:
diff --git a/client/record_channel.cpp b/client/record_channel.cpp
index d9332c6..dbf8344 100644
--- a/client/record_channel.cpp
+++ b/client/record_channel.cpp
@@ -72,8 +72,10 @@ RecordChannel::RecordChannel(RedClient& client, uint32_t id)
: RedChannel(client, SPICE_CHANNEL_RECORD, id, new RecordHandler(*this))
, _wave_recorder (NULL)
, _mode (SPICE_AUDIO_DATA_MODE_INVALID)
+#if HAVE_CELT051
, _celt_mode (NULL)
, _celt_encoder (NULL)
+#endif
{
for (int i = 0; i < NUM_SAMPLES_MESSAGES; i++) {
_messages.push_front(new RecordSamplesMessage(*this));
@@ -142,7 +144,11 @@ void RecordChannel::handle_start(RedPeer::InMessage* message)
handler->set_handler(SPICE_MSG_RECORD_START, NULL);
handler->set_handler(SPICE_MSG_RECORD_STOP, &RecordChannel::handle_stop);
+#if HAVE_CELT051
ASSERT(!_wave_recorder && !_celt_mode && !_celt_encoder);
+#else
+ ASSERT(!_wave_recorder);
+#endif
// for now support only one setting
if (start->format != SPICE_AUDIO_FMT_S16) {
@@ -160,8 +166,9 @@ void RecordChannel::handle_start(RedPeer::InMessage* message)
}
int frame_size = 256;
- int celt_mode_err;
_frame_bytes = frame_size * bits_per_sample * start->channels / 8;
+#if HAVE_CELT051
+ int celt_mode_err;
if (!(_celt_mode = celt051_mode_create(start->frequency, start->channels, frame_size,
&celt_mode_err))) {
THROW("create celt mode failed %d", celt_mode_err);
@@ -170,6 +177,7 @@ void RecordChannel::handle_start(RedPeer::InMessage* message)
if (!(_celt_encoder = celt051_encoder_create(_celt_mode))) {
THROW("create celt encoder failed");
}
+#endif
send_start_mark();
_wave_recorder->start();
@@ -182,6 +190,7 @@ void RecordChannel::clear()
delete _wave_recorder;
_wave_recorder = NULL;
}
+#if HAVE_CELT051
if (_celt_encoder) {
celt051_encoder_destroy(_celt_encoder);
_celt_encoder = NULL;
@@ -190,6 +199,7 @@ void RecordChannel::clear()
celt051_mode_destroy(_celt_mode);
_celt_mode = NULL;
}
+#endif
}
void RecordChannel::handle_stop(RedPeer::InMessage* message)
@@ -200,7 +210,9 @@ void RecordChannel::handle_stop(RedPeer::InMessage* message)
if (!_wave_recorder) {
return;
}
+#if HAVE_CELT051
ASSERT(_celt_mode && _celt_encoder);
+#endif
clear();
}
@@ -254,8 +266,9 @@ void RecordChannel::push_frame(uint8_t *frame)
DBG(0, "blocked");
return;
}
- uint8_t celt_buf[CELT_COMPRESSED_FRAME_BYTES];
int n;
+#if HAVE_CELT051
+ uint8_t celt_buf[CELT_COMPRESSED_FRAME_BYTES];
if (_mode == SPICE_AUDIO_DATA_MODE_CELT_0_5_1) {
n = celt051_encode(_celt_encoder, (celt_int16_t *)frame, NULL, celt_buf,
@@ -264,7 +277,9 @@ void RecordChannel::push_frame(uint8_t *frame)
THROW("celt encode failed");
}
frame = celt_buf;
- } else {
+ } else
+#endif
+ {
n = _frame_bytes;
}
RedPeer::OutMessage& peer_message = message->peer_message();
diff --git a/configure.ac b/configure.ac
index 66f9d12..21bd326 100644
--- a/configure.ac
+++ b/configure.ac
@@ -125,6 +125,9 @@ AM_CONDITIONAL(SUPPORT_SMARTCARD, test "x$enable_smartcard" != "xno")
if test "x$enable_smartcard" = "xyes"; then
AC_DEFINE([USE_SMARTCARD], [1], [Define if supporting smartcard proxying])
fi
+AC_ARG_ENABLE(celt051,
+[ --disable-celt051 Disable celt051 audio codec (enabled by default)],,
+[enable_celt051="yes"])
AC_ARG_ENABLE(client,
[ --enable-client Enable spice client],,
@@ -220,11 +223,14 @@ AC_SUBST(PIXMAN_CFLAGS)
AC_SUBST(PIXMAN_LIBS)
SPICE_REQUIRES+=" pixman-1 >= 0.17.7"
-PKG_CHECK_MODULES(CELT051, celt051 >= 0.5.1.1)
-AC_SUBST(CELT051_CFLAGS)
-AC_SUBST(CELT051_LIBS)
-AC_SUBST(CELT051_LIBDIR)
-SPICE_REQUIRES+=" celt051 >= 0.5.1.1"
+if test "x$enable_celt051" = "xyes"; then
+ PKG_CHECK_MODULES(CELT051, celt051 >= 0.5.1.1)
+ SPICE_REQUIRES+=" celt051 >= 0.5.1.1"
+ AC_DEFINE([HAVE_CELT051], 1, [Define if we have celt051 codec])
+ AC_SUBST(CELT051_CFLAGS)
+ AC_SUBST(CELT051_LIBS)
+ AC_SUBST(CELT051_LIBDIR)
+fi
if test ! -e client/generated_marshallers.cpp; then
AC_MSG_CHECKING([for pyparsing python module])
diff --git a/server/snd_worker.c b/server/snd_worker.c
index caffe67..a72aece 100644
--- a/server/snd_worker.c
+++ b/server/snd_worker.c
@@ -25,7 +25,9 @@
#include <sys/socket.h>
#include <netinet/ip.h>
#include <netinet/tcp.h>
+#if HAVE_CELT051
#include <celt051/celt.h>
+#endif
#include "common/marshaller.h"
#include "common/generated_server_marshallers.h"
@@ -136,12 +138,14 @@ typedef struct PlaybackChannel {
AudioFrame *free_frames;
AudioFrame *in_progress;
AudioFrame *pending_frame;
+ uint32_t mode;
+#if HAVE_CELT051
CELTMode *celt_mode;
CELTEncoder *celt_encoder;
- uint32_t mode;
struct {
uint8_t celt_buf[CELT_COMPRESSED_FRAME_BYTES];
} send_data;
+#endif
} PlaybackChannel;
struct SndWorker {
@@ -187,13 +191,21 @@ typedef struct RecordChannel {
uint32_t mode;
uint32_t mode_time;
uint32_t start_time;
+#if HAVE_CELT051
CELTDecoder *celt_decoder;
CELTMode *celt_mode;
uint32_t celt_buf[FRAME_SIZE];
+#endif
} RecordChannel;
static SndWorker *workers;
-static uint32_t playback_compression = SPICE_AUDIO_DATA_MODE_CELT_0_5_1;
+static uint32_t playback_compression =
+#if HAVE_CELT051
+ SPICE_AUDIO_DATA_MODE_CELT_0_5_1
+#else
+ SPICE_AUDIO_DATA_MODE_RAW
+#endif
+ ;
static void snd_receive(void* data);
@@ -322,6 +334,7 @@ static int snd_record_handle_write(RecordChannel *record_channel, size_t size, v
packet = (SpiceMsgcRecordPacket *)message;
size = packet->data_size;
+#if HAVE_CELT051
if (record_channel->mode == SPICE_AUDIO_DATA_MODE_CELT_0_5_1) {
int celt_err = celt051_decode(record_channel->celt_decoder, packet->data, size,
(celt_int16_t *)record_channel->celt_buf);
@@ -331,7 +344,9 @@ static int snd_record_handle_write(RecordChannel *record_channel, size_t size, v
}
data = record_channel->celt_buf;
size = FRAME_SIZE;
- } else if (record_channel->mode == SPICE_AUDIO_DATA_MODE_RAW) {
+ } else
+#endif
+ if (record_channel->mode == SPICE_AUDIO_DATA_MODE_RAW) {
data = (uint32_t *)packet->data;
size = size >> 2;
size = MIN(size, RECORD_SAMPLES_SIZE);
@@ -386,8 +401,11 @@ static int snd_record_handle_message(SndChannel *channel, size_t size, uint32_t
SpiceMsgcRecordMode *mode = (SpiceMsgcRecordMode *)message;
record_channel->mode = mode->mode;
record_channel->mode_time = mode->time;
- if (record_channel->mode != SPICE_AUDIO_DATA_MODE_CELT_0_5_1 &&
- record_channel->mode != SPICE_AUDIO_DATA_MODE_RAW) {
+ if (record_channel->mode != SPICE_AUDIO_DATA_MODE_RAW
+#if HAVE_CELT051
+ && record_channel->mode != SPICE_AUDIO_DATA_MODE_CELT_0_5_1
+#endif
+ ) {
spice_printerr("unsupported mode");
}
break;
@@ -779,6 +797,7 @@ static int snd_playback_send_write(PlaybackChannel *playback_channel)
spice_marshall_msg_playback_data(channel->send_data.marshaller, &msg);
+#if HAVE_CELT051
if (playback_channel->mode == SPICE_AUDIO_DATA_MODE_CELT_0_5_1) {
int n = celt051_encode(playback_channel->celt_encoder, (celt_int16_t *)frame->samples, NULL,
playback_channel->send_data.celt_buf, CELT_COMPRESSED_FRAME_BYTES);
@@ -789,7 +808,9 @@ static int snd_playback_send_write(PlaybackChannel *playback_channel)
}
spice_marshaller_add_ref(channel->send_data.marshaller,
playback_channel->send_data.celt_buf, n);
- } else {
+ } else
+#endif
+ {
spice_marshaller_add_ref(channel->send_data.marshaller,
(uint8_t *)frame->samples, sizeof(frame->samples));
}
@@ -1154,8 +1175,10 @@ static void snd_playback_cleanup(SndChannel *channel)
reds_enable_mm_timer();
}
+#if HAVE_CELT051
celt051_encoder_destroy(playback_channel->celt_encoder);
celt051_mode_destroy(playback_channel->celt_mode);
+#endif
}
static void snd_set_playback_peer(RedChannel *channel, RedClient *client, RedsStream *stream,
@@ -1165,13 +1188,13 @@ static void snd_set_playback_peer(RedChannel *channel, RedClient *client, RedsSt
SndWorker *worker = channel->data;
PlaybackChannel *playback_channel;
SpicePlaybackState *st = SPICE_CONTAINEROF(worker, SpicePlaybackState, worker);
- CELTEncoder *celt_encoder;
- CELTMode *celt_mode;
- int celt_error;
- RedChannelClient *rcc;
snd_disconnect_channel(worker->connection);
+#if HAVE_CELT051
+ CELTEncoder *celt_encoder;
+ CELTMode *celt_mode;
+ int celt_error;
if (!(celt_mode = celt051_mode_create(SPICE_INTERFACE_PLAYBACK_FREQ,
SPICE_INTERFACE_PLAYBACK_CHAN,
FRAME_SIZE, &celt_error))) {
@@ -1183,6 +1206,7 @@ static void snd_set_playback_peer(RedChannel *channel, RedClient *client, RedsSt
spice_printerr("create celt encoder failed");
goto error_1;
}
+#endif
if (!(playback_channel = (PlaybackChannel *)__new_channel(worker,
sizeof(*playback_channel),
@@ -1199,16 +1223,20 @@ static void snd_set_playback_peer(RedChannel *channel, RedClient *client, RedsSt
goto error_2;
}
worker->connection = &playback_channel->base;
- rcc = playback_channel->base.channel_client;
snd_playback_free_frame(playback_channel, &playback_channel->frames[0]);
snd_playback_free_frame(playback_channel, &playback_channel->frames[1]);
snd_playback_free_frame(playback_channel, &playback_channel->frames[2]);
+#if HAVE_CELT051
playback_channel->celt_mode = celt_mode;
playback_channel->celt_encoder = celt_encoder;
- playback_channel->mode = red_channel_client_test_remote_cap(rcc,
- SPICE_PLAYBACK_CAP_CELT_0_5_1) ?
+ playback_channel->mode =
+ red_channel_client_test_remote_cap(playback_channel->base.channel_client,
+ SPICE_PLAYBACK_CAP_CELT_0_5_1) ?
playback_compression : SPICE_AUDIO_DATA_MODE_RAW;
+#else
+ playback_channel->mode = SPICE_AUDIO_DATA_MODE_RAW;
+#endif
on_new_playback_channel(worker);
if (worker->active) {
@@ -1218,10 +1246,13 @@ static void snd_set_playback_peer(RedChannel *channel, RedClient *client, RedsSt
return;
error_2:
+#if HAVE_CELT051
celt051_encoder_destroy(celt_encoder);
error_1:
celt051_mode_destroy(celt_mode);
+#endif
+ return;
}
static void snd_record_migrate_channel_client(RedChannelClient *rcc)
@@ -1362,10 +1393,12 @@ static void on_new_record_channel(SndWorker *worker)
static void snd_record_cleanup(SndChannel *channel)
{
+#if HAVE_CELT051
RecordChannel *record_channel = SPICE_CONTAINEROF(channel, RecordChannel, base);
celt051_decoder_destroy(record_channel->celt_decoder);
celt051_mode_destroy(record_channel->celt_mode);
+#endif
}
static void snd_set_record_peer(RedChannel *channel, RedClient *client, RedsStream *stream,
@@ -1375,12 +1408,13 @@ static void snd_set_record_peer(RedChannel *channel, RedClient *client, RedsStre
SndWorker *worker = channel->data;
RecordChannel *record_channel;
SpiceRecordState *st = SPICE_CONTAINEROF(worker, SpiceRecordState, worker);
- CELTDecoder *celt_decoder;
- CELTMode *celt_mode;
- int celt_error;
snd_disconnect_channel(worker->connection);
+#if HAVE_CELT051
+ CELTDecoder *celt_decoder;
+ CELTMode *celt_mode;
+ int celt_error;
if (!(celt_mode = celt051_mode_create(SPICE_INTERFACE_RECORD_FREQ,
SPICE_INTERFACE_RECORD_CHAN,
FRAME_SIZE, &celt_error))) {
@@ -1392,6 +1426,7 @@ static void snd_set_record_peer(RedChannel *channel, RedClient *client, RedsStre
spice_printerr("create celt decoder failed");
goto error_1;
}
+#endif
if (!(record_channel = (RecordChannel *)__new_channel(worker,
sizeof(*record_channel),
@@ -1410,8 +1445,10 @@ static void snd_set_record_peer(RedChannel *channel, RedClient *client, RedsStre
worker->connection = &record_channel->base;
+#if HAVE_CELT051
record_channel->celt_mode = celt_mode;
record_channel->celt_decoder = celt_decoder;
+#endif
on_new_record_channel(worker);
if (worker->active) {
@@ -1421,10 +1458,13 @@ static void snd_set_record_peer(RedChannel *channel, RedClient *client, RedsStre
return;
error_2:
+#if HAVE_CELT051
celt051_decoder_destroy(celt_decoder);
error_1:
celt051_mode_destroy(celt_mode);
+#endif
+ return;
}
static void snd_playback_migrate_channel_client(RedChannelClient *rcc)
@@ -1480,7 +1520,9 @@ void snd_attach_playback(SpicePlaybackInstance *sin)
client_cbs.migrate = snd_playback_migrate_channel_client;
red_channel_register_client_cbs(channel, &client_cbs);
red_channel_set_data(channel, playback_worker);
+#if HAVE_CELT051
red_channel_set_cap(channel, SPICE_PLAYBACK_CAP_CELT_0_5_1);
+#endif
red_channel_set_cap(channel, SPICE_PLAYBACK_CAP_VOLUME);
playback_worker->base_channel = channel;
@@ -1507,7 +1549,9 @@ void snd_attach_record(SpiceRecordInstance *sin)
client_cbs.migrate = snd_record_migrate_channel_client;
red_channel_register_client_cbs(channel, &client_cbs);
red_channel_set_data(channel, record_worker);
+#if HAVE_CELT051
red_channel_set_cap(channel, SPICE_RECORD_CAP_CELT_0_5_1);
+#endif
red_channel_set_cap(channel, SPICE_RECORD_CAP_VOLUME);
record_worker->base_channel = channel;
@@ -1554,7 +1598,11 @@ void snd_set_playback_compression(int on)
{
SndWorker *now = workers;
- playback_compression = on ? SPICE_AUDIO_DATA_MODE_CELT_0_5_1 : SPICE_AUDIO_DATA_MODE_RAW;
+ playback_compression =
+#if HAVE_CELT051
+ on ? SPICE_AUDIO_DATA_MODE_CELT_0_5_1 :
+#endif
+ SPICE_AUDIO_DATA_MODE_RAW;
for (; now; now = now->next) {
if (now->base_channel->type == SPICE_CHANNEL_PLAYBACK && now->connection) {
SndChannel* sndchannel = now->connection;
Reply to: