summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorirungentoo <irungentoo@gmail.com>2014-07-05 14:36:19 -0400
committerirungentoo <irungentoo@gmail.com>2014-07-05 14:36:19 -0400
commit65b4c026f4a2aa965f89f28958fe75bceb16475c (patch)
tree6c7eb2c6760c2606f7e86bc03777c4abcb92b2ee
parentbdb00322e3ecb9eb213ce01688089cdad39304f0 (diff)
The width and height set during the video encoder initialization is
now described as the maximum width and height of images. This is to work around what appears to be a bug in libvpx where the resolution of the stream can be decreased but increasing it above its originally set value introduces memory corruption.
-rw-r--r--auto_tests/toxav_basic_test.c2
-rw-r--r--toxav/codec.c25
-rw-r--r--toxav/codec.h3
-rw-r--r--toxav/toxav.c11
-rw-r--r--toxav/toxav.h4
5 files changed, 27 insertions, 18 deletions
diff --git a/auto_tests/toxav_basic_test.c b/auto_tests/toxav_basic_test.c
index a1bccd7c..0a710746 100644
--- a/auto_tests/toxav_basic_test.c
+++ b/auto_tests/toxav_basic_test.c
@@ -199,7 +199,7 @@ START_TEST(test_AV_flows)
199 printf("All set after %llu seconds! Starting call...\n", time(NULL) - cur_time); 199 printf("All set after %llu seconds! Starting call...\n", time(NULL) - cur_time);
200 200
201 muhcaps = av_DefaultSettings; 201 muhcaps = av_DefaultSettings;
202 muhcaps.video_height = muhcaps.video_width = 128; 202 muhcaps.max_video_height = muhcaps.max_video_width = 128;
203 203
204 Status status_control = { 204 Status status_control = {
205 {none, toxav_new(Alice, 1), NULL, -1}, 205 {none, toxav_new(Alice, 1), NULL, -1},
diff --git a/toxav/codec.c b/toxav/codec.c
index ed0c8e54..595c0359 100644
--- a/toxav/codec.c
+++ b/toxav/codec.c
@@ -217,6 +217,9 @@ int reconfigure_video_encoder_resolution(CodecState *cs, uint16_t width, uint16_
217 if (cfg.g_w == width && cfg.g_h == height) 217 if (cfg.g_w == width && cfg.g_h == height)
218 return 0; 218 return 0;
219 219
220 if (width * height > cs->max_width * cs->max_height)
221 return -1;
222
220 LOGGER_DEBUG("New video resolution: %u %u", width, height); 223 LOGGER_DEBUG("New video resolution: %u %u", width, height);
221 cfg.g_w = width; 224 cfg.g_w = width;
222 cfg.g_h = height; 225 cfg.g_h = height;
@@ -249,7 +252,7 @@ int reconfigure_video_encoder_bitrate(CodecState *cs, uint32_t video_bitrate)
249 return 0; 252 return 0;
250} 253}
251 254
252int init_video_encoder(CodecState *cs, uint16_t width, uint16_t height, uint32_t video_bitrate) 255int init_video_encoder(CodecState *cs, uint16_t max_width, uint16_t max_height, uint32_t video_bitrate)
253{ 256{
254 vpx_codec_enc_cfg_t cfg; 257 vpx_codec_enc_cfg_t cfg;
255 int rc = vpx_codec_enc_config_default(VIDEO_CODEC_ENCODER_INTERFACE, &cfg, 0); 258 int rc = vpx_codec_enc_config_default(VIDEO_CODEC_ENCODER_INTERFACE, &cfg, 0);
@@ -260,13 +263,18 @@ int init_video_encoder(CodecState *cs, uint16_t width, uint16_t height, uint32_t
260 } 263 }
261 264
262 cfg.rc_target_bitrate = video_bitrate; 265 cfg.rc_target_bitrate = video_bitrate;
263 cfg.g_w = 8192; 266 cfg.g_w = max_width;
264 cfg.g_h = 8192; 267 cfg.g_h = max_height;
265 cfg.g_pass = VPX_RC_ONE_PASS; 268 cfg.g_pass = VPX_RC_ONE_PASS;
266 cfg.g_error_resilient = VPX_ERROR_RESILIENT_DEFAULT | VPX_ERROR_RESILIENT_PARTITIONS; 269 cfg.g_error_resilient = VPX_ERROR_RESILIENT_DEFAULT | VPX_ERROR_RESILIENT_PARTITIONS;
267 cfg.g_lag_in_frames = 0; 270 cfg.g_lag_in_frames = 0;
268 cfg.kf_min_dist = 0; 271 cfg.kf_min_dist = 0;
269 cfg.kf_max_dist = 300; 272 cfg.kf_max_dist = 300;
273 cfg.kf_mode = VPX_KF_AUTO;
274
275 cs->max_width = max_width;
276 cs->max_height = max_height;
277 cs->bitrate = video_bitrate;
270 278
271 rc = vpx_codec_enc_init_ver(&cs->v_encoder, VIDEO_CODEC_ENCODER_INTERFACE, &cfg, 0, VPX_ENCODER_ABI_VERSION); 279 rc = vpx_codec_enc_init_ver(&cs->v_encoder, VIDEO_CODEC_ENCODER_INTERFACE, &cfg, 0, VPX_ENCODER_ABI_VERSION);
272 280
@@ -282,9 +290,6 @@ int init_video_encoder(CodecState *cs, uint16_t width, uint16_t height, uint32_t
282 return -1; 290 return -1;
283 } 291 }
284 292
285 if (reconfigure_video_encoder_resolution(cs, width, height) != 0)
286 return -1;
287
288 return 0; 293 return 0;
289} 294}
290 295
@@ -322,8 +327,8 @@ CodecState *codec_init_session ( uint32_t audio_bitrate,
322 uint32_t audio_sample_rate, 327 uint32_t audio_sample_rate,
323 uint32_t audio_channels, 328 uint32_t audio_channels,
324 uint32_t audio_VAD_tolerance_ms, 329 uint32_t audio_VAD_tolerance_ms,
325 uint16_t video_width, 330 uint16_t max_video_width,
326 uint16_t video_height, 331 uint16_t max_video_height,
327 uint32_t video_bitrate ) 332 uint32_t video_bitrate )
328{ 333{
329 CodecState *retu = calloc(sizeof(CodecState), 1); 334 CodecState *retu = calloc(sizeof(CodecState), 1);
@@ -334,11 +339,11 @@ CodecState *codec_init_session ( uint32_t audio_bitrate,
334 retu->audio_sample_rate = audio_sample_rate; 339 retu->audio_sample_rate = audio_sample_rate;
335 340
336 /* Encoders */ 341 /* Encoders */
337 if (!video_width || !video_height) { /* Disable video */ 342 if (!max_video_width || !max_video_height) { /* Disable video */
338 /*video_width = 320; 343 /*video_width = 320;
339 video_height = 240; */ 344 video_height = 240; */
340 } else { 345 } else {
341 retu->capabilities |= ( 0 == init_video_encoder(retu, video_width, video_height, video_bitrate) ) ? v_encoding : 0; 346 retu->capabilities |= ( 0 == init_video_encoder(retu, max_video_width, max_video_height, video_bitrate) ) ? v_encoding : 0;
342 retu->capabilities |= ( 0 == init_video_decoder(retu) ) ? v_decoding : 0; 347 retu->capabilities |= ( 0 == init_video_decoder(retu) ) ? v_decoding : 0;
343 } 348 }
344 349
diff --git a/toxav/codec.h b/toxav/codec.h
index d8e9f1a7..a464ec8f 100644
--- a/toxav/codec.h
+++ b/toxav/codec.h
@@ -56,6 +56,9 @@ typedef struct _CodecState {
56 56
57 /* video decoding */ 57 /* video decoding */
58 vpx_codec_ctx_t v_decoder; 58 vpx_codec_ctx_t v_decoder;
59 int bitrate;
60 int max_width;
61 int max_height;
59 62
60 /* audio encoding */ 63 /* audio encoding */
61 OpusEncoder *audio_encoder; 64 OpusEncoder *audio_encoder;
diff --git a/toxav/toxav.c b/toxav/toxav.c
index 9a1c5e3e..606f1370 100644
--- a/toxav/toxav.c
+++ b/toxav/toxav.c
@@ -81,8 +81,8 @@ struct _ToxAv {
81 81
82const ToxAvCodecSettings av_DefaultSettings = { 82const ToxAvCodecSettings av_DefaultSettings = {
83 500, 83 500,
84 800, 84 1280,
85 600, 85 720,
86 86
87 64000, 87 64000,
88 20, 88 20,
@@ -350,8 +350,8 @@ int toxav_prepare_transmission ( ToxAv *av, int32_t call_index, ToxAvCodecSettin
350 codec_settings->audio_sample_rate, 350 codec_settings->audio_sample_rate,
351 codec_settings->audio_channels, 351 codec_settings->audio_channels,
352 codec_settings->audio_VAD_tolerance, 352 codec_settings->audio_VAD_tolerance,
353 codec_settings->video_width, 353 codec_settings->max_video_width,
354 codec_settings->video_height, 354 codec_settings->max_video_height,
355 codec_settings->video_bitrate) )) { 355 codec_settings->video_bitrate) )) {
356 356
357 if ( pthread_mutex_init(&call->mutex, NULL) != 0 ) goto error; 357 if ( pthread_mutex_init(&call->mutex, NULL) != 0 ) goto error;
@@ -642,7 +642,8 @@ inline__ int toxav_prepare_video_frame(ToxAv *av, int32_t call_index, uint8_t *d
642 CallSpecific *call = &av->calls[call_index]; 642 CallSpecific *call = &av->calls[call_index];
643 pthread_mutex_lock(&call->mutex); 643 pthread_mutex_lock(&call->mutex);
644 644
645 reconfigure_video_encoder_resolution(call->cs, input->d_w, input->d_h); 645 if (reconfigure_video_encoder_resolution(call->cs, input->d_w, input->d_h) != 0)
646 return ErrorInternal;
646 647
647 int rc = vpx_codec_encode(&call->cs->v_encoder, input, call->cs->frame_counter, 1, 0, MAX_ENCODE_TIME_US); 648 int rc = vpx_codec_encode(&call->cs->v_encoder, input, call->cs->frame_counter, 1, 0, MAX_ENCODE_TIME_US);
648 649
diff --git a/toxav/toxav.h b/toxav/toxav.h
index 2e71c4da..b7659441 100644
--- a/toxav/toxav.h
+++ b/toxav/toxav.h
@@ -120,8 +120,8 @@ typedef enum {
120 */ 120 */
121typedef struct _ToxAvCodecSettings { 121typedef struct _ToxAvCodecSettings {
122 uint32_t video_bitrate; /* In kbits/s */ 122 uint32_t video_bitrate; /* In kbits/s */
123 uint16_t video_width; /* In px */ 123 uint16_t max_video_width; /* In px */
124 uint16_t video_height; /* In px */ 124 uint16_t max_video_height; /* In px */
125 125
126 uint32_t audio_bitrate; /* In bits/s */ 126 uint32_t audio_bitrate; /* In bits/s */
127 uint16_t audio_frame_duration; /* In ms */ 127 uint16_t audio_frame_duration; /* In ms */