Video works but there is one deadlock left and video replay is slow

This commit is contained in:
mannol 2015-04-07 01:24:36 +02:00
parent 62c4fd7409
commit bf9f7e2ae8
4 changed files with 92 additions and 67 deletions

View File

@ -60,6 +60,12 @@ typedef struct {
uint32_t state; uint32_t state;
} CallControl; } CallControl;
struct toxav_thread_data {
ToxAV* AliceAV;
ToxAV* BobAV;
int32_t sig;
};
const char* vdout = "AV Test"; const char* vdout = "AV Test";
uint32_t adout; uint32_t adout;
@ -240,17 +246,24 @@ int iterate_tox(Tox* bootstrap, ToxAV* AliceAV, ToxAV* BobAV)
tox_do(toxav_get_tox(AliceAV)); tox_do(toxav_get_tox(AliceAV));
tox_do(toxav_get_tox(BobAV)); tox_do(toxav_get_tox(BobAV));
toxav_iterate(AliceAV); uint32_t rc = MIN(tox_do_interval(toxav_get_tox(AliceAV)), tox_do_interval(toxav_get_tox(BobAV)));
toxav_iterate(BobAV);
int mina = MIN(tox_do_interval(toxav_get_tox(AliceAV)), toxav_iteration_interval(AliceAV));
int minb = MIN(tox_do_interval(toxav_get_tox(BobAV)), toxav_iteration_interval(BobAV));
int rc = MIN(mina, minb);
c_sleep(rc); c_sleep(rc);
return rc; return rc;
} }
void* iterate_toxav (void * data)
{
struct toxav_thread_data* data_cast = data;
while (data_cast->sig == 0) {
toxav_iterate(data_cast->AliceAV);
toxav_iterate(data_cast->BobAV);
// c_sleep(1);
}
data_cast->sig = 1;
cvDestroyWindow(vdout);
pthread_exit(NULL);
}
int send_opencv_img(ToxAV* av, uint32_t friend_number, const IplImage* img) int send_opencv_img(ToxAV* av, uint32_t friend_number, const IplImage* img)
{ {
@ -282,13 +295,11 @@ int send_opencv_img(ToxAV* av, uint32_t friend_number, const IplImage* img)
} }
// int rc = toxav_send_video_frame(av, friend_number, img->width, img->height, planes[0], planes[1], planes[2], NULL); int rc = toxav_send_video_frame(av, friend_number, img->width, img->height, planes[0], planes[1], planes[2], NULL);
t_toxav_receive_video_frame_cb(av, 0, img->width, img->height, (const uint8_t**) planes, strides, NULL);
free(planes[0]); free(planes[0]);
free(planes[1]); free(planes[1]);
free(planes[2]); free(planes[2]);
// return rc; return rc;
return 0;
} }
ALCdevice* open_audio_device(const char* audio_out_dev_name) ALCdevice* open_audio_device(const char* audio_out_dev_name)
@ -349,8 +360,10 @@ int print_help (const char* name)
return 0; return 0;
} }
int main (int argc, char** argv) int main (int argc, char** argv)
{ {
cvNamedWindow(vdout, CV_WINDOW_AUTOSIZE);
struct stat st; struct stat st;
/* AV files for testing */ /* AV files for testing */
@ -409,32 +422,6 @@ int main (int argc, char** argv)
} }
} }
cvNamedWindow(vdout, CV_WINDOW_AUTOSIZE);
CvCapture* capture = cvCreateFileCapture(vf_name);
if (!capture) {
printf("Failed to open video file: %s\n", vf_name);
exit(1);
}
IplImage* frame;
time_t start_time = time(NULL);
int frame_rate = cvGetCaptureProperty(capture, CV_CAP_PROP_FPS);
while(start_time + 4 > time(NULL)) {
frame = cvQueryFrame( capture );
if (!frame)
break;
send_opencv_img(NULL, 0, frame);
c_sleep(1);
}
cvReleaseCapture(&capture);
cvDestroyWindow(vdout);
return 0;
const char* audio_out_dev_name = NULL; const char* audio_out_dev_name = NULL;
int i = 0; int i = 0;
@ -459,9 +446,6 @@ int main (int argc, char** argv)
initialize_tox(&bootstrap, &AliceAV, &AliceCC, &BobAV, &BobCC); initialize_tox(&bootstrap, &AliceAV, &AliceCC, &BobAV, &BobCC);
#define REGULAR_CALL_FLOW(A_BR, V_BR) \ #define REGULAR_CALL_FLOW(A_BR, V_BR) \
do { \ do { \
memset(&AliceCC, 0, sizeof(CallControl)); \ memset(&AliceCC, 0, sizeof(CallControl)); \
@ -737,6 +721,18 @@ int main (int argc, char** argv)
time_t start_time = time(NULL); time_t start_time = time(NULL);
time_t expected_time = af_info.frames / af_info.samplerate + 2; time_t expected_time = af_info.frames / af_info.samplerate + 2;
/* Start decode thread */
struct toxav_thread_data data = {
.AliceAV = AliceAV,
.BobAV = BobAV,
.sig = 0
};
pthread_t dect;
pthread_create(&dect, NULL, iterate_toxav, &data);
pthread_detach(dect);
while ( start_time + expected_time > time(NULL) ) { while ( start_time + expected_time > time(NULL) ) {
int frame_size = (af_info.samplerate * frame_duration / 1000) * af_info.channels; int frame_size = (af_info.samplerate * frame_duration / 1000) * af_info.channels;
@ -772,6 +768,10 @@ int main (int argc, char** argv)
iterate_tox(bootstrap, AliceAV, BobAV); iterate_tox(bootstrap, AliceAV, BobAV);
assert(BobCC.state == TOXAV_CALL_STATE_END); assert(BobCC.state == TOXAV_CALL_STATE_END);
/* Stop decode thread */
data.sig = -1;
while(data.sig != 1);
printf("Success!"); printf("Success!");
} }
@ -783,7 +783,7 @@ int main (int argc, char** argv)
{ /* Call */ { /* Call */
TOXAV_ERR_CALL rc; TOXAV_ERR_CALL rc;
toxav_call(AliceAV, 0, 0, 500000, &rc); toxav_call(AliceAV, 0, 0, 5000000, &rc);
if (rc != TOXAV_ERR_CALL_OK) { if (rc != TOXAV_ERR_CALL_OK) {
printf("toxav_call failed: %d\n", rc); printf("toxav_call failed: %d\n", rc);
@ -796,7 +796,7 @@ int main (int argc, char** argv)
{ /* Answer */ { /* Answer */
TOXAV_ERR_ANSWER rc; TOXAV_ERR_ANSWER rc;
toxav_answer(BobAV, 0, 0, 500000, &rc); toxav_answer(BobAV, 0, 0, 5000000, &rc);
if (rc != TOXAV_ERR_ANSWER_OK) { if (rc != TOXAV_ERR_ANSWER_OK) {
printf("toxav_answer failed: %d\n", rc); printf("toxav_answer failed: %d\n", rc);
@ -806,7 +806,16 @@ int main (int argc, char** argv)
iterate_tox(bootstrap, AliceAV, BobAV); iterate_tox(bootstrap, AliceAV, BobAV);
cvNamedWindow(vdout, CV_WINDOW_AUTOSIZE); /* Start decode thread */
struct toxav_thread_data data = {
.AliceAV = AliceAV,
.BobAV = BobAV,
.sig = 0
};
pthread_t dect;
pthread_create(&dect, NULL, iterate_toxav, &data);
pthread_detach(dect);
CvCapture* capture = cvCreateFileCapture(vf_name); CvCapture* capture = cvCreateFileCapture(vf_name);
if (!capture) { if (!capture) {
@ -814,23 +823,17 @@ int main (int argc, char** argv)
exit(1); exit(1);
} }
IplImage* frame;
time_t start_time = time(NULL); time_t start_time = time(NULL);
while(start_time + 6 > time(NULL)) {
int frame_rate = cvGetCaptureProperty(capture, CV_CAP_PROP_FPS); IplImage* frame = cvQueryFrame( capture );
while(start_time + 10 > time(NULL)) {
frame = cvQueryFrame( capture );
if (!frame) if (!frame)
break; break;
// cvShowImage(vdout, frame);
// cvWaitKey(frame_rate);
send_opencv_img(AliceAV, 0, frame); send_opencv_img(AliceAV, 0, frame);
iterate_tox(bootstrap, AliceAV, BobAV); iterate_tox(bootstrap, AliceAV, BobAV);
} }
cvReleaseCapture(&capture); cvReleaseCapture(&capture);
cvDestroyWindow(vdout);
{ /* Hangup */ { /* Hangup */
TOXAV_ERR_CALL_CONTROL rc; TOXAV_ERR_CALL_CONTROL rc;
@ -845,6 +848,11 @@ int main (int argc, char** argv)
iterate_tox(bootstrap, AliceAV, BobAV); iterate_tox(bootstrap, AliceAV, BobAV);
assert(BobCC.state == TOXAV_CALL_STATE_END); assert(BobCC.state == TOXAV_CALL_STATE_END);
/* Stop decode thread */
printf("Stopping decode thread");
data.sig = -1;
while(data.sig != 1);
printf("Success!"); printf("Success!");
} }

View File

@ -423,7 +423,7 @@ CSession *cs_new(uint32_t peer_video_frame_piece_size)
return NULL; return NULL;
} }
if (create_recursive_mutex(cs->queue_mutex) != 0) { if (pthread_mutex_init(cs->queue_mutex, NULL) != 0) {
LOGGER_WARNING("Failed to create recursive mutex!"); LOGGER_WARNING("Failed to create recursive mutex!");
free(cs); free(cs);
return NULL; return NULL;

View File

@ -28,6 +28,18 @@
#include "../toxcore/Messenger.h" #include "../toxcore/Messenger.h"
#define LOGGED_LOCK(mutex) do { \
LOGGER_DEBUG("Locking mutex: %p", mutex);\
pthread_mutex_lock(mutex);\
LOGGER_DEBUG("Locked mutex: %p", mutex);\
} while(0)
#define LOGGED_UNLOCK(mutex) do { \
LOGGER_DEBUG("Unlocking mutex: %p", mutex);\
pthread_mutex_unlock(mutex);\
LOGGER_DEBUG("Unlocked mutex: %p", mutex);\
} while(0)
#define MAX_SEQU_NUM 65535 #define MAX_SEQU_NUM 65535
#define MAX_RTP_SIZE 65535 #define MAX_RTP_SIZE 65535

View File

@ -47,7 +47,7 @@ typedef struct ToxAVCall_s {
pthread_mutex_t mutex_audio_sending[1]; pthread_mutex_t mutex_audio_sending[1];
pthread_mutex_t mutex_video_sending[1]; pthread_mutex_t mutex_video_sending[1];
/* Only audio or video can be decoded at one time */ /* Only audio or video can be decoded at the time */
pthread_mutex_t mutex_decoding[1]; pthread_mutex_t mutex_decoding[1];
bool active; bool active;
@ -129,7 +129,8 @@ ToxAV* toxav_new(Tox* tox, TOXAV_ERR_NEW* error)
goto FAILURE; goto FAILURE;
} }
if (create_recursive_mutex(av->mutex) == -1) { // if (create_recursive_mutex(av->mutex) == -1) {
if (pthread_mutex_init(av->mutex, NULL) == -1) {
LOGGER_WARNING("Mutex creation failed!"); LOGGER_WARNING("Mutex creation failed!");
rc = TOXAV_ERR_NEW_MALLOC; rc = TOXAV_ERR_NEW_MALLOC;
goto FAILURE; goto FAILURE;
@ -204,26 +205,30 @@ uint32_t toxav_iteration_interval(const ToxAV* av)
void toxav_iterate(ToxAV* av) void toxav_iterate(ToxAV* av)
{ {
if (av->calls == NULL) pthread_mutex_lock(av->mutex);
if (av->calls == NULL) {
pthread_mutex_unlock(av->mutex);
return; return;
}
uint64_t start = current_time_monotonic(); uint64_t start = current_time_monotonic();
uint32_t rc = 500; uint32_t rc = 500;
pthread_mutex_lock(av->mutex);
ToxAVCall* i = av->calls[av->calls_head]; ToxAVCall* i = av->calls[av->calls_head];
for (; i; i = i->next) { while (i) {
if (i->active) { if (i->active) {
pthread_mutex_lock(i->mutex_decoding); pthread_mutex_lock(i->mutex_decoding);
pthread_mutex_unlock(av->mutex); pthread_mutex_unlock(av->mutex);
cs_do(i->cs); cs_do(i->cs);
rc = MIN(i->cs->last_packet_frame_duration, rc); rc = MIN(i->cs->last_packet_frame_duration, rc);
pthread_mutex_unlock(i->mutex_decoding);
} else
continue;
pthread_mutex_lock(av->mutex); pthread_mutex_lock(av->mutex);
pthread_mutex_unlock(i->mutex_decoding);
i = i->next;
} }
}
pthread_mutex_unlock(av->mutex);
av->interval = rc < av->dmssa ? 0 : (rc - av->dmssa); av->interval = rc < av->dmssa ? 0 : (rc - av->dmssa);
av->dmsst += current_time_monotonic() - start; av->dmsst += current_time_monotonic() - start;
@ -1048,6 +1053,11 @@ void call_kill_transmission(ToxAVCall* call)
call->active = 0; call->active = 0;
rtp_kill(call->rtps[audio_index]);
call->rtps[audio_index] = NULL;
rtp_kill(call->rtps[video_index]);
call->rtps[video_index] = NULL;
pthread_mutex_lock(call->mutex_audio_sending); pthread_mutex_lock(call->mutex_audio_sending);
pthread_mutex_unlock(call->mutex_audio_sending); pthread_mutex_unlock(call->mutex_audio_sending);
pthread_mutex_lock(call->mutex_video_sending); pthread_mutex_lock(call->mutex_video_sending);
@ -1055,11 +1065,6 @@ void call_kill_transmission(ToxAVCall* call)
pthread_mutex_lock(call->mutex_decoding); pthread_mutex_lock(call->mutex_decoding);
pthread_mutex_unlock(call->mutex_decoding); pthread_mutex_unlock(call->mutex_decoding);
rtp_kill(call->rtps[audio_index]);
call->rtps[audio_index] = NULL;
rtp_kill(call->rtps[video_index]);
call->rtps[video_index] = NULL;
cs_kill(call->cs); cs_kill(call->cs);
call->cs = NULL; call->cs = NULL;