コード例 #1
0
ファイル: codec.c プロジェクト: ittner/toxcore
int cs_set_video_encoder_resolution(CSSession *cs, uint16_t width, uint16_t height)
{
    vpx_codec_enc_cfg_t cfg = *cs->v_encoder.config.enc;

    if (cfg.g_w == width && cfg.g_h == height)
        return 0;

    if (width * height > cs->max_width * cs->max_height) {
        vpx_codec_ctx_t v_encoder = cs->v_encoder;

        if (init_video_encoder(cs, width, height, cs->video_bitrate) == -1) {
            cs->v_encoder = v_encoder;
            return cs_ErrorSettingVideoResolution;
        }

        vpx_codec_destroy(&v_encoder);
        return 0;
    }

    LOGGER_DEBUG("New video resolution: %u %u", width, height);
    cfg.g_w = width;
    cfg.g_h = height;
    int rc = vpx_codec_enc_config_set(&cs->v_encoder, &cfg);

    if ( rc != VPX_CODEC_OK) {
        LOGGER_ERROR("Failed to set encoder control setting: %s", vpx_codec_err_to_string(rc));
        return cs_ErrorSettingVideoResolution;
    }

    return 0;
}
コード例 #2
0
ファイル: video.c プロジェクト: TokTok/toxcore
int vc_reconfigure_encoder(VCSession *vc, uint32_t bit_rate, uint16_t width, uint16_t height, int16_t kf_max_dist)
{
    if (!vc) {
        return -1;
    }

    vpx_codec_enc_cfg_t cfg2 = *vc->encoder->config.enc;
    vpx_codec_err_t rc;

    if (cfg2.rc_target_bitrate == bit_rate && cfg2.g_w == width && cfg2.g_h == height && kf_max_dist == -1) {
        return 0; /* Nothing changed */
    }

    if (cfg2.g_w == width && cfg2.g_h == height && kf_max_dist == -1) {
        /* Only bit rate changed */
        LOGGER_INFO(vc->log, "bitrate change from: %u to: %u", (uint32_t)cfg2.rc_target_bitrate, (uint32_t)bit_rate);
        cfg2.rc_target_bitrate = bit_rate;
        rc = vpx_codec_enc_config_set(vc->encoder, &cfg2);

        if (rc != VPX_CODEC_OK) {
            LOGGER_ERROR(vc->log, "Failed to set encoder control setting: %s", vpx_codec_err_to_string(rc));
            return -1;
        }
    } else {
        /* Resolution is changed, must reinitialize encoder since libvpx v1.4 doesn't support
         * reconfiguring encoder to use resolutions greater than initially set.
         */
        LOGGER_DEBUG(vc->log, "Have to reinitialize vpx encoder on session %p", (void *)vc);
        vpx_codec_ctx_t new_c;
        vpx_codec_enc_cfg_t  cfg;
        vc_init_encoder_cfg(vc->log, &cfg, kf_max_dist);
        cfg.rc_target_bitrate = bit_rate;
        cfg.g_w = width;
        cfg.g_h = height;

        LOGGER_DEBUG(vc->log, "Using VP8 codec for encoder");
        rc = vpx_codec_enc_init(&new_c, video_codec_encoder_interface(), &cfg, VPX_CODEC_USE_FRAME_THREADING);

        if (rc != VPX_CODEC_OK) {
            LOGGER_ERROR(vc->log, "Failed to initialize encoder: %s", vpx_codec_err_to_string(rc));
            return -1;
        }

        int cpu_used_value = VP8E_SET_CPUUSED_VALUE;

        rc = vpx_codec_control(&new_c, VP8E_SET_CPUUSED, cpu_used_value);

        if (rc != VPX_CODEC_OK) {
            LOGGER_ERROR(vc->log, "Failed to set encoder control setting: %s", vpx_codec_err_to_string(rc));
            vpx_codec_destroy(&new_c);
            return -1;
        }

        vpx_codec_destroy(vc->encoder);
        memcpy(vc->encoder, &new_c, sizeof(new_c));
    }

    return 0;
}
コード例 #3
0
ファイル: krad_vpx.c プロジェクト: brooss/krcam
void krad_vpx_encoder_config_set (krad_vpx_encoder_t *vpx,
                                  vpx_codec_enc_cfg_t *cfg) {
  int ret;

  ret = vpx_codec_enc_config_set (&vpx->encoder, cfg);

  if (ret != VPX_CODEC_OK) {
    printke ("VPX Config problem: %s\n", vpx_codec_err_to_string (ret));
  }
}
コード例 #4
0
/*
 * Method:    codec_enc_config_set
 */
