void set_encoding_quality(struct x264lib_ctx *ctx, int pct) { if (ctx->supports_csc_option) { int new_colour_sampling = get_x264_colour_sampling(ctx, pct); if (ctx->colour_sampling!=new_colour_sampling) { //pixel encoding has changed, we must re-init everything: //printf("set_encoding_quality(%i) old colour_sampling=%i, new colour_sampling %i\n", pct, ctx->colour_sampling, new_colour_sampling); do_clean_encoder(ctx); do_init_encoder(ctx, ctx->width , ctx->height, pct, ctx->supports_csc_option); return; } } if ((ctx->quality & ~0x1)!=(pct & ~0x1)) { float new_quality = get_x264_quality(pct); //float old_quality = ctx->x264_quality; //printf("set_encoding_quality(%i) was %i, new x264 quality %f was %f\n", pct, ctx->quality, new_quality, old_quality); //only f_rf_constant was changed, //read new configuration is sufficient x264_param_t param; // Retrieve current parameters x264_encoder_parameters(ctx->encoder, ¶m); ctx->quality = pct; ctx->x264_quality = new_quality; param.rc.f_rf_constant = new_quality; x264_encoder_reconfig(ctx->encoder, ¶m); } int old_csc_algo = ctx->csc_algo; ctx->csc_algo = get_csc_algo_for_quality(pct); if (old_csc_algo!=ctx->csc_algo) { ctx->rgb2yuv = init_encoder_csc(ctx); } }
HRESULT CX264Encoder::SetParam(int nBitrate, int nFPS) { if(!m_px264Handle) return false; if ( nBitrate <= 0 || nFPS <= 0 ) { LOG(stderr, "ChangeParam(): invalid value\n"); return E_INVALIDARG; } if ( nBitrate == m_stEncParam.iBitrate && nFPS == m_stEncParam.iFPS ) { return S_FALSE; } //x264_t *h = (x264_t*)m_px264Handle; //x264_picture_t *pic = (x264_picture_t*)m_pPic; m_stEncParam.iBitrate = nBitrate; m_stEncParam.iFPS = nFPS; x264_param_t st264Param; ConfigParam( &st264Param ); if ( x264_encoder_reconfig( (x264_t*)m_px264Handle, &st264Param ) < 0 ) { return false; } return true; }
virtual bool SetBitRate(DWORD maxBitrate, DWORD bufferSize) { SetBitRateParams(maxBitrate, bufferSize); int retVal = x264_encoder_reconfig(x264, ¶mData); if(retVal < 0) Log(TEXT("Could not set new encoder bitrate, error value %u"), retVal); return retVal == 0; }
static int enc_set_br(MSFilter *f, void *arg) { EncData *d=(EncData*)f->data; d->bitrate=*(int*)arg; if (d->enc) { ms_filter_lock(f); apply_bitrate(f,d->bitrate); if (x264_encoder_reconfig(d->enc,&d->params)!=0) { ms_error("x264_encoder_reconfig() failed."); } ms_filter_unlock(f); return 0; } if (d->bitrate>=1024000) { d->vsize.width = MS_VIDEO_SIZE_SVGA_W; d->vsize.height = MS_VIDEO_SIZE_SVGA_H; d->fps=25; } else if (d->bitrate>=512000) { d->vsize.width = MS_VIDEO_SIZE_VGA_W; d->vsize.height = MS_VIDEO_SIZE_VGA_H; d->fps=25; } else if (d->bitrate>=256000) { d->vsize.width = MS_VIDEO_SIZE_VGA_W; d->vsize.height = MS_VIDEO_SIZE_VGA_H; d->fps=15; } else if (d->bitrate>=170000) { d->vsize.width=MS_VIDEO_SIZE_QVGA_W; d->vsize.height=MS_VIDEO_SIZE_QVGA_H; d->fps=15; } else if (d->bitrate>=128000) { d->vsize.width=MS_VIDEO_SIZE_QCIF_W; d->vsize.height=MS_VIDEO_SIZE_QCIF_H; d->fps=10; } else if (d->bitrate>=64000) { d->vsize.width=MS_VIDEO_SIZE_QCIF_W; d->vsize.height=MS_VIDEO_SIZE_QCIF_H; d->fps=7; } else { d->vsize.width=MS_VIDEO_SIZE_QCIF_W; d->vsize.height=MS_VIDEO_SIZE_QCIF_H; d->fps=5; } #if defined (ANDROID) || TARGET_OS_IPHONE==1 d->vsize.width=MS_VIDEO_SIZE_QVGA_W; d->vsize.height=MS_VIDEO_SIZE_QVGA_H; d->fps=12; #endif ms_message("bitrate requested...: %d (%d x %d)\n", d->bitrate, d->vsize.width, d->vsize.height); return 0; }
void change_encoding_speed(struct x264lib_ctx *ctx, int increase) { x264_param_t param; x264_encoder_parameters(ctx->encoder, ¶m); ctx->encoding_preset -= increase; if (ctx->encoding_preset < 0) ctx->encoding_preset = 0; if (ctx->encoding_preset > 5) ctx->encoding_preset = 5; x264_param_default_preset(¶m, x264_preset_names[ctx->encoding_preset], "zerolatency"); //printf("Setting encoding preset %s %d\n", x264_preset_names[ctx->encoding_preset], ctx->encoding_preset); x264_param_apply_profile(¶m, "baseline"); x264_encoder_reconfig(ctx->encoder, ¶m); }
static bool obs_x264_update(void *data, obs_data_t *settings) { struct obs_x264 *obsx264 = data; bool success = update_settings(obsx264, settings); int ret; if (success) { ret = x264_encoder_reconfig(obsx264->context, &obsx264->params); if (ret != 0) warn("Failed to reconfigure: %d", ret); return ret == 0; } return false; }
void set_encoding_speed(struct x264lib_ctx *ctx, int pct) { x264_param_t param; x264_encoder_parameters(ctx->encoder, ¶m); int new_preset = 7-MAX(0, MIN(7, pct/12.5)); if (new_preset==ctx->encoding_preset) return; ctx->encoding_preset = new_preset; //"tune" options: film, animation, grain, stillimage, psnr, ssim, fastdecode, zerolatency //Multiple tunings can be used if separated by a delimiter in ",./-+" //however multiple psy tunings cannot be used. //film, animation, grain, stillimage, psnr, and ssim are psy tunings. x264_param_default_preset(¶m, x264_preset_names[ctx->encoding_preset], "zerolatency"); x264_param_apply_profile(¶m, "baseline"); x264_encoder_reconfig(ctx->encoder, ¶m); }
static int enc_set_configuration(MSFilter *f, void *arg) { EncData *d = (EncData *)f->data; const MSVideoConfiguration *vconf = (const MSVideoConfiguration *)arg; if (vconf != &d->vconf) memcpy(&d->vconf, vconf, sizeof(MSVideoConfiguration)); if (d->vconf.required_bitrate > d->vconf.bitrate_limit) d->vconf.required_bitrate = d->vconf.bitrate_limit; if (d->enc) { ms_filter_lock(f); apply_bitrate(f); if (x264_encoder_reconfig(d->enc, &d->params) != 0) { ms_error("x264_encoder_reconfig() failed."); } ms_filter_unlock(f); return 0; } ms_message("Video configuration set: bitrate=%dbits/s, fps=%f, vsize=%dx%d", d->vconf.required_bitrate, d->vconf.fps, d->vconf.vsize.width, d->vconf.vsize.height); return 0; }
virtual bool SetBitRate(DWORD maxBitrate, DWORD bufferSize) { DWORD old_bitrate = paramData.rc.i_vbv_max_bitrate; DWORD old_buffer = paramData.rc.i_vbv_buffer_size; SetBitRateParams(maxBitrate, bufferSize); int retVal = x264_encoder_reconfig(x264, ¶mData); if (retVal < 0) Log(TEXT("Could not set new encoder bitrate, error value %u"), retVal); else { String changes; if (old_bitrate != maxBitrate) changes << FormattedString(L"bitrate %d->%d", old_bitrate, maxBitrate); if (old_buffer != bufferSize) changes << FormattedString(L"%sbuffer size %d->%d", changes.Length() ? L", " : L"", old_buffer, bufferSize); if (changes) Log(L"x264: %s", changes.Array()); } return retVal == 0; }
static void apply_preset( x264_t *h, int preset ) { x264_speedcontrol_t *sc = h->sc; preset = x264_clip3( preset, 0, PRESETS-1 ); //if( preset != sc->preset ) { const sc_preset_t *s = &presets[preset]; x264_param_t p = sc->user_param; p.i_frame_reference = s->refs; p.analyse.inter = s->partitions; p.analyse.i_subpel_refine = s->subme; p.analyse.i_me_method = s->me; p.analyse.i_trellis = s->trellis; p.analyse.b_mixed_references = s->mix; p.analyse.b_chroma_me = s->chromame; p.analyse.f_psy_rd = s->psy_rd; p.analyse.f_psy_trellis = s->psy_trellis; x264_encoder_reconfig( h, &p ); sc->preset = preset; x264_log( h, X264_LOG_DEBUG, "Applying speedcontrol preset %d.\n", preset ); } }
virtual bool SetBitRate(DWORD maxBitrate, DWORD bufferSize) { DWORD old_bitrate = paramData.rc.i_vbv_max_bitrate; DWORD old_buffer = paramData.rc.i_vbv_buffer_size; SetBitRateParams(maxBitrate, bufferSize); int retVal = x264_encoder_reconfig(x264, ¶mData); if (retVal < 0) { DOLOG("Could not set new encoder bitrate, error value " + retVal); } else { if (old_bitrate != maxBitrate){ DOLOG("bitrate " + old_bitrate + "->" + maxBitrate); } if (old_buffer != bufferSize){ DOLOG("bitrate size " + old_buffer + "->" + bufferSize); } } return retVal == 0; }
static void *start_encoder( void *ptr ) { obe_vid_enc_params_t *enc_params = ptr; obe_t *h = enc_params->h; obe_encoder_t *encoder = enc_params->encoder; x264_t *s = NULL; x264_picture_t pic, pic_out; x264_nal_t *nal; int i_nal, frame_size = 0, user_sar_width, user_sar_height; int64_t pts = 0, arrival_time = 0, frame_duration, buffer_duration; int64_t *pts2; float buffer_fill; obe_raw_frame_t *raw_frame; obe_coded_frame_t *coded_frame; /* TODO: check for width, height changes */ /* Lock the mutex until we verify and fetch new parameters */ pthread_mutex_lock( &encoder->encoder_mutex ); enc_params->avc_param.pf_log = x264_logger; s = x264_encoder_open( &enc_params->avc_param ); if( !s ) { pthread_mutex_unlock( &encoder->encoder_mutex ); fprintf( stderr, "[x264]: encoder configuration failed\n" ); goto end; } x264_encoder_parameters( s, &enc_params->avc_param ); encoder->encoder_params = malloc( sizeof(enc_params->avc_param) ); if( !encoder->encoder_params ) { pthread_mutex_unlock( &encoder->encoder_mutex ); syslog( LOG_ERR, "Malloc failed\n" ); goto end; } memcpy( encoder->encoder_params, &enc_params->avc_param, sizeof(enc_params->avc_param) ); encoder->is_ready = 1; /* XXX: This will need fixing for soft pulldown streams */ frame_duration = av_rescale_q( 1, (AVRational){enc_params->avc_param.i_fps_den, enc_params->avc_param.i_fps_num}, (AVRational){1, OBE_CLOCK} ); buffer_duration = frame_duration * enc_params->avc_param.sc.i_buffer_size; /* Broadcast because input and muxer can be stuck waiting for encoder */ pthread_cond_broadcast( &encoder->encoder_cv ); pthread_mutex_unlock( &encoder->encoder_mutex ); user_sar_width = enc_params->avc_param.vui.i_sar_width; user_sar_height = enc_params->avc_param.vui.i_sar_height; while( 1 ) { pthread_mutex_lock( &encoder->encoder_mutex ); if( encoder->cancel_thread ) { pthread_mutex_unlock( &encoder->encoder_mutex ); break; } if( !encoder->num_raw_frames ) pthread_cond_wait( &encoder->encoder_cv, &encoder->encoder_mutex ); if( encoder->cancel_thread ) { pthread_mutex_unlock( &encoder->encoder_mutex ); break; } /* Reset the speedcontrol buffer if the source has dropped frames. Otherwise speedcontrol * stays in an underflow state and is locked to the fastest preset */ pthread_mutex_lock( &h->drop_mutex ); if( h->encoder_drop ) { pthread_mutex_lock( &h->smoothing_mutex ); h->smoothing_buffer_complete = 0; pthread_mutex_unlock( &h->smoothing_mutex ); syslog( LOG_INFO, "Speedcontrol reset\n" ); x264_speedcontrol_sync( s, enc_params->avc_param.sc.i_buffer_size, enc_params->avc_param.sc.f_buffer_init, 0 ); h->encoder_drop = 0; } pthread_mutex_unlock( &h->drop_mutex ); raw_frame = encoder->frames[0]; pthread_mutex_unlock( &encoder->encoder_mutex ); if( convert_obe_to_x264_pic( &pic, raw_frame ) < 0 ) { syslog( LOG_ERR, "Malloc failed\n" ); break; } /* FIXME: if frames are dropped this might not be true */ pic.i_pts = pts++; pts2 = malloc( sizeof(int64_t) ); if( !pts2 ) { syslog( LOG_ERR, "Malloc failed\n" ); break; } pts2[0] = raw_frame->pts; pic.opaque = pts2; /* If the AFD has changed, then change the SAR. x264 will write the SAR at the next keyframe * TODO: allow user to force keyframes in order to be frame accurate */ if( raw_frame->sar_width != enc_params->avc_param.vui.i_sar_width || raw_frame->sar_height != enc_params->avc_param.vui.i_sar_height ) { /* If the frame's SAR has been guessed but the user entered a reasonable SAR, then use it. * Otherwise, use the guessed SAR. */ if( raw_frame->sar_guess && user_sar_width > 0 && user_sar_height > 0 ) { enc_params->avc_param.vui.i_sar_width = user_sar_width; enc_params->avc_param.vui.i_sar_height = user_sar_height; } else { enc_params->avc_param.vui.i_sar_width = raw_frame->sar_width; enc_params->avc_param.vui.i_sar_height = raw_frame->sar_height; } x264_encoder_reconfig( s, &enc_params->avc_param ); } /* Update speedcontrol based on the system state */ if( h->obe_system == OBE_SYSTEM_TYPE_GENERIC ) { pthread_mutex_lock( &h->smoothing_mutex ); if( h->smoothing_buffer_complete ) { /* Wait until a frame is sent out. */ while( !h->smoothing_last_exit_time ) pthread_cond_wait( &h->smoothing_out_cv, &h->smoothing_mutex ); /* time elapsed since last frame was removed */ int64_t last_frame_delta = get_input_clock_in_mpeg_ticks( h ) - h->smoothing_last_exit_time; if( h->num_smoothing_frames ) { int64_t frame_durations = h->smoothing_frames[h->num_smoothing_frames-1]->real_dts - h->smoothing_frames[0]->real_dts + frame_duration; buffer_fill = (float)(frame_durations - last_frame_delta)/buffer_duration; } else buffer_fill = (float)(-1 * last_frame_delta)/buffer_duration; x264_speedcontrol_sync( s, buffer_fill, enc_params->avc_param.sc.i_buffer_size, 1 ); } pthread_mutex_unlock( &h->smoothing_mutex ); } frame_size = x264_encoder_encode( s, &nal, &i_nal, &pic, &pic_out ); arrival_time = raw_frame->arrival_time; raw_frame->release_data( raw_frame ); raw_frame->release_frame( raw_frame ); remove_frame_from_encode_queue( encoder ); if( frame_size < 0 ) { syslog( LOG_ERR, "x264_encoder_encode failed\n" ); break; } if( frame_size ) { coded_frame = new_coded_frame( encoder->stream_id, frame_size ); if( !coded_frame ) { syslog( LOG_ERR, "Malloc failed\n" ); break; } memcpy( coded_frame->data, nal[0].p_payload, frame_size ); coded_frame->is_video = 1; coded_frame->len = frame_size; coded_frame->cpb_initial_arrival_time = pic_out.hrd_timing.safe_cpb_initial_arrival_time; coded_frame->cpb_final_arrival_time = pic_out.hrd_timing.cpb_final_arrival_time; coded_frame->real_dts = pic_out.hrd_timing.cpb_removal_time; coded_frame->real_pts = pic_out.hrd_timing.dpb_output_time; pts2 = pic_out.opaque; coded_frame->pts = pts2[0]; coded_frame->random_access = pic_out.b_keyframe; coded_frame->priority = IS_X264_TYPE_I( pic_out.i_type ); free( pic_out.opaque ); if( h->obe_system == OBE_SYSTEM_TYPE_LOW_LATENCY ) { coded_frame->arrival_time = arrival_time; //printf("\n Encode Latency %"PRIi64" \n", obe_mdate() - coded_frame->arrival_time ); } add_to_smoothing_queue( h, coded_frame ); } } end: if( s ) x264_encoder_close( s ); free( enc_params ); return NULL; }