Update latest

This commit is contained in:
mannol 2015-04-17 15:31:14 +02:00
parent da6c17222f
commit 969367b72a
4 changed files with 120 additions and 37 deletions

View File

@ -26,6 +26,7 @@
#include "../toxav/toxav.h" #include "../toxav/toxav.h"
#include "../toxcore/tox.h" #include "../toxcore/tox.h"
#include "../toxcore/util.h" #include "../toxcore/util.h"
#include "../toxcore/network.h" /* current_time_monotonic() */
#define LOGGING #define LOGGING
#include "../toxcore/logger.h" #include "../toxcore/logger.h"
@ -84,6 +85,9 @@ typedef struct {
bool incoming; bool incoming;
uint32_t state; uint32_t state;
uint32_t abitrate; uint32_t abitrate;
pthread_mutex_t arb_mutex[1];
RingBuffer* arb; /* Audio ring buffer */
} CallControl; } CallControl;
struct toxav_thread_data { struct toxav_thread_data {
@ -95,6 +99,32 @@ struct toxav_thread_data {
const char* vdout = "AV Test"; /* Video output */ const char* vdout = "AV Test"; /* Video output */
PaStream* adout = NULL; /* Audio output */ PaStream* adout = NULL; /* Audio output */
typedef struct {
uint16_t size;
int16_t data[];
} frame;
void* pa_write_thread (void* d)
{
/* The purpose of this thread is to make sure Pa_WriteStream will not block
* toxav_iterate thread
*/
CallControl* cc = d;
while (Pa_IsStreamActive(adout)) {
frame* f;
pthread_mutex_lock(cc->arb_mutex);
if (rb_read(cc->arb, (void**)&f)) {
pthread_mutex_unlock(cc->arb_mutex);
Pa_WriteStream(adout, f->data, f->size);
free(f);
} else
pthread_mutex_unlock(cc->arb_mutex);
}
}
/** /**
* Callbacks * Callbacks
*/ */
@ -106,15 +136,38 @@ void t_toxav_call_cb(ToxAV *av, uint32_t friend_number, bool audio_enabled, bool
void t_toxav_call_state_cb(ToxAV *av, uint32_t friend_number, uint32_t state, void *user_data) void t_toxav_call_state_cb(ToxAV *av, uint32_t friend_number, uint32_t state, void *user_data)
{ {
((CallControl*)user_data)->state = state; ((CallControl*)user_data)->state = state;
uint32_t abitrate = ((CallControl*)user_data)->abitrate;
if (state & TOXAV_CALL_STATE_INCREASE_AUDIO_BITRATE) { if (state & TOXAV_CALL_STATE_INCREASE_AUDIO_BITRATE) {
uint32_t bitrate = ((CallControl*)user_data)->abitrate;
if (bitrate < 64) { // /* NOTE: I'm using values 8, 16, 24, 48, 64. You can use whatever OPUS supports. */
printf("Changing bitrate to: %d\n", 64); // switch (abitrate) {
toxav_set_audio_bit_rate(av, friend_number, 64, 0); // case 8: abitrate = 16; break;
} // case 16: abitrate = 24; break;
} else if (state & TOXAV_CALL_STATE_INCREASE_VIDEO_BITRATE) { // case 24: abitrate = 48; break;
// case 48: abitrate = 64; break;
// default: return;
// }
//
// printf("Increasing bitrate to: %d\n", abitrate);
// toxav_set_audio_bit_rate(av, friend_number, abitrate, 0);
} else if (state & TOXAV_CALL_STATE_DECREASE_AUDIO_BITRATE) {
// /* NOTE: I'm using values 8, 16, 24, 48, 64. You can use whatever OPUS supports. */
// switch (abitrate) {
// case 16: abitrate = 8; break;
// case 24: abitrate = 16; break;
// case 48: abitrate = 24; break;
// case 64: abitrate = 48; break;
// default: return;
// }
//
// printf("Decreasing bitrate to: %d\n", abitrate);
// toxav_set_audio_bit_rate(av, friend_number, abitrate, 0);
//
}
if (state & TOXAV_CALL_STATE_INCREASE_VIDEO_BITRATE) {
} else { } else {
printf("Handling CALL STATE callback: %d\n", state); printf("Handling CALL STATE callback: %d\n", state);
@ -158,7 +211,16 @@ void t_toxav_receive_audio_frame_cb(ToxAV *av, uint32_t friend_number,
uint32_t sampling_rate, uint32_t sampling_rate,
void *user_data) void *user_data)
{ {
Pa_WriteStream(adout, pcm, sample_count/channels); CallControl* cc = user_data;
frame* f = malloc(sizeof(frame) + sample_count * sizeof(int16_t));
memcpy(f->data, pcm, sample_count);
f->size = sample_count/channels;
pthread_mutex_lock(cc->arb_mutex);
free(rb_write(cc->arb, f));
pthread_mutex_unlock(cc->arb_mutex);
// Pa_WriteStream(adout, pcm, sample_count/channels);
} }
void t_accept_friend_request_cb(Tox *m, const uint8_t *public_key, const uint8_t *data, uint16_t length, void *userdata) void t_accept_friend_request_cb(Tox *m, const uint8_t *public_key, const uint8_t *data, uint16_t length, void *userdata)
{ {
@ -220,6 +282,7 @@ void initialize_tox(Tox** bootstrap, ToxAV** AliceAV, CallControl* AliceCC, ToxA
*BobAV = toxav_new(Bob, &rc); *BobAV = toxav_new(Bob, &rc);
assert(rc == TOXAV_ERR_NEW_OK); assert(rc == TOXAV_ERR_NEW_OK);
/* Alice */ /* Alice */
toxav_callback_call(*AliceAV, t_toxav_call_cb, AliceCC); toxav_callback_call(*AliceAV, t_toxav_call_cb, AliceCC);
toxav_callback_call_state(*AliceAV, t_toxav_call_state_cb, AliceCC); toxav_callback_call_state(*AliceAV, t_toxav_call_state_cb, AliceCC);
@ -255,7 +318,9 @@ void* iterate_toxav (void * data)
int rc = MIN(toxav_iteration_interval(data_cast->AliceAV), toxav_iteration_interval(data_cast->BobAV)); int rc = MIN(toxav_iteration_interval(data_cast->AliceAV), toxav_iteration_interval(data_cast->BobAV));
// cvWaitKey(10); // cvWaitKey(10);
c_sleep(10); printf("\rSleeping for: %d ", rc);
fflush(stdout);
c_sleep(rc);
} }
data_cast->sig = 1; data_cast->sig = 1;
@ -330,6 +395,7 @@ int print_help (const char* name)
int main (int argc, char** argv) int main (int argc, char** argv)
{ {
freopen("/dev/zero", "w", stderr);
Pa_Initialize(); Pa_Initialize();
struct stat st; struct stat st;
@ -669,7 +735,13 @@ int main (int argc, char** argv)
memset(&AliceCC, 0, sizeof(CallControl)); memset(&AliceCC, 0, sizeof(CallControl));
memset(&BobCC, 0, sizeof(CallControl)); memset(&BobCC, 0, sizeof(CallControl));
AliceCC.abitrate = BobCC.abitrate = 8; pthread_mutex_init(AliceCC.arb_mutex, NULL);
pthread_mutex_init(BobCC.arb_mutex, NULL);
AliceCC.arb = rb_new(16);
BobCC.arb = rb_new(16);
AliceCC.abitrate = BobCC.abitrate = 16;
{ /* Call */ { /* Call */
TOXAV_ERR_CALL rc; TOXAV_ERR_CALL rc;
@ -704,21 +776,6 @@ int main (int argc, char** argv)
} }
int frame_size = (af_info.samplerate * audio_frame_duration / 1000) * af_info.channels;
struct PaStreamParameters output;
output.device = audio_out_dev_idx;
output.channelCount = af_info.channels;
output.sampleFormat = paInt16;
output.suggestedLatency = audio_dev->defaultHighOutputLatency;
output.hostApiSpecificStreamInfo = NULL;
PaError err = Pa_OpenStream(&adout, NULL, &output, af_info.samplerate, frame_size, paNoFlag, NULL, NULL);
assert(err == paNoError);
err = Pa_StartStream(adout);
assert(err == paNoError);
int16_t PCM[5760]; int16_t PCM[5760];
time_t start_time = time(NULL); time_t start_time = time(NULL);
@ -736,8 +793,25 @@ int main (int argc, char** argv)
pthread_create(&dect, NULL, iterate_toxav, &data); pthread_create(&dect, NULL, iterate_toxav, &data);
pthread_detach(dect); pthread_detach(dect);
int frame_size = (af_info.samplerate * audio_frame_duration / 1000) * af_info.channels;
struct PaStreamParameters output;
output.device = audio_out_dev_idx;
output.channelCount = af_info.channels;
output.sampleFormat = paInt16;
output.suggestedLatency = audio_dev->defaultHighOutputLatency;
output.hostApiSpecificStreamInfo = NULL;
PaError err = Pa_OpenStream(&adout, NULL, &output, af_info.samplerate, frame_size, paNoFlag, NULL, NULL);
assert(err == paNoError);
err = Pa_StartStream(adout);
assert(err == paNoError);
printf("Sample rate %d\n", af_info.samplerate); printf("Sample rate %d\n", af_info.samplerate);
while ( start_time + expected_time > time(NULL) ) { while ( start_time + expected_time > time(NULL) ) {
uint64_t enc_start_time = current_time_monotonic();
int64_t count = sf_read_short(af_handle, PCM, frame_size); int64_t count = sf_read_short(af_handle, PCM, frame_size);
if (count > 0) { if (count > 0) {
TOXAV_ERR_SEND_FRAME rc; TOXAV_ERR_SEND_FRAME rc;
@ -746,9 +820,10 @@ int main (int argc, char** argv)
} }
} }
iterate_tox(bootstrap, AliceAV, BobAV); iterate_tox(bootstrap, AliceAV, BobAV);
c_sleep(53); c_sleep(abs(audio_frame_duration - (current_time_monotonic() - enc_start_time) - 1));
} }
Pa_StopStream(adout);
printf("Played file in: %lu\n", time(NULL) - start_time); printf("Played file in: %lu\n", time(NULL) - start_time);
@ -772,7 +847,15 @@ int main (int argc, char** argv)
while(data.sig != 1) while(data.sig != 1)
pthread_yield(); pthread_yield();
Pa_StopStream(adout); pthread_mutex_destroy(AliceCC.arb_mutex);
pthread_mutex_destroy(BobCC.arb_mutex);
void* f = NULL;
while(rb_read(AliceCC.arb, &f))
free(f);
while(rb_read(BobCC.arb, &f))
free(f);
printf("Success!"); printf("Success!");
} }

View File

@ -293,7 +293,7 @@ void cs_do(CSession *cs)
/* The maximum for 120 ms 48 KHz audio */ /* The maximum for 120 ms 48 KHz audio */
int16_t tmp[5760]; int16_t tmp[5760];
if ((msg = jbuf_read(cs->j_buf, &success)) || success == 2) { while ((msg = jbuf_read(cs->j_buf, &success)) || success == 2) {
LOGGED_UNLOCK(cs->queue_mutex); LOGGED_UNLOCK(cs->queue_mutex);
if (success == 2) { if (success == 2) {
@ -327,7 +327,8 @@ void cs_do(CSession *cs)
if (!reconfigure_audio_decoder(cs, cs->last_packet_sampling_rate, cs->last_packet_channel_count)) { if (!reconfigure_audio_decoder(cs, cs->last_packet_sampling_rate, cs->last_packet_channel_count)) {
LOGGER_WARNING("Failed to reconfigure decoder!"); LOGGER_WARNING("Failed to reconfigure decoder!");
rtp_free_msg(NULL, msg); rtp_free_msg(NULL, msg);
goto DONE; continue;
// goto DONE;
} }
rc = opus_decode(cs->audio_decoder, msg->data + 4, msg->length - 4, tmp, 5760, 0); rc = opus_decode(cs->audio_decoder, msg->data + 4, msg->length - 4, tmp, 5760, 0);
@ -337,7 +338,6 @@ void cs_do(CSession *cs)
if (rc < 0) { if (rc < 0) {
LOGGER_WARNING("Decoding error: %s", opus_strerror(rc)); LOGGER_WARNING("Decoding error: %s", opus_strerror(rc));
} else if (cs->acb.first) { } else if (cs->acb.first) {
cs->last_packet_channel_count = 2;
cs->last_packet_frame_duration = (rc * 1000) / cs->last_packet_sampling_rate * cs->last_packet_channel_count; cs->last_packet_frame_duration = (rc * 1000) / cs->last_packet_sampling_rate * cs->last_packet_channel_count;
cs->acb.first(cs->av, cs->friend_id, tmp, rc * cs->last_packet_channel_count, cs->acb.first(cs->av, cs->friend_id, tmp, rc * cs->last_packet_channel_count,
@ -347,7 +347,7 @@ void cs_do(CSession *cs)
LOGGED_LOCK(cs->queue_mutex); LOGGED_LOCK(cs->queue_mutex);
} }
DONE:; // DONE:;
} }
/********************* VIDEO *********************/ /********************* VIDEO *********************/

View File

@ -249,8 +249,8 @@ void toxav_iterate(ToxAV* av)
} }
LOGGED_UNLOCK(av->mutex); LOGGED_UNLOCK(av->mutex);
// av->interval = rc < av->dmssa ? 0 : (rc - av->dmssa); av->interval = rc < av->dmssa ? 0 : (rc - av->dmssa);
av->interval = rc < 5 ? 1: rc - 5; // av->interval = rc < 5 ? 1: rc - 5;
av->dmsst += current_time_monotonic() - start; av->dmsst += current_time_monotonic() - start;
if (++av->dmssc == 3) { if (++av->dmssc == 3) {
@ -993,7 +993,7 @@ void qc_do(ToxAVCall* call)
LOGGER_DEBUG("Suggesting lower bitrate for audio..."); LOGGER_DEBUG("Suggesting lower bitrate for audio...");
call->time_audio_good = 0; call->time_audio_good = 0;
call->last_bad_audio_bit_rate = call->audio_bit_rate; call->last_bad_audio_bit_rate = call->audio_bit_rate;
invoke_call_state(call->av, call->friend_id, TOXAV_CALL_STATE_LOWER_AUDIO_BITRATE); invoke_call_state(call->av, call->friend_id, TOXAV_CALL_STATE_DECREASE_AUDIO_BITRATE);
break; break;
case rtp_StateGood: case rtp_StateGood:
if (call->time_audio_good == 0) if (call->time_audio_good == 0)
@ -1017,7 +1017,7 @@ void qc_do(ToxAVCall* call)
LOGGER_DEBUG("Suggesting lower bitrate for video..."); LOGGER_DEBUG("Suggesting lower bitrate for video...");
call->time_video_good = 0; call->time_video_good = 0;
call->last_bad_video_bit_rate = call->video_bit_rate; call->last_bad_video_bit_rate = call->video_bit_rate;
invoke_call_state(call->av, call->friend_id, TOXAV_CALL_STATE_LOWER_VIDEO_BITRATE); invoke_call_state(call->av, call->friend_id, TOXAV_CALL_STATE_DECREASE_VIDEO_BITRATE);
break; break;
case rtp_StateGood: case rtp_StateGood:
if (call->time_video_good == 0) if (call->time_video_good == 0)

View File

@ -215,11 +215,11 @@ typedef enum TOXAV_CALL_STATE {
/** /**
* AV core suggests you to lower bitrate for audio. * AV core suggests you to lower bitrate for audio.
*/ */
TOXAV_CALL_STATE_LOWER_AUDIO_BITRATE = 32, TOXAV_CALL_STATE_DECREASE_AUDIO_BITRATE = 32,
/** /**
* AV core suggests you to lower bitrate for video. * AV core suggests you to lower bitrate for video.
*/ */
TOXAV_CALL_STATE_LOWER_VIDEO_BITRATE = 64, TOXAV_CALL_STATE_DECREASE_VIDEO_BITRATE = 64,
/** /**
* AV core suggests you to increase bitrate for audio. * AV core suggests you to increase bitrate for audio.
*/ */