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.
This commit is contained in:
irungentoo 2014-07-05 14:36:19 -04:00
parent bdb00322e3
commit 65b4c026f4
No known key found for this signature in database
GPG Key ID: 10349DC9BED89E98
5 changed files with 27 additions and 18 deletions

View File

@ -199,7 +199,7 @@ START_TEST(test_AV_flows)
printf("All set after %llu seconds! Starting call...\n", time(NULL) - cur_time); printf("All set after %llu seconds! Starting call...\n", time(NULL) - cur_time);
muhcaps = av_DefaultSettings; muhcaps = av_DefaultSettings;
muhcaps.video_height = muhcaps.video_width = 128; muhcaps.max_video_height = muhcaps.max_video_width = 128;
Status status_control = { Status status_control = {
{none, toxav_new(Alice, 1), NULL, -1}, {none, toxav_new(Alice, 1), NULL, -1},

View File

@ -217,6 +217,9 @@ int reconfigure_video_encoder_resolution(CodecState *cs, uint16_t width, uint16_
if (cfg.g_w == width && cfg.g_h == height) if (cfg.g_w == width && cfg.g_h == height)
return 0; return 0;
if (width * height > cs->max_width * cs->max_height)
return -1;
LOGGER_DEBUG("New video resolution: %u %u", width, height); LOGGER_DEBUG("New video resolution: %u %u", width, height);
cfg.g_w = width; cfg.g_w = width;
cfg.g_h = height; cfg.g_h = height;
@ -249,7 +252,7 @@ int reconfigure_video_encoder_bitrate(CodecState *cs, uint32_t video_bitrate)
return 0; return 0;
} }
int init_video_encoder(CodecState *cs, uint16_t width, uint16_t height, uint32_t video_bitrate) int init_video_encoder(CodecState *cs, uint16_t max_width, uint16_t max_height, uint32_t video_bitrate)
{ {
vpx_codec_enc_cfg_t cfg; vpx_codec_enc_cfg_t cfg;
int rc = vpx_codec_enc_config_default(VIDEO_CODEC_ENCODER_INTERFACE, &cfg, 0); 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
} }
cfg.rc_target_bitrate = video_bitrate; cfg.rc_target_bitrate = video_bitrate;
cfg.g_w = 8192; cfg.g_w = max_width;
cfg.g_h = 8192; cfg.g_h = max_height;
cfg.g_pass = VPX_RC_ONE_PASS; cfg.g_pass = VPX_RC_ONE_PASS;
cfg.g_error_resilient = VPX_ERROR_RESILIENT_DEFAULT | VPX_ERROR_RESILIENT_PARTITIONS; cfg.g_error_resilient = VPX_ERROR_RESILIENT_DEFAULT | VPX_ERROR_RESILIENT_PARTITIONS;
cfg.g_lag_in_frames = 0; cfg.g_lag_in_frames = 0;
cfg.kf_min_dist = 0; cfg.kf_min_dist = 0;
cfg.kf_max_dist = 300; cfg.kf_max_dist = 300;
cfg.kf_mode = VPX_KF_AUTO;
cs->max_width = max_width;
cs->max_height = max_height;
cs->bitrate = video_bitrate;
rc = vpx_codec_enc_init_ver(&cs->v_encoder, VIDEO_CODEC_ENCODER_INTERFACE, &cfg, 0, VPX_ENCODER_ABI_VERSION); rc = vpx_codec_enc_init_ver(&cs->v_encoder, VIDEO_CODEC_ENCODER_INTERFACE, &cfg, 0, VPX_ENCODER_ABI_VERSION);
@ -282,9 +290,6 @@ int init_video_encoder(CodecState *cs, uint16_t width, uint16_t height, uint32_t
return -1; return -1;
} }
if (reconfigure_video_encoder_resolution(cs, width, height) != 0)
return -1;
return 0; return 0;
} }
@ -322,8 +327,8 @@ CodecState *codec_init_session ( uint32_t audio_bitrate,
uint32_t audio_sample_rate, uint32_t audio_sample_rate,
uint32_t audio_channels, uint32_t audio_channels,
uint32_t audio_VAD_tolerance_ms, uint32_t audio_VAD_tolerance_ms,
uint16_t video_width, uint16_t max_video_width,
uint16_t video_height, uint16_t max_video_height,
uint32_t video_bitrate ) uint32_t video_bitrate )
{ {
CodecState *retu = calloc(sizeof(CodecState), 1); CodecState *retu = calloc(sizeof(CodecState), 1);
@ -334,11 +339,11 @@ CodecState *codec_init_session ( uint32_t audio_bitrate,
retu->audio_sample_rate = audio_sample_rate; retu->audio_sample_rate = audio_sample_rate;
/* Encoders */ /* Encoders */
if (!video_width || !video_height) { /* Disable video */ if (!max_video_width || !max_video_height) { /* Disable video */
/*video_width = 320; /*video_width = 320;
video_height = 240; */ video_height = 240; */
} else { } else {
retu->capabilities |= ( 0 == init_video_encoder(retu, video_width, video_height, video_bitrate) ) ? v_encoding : 0; retu->capabilities |= ( 0 == init_video_encoder(retu, max_video_width, max_video_height, video_bitrate) ) ? v_encoding : 0;
retu->capabilities |= ( 0 == init_video_decoder(retu) ) ? v_decoding : 0; retu->capabilities |= ( 0 == init_video_decoder(retu) ) ? v_decoding : 0;
} }

View File

@ -56,6 +56,9 @@ typedef struct _CodecState {
/* video decoding */ /* video decoding */
vpx_codec_ctx_t v_decoder; vpx_codec_ctx_t v_decoder;
int bitrate;
int max_width;
int max_height;
/* audio encoding */ /* audio encoding */
OpusEncoder *audio_encoder; OpusEncoder *audio_encoder;

View File

@ -81,8 +81,8 @@ struct _ToxAv {
const ToxAvCodecSettings av_DefaultSettings = { const ToxAvCodecSettings av_DefaultSettings = {
500, 500,
800, 1280,
600, 720,
64000, 64000,
20, 20,
@ -350,8 +350,8 @@ int toxav_prepare_transmission ( ToxAv *av, int32_t call_index, ToxAvCodecSettin
codec_settings->audio_sample_rate, codec_settings->audio_sample_rate,
codec_settings->audio_channels, codec_settings->audio_channels,
codec_settings->audio_VAD_tolerance, codec_settings->audio_VAD_tolerance,
codec_settings->video_width, codec_settings->max_video_width,
codec_settings->video_height, codec_settings->max_video_height,
codec_settings->video_bitrate) )) { codec_settings->video_bitrate) )) {
if ( pthread_mutex_init(&call->mutex, NULL) != 0 ) goto error; 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
CallSpecific *call = &av->calls[call_index]; CallSpecific *call = &av->calls[call_index];
pthread_mutex_lock(&call->mutex); pthread_mutex_lock(&call->mutex);
reconfigure_video_encoder_resolution(call->cs, input->d_w, input->d_h); if (reconfigure_video_encoder_resolution(call->cs, input->d_w, input->d_h) != 0)
return ErrorInternal;
int rc = vpx_codec_encode(&call->cs->v_encoder, input, call->cs->frame_counter, 1, 0, MAX_ENCODE_TIME_US); int rc = vpx_codec_encode(&call->cs->v_encoder, input, call->cs->frame_counter, 1, 0, MAX_ENCODE_TIME_US);

View File

@ -120,8 +120,8 @@ typedef enum {
*/ */
typedef struct _ToxAvCodecSettings { typedef struct _ToxAvCodecSettings {
uint32_t video_bitrate; /* In kbits/s */ uint32_t video_bitrate; /* In kbits/s */
uint16_t video_width; /* In px */ uint16_t max_video_width; /* In px */
uint16_t video_height; /* In px */ uint16_t max_video_height; /* In px */
uint32_t audio_bitrate; /* In bits/s */ uint32_t audio_bitrate; /* In bits/s */
uint16_t audio_frame_duration; /* In ms */ uint16_t audio_frame_duration; /* In ms */