JNIEXPORT jint JNICALL
Java_org_jitsi_impl_neomedia_codec_video_VPX_codec_1enc_1config_1set
    (JNIEnv *env,
     jclass clazz,
     jlong context,
     jlong cfg)
{
    return (jint) vpx_codec_enc_config_set(
                (vpx_codec_ctx_t *) (intptr_t) context,
                (vpx_codec_enc_cfg_t *) (intptr_t) context);
}
コード例 #5
0
ファイル: codec.c プロジェクト: D3cryptor/toxcore
int reconfigure_video_encoder_bitrate(CodecState *cs, uint32_t video_bitrate)
{
    vpx_codec_enc_cfg_t cfg = *cs->v_encoder.config.enc;

    if (cfg.rc_target_bitrate == video_bitrate)
        return 0;

    LOGGER_DEBUG("New video bitrate: %u", video_bitrate);
    cfg.rc_target_bitrate = video_bitrate;
    int rc = vpx_codec_enc_config_set(&cs->v_encoder, &cfg);

    if ( rc != VPX_CODEC_OK) {
        LOGGER_ERROR("Failed to set encoder control setting: %s", vpx_codec_err_to_string(rc));
        return -1;
    }

    return 0;
}
コード例 #6
0
ファイル: codec.c プロジェクト: D3cryptor/toxcore
int reconfigure_video_encoder_resolution(CodecState *cs, uint16_t width, uint16_t height)
{
    vpx_codec_enc_cfg_t cfg = *cs->v_encoder.config.enc;

    if (cfg.g_w == width && cfg.g_h == height)
        return 0;

    if (width * height > cs->max_width * cs->max_height)
        return -1;

    LOGGER_DEBUG("New video resolution: %u %u", width, height);
    cfg.g_w = width;
    cfg.g_h = height;
    int rc = vpx_codec_enc_config_set(&cs->v_encoder, &cfg);

    if ( rc != VPX_CODEC_OK) {
        LOGGER_ERROR("Failed to set encoder control setting: %s", vpx_codec_err_to_string(rc));
        return -1;
    }

    return 0;
}
コード例 #7
0
static switch_status_t init_encoder(switch_codec_t *codec)
{
	vpx_context_t *context = (vpx_context_t *)codec->private_info;
	vpx_codec_enc_cfg_t *config = &context->config;
	int token_parts = 1;
	int cpus = switch_core_cpu_count();

	if (!context->codec_settings.video.width) {
		context->codec_settings.video.width = 1280;
	}

	if (!context->codec_settings.video.height) {
		context->codec_settings.video.height = 720;
	}

	if (context->codec_settings.video.bandwidth == -1) {
		context->codec_settings.video.bandwidth = 0;
	}

	if (context->codec_settings.video.bandwidth) {
		context->bandwidth = context->codec_settings.video.bandwidth;
	} else {
		context->bandwidth = switch_calc_bitrate(context->codec_settings.video.width, context->codec_settings.video.height, 0, 0);
	}

	if (context->bandwidth > 40960) {
		context->bandwidth = 40960;
	}

	context->pkt = NULL;

	switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(codec->session), SWITCH_LOG_DEBUG1, 
					  "VPX reset encoder picture from %dx%d to %dx%d %u BW\n", 
					  config->g_w, config->g_h, context->codec_settings.video.width, context->codec_settings.video.height, context->bandwidth);

	context->start_time = switch_micro_time_now();
	
	config->g_timebase.num = 1;
	config->g_timebase.den = 1000;
	config->g_pass = VPX_RC_ONE_PASS;
	config->g_w = context->codec_settings.video.width;
	config->g_h = context->codec_settings.video.height;	
	config->rc_target_bitrate = context->bandwidth;
	config->g_lag_in_frames = 0;
	config->kf_max_dist = 2000;
	config->g_threads = (cpus > 1) ? 2 : 1;
	
	if (context->is_vp9) {
		//config->rc_dropframe_thresh = 2;
		token_parts = (cpus > 1) ? 3 : 0;

		if (context->lossless) {
			config->rc_min_quantizer = 0;
			config->rc_max_quantizer = 0;
		} else {
			config->rc_min_quantizer = 0;
			config->rc_max_quantizer = 63;
		}

	} else {

		// settings
		config->g_profile = 2;
		config->g_error_resilient = VPX_ERROR_RESILIENT_PARTITIONS;
		token_parts = (cpus > 1) ? 3 : 0;

		// rate control settings
		config->rc_dropframe_thresh = 0;
		config->rc_end_usage = VPX_CBR;
		//config->g_pass = VPX_RC_ONE_PASS;
		config->kf_mode = VPX_KF_AUTO;
		config->kf_max_dist = 1000;

		//config->kf_mode = VPX_KF_DISABLED;
		config->rc_resize_allowed = 1;
		//config->rc_min_quantizer = 0;
		//config->rc_max_quantizer = 63;
		config->rc_min_quantizer = 0;
		config->rc_max_quantizer = 63;
		//Rate control adaptation undershoot control.
		//	This value, expressed as a percentage of the target bitrate,
		//	controls the maximum allowed adaptation speed of the codec.
		//	This factor controls the maximum amount of bits that can be
		//	subtracted from the target bitrate in order to compensate for
		//	prior overshoot.
		//	Valid values in the range 0-1000.
		config->rc_undershoot_pct = 100;
		//Rate control adaptation overshoot control.
		//	This value, expressed as a percentage of the target bitrate,
		//	controls the maximum allowed adaptation speed of the codec.
		//	This factor controls the maximum amount of bits that can be
		//	added to the target bitrate in order to compensate for prior
		//	undershoot.
		//	Valid values in the range 0-1000.
		config->rc_overshoot_pct = 15;
		//Decoder Buffer Size.
		//	This value indicates the amount of data that may be buffered
		//	by the decoding application. Note that this value is expressed
		//	in units of time (milliseconds). For example, a value of 5000
		//	indicates that the client will buffer (at least) 5000ms worth
		//	of encoded data. Use the target bitrate (rc_target_bitrate) to
		//	convert to bits/bytes, if necessary.
		config->rc_buf_sz = 5000;
		//Decoder Buffer Initial Size.
		//	This value indicates the amount of data that will be buffered
		//	by the decoding application prior to beginning playback.
		//	This value is expressed in units of time (milliseconds).
		//	Use the target bitrate (rc_target_bitrate) to convert to
		//	bits/bytes, if necessary.
		config->rc_buf_initial_sz = 1000;
		//Decoder Buffer Optimal Size.
		//	This value indicates the amount of data that the encoder should
		//	try to maintain in the decoder's buffer. This value is expressed
		//	in units of time (milliseconds).
		//	Use the target bitrate (rc_target_bitrate) to convert to
		//	bits/bytes, if necessary.
		config->rc_buf_optimal_sz = 1000;
	}

	if (context->encoder_init) {
		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "VPX ENCODER RESET\n");
		if (vpx_codec_enc_config_set(&context->encoder, config) != VPX_CODEC_OK) {
			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Codec init error: [%d:%s]\n", context->encoder.err, context->encoder.err_detail);
		}
	} else if (context->flags & SWITCH_CODEC_FLAG_ENCODE) {

		if (vpx_codec_enc_init(&context->encoder, context->encoder_interface, config, 0 & VPX_CODEC_USE_OUTPUT_PARTITION) != VPX_CODEC_OK) {
			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Codec init error: [%d:%s]\n", context->encoder.err, context->encoder.err_detail);
			return SWITCH_STATUS_FALSE;
		}
		
		context->encoder_init = 1;

		if (context->is_vp9) {
			if (context->lossless) {
				vpx_codec_control(&context->encoder, VP9E_SET_LOSSLESS, 1);
				vpx_codec_control(&context->encoder, VP8E_SET_CPUUSED, -6);
			} else {
				vpx_codec_control(&context->encoder, VP8E_SET_CPUUSED, -8);
			}

			vpx_codec_control(&context->encoder, VP8E_SET_STATIC_THRESHOLD, 100);
			vpx_codec_control(&context->encoder, VP8E_SET_TOKEN_PARTITIONS, token_parts);
			vpx_codec_control(&context->encoder, VP9E_SET_TUNE_CONTENT, VP9E_CONTENT_SCREEN);

		} else {
			// The static threshold imposes a change threshold on blocks below which they will be skipped by the encoder.
			vpx_codec_control(&context->encoder, VP8E_SET_STATIC_THRESHOLD, 100);
			//Set cpu usage, a bit lower than normal (-6) but higher than android (-12)
			vpx_codec_control(&context->encoder, VP8E_SET_CPUUSED, -6);
			vpx_codec_control(&context->encoder, VP8E_SET_TOKEN_PARTITIONS, token_parts);
			
			// Enable noise reduction
			vpx_codec_control(&context->encoder, VP8E_SET_NOISE_SENSITIVITY, 1);
			//Set max data rate for Intra frames.
			//	This value controls additional clamping on the maximum size of a keyframe.
			//	It is expressed as a percentage of the average per-frame bitrate, with the
			//	special (and default) value 0 meaning unlimited, or no additional clamping
			//	beyond the codec's built-in algorithm.
			//	For example, to allocate no more than 4.5 frames worth of bitrate to a keyframe, set this to 450.
			//vpx_codec_control(&context->encoder, VP8E_SET_MAX_INTRA_BITRATE_PCT, 0);
		}
	}

	return SWITCH_STATUS_SUCCESS;
}