Example #1
0
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, &param);
		ctx->quality = pct;
		ctx->x264_quality = new_quality;
		param.rc.f_rf_constant = new_quality;
		x264_encoder_reconfig(ctx->encoder, &param);
	}
	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);
	}
}
Example #2
0
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;
}
Example #3
0
    virtual bool SetBitRate(DWORD maxBitrate, DWORD bufferSize)
    {
        SetBitRateParams(maxBitrate, bufferSize);

        int retVal = x264_encoder_reconfig(x264, &paramData);
        if(retVal < 0)
            Log(TEXT("Could not set new encoder bitrate, error value %u"), retVal);

        return retVal == 0;
    }
Example #4
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;
}
Example #5
0
void change_encoding_speed(struct x264lib_ctx *ctx, int increase)
{
	x264_param_t param;
	x264_encoder_parameters(ctx->encoder, &param);
	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(&param, 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(&param, "baseline");
	x264_encoder_reconfig(ctx->encoder, &param);
}
Example #6
0
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;
}
Example #7
0
void set_encoding_speed(struct x264lib_ctx *ctx, int pct)
{
	x264_param_t param;
	x264_encoder_parameters(ctx->encoder, &param);
	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(&param, x264_preset_names[ctx->encoding_preset], "zerolatency");
	x264_param_apply_profile(&param, "baseline");
	x264_encoder_reconfig(ctx->encoder, &param);
}
Example #8
0
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;
}
Example #9
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, &paramData);
        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;
    }
Example #10
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 );
    }
}
Example #11
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, &paramData);
		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;
    }
Example #12
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;
}