mirror of
https://github.com/irungentoo/toxcore.git
synced 2024-03-22 13:30:51 +08:00
working av new api
This commit is contained in:
parent
27e0254a98
commit
e4a020333d
|
@ -77,8 +77,8 @@
|
|||
#define TEST_REJECT 0
|
||||
#define TEST_CANCEL 0
|
||||
#define TEST_MUTE_UNMUTE 0
|
||||
#define TEST_TRANSFER_A 1
|
||||
#define TEST_TRANSFER_V 0
|
||||
#define TEST_TRANSFER_A 0
|
||||
#define TEST_TRANSFER_V 1
|
||||
|
||||
|
||||
typedef struct {
|
||||
|
@ -218,20 +218,28 @@ void initialize_tox(Tox** bootstrap, ToxAV** AliceAV, CallControl* AliceCC, ToxA
|
|||
Tox* Alice;
|
||||
Tox* Bob;
|
||||
|
||||
struct Tox_Options opts;
|
||||
tox_options_default(&opts);
|
||||
|
||||
opts.end_port = 0;
|
||||
|
||||
{
|
||||
TOX_ERR_NEW error;
|
||||
*bootstrap = tox_new(NULL, NULL, 0, &error);
|
||||
|
||||
opts.start_port = 33445;
|
||||
*bootstrap = tox_new(&opts, NULL, 0, &error);
|
||||
assert(error == TOX_ERR_NEW_OK);
|
||||
|
||||
Alice = tox_new(NULL, NULL, 0, &error);
|
||||
opts.start_port = 33455;
|
||||
Alice = tox_new(&opts, NULL, 0, &error);
|
||||
assert(error == TOX_ERR_NEW_OK);
|
||||
|
||||
Bob = tox_new(NULL, NULL, 0, &error);
|
||||
opts.start_port = 33465;
|
||||
Bob = tox_new(&opts, NULL, 0, &error);
|
||||
assert(error == TOX_ERR_NEW_OK);
|
||||
}
|
||||
|
||||
printf("Created 3 instances of Tox\n");
|
||||
|
||||
printf("Preparing network...\n");
|
||||
long long unsigned int cur_time = time(NULL);
|
||||
|
||||
|
@ -768,7 +776,8 @@ int main (int argc, char** argv)
|
|||
}
|
||||
}
|
||||
|
||||
iterate_tox(bootstrap, AliceAV, BobAV);
|
||||
while (AliceCC.state == 0)
|
||||
iterate_tox(bootstrap, AliceAV, BobAV);
|
||||
|
||||
/* Open audio file */
|
||||
af_handle = sf_open(af_name, SFM_READ, &af_info);
|
||||
|
@ -809,7 +818,7 @@ int main (int argc, char** argv)
|
|||
err = Pa_StartStream(adout);
|
||||
assert(err == paNoError);
|
||||
|
||||
assert(toxav_set_audio_bit_rate(AliceAV, 0, 64, false, NULL));
|
||||
toxav_set_audio_bit_rate(AliceAV, 0, 64, false, NULL);
|
||||
|
||||
/* Start write thread */
|
||||
pthread_t t;
|
||||
|
@ -874,7 +883,7 @@ int main (int argc, char** argv)
|
|||
|
||||
{ /* Call */
|
||||
TOXAV_ERR_CALL rc;
|
||||
toxav_call(AliceAV, 0, 0, 5000000, &rc);
|
||||
toxav_call(AliceAV, 0, 0, 3000, &rc);
|
||||
|
||||
if (rc != TOXAV_ERR_CALL_OK) {
|
||||
printf("toxav_call failed: %d\n", rc);
|
||||
|
@ -887,7 +896,7 @@ int main (int argc, char** argv)
|
|||
|
||||
{ /* Answer */
|
||||
TOXAV_ERR_ANSWER rc;
|
||||
toxav_answer(BobAV, 0, 0, 5000000, &rc);
|
||||
toxav_answer(BobAV, 0, 0, 500, &rc);
|
||||
|
||||
if (rc != TOXAV_ERR_ANSWER_OK) {
|
||||
printf("toxav_answer failed: %d\n", rc);
|
||||
|
@ -899,8 +908,8 @@ int main (int argc, char** argv)
|
|||
|
||||
/* Start decode thread */
|
||||
struct toxav_thread_data data = {
|
||||
.AliceAV = AliceAV,
|
||||
.BobAV = BobAV,
|
||||
.AliceAV = AliceAV,
|
||||
.BobAV = BobAV,
|
||||
.sig = 0
|
||||
};
|
||||
|
||||
|
@ -914,6 +923,8 @@ int main (int argc, char** argv)
|
|||
exit(1);
|
||||
}
|
||||
|
||||
toxav_set_video_bit_rate(AliceAV, 0, 5000, false, NULL);
|
||||
|
||||
time_t start_time = time(NULL);
|
||||
while(start_time + 90 > time(NULL)) {
|
||||
IplImage* frame = cvQueryFrame( capture );
|
||||
|
|
|
@ -193,13 +193,13 @@ int rtp_do(RTPSession *session)
|
|||
}
|
||||
|
||||
if (quality <= 90) {
|
||||
LOGGER_WARNING("Stream quality: BAD");
|
||||
LOGGER_WARNING("Stream quality: BAD (%d)", quality);
|
||||
return rtp_StateBad;
|
||||
} else if (quality >= 99) {
|
||||
LOGGER_DEBUG("Stream quality: GOOD");
|
||||
LOGGER_DEBUG("Stream quality: GOOD (%d)", quality);
|
||||
return rtp_StateGood;
|
||||
} else {
|
||||
LOGGER_DEBUG("Stream quality: NORMAL");
|
||||
LOGGER_DEBUG("Stream quality: NORMAL (%d)", quality);
|
||||
}
|
||||
}
|
||||
return rtp_StateNormal;
|
||||
|
|
104
toxav/toxav.c
104
toxav/toxav.c
|
@ -592,17 +592,22 @@ bool toxav_set_video_bit_rate(ToxAV* av, uint32_t friend_number, uint32_t video_
|
|||
goto END;
|
||||
}
|
||||
|
||||
if (call->video_bit_rate == video_bit_rate && call->vba.active && call->vba.bit_rate == video_bit_rate) {
|
||||
if (call->video_bit_rate == video_bit_rate || call->vba.active || call->vba.bit_rate == video_bit_rate) {
|
||||
pthread_mutex_unlock(av->mutex);
|
||||
goto END;
|
||||
}
|
||||
|
||||
pthread_mutex_lock(call->mutex);
|
||||
if (force) {
|
||||
call->video_bit_rate = video_bit_rate;
|
||||
} else {
|
||||
|
||||
if (video_bit_rate > call->video_bit_rate && !force)
|
||||
ba_set(&call->vba, video_bit_rate);
|
||||
else {
|
||||
call->video_bit_rate = video_bit_rate;
|
||||
|
||||
if (!force && av->vbcb.first)
|
||||
av->vbcb.first (av, call->friend_id, true, video_bit_rate, av->vbcb.second);
|
||||
}
|
||||
|
||||
pthread_mutex_unlock(call->mutex);
|
||||
pthread_mutex_unlock(av->mutex);
|
||||
|
||||
|
@ -644,16 +649,21 @@ bool toxav_set_audio_bit_rate(ToxAV* av, uint32_t friend_number, uint32_t audio_
|
|||
goto END;
|
||||
}
|
||||
|
||||
if (call->audio_bit_rate == audio_bit_rate && call->aba.active && call->aba.bit_rate == audio_bit_rate) {
|
||||
if (call->audio_bit_rate == audio_bit_rate || call->aba.active || call->aba.bit_rate == audio_bit_rate) {
|
||||
pthread_mutex_unlock(av->mutex);
|
||||
goto END;
|
||||
}
|
||||
|
||||
pthread_mutex_lock(call->mutex);
|
||||
if (force) {
|
||||
call->audio_bit_rate = audio_bit_rate;
|
||||
} else
|
||||
|
||||
if (audio_bit_rate > call->audio_bit_rate && !force)
|
||||
ba_set(&call->aba, audio_bit_rate);
|
||||
else {
|
||||
call->audio_bit_rate = audio_bit_rate;
|
||||
|
||||
if (!force && av->abcb.first)
|
||||
av->abcb.first (av, call->friend_id, true, audio_bit_rate, av->abcb.second);
|
||||
}
|
||||
|
||||
pthread_mutex_unlock(call->mutex);
|
||||
pthread_mutex_unlock(av->mutex);
|
||||
|
@ -692,7 +702,7 @@ bool toxav_send_video_frame(ToxAV* av, uint32_t friend_number, uint16_t width, u
|
|||
goto END;
|
||||
}
|
||||
|
||||
if ( vc_reconfigure_encoder(call->video.second, call->video_bit_rate, width, height) != 0 ) {
|
||||
if ( vc_reconfigure_encoder(call->video.second, call->video_bit_rate * 1000, width, height) != 0 ) {
|
||||
pthread_mutex_unlock(call->mutex_video);
|
||||
rc = TOXAV_ERR_SEND_FRAME_INVALID;
|
||||
goto END;
|
||||
|
@ -755,6 +765,69 @@ bool toxav_send_video_frame(ToxAV* av, uint32_t friend_number, uint16_t width, u
|
|||
}
|
||||
}
|
||||
|
||||
if (ba_shoud_send_dummy(&call->vba)) {
|
||||
if ( vc_reconfigure_test_encoder(call->video.second, call->vba.bit_rate * 1000, width, height) != 0 ) {
|
||||
pthread_mutex_unlock(call->mutex_video);
|
||||
rc = TOXAV_ERR_SEND_FRAME_INVALID;
|
||||
goto END;
|
||||
}
|
||||
|
||||
/* FIXME use the same image as before */
|
||||
vpx_image_t img;
|
||||
img.w = img.h = img.d_w = img.d_h = 0;
|
||||
vpx_img_alloc(&img, VPX_IMG_FMT_VPXI420, width, height, 1);
|
||||
|
||||
/* I420 "It comprises an NxM Y plane followed by (N/2)x(M/2) V and U planes."
|
||||
* http://fourcc.org/yuv.php#IYUV
|
||||
*/
|
||||
memcpy(img.planes[VPX_PLANE_Y], y, width * height);
|
||||
memcpy(img.planes[VPX_PLANE_U], u, (width/2) * (height/2));
|
||||
memcpy(img.planes[VPX_PLANE_V], v, (width/2) * (height/2));
|
||||
|
||||
int vrc = vpx_codec_encode(call->video.second->test_encoder, &img,
|
||||
call->video.second->test_frame_counter, 1, 0, MAX_ENCODE_TIME_US);
|
||||
|
||||
vpx_img_free(&img);
|
||||
if ( vrc != VPX_CODEC_OK) {
|
||||
pthread_mutex_unlock(call->mutex_video);
|
||||
LOGGER_ERROR("Could not encode video frame: %s\n", vpx_codec_err_to_string(vrc));
|
||||
rc = TOXAV_ERR_SEND_FRAME_INVALID;
|
||||
goto END;
|
||||
}
|
||||
|
||||
call->video.second->test_frame_counter++;
|
||||
|
||||
vpx_codec_iter_t iter = NULL;
|
||||
const vpx_codec_cx_pkt_t *pkt;
|
||||
|
||||
/* Send the encoded data as dummy packets */
|
||||
while ( (pkt = vpx_codec_get_cx_data(call->video.second->test_encoder, &iter)) ) {
|
||||
if (pkt->kind == VPX_CODEC_CX_FRAME_PKT) {
|
||||
|
||||
int parts = pkt->data.frame.sz / 1300;
|
||||
int i;
|
||||
for (i = 0; i < parts; i++) {
|
||||
if (rtp_send_data(call->video.first, pkt->data.frame.buf + i * 1300, 1300, true) < 0) {
|
||||
pthread_mutex_unlock(call->mutex_video);
|
||||
LOGGER_WARNING("Could not send video frame: %s\n", strerror(errno));
|
||||
goto END;
|
||||
}
|
||||
}
|
||||
|
||||
if (pkt->data.frame.sz % 1300) {
|
||||
if (rtp_send_data(call->video.first, pkt->data.frame.buf + parts * 1300, pkt->data.frame.sz % 1300, true) < 0) {
|
||||
pthread_mutex_unlock(call->mutex_video);
|
||||
LOGGER_WARNING("Could not send video frame: %s\n", strerror(errno));
|
||||
goto END;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (call->vba.end_time == ~0)
|
||||
call->vba.end_time = current_time_monotonic() + BITRATE_CHANGE_TESTING_TIME_MS;
|
||||
}
|
||||
|
||||
pthread_mutex_unlock(call->mutex_video);
|
||||
|
||||
END:
|
||||
|
@ -824,8 +897,8 @@ bool toxav_send_audio_frame(ToxAV* av, uint32_t friend_number, const int16_t* pc
|
|||
}
|
||||
|
||||
|
||||
/* For bitrate measurement; send dummy packet */
|
||||
if (ba_shoud_send_dummy(&call->aba)) {
|
||||
/* For bitrate measurement; send dummy packet */
|
||||
if (ba_shoud_send_dummy(&call->aba)) {
|
||||
sampling_rate = ntohl(sampling_rate);
|
||||
if (ac_reconfigure_test_encoder(call->audio.second, call->audio_bit_rate * 1000, sampling_rate, channels) != 0) {
|
||||
/* FIXME should the bitrate changing fail here? */
|
||||
|
@ -837,7 +910,7 @@ bool toxav_send_audio_frame(ToxAV* av, uint32_t friend_number, const int16_t* pc
|
|||
sampling_rate = htonl(sampling_rate);
|
||||
memcpy(dest, &sampling_rate, sizeof(sampling_rate));
|
||||
vrc = opus_encode(call->audio.second->test_encoder, pcm, sample_count,
|
||||
dest + sizeof(sampling_rate), sizeof(dest) - sizeof(sampling_rate));
|
||||
dest + sizeof(sampling_rate), sizeof(dest) - sizeof(sampling_rate));
|
||||
|
||||
if (vrc < 0) {
|
||||
LOGGER_WARNING("Failed to encode frame %s", opus_strerror(vrc));
|
||||
|
@ -850,10 +923,13 @@ bool toxav_send_audio_frame(ToxAV* av, uint32_t friend_number, const int16_t* pc
|
|||
LOGGER_WARNING("Failed to send audio packet");
|
||||
rc = TOXAV_ERR_SEND_FRAME_RTP_FAILED;
|
||||
}
|
||||
|
||||
if (call->aba.end_time == ~0)
|
||||
call->aba.end_time = current_time_monotonic() + BITRATE_CHANGE_TESTING_TIME_MS;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
pthread_mutex_unlock(call->mutex_audio);
|
||||
|
||||
END:
|
||||
|
@ -1219,7 +1295,7 @@ void ba_set(ToxAvBitrateAdapter* ba, uint32_t bit_rate)
|
|||
{
|
||||
ba->bit_rate = bit_rate;
|
||||
ba->next_send = current_time_monotonic();
|
||||
ba->end_time = ba->next_send + BITRATE_CHANGE_TESTING_TIME_MS;
|
||||
ba->end_time = ~0;
|
||||
ba->next_send_interval = 1000;
|
||||
ba->active = true;
|
||||
}
|
||||
|
|
|
@ -76,6 +76,11 @@ VCSession* vc_new(ToxAV* av, uint32_t friend_id, toxav_receive_video_frame_cb* c
|
|||
vpx_codec_destroy(vc->decoder);
|
||||
goto BASE_CLEANUP;
|
||||
}
|
||||
if (!create_video_encoder(vc->test_encoder, 500000)) {
|
||||
vpx_codec_destroy(vc->encoder);
|
||||
vpx_codec_destroy(vc->decoder);
|
||||
goto BASE_CLEANUP;
|
||||
}
|
||||
|
||||
vc->linfts = current_time_monotonic();
|
||||
vc->lcfd = 60;
|
||||
|
@ -100,6 +105,7 @@ void vc_kill(VCSession* vc)
|
|||
return;
|
||||
|
||||
vpx_codec_destroy(vc->encoder);
|
||||
vpx_codec_destroy(vc->test_encoder);
|
||||
vpx_codec_destroy(vc->decoder);
|
||||
rb_free(vc->vbuf_raw);
|
||||
free(vc->split_video_frame);
|
||||
|
@ -288,7 +294,7 @@ int vc_reconfigure_encoder(VCSession* vc, int32_t bitrate, uint16_t width, uint1
|
|||
if (!vc)
|
||||
return -1;
|
||||
|
||||
vpx_codec_enc_cfg_t cfg = *vc->encoder[0].config.enc;
|
||||
vpx_codec_enc_cfg_t cfg = *vc->encoder->config.enc;
|
||||
if (cfg.rc_target_bitrate == bitrate && cfg.g_w == width && cfg.g_h == height)
|
||||
return 0; /* Nothing changed */
|
||||
|
||||
|
@ -304,6 +310,27 @@ int vc_reconfigure_encoder(VCSession* vc, int32_t bitrate, uint16_t width, uint1
|
|||
|
||||
return 0;
|
||||
}
|
||||
int vc_reconfigure_test_encoder(VCSession* vc, int32_t bitrate, uint16_t width, uint16_t height)
|
||||
{
|
||||
if (!vc)
|
||||
return -1;
|
||||
|
||||
vpx_codec_enc_cfg_t cfg = *vc->test_encoder->config.enc;
|
||||
if (cfg.rc_target_bitrate == bitrate && cfg.g_w == width && cfg.g_h == height)
|
||||
return 0; /* Nothing changed */
|
||||
|
||||
cfg.rc_target_bitrate = bitrate;
|
||||
cfg.g_w = width;
|
||||
cfg.g_h = height;
|
||||
|
||||
int rc = vpx_codec_enc_config_set(vc->test_encoder, &cfg);
|
||||
if ( rc != VPX_CODEC_OK) {
|
||||
LOGGER_ERROR("Failed to set test encoder control setting: %s", vpx_codec_err_to_string(rc));
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -42,7 +42,9 @@ typedef struct VCSession_s {
|
|||
|
||||
/* encoding */
|
||||
vpx_codec_ctx_t encoder[1];
|
||||
vpx_codec_ctx_t test_encoder[1];
|
||||
uint32_t frame_counter;
|
||||
uint32_t test_frame_counter;
|
||||
|
||||
/* decoding */
|
||||
vpx_codec_ctx_t decoder[1];
|
||||
|
@ -80,5 +82,6 @@ int vc_update_video_splitter_cycle(VCSession* vc, const uint8_t* payload, uint16
|
|||
const uint8_t *vc_iterate_split_video_frame(VCSession* vc, uint16_t *size);
|
||||
int vc_queue_message(void *vcp, struct RTPMessage_s *msg);
|
||||
int vc_reconfigure_encoder(VCSession* vc, int32_t bitrate, uint16_t width, uint16_t height);
|
||||
int vc_reconfigure_test_encoder(VCSession* vc, int32_t bitrate, uint16_t width, uint16_t height);
|
||||
|
||||
#endif /* VIDEO_H */
|
Loading…
Reference in New Issue
Block a user