static void dec_preprocess(MSFilter* f) { DecState *s = (DecState *)f->data; vpx_codec_caps_t caps = vpx_codec_get_caps(s->iface); /* Initialize codec */ if (!s->ready){ s->flags = 0; if ((s->avpf_enabled == TRUE) && (caps & VPX_CODEC_CAP_INPUT_FRAGMENTS)) { s->flags |= VPX_CODEC_USE_INPUT_FRAGMENTS; } if (caps & VPX_CODEC_CAP_ERROR_CONCEALMENT) { s->flags |= VPX_CODEC_USE_ERROR_CONCEALMENT; } #ifdef VPX_CODEC_CAP_FRAME_THREADING if ((caps & VPX_CODEC_CAP_FRAME_THREADING) && (ms_factory_get_cpu_count(f->factory) > 1)) { s->flags |= VPX_CODEC_USE_FRAME_THREADING; } #endif if(vpx_codec_dec_init(&s->codec, s->iface, NULL, s->flags)) ms_error("Failed to initialize decoder"); ms_message("VP8: initializing decoder context: avpf=[%i] freeze_on_error=[%i]",s->avpf_enabled,s->freeze_on_error); vp8rtpfmt_unpacker_init(&s->unpacker, f, s->avpf_enabled, s->freeze_on_error, (s->flags & VPX_CODEC_USE_INPUT_FRAGMENTS) ? TRUE : FALSE); s->first_image_decoded = FALSE; s->ready=TRUE; } }
static int enc_set_vsize(MSFilter *f, void *data) { MSVideoConfiguration best_vconf; MSVideoSize *vs = (MSVideoSize *)data; EncState *s = (EncState *)f->data; best_vconf = ms_video_find_best_configuration_for_size(s->vconf_list, *vs, ms_factory_get_cpu_count(f->factory)); s->vconf.vsize = *vs; s->vconf.fps = best_vconf.fps; s->vconf.bitrate_limit = best_vconf.bitrate_limit; enc_set_configuration(f, &s->vconf); return 0; }
static int dec_initialize_impl(MSFilter *f){ DecState *s = (DecState *)f->data; vpx_codec_dec_cfg_t cfg; memset(&cfg, 0, sizeof(cfg)); cfg.threads = ms_factory_get_cpu_count(f->factory); if (vpx_codec_dec_init(&s->codec, s->iface, &cfg, s->flags)){ ms_error("Failed to initialize VP8 decoder"); return -1; } return 0; }
static int enc_set_vsize(MSFilter *f, void *arg){ MSVideoConfiguration best_vconf; EncData *d = (EncData *)f->data; MSVideoSize *vs = (MSVideoSize *)arg; best_vconf = ms_video_find_best_configuration_for_size(d->vconf_list, *vs, ms_factory_get_cpu_count(f->factory)); d->vconf.vsize = *vs; d->vconf.fps = best_vconf.fps; d->vconf.bitrate_limit = best_vconf.bitrate_limit; enc_set_configuration(f, &d->vconf); return 0; }
static void enc_init(MSFilter *f){ MSVideoSize vsize; EncData *d=ms_new0(EncData,1); d->packer=NULL; d->isYUV=TRUE; d->mode=1; d->avpf_enabled=FALSE; d->force_keyframe=FALSE; d->framenum=0; d->vconf_list=mediaCodecH264_conf_list; MS_VIDEO_SIZE_ASSIGN(vsize, CIF); d->vconf = ms_video_find_best_configuration_for_size(d->vconf_list, vsize, ms_factory_get_cpu_count(f->factory)); f->data=d; }
static void ms_opus_enc_preprocess(MSFilter *f) { int error; OpusEncData *d = (OpusEncData *)f->data; /* create the encoder */ d->state = opus_encoder_create(d->samplerate, d->channels, d->application, &error); if (error != OPUS_OK) { ms_error("Opus encoder creation failed: %s", opus_strerror(error)); return; } /* set complexity to 0 for single processor arm devices */ #if defined(__arm__) || defined(_M_ARM) if (ms_factory_get_cpu_count(f->factory)==1){ opus_encoder_ctl(d->state, OPUS_SET_COMPLEXITY(0)); }else{ opus_encoder_ctl(d->state, OPUS_SET_COMPLEXITY(5)); } #endif error = opus_encoder_ctl(d->state, OPUS_SET_PACKET_LOSS_PERC(10)); if (error != OPUS_OK) { ms_error("Could not set default loss percentage to opus encoder: %s", opus_strerror(error)); } /* set the encoder parameters: VBR, IN_BAND_FEC, DTX and bitrate settings */ ms_opus_enc_set_vbr(f); ms_opus_enc_set_inbandfec(f); ms_opus_enc_set_dtx(f); /* if decoder prefers mono signal, force encoder to output mono signal */ if (d->stereo == 0) { error = opus_encoder_ctl(d->state, OPUS_SET_FORCE_CHANNELS(1)); if (error != OPUS_OK) { ms_error("could not force mono channel to opus encoder: %s", opus_strerror(error)); } if (d->channels == 2) ms_message("Opus encoder configured to encode mono despite it is feed with stereo."); }else if (d->channels == 2){ ms_message("Opus encoder configured to encode stereo."); } ms_filter_lock(f); // set bitrate wasn't call, compute it with the default network bitrate (36000) if (d->bitrate==-1) { compute_max_bitrate(d, 0); } apply_max_bitrate(d); ms_filter_unlock(f); }
static void enc_init(MSFilter *f) { EncState *s = (EncState *)ms_new0(EncState, 1); MSVideoSize vsize; s->iface = vpx_codec_vp8_cx(); ms_message("Using %s", vpx_codec_iface_name(s->iface)); s->vconf_list = &vp8_conf_list[0]; MS_VIDEO_SIZE_ASSIGN(vsize, CIF); s->vconf = ms_video_find_best_configuration_for_size(s->vconf_list, vsize, ms_factory_get_cpu_count(f->factory)); s->frame_count = 0; s->last_fir_seq_nr = -1; #ifdef PICTURE_ID_ON_16_BITS s->picture_id = (ortp_random() & 0x7FFF) | 0x8000; #else s->picture_id = ortp_random() & 0x007F; #endif s->avpf_enabled = FALSE; enc_reset_frames_state(s); f->data = s; }
unsigned int ms_get_cpu_count() { return ms_factory_get_cpu_count(ms_factory_get_fallback()); }
static int enc_set_br(MSFilter *f, void *data) { EncState *s = (EncState *)f->data; int br = *(int *)data; if (s->ready) { /* Encoding is already ongoing, do not change video size, only bitrate. */ s->vconf.required_bitrate = br; enc_set_configuration(f, &s->vconf); } else { MSVideoConfiguration best_vconf = ms_video_find_best_configuration_for_bitrate(s->vconf_list, br, ms_factory_get_cpu_count(f->factory)); enc_set_configuration(f, &best_vconf); } return 0; }
static void enc_preprocess(MSFilter *f) { EncState *s = (EncState *)f->data; vpx_codec_err_t res; vpx_codec_caps_t caps; int cpuused=0; /* Populate encoder configuration */ s->flags = 0; caps = vpx_codec_get_caps(s->iface); if ((s->avpf_enabled == TRUE) && (caps & VPX_CODEC_CAP_OUTPUT_PARTITION)) { s->flags |= VPX_CODEC_USE_OUTPUT_PARTITION; } res = vpx_codec_enc_config_default(s->iface, &s->cfg, 0); if (res) { ms_error("Failed to get config: %s", vpx_codec_err_to_string(res)); return; } s->cfg.rc_target_bitrate = (unsigned int)(((float)s->vconf.required_bitrate) * 0.92f / 1024.0f); //0.92=take into account IP/UDP/RTP overhead, in average. s->cfg.g_pass = VPX_RC_ONE_PASS; /* -p 1 */ s->cfg.g_timebase.num = 1; s->cfg.g_timebase.den = (int)s->vconf.fps; s->cfg.rc_end_usage = VPX_CBR; /* --end-usage=cbr */ if (s->avpf_enabled == TRUE) { s->cfg.kf_mode = VPX_KF_DISABLED; } else { s->cfg.kf_mode = VPX_KF_AUTO; /* encoder automatically places keyframes */ s->cfg.kf_max_dist = 10 * s->cfg.g_timebase.den; /* 1 keyframe each 10s. */ } #if TARGET_IPHONE_SIMULATOR s->cfg.g_threads = 1; /*workaround to remove crash on ipad simulator*/ #else s->cfg.g_threads = ms_factory_get_cpu_count(f->factory); #endif ms_message("VP8 g_threads=%d", s->cfg.g_threads); s->cfg.rc_undershoot_pct = 95; /* --undershoot-pct=95 */ s->cfg.g_error_resilient = VPX_ERROR_RESILIENT_DEFAULT|VPX_ERROR_RESILIENT_PARTITIONS; s->cfg.g_lag_in_frames = 0; #if defined(ANDROID) || (TARGET_OS_IPHONE == 1) || defined(__arm__) || defined(_M_ARM) cpuused = 10 - s->cfg.g_threads; /*cpu/quality tradeoff: positive values decrease CPU usage at the expense of quality*/ if (cpuused < 7) cpuused = 7; /*values beneath 7 consume too much CPU*/ if( s->cfg.g_threads == 1 ){ /* on mono-core iOS devices, we reduce the quality a bit more due to VP8 being slower with new Clang compilers */ cpuused = 16; } #endif s->cfg.g_w = s->vconf.vsize.width; s->cfg.g_h = s->vconf.vsize.height; /* Initialize codec */ res = vpx_codec_enc_init(&s->codec, s->iface, &s->cfg, s->flags); if (res) { ms_error("vpx_codec_enc_init failed: %s (%s)", vpx_codec_err_to_string(res), vpx_codec_error_detail(&s->codec)); return; } vpx_codec_control(&s->codec, VP8E_SET_CPUUSED, cpuused); vpx_codec_control(&s->codec, VP8E_SET_STATIC_THRESHOLD, 0); vpx_codec_control(&s->codec, VP8E_SET_ENABLEAUTOALTREF, !s->avpf_enabled); vpx_codec_control(&s->codec, VP8E_SET_MAX_INTRA_BITRATE_PCT, 400); /*limite iFrame size to 4 pframe*/ if (s->flags & VPX_CODEC_USE_OUTPUT_PARTITION) { vpx_codec_control(&s->codec, VP8E_SET_TOKEN_PARTITIONS, 2); /* Output 4 partitions per frame */ } else { vpx_codec_control(&s->codec, VP8E_SET_TOKEN_PARTITIONS, 0); } s->invalid_frame_reported = FALSE; vp8rtpfmt_packer_init(&s->packer); if (s->avpf_enabled == TRUE) { s->force_keyframe = TRUE; } else if (s->frame_count == 0) { ms_video_starter_init(&s->starter); } s->ready = TRUE; }
static void ms_opus_enc_preprocess(MSFilter *f) { int error; int opusComplexity = -1; const char *env = NULL; OpusEncData *d = (OpusEncData *)f->data; /* create the encoder */ d->state = opus_encoder_create(d->samplerate, d->channels, d->application, &error); if (error != OPUS_OK) { ms_error("Opus encoder creation failed: %s", opus_strerror(error)); return; } #ifndef MS2_WINDOWS_UNIVERSAL env = getenv("MS2_OPUS_COMPLEXITY"); #endif if (env != NULL) { opusComplexity = atoi(env); if (opusComplexity < -1) opusComplexity = -1; /*our default value*/ if (opusComplexity > 10) opusComplexity = 10; } if (opusComplexity == -1){ #if defined(__arm__) || defined(_M_ARM) int cpucount = ms_factory_get_cpu_count(f->factory); if (cpucount == 1){ opusComplexity = 0; /* set complexity to 0 for single processor arm devices */ }else if (cpucount == 2) { opusComplexity = 5; } #endif } if (opusComplexity != -1){ ms_message("Set Opus complexity to %d", opusComplexity); opus_encoder_ctl(d->state, OPUS_SET_COMPLEXITY(opusComplexity)); } /*otherwise we let opus with its default value, which is 9*/ error = opus_encoder_ctl(d->state, OPUS_SET_PACKET_LOSS_PERC(10)); if (error != OPUS_OK) { ms_error("Could not set default loss percentage to opus encoder: %s", opus_strerror(error)); } /* set the encoder parameters: VBR, IN_BAND_FEC, DTX and bitrate settings */ ms_opus_enc_set_vbr(f); ms_opus_enc_set_inbandfec(f); ms_opus_enc_set_dtx(f); /* if decoder prefers mono signal, force encoder to output mono signal */ if (d->stereo == 0) { error = opus_encoder_ctl(d->state, OPUS_SET_FORCE_CHANNELS(1)); if (error != OPUS_OK) { ms_error("could not force mono channel to opus encoder: %s", opus_strerror(error)); } if (d->channels == 2) ms_message("Opus encoder configured to encode mono despite it is feed with stereo."); }else if (d->channels == 2){ ms_message("Opus encoder configured to encode stereo."); } ms_filter_lock(f); // set bitrate wasn't call, compute it with the default network bitrate (36000) if (d->bitrate==-1) { compute_max_bitrate(d, 0); } apply_max_bitrate(d); ms_filter_unlock(f); }
static int enc_set_br(MSFilter *f, void *arg) { EncData *d = (EncData *)f->data; int br = *(int *)arg; if (d->codec != NULL) { /* Encoding is already ongoing, do not change video size, only bitrate. */ d->vconf.required_bitrate = br; enc_set_configuration(f,&d->vconf); } else { MSVideoConfiguration best_vconf = ms_video_find_best_configuration_for_bitrate(d->vconf_list, br, ms_factory_get_cpu_count(f->factory)); enc_set_configuration(f, &best_vconf); } return 0; }