H264Encoder::H264Encoder(int width, int height, int fps) : m_width(width), m_height(height), m_fps(fps) { m_stride = width*4; /* Parametrize x264 for real-time */ x264_param_default_preset(&m_param, "veryfast", "zerolatency"); m_param.i_threads = 1; m_param.i_width = width; m_param.i_height = height; m_param.i_fps_num = fps; m_param.i_fps_den = 1; // Intra refres: m_param.i_keyint_max = fps; m_param.b_intra_refresh = 1; //Rate control: m_param.rc.i_rc_method = X264_RC_CRF; m_param.rc.f_rf_constant = 25; m_param.rc.f_rf_constant_max = 35; //For streaming: m_param.b_repeat_headers = 1; m_param.b_annexb = 1; x264_param_apply_profile(&m_param, "baseline"); Init(&m_param); }
void do_init_encoder(struct x264lib_ctx *ctx, int width, int height, int initial_quality, int supports_csc_option) { ctx->quality = initial_quality; ctx->supports_csc_option = supports_csc_option; ctx->colour_sampling = get_x264_colour_sampling(ctx, initial_quality); ctx->x264_quality = get_x264_quality(initial_quality); ctx->csc_format = get_csc_format_for_x264_format(ctx->colour_sampling); ctx->encoding_preset = 2; ctx->preset = x264_preset_names[ctx->encoding_preset]; ctx->profile = get_profile_for_quality(initial_quality); ctx->csc_algo = get_csc_algo_for_quality(initial_quality); //printf("do_init_encoder(%p, %i, %i, %i, %i) colour_sampling=%i, x264_quality=%f, profile=%s\n", ctx, width, height, initial_quality, supports_csc_option, ctx->colour_sampling, ctx->x264_quality, ctx->profile); x264_param_t param; x264_param_default_preset(¶m, ctx->preset, "zerolatency"); param.i_threads = 1; param.i_width = width; param.i_height = height; param.i_csp = ctx->colour_sampling; param.rc.f_rf_constant = ctx->x264_quality; param.i_log_level = 0; x264_param_apply_profile(¶m, ctx->profile); ctx->encoder = x264_encoder_open(¶m); ctx->width = width; ctx->height = height; ctx->rgb2yuv = init_encoder_csc(ctx); }
void H264Encoder::init_(const int wid, const int hei) { // 0. building encoder parameters. x264_param_default_preset(&x264_opt_, "ultrafast", "zerolatency"); x264_opt_.i_width = wid; x264_opt_.i_height = hei; x264_opt_.i_threads = 1; x264_opt_.b_repeat_headers = 1; x264_opt_.b_intra_refresh = 1; x264_opt_.rc.i_rc_method = X264_RC_CQP; x264_opt_.rc.i_qp_constant = 24; x264_opt_.rc.i_qp_min = 24; x264_opt_.rc.i_qp_max = 24; //x264_param_default(&opt); x264_param_apply_profile(&x264_opt_, "baseline"); // 1. Prepare the output buffer and target file x264_picture_alloc(&x264_picin_, X264_CSP_NV12, x264_opt_.i_width, x264_opt_.i_height); x264_picture_alloc(&x264_picout_, X264_CSP_NV12, x264_opt_.i_width, x264_opt_.i_height); // 2. Building the encoder handler x264_hdl_ = x264_encoder_open(&x264_opt_); x264_encoder_parameters(x264_hdl_, &x264_opt_); }
EncodeContext encode_context_create(int width, int height) { EncodeContext context; context.width = width; context.height = height; x264_param_t param; x264_param_default_preset(¶m, "veryfast", "zerolatency"); param.i_threads = 1; param.i_width = width; param.i_height = height; param.i_fps_num = 20; // the FPS doesn't matter param.i_fps_den = 1; // Intra refres: param.i_keyint_max = 20; // once every twenty frames param.b_intra_refresh = 1; //Rate control: param.rc.i_rc_method = X264_RC_CRF; param.rc.f_rf_constant = 25; param.rc.f_rf_constant_max = 35; //For streaming: param.b_repeat_headers = 1; param.b_annexb = 1; x264_param_apply_profile(¶m, "baseline"); context.encoder = x264_encoder_open(¶m); context.converter = sws_getContext(width, height, PIX_FMT_RGB24, width, height, PIX_FMT_YUV420P, SWS_FAST_BILINEAR, NULL, NULL, NULL); return context; }
EncoderVideoSource::EncoderVideoSource(UsageEnvironment& env, unsigned int width, unsigned int height, unsigned int framerate, unsigned int bitrate, unsigned int keyinterval, VideoCodec codec, char *type): FramedSource(env), fp(NULL), fWidth(width), fHeight(height), fFramerate(framerate), fBitrate(bitrate), fKeyInterval(keyinterval), fCodec(codec), fConfigBytes(NULL), fStartTime(0), fEncoderHandle(NULL) { memset(mediaType, 0, sizeof(mediaType)); memcpy(mediaType, type, strlen(type)); #ifdef STARV_TEST if(strcmp(type, "live") == 0 || strcmp(type, "livehd") == 0) fp = fopen(VIDEO_FILE, "rb"); if(strcmp(type, "mobile") == 0) fp = fopen(VIDEO_FILE, "rb"); #endif Debug(ckite_log_message, "type = %s\n", type); if(strcmp(type, "store") == 0) { Debug(ckite_log_message, "EncoderVideoSource store \n"); } fBuffer = new unsigned char[fWidth*fHeight*3/2]; #ifdef SDKH264 #ifdef ENC_SOURCE x264_param_default(&m_param); x264_param_apply_profile(&m_param, "baseline"); m_param.i_width = fWidth; m_param.i_height = fHeight; m_param.i_fps_num = 10; // m_param.i_fps_den = 1000; m_param.i_frame_reference = 1; //m_param.i_maxframes = 0; // no find this parameter m_param.i_keyint_max = 250; m_param.i_bframe = 0; m_param.rc.i_bitrate = 1000; // the unit is kbps //m_param.rc.b_cbr = 0; m_param.rc.f_qcompress = 0; //m_param.rc.b_stat_write = 0; //m_param.analyse.inter = 0; m_param.analyse.b_psnr = 0; m_param.b_cabac = 0; m_param.rc.b_mb_tree = 0; //m_param.pf_log = NULL //if set NULL , it will segment fault x264_handle = x264_encoder_open(&m_param); //memset(p_nal, 0x0, sizeof (struct nal)); fprintf(stderr, "x264_encoder_open x264_handle:%x\n", x264_handle); #endif for(int i = 0; i < 4; i++) { more_nal[i] = NULL; more_nal_len[i] = 0; } #endif #ifdef SDKMPEG4 #ifdef ENC_SOURCE Debug(ckite_log_message, "xvid fWidth = %d, fHeight = %d\n", fWidth, fHeight); fEncoderHandle = xvid_enc_init(fWidth, fHeight, fBitrate, fFramerate, fKeyInterval, 1); #endif #endif }
static inline void apply_x264_profile(struct obs_x264 *obsx264, const char *profile) { if (!obsx264->context && profile && *profile) { int ret = x264_param_apply_profile(&obsx264->params, profile); if (ret != 0) warn("Failed to set x264 profile '%s'", profile); } }
VideoEncoder* video_encoder_init(int width, int height, int fpsNum, int fpsDen, int maxWidth){ printf("[arcade encoder init] %d x %d @ (%d / %d)\n",width,height,fpsNum,fpsDen); VideoEncoder *enc = (VideoEncoder*) malloc(sizeof(VideoEncoder)); memset(enc,0,sizeof(VideoEncoder)); //TODO: this needs to become a parameter enc->in_fmt = AV_PIX_FMT_BGRA; enc->width = width; enc->height = height; enc->max_width = maxWidth; printf("[arcade encoder] capping width at %dpx\n",enc->max_width); float aspectRatio = (float) enc->width / (float) enc->height; enc->out_width = enc->width > enc->max_width ? enc->max_width : enc->width; enc->out_height = (int) ((float) enc->out_width / aspectRatio); printf("[arcade encoder init]\n\t%d x %d --> %d x %d\n\t@ (%d / %d)\n", enc->width,enc->height, enc->out_width,enc->out_height, fpsNum,fpsDen); x264_param_t param; x264_param_default_preset(¶m, "ultrafast", "zerolatency"); param.i_threads = 1; param.i_width = enc->out_width; param.i_height = enc->out_height; param.i_fps_num = fpsNum; param.i_fps_den = fpsDen; // Intra refres: param.i_keyint_max = 30000; param.b_intra_refresh = 1; //Rate control: param.rc.i_rc_method = X264_RC_CRF; param.rc.f_rf_constant = 25; param.rc.f_rf_constant_max = 35; //For streaming: param.b_repeat_headers = 1; param.b_annexb = 1; x264_param_apply_profile(¶m, "baseline"); enc->encoder = x264_encoder_open(¶m); x264_picture_alloc(&enc->pic_in, X264_CSP_I420, enc->out_width, enc->out_height); enc->output_buffer_size = (int)sizeof(uint8_t)*4096*1024; enc->output_buffer = malloc(enc->output_buffer_size); enc->sws = sws_getContext(enc->width, enc->height, enc->in_fmt, enc->out_width, enc->out_height, AV_PIX_FMT_YUV420P, SWS_FAST_BILINEAR, NULL, NULL, NULL); enc->num_frames = 0; return enc; }
void rtspStream::initH264Encoder(int width,int height,int fps,int bitRate) { frame_num = 0; pX264Handle = NULL; pX264Param = new x264_param_t; assert(pX264Param); m_nFPS = 25; //* 配置参数 //* 使用默认参数,在这里因为我的是实时网络传输,所以我使用了zerolatency的选项,使用这个选项之后就不会有delayed_frames,如果你使用的不是这样的话,还需要在编码完成之后得到缓存的编码帧 x264_param_default_preset(pX264Param, "veryfast", "zerolatency"); //* cpuFlags pX264Param->i_threads = X264_SYNC_LOOKAHEAD_AUTO;//* 取空缓冲区继续使用不死锁的保证. //* 视频选项 pX264Param->i_width = width; //* 要编码的图像宽度. pX264Param->i_height = height; //* 要编码的图像高度 pX264Param->i_frame_total = 0; //* 编码总帧数.不知道用0. pX264Param->i_keyint_max = 10; //* 流参数 pX264Param->i_bframe = 5; pX264Param->b_open_gop = 0; pX264Param->i_bframe_pyramid = 0; pX264Param->i_bframe_adaptive = X264_B_ADAPT_TRELLIS; //* Log参数,不需要打印编码信息时直接注释掉就行 // pX264Param->i_log_level = X264_LOG_DEBUG; //* 速率控制参数 pX264Param->rc.i_bitrate = bitRate;//* 码率(比特率,单位Kbps) //* muxing parameters pX264Param->i_fps_den = 1; //* 帧率分母 pX264Param->i_fps_num = fps;//* 帧率分子 pX264Param->i_timebase_den = pX264Param->i_fps_num; pX264Param->i_timebase_num = pX264Param->i_fps_den; //* 设置Profile.使用Baseline profile x264_param_apply_profile(pX264Param, x264_profile_names[0]); pNals = NULL; pPicIn = new x264_picture_t; pPicOut = new x264_picture_t; x264_picture_init(pPicOut); x264_picture_alloc(pPicIn, X264_CSP_I420, pX264Param->i_width, pX264Param->i_height); pPicIn->img.i_csp = X264_CSP_I420; pPicIn->img.i_plane = 3; //* 打开编码器句柄,通过x264_encoder_parameters得到设置给X264 //* 的参数.通过x264_encoder_reconfig更新X264的参数 pX264Handle = x264_encoder_open(pX264Param); assert(pX264Handle); pPicIn->img.plane[0] = PYUVBuf; pPicIn->img.plane[1] = PYUVBuf + width *height; pPicIn->img.plane[2] = PYUVBuf + width * height * 5 / 4; pPicIn->img.plane[3] = 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); }
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); }
int CX264Encoder::set_param(x264_param_t* p) { int ret = -1; ret = x264_param_default_preset(¶m, "ultrafast", NULL); param.i_csp = X264_CSP_I420;// X264_CSP_I420;// X264_CSP_RGB; param.i_width = width; param.i_height = height; param.b_vfr_input = 0; param.b_repeat_headers = 1; param.b_annexb = 1; param.i_nal_hrd = X264_NAL_HRD_VBR; ret = x264_param_apply_profile(¶m, "high"); return ret; }
void x264Encoder::Initilize() { x264_param_default_preset(¶meters, "veryfast", "zerolatency"); parameters.i_log_level = X264_LOG_INFO; parameters.i_threads = 1; parameters.i_width = 512 / 2; parameters.i_height = 424 / 2; parameters.i_fps_num = _fps; parameters.i_fps_den = 1; parameters.i_keyint_max = 15; parameters.b_intra_refresh = 1; parameters.rc.i_rc_method = X264_RC_CRF; parameters.rc.i_vbv_buffer_size = 1000000; parameters.rc.i_vbv_max_bitrate = 90000; parameters.rc.f_rf_constant = 25; parameters.rc.f_rf_constant_max = 35; parameters.i_sps_id = 7; // the following two value you should keep 1 parameters.b_repeat_headers = 1; // to get header before every I-Frame parameters.b_annexb = 1; // put start code in front of nal. we will remove start code later x264_param_apply_profile(¶meters, "baseline"); encoder = x264_encoder_open(¶meters); x264_picture_alloc(&picture_in, X264_CSP_I420, 512 / 2, 424 / 2); picture_in.i_type = X264_TYPE_AUTO; picture_in.img.i_csp = X264_CSP_I420; x264_picture_alloc(&picture_out, X264_CSP_I420, parameters.i_width, parameters.i_height); picture_out.i_type = X264_TYPE_AUTO; picture_out.img.i_csp = X264_CSP_I420; // i have initilized my color space converter for BGR24 to YUV420 because my opencv // video capture gives BGR24 image. You can initilize according to your input pixelFormat convertContext = sws_getContext( 512 / 2, 424 / 2, PIX_FMT_BGR24, parameters.i_width, parameters.i_height, PIX_FMT_YUV420P, SWS_FAST_BILINEAR, NULL, NULL, NULL); }
void encode_init() { // fill x264_param_t with default values and do CPU detection x264_param_default(x264_encode.para); if(x264_param_default_preset(x264_encode.para, capg.preset, capg.tune) < 0) CAP_DBG_EXIT("x264_param_default_preset error!\n"); // ricann debug CAP_DBG("-------------------after x264_param_default_preset\n"); encode_printpara(); // Configure non-default params // real frame rate is i_fps_num/i_fps_den x264_encode.para->i_fps_num = capg.frame_rate; x264_encode.para->i_width = capg.width; x264_encode.para->i_height = capg.height; x264_encode.para->i_keyint_max = capg.gop_size; x264_encode.para->i_csp = x264_encode.colorspace; x264_encode.para->b_vfr_input = 0; x264_encode.para->b_repeat_headers = 1; // ricann debug CAP_DBG("-------------------after assign value\n"); encode_printpara(); x264_encode.pic->img.i_csp = x264_encode.colorspace; x264_encode.pic->img.i_plane = 3; x264_encode.pic->i_type = X264_TYPE_AUTO; if(x264_param_apply_profile(x264_encode.para, capg.profile) < 0) CAP_DBG_EXIT("x264_param_apply_profile error!\n"); x264_encode.handle = x264_encoder_open(x264_encode.para); if(!x264_encode.handle) CAP_DBG_EXIT("x264_encoder_open error!\n"); // ricann debug CAP_DBG("-------------------after x264_encoder_open\n"); encode_printpara(); }
bool init_x264_encoder(Encoder * enc,int width,int height) { enc->param = (x264_param_t*)malloc(sizeof(x264_param_t)); enc->picture = (x264_picture_t*)malloc(sizeof(x264_picture_t)); enc->picture->i_pts = 0 ; // set default param // todo improvements later x264_param_default(enc->param); // set width and height enc->param->i_width = width; enc->param->i_height = height ; enc->param->rc.i_lookahead = 0; // set fps enc->param->i_fps_num = 10 ; enc->param->i_fps_den = 1 ; // set baseline x264_param_apply_profile(enc->param, x264_profile_names[0]); // open encoder if( (enc->handle = x264_encoder_open(enc->param)) == 0 ) { SKY_LOG(1,(TAG_H264ENCODER,"Could not Open x264_encoder")); // will free when encoder close or now //free(enc->param); //free(enc->picture); return false ; } // create a new picture malloc enc->picture here X264_CSP_I422 X264_CSP_YV16 X264_CSP_NV16 //x264_picture_alloc(enc->picture,X264_CSP_YV12,enc->param->i_width,enc->param->i_height); //enc->picture->img.i_csp = X264_CSP_YV12 ; //x264_picture_alloc(enc->picture,X264_CSP_NV12,enc->param->i_width,enc->param->i_height); //enc->picture->img.i_csp = X264_CSP_NV12 ; x264_picture_alloc(enc->picture,X264_CSP_YV12,enc->param->i_width,enc->param->i_height); enc->picture->img.i_csp = X264_CSP_YV12 ; enc->picture->img.i_plane = 3 ; return true ; }
struct x264lib_ctx *init_encoder(int width, int height) { struct x264lib_ctx *ctx = malloc(sizeof(struct x264lib_ctx)); ctx->encoding_preset = 2; x264_param_t param; x264_param_default_preset(¶m, x264_preset_names[ctx->encoding_preset], "zerolatency"); param.i_threads = 1; param.i_width = width; param.i_height = height; param.i_csp = X264_CSP_I420; param.i_log_level = 0; x264_param_apply_profile(¶m, "baseline"); ctx->encoder = x264_encoder_open(¶m); ctx->width = width; ctx->height = height; ctx->rgb2yuv = sws_getContext(ctx->width, ctx->height, PIX_FMT_RGB24, ctx->width, ctx->height, PIX_FMT_YUV420P, SWS_SINC | SWS_ACCURATE_RND, NULL, NULL, NULL); return ctx; }
void encode_init(Encoder *encoder, int img_width, int img_height) { //Set default x264 parameters encoder->param = (x264_param_t *) malloc(sizeof(x264_param_t)); encoder->picture = (x264_picture_t *) malloc(sizeof(x264_picture_t)); x264_param_default(encoder->param); encoder->param->i_width = img_width; //set frame width encoder->param->i_height = img_height; //set frame height encoder->param->rc.i_lookahead = 0; //表示i帧向前缓冲区 encoder->param->i_fps_num = 25; //帧率分子 encoder->param->i_fps_den = 1; //帧率分母 encoder->param->rc.i_lookahead = 0; encoder->param->i_sync_lookahead = 0; encoder->param->i_bframe = 0; encoder->param->b_sliced_threads = 1; encoder->param->b_vfr_input = 0; encoder->param->rc.b_mb_tree = 0; x264_param_apply_profile(encoder->param, x264_profile_names[0]); encoder->handle = x264_encoder_open(encoder->param); if (encoder->handle == 0) { return; } /* Create a new pic */ //encoder->picture->param->i_width = img_width; //encoder->picture->param->i_height = img_height; x264_picture_alloc(encoder->picture, X264_CSP_I420, encoder->param->i_width,encoder->param->i_height); encoder->picture->img.i_csp = X264_CSP_I420; encoder->picture->img.i_plane = 3; g_H264_Buf = (uint8_t *) malloc( sizeof(uint8_t) * g_ImgWidth * g_ImgHeight * 3); // 设置缓冲区 }
void init_encoder(void) { x264_param_default_preset(¶m, "veryfast", "zerolatency"); param.i_threads=1; param.i_width=x264_width; param.i_height=x264_height; param.i_fps_num=fps; param.i_fps_den=1; param.i_keyint_max=25; param.b_intra_refresh=1; //If param->b_annexb is set, Annex-B bytestream with startcode. //* This size is the size used in mp4/similar muxing; it is equal to ( i_payload-4 ) --> uint8_t *p_payload; param.b_annexb=1; x264_param_apply_profile(¶m,"baseline"); encoder=x264_encoder_open(¶m); printf("in init_encoder function\n"); }
H264Exporter::H264Exporter(const exporter_settings& settings) : _success{false} , _settings(settings) , _file{settings.path, std::ios::binary} , _frame{0} , _encoder{nullptr} { x264_param_t param; // Best quality (0) -> "veryslow" (8); worst quality (4) -> "ultrafast" (0). auto quality = std::to_string(2 * (4 - settings.quality)); if (x264_param_default_preset(¶m, quality.c_str(), "film") < 0) { std::cerr << "couldn't get default preset" << std::endl; return; } param.i_threads = settings.threads > 1 ? settings.threads - 1 : 1; param.i_lookahead_threads = settings.threads > 1 ? 1 : 0; param.i_width = settings.width; param.i_height = settings.height; param.i_fps_num = settings.fps; param.i_fps_den = 1; param.i_frame_total = settings.fps * settings.length; param.i_keyint_min = 0; param.i_keyint_max = settings.fps; if (x264_param_apply_profile(¶m, "high") < 0) { std::cerr << "couldn't get apply profile" << std::endl; return; } _encoder = x264_encoder_open(¶m); if (!_encoder) { std::cerr << "couldn't create encoder" << std::endl; return; } if (x264_picture_alloc(&_pic, X264_CSP_I420, _settings.width, _settings.height) < 0) { std::cerr << "couldn't allocate picture" << std::endl; return; } _success = true; }
jlong Java_h264_com_H264Encoder_CompressBegin(JNIEnv* env, jobject thiz, jint width, jint height) { Encoder * en = (Encoder *) malloc(sizeof(Encoder)); en->param = (x264_param_t *) malloc(sizeof(x264_param_t)); en->picture = (x264_param_t *) malloc(sizeof(x264_picture_t)); x264_param_default(en->param); //set default param x264_param_apply_profile(en->param,"baseline"); //en->param->rc.i_rc_method = X264_RC_CQP; en->param->i_log_level = X264_LOG_NONE; en->param->i_width = width; //set frame width en->param->i_height = height; //set frame height en->param->rc.i_lookahead =0; en->param->i_fps_num =5; en->param->i_fps_den = 1; if ((en->handle = x264_encoder_open(en->param)) == 0) { return 0; } /* Create a new pic */ x264_picture_alloc(en->picture, X264_CSP_I420, en->param->i_width, en->param->i_height); return (jlong) en; }
// See https://gist.github.com/roxlu/0f61a499df75e64b764d for an older version of this, with some rate control tests // @todo - we should check if the supplied settings are valid for the current profile.. e.g. bframes are not supported by the baseline profile bool VideoEncoder::initializeX264() { assert(settings.width > 0); assert(settings.height > 0); assert(settings.fps > 0); int r = 0; x264_param_t* p = ¶ms; std::string preset = (settings.preset.size()) ? settings.preset : "superfast"; std::string tune = (settings.tune.size()) ? settings.tune : "zerolatency"; STREAMER_STATUS("x264 using preset: %s and tune: %s\n", preset.c_str(), tune.c_str()); r = x264_param_default_preset(p, preset.c_str(), tune.c_str()); if(r != 0) { STREAMER_ERROR("error: cannot set the default preset on x264.\n"); return false; } p->i_threads = settings.threads; p->i_width = settings.width; p->i_height = settings.height; p->i_fps_num = settings.fps; p->i_fps_den = 1; p->b_annexb = 0; // flv == no annexb, but strangely, when I disable it the generated flv cannot be played back, for raw h264 you'll need to set annexb to 1 when you want to play it in vlc (vlc isn't properly playing back flv) p->rc.i_rc_method = X264_RC_ABR; // when you're limited to bandwidth you set the vbv_buffer_size and vbv_max_bitrate using the X264_RC_ABR rate control method. The vbv_buffer_size is a decoder option and tells the decoder how much data must be buffered before playback can start. When vbv_max_bitrate == vbv_buffer_size, then it will take one second before the playback might start. when vbv_buffer_size == vbv_max_bitrate * 0.5, it might start in 0.5 sec. p->rc.i_bitrate = settings.bitrate; p->rc.i_vbv_buffer_size = (settings.vbv_buffer_size < 0) ? p->rc.i_bitrate : settings.vbv_buffer_size; p->rc.i_vbv_max_bitrate = (settings.vbv_max_bitrate < 0) ? p->rc.i_bitrate : settings.vbv_max_bitrate;; if(settings.keyint_max > 0) { p->i_keyint_max = settings.keyint_max; } if(settings.bframe > 0) { p->i_bframe = settings.bframe; } if(settings.level_idc > 0) { p->i_level_idc = settings.level_idc; } #if !defined(NDEBUG) p->i_log_level = X264_LOG_DEBUG; p->pf_log = videoencoder_x264_log; #endif if(settings.profile.size()) { r = x264_param_apply_profile(p, settings.profile.c_str()); if(r != 0) { STREAMER_ERROR("error: cannot set the baseline profile on x264.\n"); return false; } } encoder = x264_encoder_open(p); if(!encoder) { STREAMER_ERROR("error: cannot create the encoder.\n"); return false; } x264_encoder_parameters(encoder, ¶ms); print_x264_params(p); return true; }
int main(int argc, char* argv[]){ x264_param_t param; x264_t *h = NULL; x264_picture_t pic_in; x264_picture_t pic_out; x264_nal_t *nal; uint8_t *data = NULL; int widthXheight = width * height; int frame_size = width * height * 1.5; int read_sum = 0, write_sum = 0; int frames = 0; int i, rnum, i_size; x264_nal_t* pNals = NULL; x264_param_default(¶m); param.i_width = width; param.i_height = height; param.i_bframe = 3; param.i_fps_num = 25; param.i_fps_den = 1; param.b_vfr_input = 0; param.i_keyint_max = 250; param.rc.i_bitrate = 1500; param.i_scenecut_threshold = 40; param.i_level_idc = 51; x264_param_apply_profile(¶m, "high"); h = x264_encoder_open( ¶m ); // printf("param.rc.i_qp_min=%d, param.rc.i_qp_max=%d, param.rc.i_qp_step=%d param.rc.i_qp_constant=%d param.rc.i_rc_method=%d\n", // param.rc.i_qp_min, param.rc.i_qp_max, param.rc.i_qp_step, param.rc.i_qp_constant, param.rc.i_rc_method); printf("param:%s\n", x264_param2string(¶m, 1)); x264_picture_init( &pic_in ); x264_picture_alloc(&pic_in, X264_CSP_YV12, width, height); pic_in.img.i_csp = X264_CSP_YV12; pic_in.img.i_plane = 3; data = (uint8_t*)malloc(0x400000); FILE* fpr = fopen(MFILE ".yuv", "rb"); FILE* fpw1 = fopen(MFILE".szhu.h264", "wb"); // FILE* fpw2 = fopen(MFILE".h264", "wb"); if(!fpr || !fpw1 ) { printf("file open failed\n"); return -1; } while(!feof(fpr)){ rnum = fread(data, 1, frame_size, fpr); if(rnum != frame_size){ printf("read file failed\n"); break; } memcpy(pic_in.img.plane[0], data, widthXheight); memcpy(pic_in.img.plane[1], data + widthXheight, widthXheight >> 2); memcpy(pic_in.img.plane[2], data + widthXheight + (widthXheight >> 2), widthXheight >> 2); read_sum += rnum; frames ++; // printf("read frames=%d %.2fMB write:%.2fMB\n", frames, read_sum * 1.0 / 0x100000, write_sum * 1.0 / 0x100000); int i_nal; int i_frame_size = 0; if(0 && frames % 12 == 0){ pic_in.i_type = X264_TYPE_I; }else{ pic_in.i_type = X264_TYPE_AUTO; } i_frame_size = x264_encoder_encode( h, &nal, &i_nal, &pic_in, &pic_out ); if(i_frame_size <= 0){ //printf("\t!!!FAILED encode frame \n"); }else{ fwrite(nal[0].p_payload, 1, i_frame_size, fpw1); // printf("\t+++i_frame_size=%d\n", i_frame_size); write_sum += i_frame_size; } #if 0 for(i = 0; i < i_nal; i ++){ i_size = nal[i].i_payload; // fwrite(nal[i].p_payload, 1, nal[i].i_payload, fpw1); fwrite(nal[i].p_payload, 1, i_frame_size, fpw1); x264_nal_encode(h, data, &nal[i]); if(i_size != nal[i].i_payload){ printf("\t\ti_size=%d nal[i].i_payload=%d\n", i_size, nal[i].i_payload); } fwrite(data, 1, nal[i].i_payload, fpw2); } #endif } free(data); x264_picture_clean(&pic_in); x264_picture_clean(&pic_out); if(h){ x264_encoder_close(h); h = NULL; } fclose(fpw1); // fclose(fpw2); fclose(fpr); printf("h=0x%X", h); return 0; }
int main(int argc, char** argv) { int listenfd, connfd; int byterecv; int bytesum = 0; int ret = 0; struct sockaddr_in servaddr; char *buff; int width, height; x264_param_t param; x264_picture_t pic; x264_picture_t pic_out; x264_t *h; int i_frame = 0; int i_frame_size; x264_nal_t *nal; int i_nal; FILE *fout = NULL; /* Get default params for preset/tuning */ if(x264_param_default_preset( ¶m, "medium", NULL ) < 0) goto fail; /* Configure non-default params */ param.i_csp = X264_CSP_I420; param.i_width = WIDTH; param.i_height = HEIGHT; param.b_vfr_input = 0; //frame rate param.b_repeat_headers = 1; param.b_annexb = 1; /* Apply profile restrictions. */ if(x264_param_apply_profile(¶m, "baseline") < 0) goto fail; if(x264_picture_alloc(&pic, param.i_csp, param.i_width, param.i_height) < 0) goto fail; #undef fail #define fail fail2 h = x264_encoder_open(¶m); if(!h) goto fail; printf("x264 encoder init successfully\n"); int luma_size = width * height; int chroma_size = luma_size / 4; fout = fopen("test.264", "wb+"); #undef fail #define fail fail3 /* socket init*/ if((listenfd = socket(AF_INET, SOCK_STREAM, 0)) == -1){ printf("create socket error: %s(errno: %d)\n",strerror(errno),errno); exit(0); } memset(&servaddr, 0, sizeof(servaddr)); servaddr.sin_family = AF_INET; servaddr.sin_addr.s_addr = htonl(INADDR_ANY); servaddr.sin_port = htons(6666); if(bind(listenfd, (struct sockaddr*)&servaddr, sizeof(servaddr)) == -1){ printf("bind socket error: %s(errno: %d)\n",strerror(errno),errno); exit(0); } if(listen(listenfd, 10) == -1){ printf("listen socket error: %s(errno: %d)\n",strerror(errno),errno); exit(0); } printf("======waiting for client's request======\n"); if((connfd = accept(listenfd, (struct sockaddr*)NULL, NULL)) == -1){ printf("accept socket error: %s(errno: %d)",strerror(errno),errno); exit(0); } /* malloc 5k buffer for recv raw data from client*/ buff = (char *)malloc(5 * 1024 * 1024 * sizeof(char)); while(1) { byterecv = recv(connfd, buff + bytesum, 32 * 1024, 0); if (byterecv > 0) { bytesum += byterecv; /* got one frame here, encode it*/ if (bytesum >= RESOLUTION * 1.5) { pic.img.plane[0] = buff; pic.img.plane[1] = buff + luma_size; pic.img.plane[2] = buff + luma_size + chroma_size; pic.i_pts = i_frame; i_frame ++; i_frame_size = x264_encoder_encode(h, &nal, &i_nal, &pic, &pic_out); if(i_frame_size < 0) goto fail; else if(i_frame_size) { if(!fwrite( nal->p_payload, i_frame_size, 1, fout)) goto fail; printf("encode frame %d\n", i_frame); } bytesum = bytesum - RESOLUTION * 1.5; memcpy(buff, buff + (int)(RESOLUTION * 1.5), bytesum); } } else if((byterecv < 0) && (errno == EAGAIN || errno == EINTR)) { printf("coutinue\n"); continue; } else { //printf("stop recv stream frome client, bytesum: %d, total: %d\n", bytesum, total); break; } } /* Flush delayed frames */ while(x264_encoder_delayed_frames(h)) { i_frame_size = x264_encoder_encode(h, &nal, &i_nal, NULL, &pic_out); if(i_frame_size < 0) goto fail; else if(i_frame_size) { if(!fwrite( nal->p_payload, i_frame_size, 1, fout)) goto fail; } } if (fout) fclose(fout); x264_encoder_close(h); x264_picture_clean(&pic); close(connfd); close(listenfd); return 0; #undef fail fail3: x264_encoder_close(h); fail2: x264_picture_clean(&pic); fail: return -1; }
void x264enc_set_param(const m_option_t* opt, char* arg) { static int initialized = 0; int slow_firstpass = 0; char *preset = NULL, *tune = NULL, *profile = NULL; char *p, *copy, *name; if (!initialized) { x264_param_default(¶m); initialized = 1; } if (!arg) { mp_msg(MSGT_CFGPARSER, MSGL_ERR, "Option x264encopts: no options provided\n"); parse_error = 1; return; } else if (!*arg) /* Empty arguments, just doing initialization of default parameters. */ return; /* Step 1: look for initial preset/tune. */ copy = p = strdup(arg); while ((name = strsep(©, ":"))) { char *value = strpbrk(name, "=:"); if (!value) continue; *value++ = 0; if (!strcasecmp(name, "preset")) preset = value; else if (!strcasecmp(name, "tune")) tune = value; } if (x264_param_default_preset(¶m, preset, tune) < 0) { mp_msg(MSGT_CFGPARSER, MSGL_ERR, "Option x264encopts: Invalid preset or tune.\n"); parse_error = 1; } free(p); /* Step 2: explicit user overrides */ while ((name = strsep(&arg, ":")) && *name) { int ret = 0; char *value = strpbrk(name, "=:"); if (value) *value++ = 0; if (!strcasecmp(name, "profile")) profile = value; else if (!strcasecmp(name, "turbo")) { mp_msg(MSGT_CFGPARSER, MSGL_WARN, "Option x264encopts: turbo option is deprecated; " "use slow_firstpass to disable turbo\n"); if (value && *value == '0') slow_firstpass = 1; } else if (!strcasecmp(name, "slow_firstpass")) slow_firstpass = 1; else if (strcasecmp(name, "preset") && strcasecmp(name, "tune")) { ret = x264_param_parse(¶m, name, value); if (ret == X264_PARAM_BAD_NAME) mp_msg(MSGT_CFGPARSER, MSGL_ERR, "Option x264encopts: Unknown suboption %s\n", name); if (ret == X264_PARAM_BAD_VALUE) mp_msg(MSGT_CFGPARSER, MSGL_ERR, "Option x264encopts: Bad argument %s=%s\n", name, value ? value : "(null)"); } /* mark this option as done, so it's not reparsed if there's another -x264encopts */ *name = 0; parse_error |= ret; } /* Step 3: Apply fast first pass (turbo) options. */ if (!slow_firstpass) x264_param_apply_fastfirstpass(¶m); /* Step 4: enforce profile */ if (profile && x264_param_apply_profile(¶m, profile) < 0) parse_error = 1; }
int obe_populate_avc_encoder_params( obe_t *h, int input_stream_id, x264_param_t *param ) { obe_int_input_stream_t *stream = get_input_stream( h, input_stream_id ); if( !stream ) { fprintf( stderr, "Could not find stream \n" ); return -1; } if( stream->stream_type != STREAM_TYPE_VIDEO ) { fprintf( stderr, "Stream type is not video \n" ); return -1; } if( !param ) { fprintf( stderr, "Invalid parameter pointer \n" ); return -1; } if( h->obe_system == OBE_SYSTEM_TYPE_LOWEST_LATENCY || h->obe_system == OBE_SYSTEM_TYPE_LOW_LATENCY ) x264_param_default_preset( param, "veryfast", "zerolatency" ); else x264_param_default( param ); param->b_deterministic = 0; param->b_vfr_input = 0; param->b_pic_struct = 1; param->b_open_gop = 1; param->rc.i_rc_method = X264_RC_ABR; param->i_width = stream->width; param->i_height = stream->height; param->i_fps_num = stream->timebase_den; param->i_fps_den = stream->timebase_num; param->b_interlaced = stream->interlaced; if( param->b_interlaced ) param->b_tff = stream->tff; /* A reasonable default. x264 won't go higher than this parameter irrespective of speedcontrol */ if( h->obe_system == OBE_SYSTEM_TYPE_GENERIC ) param->i_frame_reference = 4; if( stream->sar_num && stream->sar_den ) { param->vui.i_sar_width = stream->sar_num; param->vui.i_sar_height = stream->sar_den; } param->vui.i_overscan = 2; if( ( param->i_fps_num == 25 || param->i_fps_num == 50 ) && param->i_fps_den == 1 ) { param->vui.i_vidformat = 1; // PAL param->vui.i_colorprim = 5; // BT.470-2 bg param->vui.i_transfer = 5; // BT.470-2 bg param->vui.i_colmatrix = 5; // BT.470-2 bg param->i_keyint_max = param->i_fps_num == 50 ? 48 : 24; } else if( ( param->i_fps_num == 30000 || param->i_fps_num == 60000 ) && param->i_fps_den == 1001 ) { param->vui.i_vidformat = 2; // NTSC param->vui.i_colorprim = 6; // BT.601-6 param->vui.i_transfer = 6; // BT.601-6 param->vui.i_colmatrix = 6; // BT.601-6 param->i_keyint_max = param->i_fps_num / 1000; } else { param->vui.i_vidformat = 5; // undefined param->vui.i_colorprim = 2; // undefined param->vui.i_transfer = 2; // undefined param->vui.i_colmatrix = 2; // undefined } /* Change to BT.709 for HD resolutions */ if( param->i_width >= 1280 && param->i_height >= 720 ) { param->vui.i_colorprim = 1; param->vui.i_transfer = 1; param->vui.i_colmatrix = 1; } x264_param_apply_profile( param, X264_BIT_DEPTH == 10 ? "high10" : "high" ); param->i_nal_hrd = X264_NAL_HRD_FAKE_VBR; param->b_aud = 1; param->i_log_level = X264_LOG_INFO; //param->rc.f_vbv_buffer_init = 0.1; if( h->obe_system == OBE_SYSTEM_TYPE_GENERIC ) { param->sc.f_speed = 1.0; param->sc.b_alt_timer = 1; if( param->i_width >= 1280 && param->i_height >= 720 ) param->sc.max_preset = 7; /* on the conservative side for HD */ else param->sc.max_preset = 10; param->rc.i_lookahead = param->i_keyint_max; } return 0; }
msx264::msx264() { pNals = NULL; iNal = 0; x264_param_default(¶ms); //x264_param_default_preset(¶ms,"fast","zerolatency"); #if 0 params.i_threads = X264_SYNC_LOOKAHEAD_AUTO; params.i_width = 640; params.i_height = 480; params.i_frame_total = 0; // Set parameters params.i_keyint_max = 25; params.i_keyint_min = 1; params.i_bframe = 0; params.b_open_gop = 0; params.i_bframe_pyramid = 0; params.i_bframe_adaptive = X264_B_ADAPT_TRELLIS; params.i_log_level = X264_LOG_DEBUG; params.i_frame_reference = 0; //params.rc.i_bitrate = (int)( ( ((float)d->bitrate)*0.8)/1000.0); params.rc.i_bitrate = 250000; params.rc.b_stat_write = 0; //params.i_slice_max_size = ms_get_payload_max_size()-100; /*arlready */ params.i_slice_max_size = 1340; /*arlready */ params.rc.i_lookahead = 0; params.b_annexb = 0; params.b_repeat_headers = 1; params.rc.i_qp_min = 2; params.rc.i_qp_max = 31; params.rc.i_qp_step = 29; params.i_fps_num = 25; params.i_fps_den = 1; #endif params.i_threads = X264_SYNC_LOOKAHEAD_AUTO; //* 取空缓冲区继续使用不死锁的保证. //* video Properties params.i_width = 640; //* 宽度. params.i_height = 480; //* 高度 params.i_frame_total = 0; //* 编码总帧数.不知道用0. params.i_keyint_max = 10; //* bitstream parameters params.i_bframe = 5; params.b_open_gop = 0; params.i_bframe_pyramid = 0; params.i_bframe_adaptive = X264_B_ADAPT_TRELLIS; //* 宽高比,有效果,但不是想要的. //pX264Param->vui.i_sar_width = 1080; //pX264Param->vui.i_sar_height = 720; //* Log params.i_log_level = X264_LOG_DEBUG; //* Rate control Parameters params.rc.i_bitrate = 1024 * 10; //* 码率(比特率,单位Kbps) //* muxing parameters params.i_fps_den = 1; //* 帧率分母 params.i_fps_num = 25; //* 帧率分子 params.i_timebase_den = params.i_fps_num; params.i_timebase_num = params.i_fps_den; // Set profile level constrains x264_param_apply_profile(¶ms,"baseline"); params.rc.i_rc_method = X264_RC_ABR; file = open("./file.h264", O_RDWR | O_NONBLOCK, 0); if (file < 0) { printf("open video error\n"); return ; } }
/********************** * OpenCodec * Abre el codec ***********************/ int H264RtspEncoder::OpenCodec() { x264_param_t params; Log("-OpenCodec H264 [%dbps,%dfps]\n",bitrate,fps); // Check if (opened) return Error("Codec already opened\n"); // Reset default values x264_param_default(¶ms); // Use a defulat preset x264_param_default_preset(¶ms,"fast","zerolatency"); // Set log params.pf_log = X264_log; params.i_log_level = X264_LOG_WARNING; // Set encoding context size params.i_width = width; params.i_height = height; // Set parameters params.i_keyint_max = intraPeriod; params.i_keyint_min = 1; params.b_cabac = 1; params.i_frame_reference = 0; params.rc.i_bitrate = bitrate / 1024; params.rc.b_stat_write = 0; params.i_slice_max_size = RTPPAYLOADSIZE; params.b_sliced_threads = 0; params.rc.i_lookahead = 0; params.i_bframe = 0; //params.b_annexb = 0; params.b_repeat_headers = 1; params.i_threads = 0; params.b_vfr_input = 0; params.rc.i_qp_min = qMin; params.rc.i_qp_max = qMax; params.rc.i_qp_step = qMax-qMin; params.i_fps_num = fps; params.i_fps_den = 2; // Set profile level constrains x264_param_apply_profile(¶ms,"baseline"); // Open encoder enc = x264_encoder_open(¶ms); //Check it is correct if (!enc) return Error("Could not open h264 codec\n"); // Clean pictures memset(&pic,0,sizeof(x264_picture_t)); memset(&pic_out,0,sizeof(x264_picture_t)); //Set picture type pic.i_type = X264_TYPE_AUTO; // We are opened opened=true; // Exit return 1; }
bool X264Encoder::openX264Encoder() { this->closeX264Encoder(); if(!pParameter) { pParameter = (x264_param_t *)malloc(sizeof(x264_param_t)); if (!pParameter) { this->closeX264Encoder(); return false; } memset(pParameter, 0, sizeof(x264_param_t)); } int ret = x264_param_default_preset(pParameter, "ultrafast", "zerolatency"); if (ret != 0) { this->closeX264Encoder(); return false; } pParameter->i_threads = 1; pParameter->b_sliced_threads = 0; pParameter->i_sync_lookahead = X264_SYNC_LOOKAHEAD_AUTO; pParameter->i_width = width; pParameter->i_height = height; pParameter->i_frame_total = 0; pParameter->b_deterministic = 1; pParameter->i_frame_reference = 4; pParameter->i_bframe = 0; pParameter->i_bframe_pyramid = 0; pParameter->i_bframe_adaptive = 0; pParameter->b_intra_refresh = 0; pParameter->i_csp = X264_CSP_I420; pParameter->i_level_idc = 9; pParameter->i_keyint_min = 10; pParameter->i_keyint_max = 30; pParameter->b_repeat_headers = 1; pParameter->b_interlaced = 0; pParameter->i_cqm_preset = X264_CQM_FLAT; pParameter->psz_cqm_file = NULL; pParameter->b_aud = 0; pParameter->i_nal_hrd = X264_NAL_HRD_NONE; pParameter->i_scenecut_threshold = 40; pParameter->i_bframe_bias = 0; pParameter->i_fps_num = i_fps; pParameter->i_fps_den = 1; pParameter->i_timebase_num = 1; pParameter->i_timebase_den = 1000000; pParameter->analyse.i_weighted_pred = 0; pParameter->analyse.b_weighted_bipred = 0; pParameter->analyse.b_chroma_me = 1; pParameter->analyse.i_trellis = 1; pParameter->analyse.i_subpel_refine = 4; pParameter->analyse.b_transform_8x8 = 1; pParameter->analyse.i_me_range = 8; pParameter->analyse.i_me_method = X264_ME_UMH; //2 pParameter->analyse.i_direct_mv_pred = X264_DIRECT_PRED_TEMPORAL; //2 pParameter->analyse.intra = 0; pParameter->analyse.inter = 0; pParameter->b_cabac = 0; pParameter->b_vfr_input = 0; pParameter->rc.i_rc_method = X264_RC_ABR;//X264_RC_CQP; pParameter->rc.f_qcompress = 0.6f; // 0.0 => cbr, 1.0 => constant qp pParameter->rc.i_lookahead = 0; pParameter->rc.b_mb_tree = 0; pParameter->rc.i_qp_min = 10; pParameter->rc.i_qp_max = 51; pParameter->rc.i_qp_step = 3; pParameter->rc.i_qp_constant = 10; pParameter->rc.f_rf_constant = 10; // 1pass VBR, nominal QP pParameter->rc.i_bitrate = 300; pParameter->rc.i_vbv_max_bitrate = 300; pParameter->rc.i_vbv_buffer_size = 300; pParameter->rc.f_vbv_buffer_init = 0.6f; pParameter->rc.f_rate_tolerance = 10 / 100.0f; // In CRF mode,maximum CRF as caused by VBV if(x264_param_apply_profile(pParameter, "baseline")) { this->closeX264Encoder(); return false; } if (!x264EncoderHandle) { x264EncoderHandle = x264_encoder_open(pParameter); assert(x264EncoderHandle != NULL); } int nal_count = 0; x264_nal_t* nals = NULL; x264_encoder_headers(x264EncoderHandle, &nals, &nal_count); assert(nal_count > 0); for (int index = 0; index < nal_count; ++index) { if (nals[index].i_type == NAL_SPS) { spslen = createNalBuffer(sps, nals[index].p_payload, nals[index].i_payload); } if (nals[index].i_type == NAL_PPS) { ppslen = createNalBuffer(pps, nals[index].p_payload, nals[index].i_payload); } } assert(spslen != 0); assert(ppslen != 0); if (!pOutput) { pOutput = (x264_picture_t *)malloc(sizeof(x264_picture_t)); if (!pOutput) { this->closeX264Encoder(); return false; } } memset(pOutput, 0, sizeof(x264_picture_t)); return true; }
X264Encoder(int fps, int width, int height, int quality, CTSTR preset, bool bUse444, ColorDescription &colorDesc, int maxBitrate, int bufferSize, bool bUseCFR) { curPreset = preset; fps_ms = 1000/fps; StringList paramList; curProfile = AppConfig->GetString(TEXT("Video Encoding"), TEXT("X264Profile"), TEXT("high")); BOOL bUseCustomParams = AppConfig->GetInt(TEXT("Video Encoding"), TEXT("UseCustomSettings")); if(bUseCustomParams) { String strCustomParams = AppConfig->GetString(TEXT("Video Encoding"), TEXT("CustomSettings")); strCustomParams.KillSpaces(); if(strCustomParams.IsValid()) { Log(TEXT("Using custom x264 settings: \"%s\""), strCustomParams.Array()); strCustomParams.GetTokenList(paramList, ' ', FALSE); for(UINT i=0; i<paramList.Num(); i++) { String &strParam = paramList[i]; if(!schr(strParam, '=')) continue; String strParamName = strParam.GetToken(0, '='); String strParamVal = strParam.GetTokenOffset(1, '='); if(strParamName.CompareI(TEXT("preset"))) { if(valid_x264_string(strParamVal, (const char**)x264_preset_names)) curPreset = strParamVal; else Log(TEXT("invalid preset: %s"), strParamVal.Array()); paramList.Remove(i--); } else if(strParamName.CompareI(TEXT("tune"))) { if(valid_x264_string(strParamVal, (const char**)x264_tune_names)) curTune = strParamVal; else Log(TEXT("invalid tune: %s"), strParamVal.Array()); paramList.Remove(i--); } else if(strParamName.CompareI(TEXT("profile"))) { if(valid_x264_string(strParamVal, (const char **)x264_profile_names)) curProfile = strParamVal; else Log(TEXT("invalid profile: %s"), strParamVal.Array()); paramList.Remove(i--); } } } } zero(¶mData, sizeof(paramData)); LPSTR lpPreset = curPreset.CreateUTF8String(); LPSTR lpTune = curTune.CreateUTF8String(); if (x264_param_default_preset(¶mData, lpPreset, lpTune)) Log(TEXT("Failed to set x264 defaults: %s/%s"), curPreset.Array(), curTune.Array()); Free(lpTune); Free(lpPreset); this->width = width; this->height = height; paramData.b_deterministic = false; bUseCBR = AppConfig->GetInt(TEXT("Video Encoding"), TEXT("UseCBR"), 1) != 0; bPadCBR = AppConfig->GetInt(TEXT("Video Encoding"), TEXT("PadCBR"), 1) != 0; this->bUseCFR = bUseCFR; SetBitRateParams(maxBitrate, bufferSize); if(bUseCBR) { if(bPadCBR) paramData.i_nal_hrd = X264_NAL_HRD_CBR; paramData.rc.i_rc_method = X264_RC_ABR; paramData.rc.f_rf_constant = 0.0f; } else { paramData.rc.i_rc_method = X264_RC_CRF; paramData.rc.f_rf_constant = baseCRF+float(10-quality); } UINT keyframeInterval = AppConfig->GetInt(TEXT("Video Encoding"), TEXT("KeyframeInterval"), 0); paramData.b_vfr_input = !bUseCFR; paramData.i_width = width; paramData.i_height = height; paramData.vui.b_fullrange = colorDesc.fullRange; paramData.vui.i_colorprim = colorDesc.primaries; paramData.vui.i_transfer = colorDesc.transfer; paramData.vui.i_colmatrix = colorDesc.matrix; if (keyframeInterval) paramData.i_keyint_max = fps*keyframeInterval; paramData.i_fps_num = fps; paramData.i_fps_den = 1; paramData.i_timebase_num = 1; paramData.i_timebase_den = 1000; paramData.pf_log = get_x264_log; paramData.i_log_level = X264_LOG_WARNING; for(UINT i=0; i<paramList.Num(); i++) { String &strParam = paramList[i]; if(!schr(strParam, '=')) continue; String strParamName = strParam.GetToken(0, '='); String strParamVal = strParam.GetTokenOffset(1, '='); if( strParamName.CompareI(TEXT("fps")) || strParamName.CompareI(TEXT("force-cfr"))) { Log(TEXT("The custom x264 command '%s' is unsupported, use the application settings instead"), strParam.Array()); continue; } else { LPSTR lpParam = strParamName.CreateUTF8String(); LPSTR lpVal = strParamVal.CreateUTF8String(); if(x264_param_parse(¶mData, lpParam, lpVal) != 0) Log(TEXT("The custom x264 command '%s' failed"), strParam.Array()); Free(lpParam); Free(lpVal); } } if(bUse444) paramData.i_csp = X264_CSP_I444; else paramData.i_csp = X264_CSP_I420; colorDesc.fullRange = paramData.vui.b_fullrange; colorDesc.primaries = paramData.vui.i_colorprim; colorDesc.transfer = paramData.vui.i_transfer; colorDesc.matrix = paramData.vui.i_colmatrix; if (curProfile) { LPSTR lpProfile = curProfile.CreateUTF8String(); if (x264_param_apply_profile (¶mData, lpProfile)) Log(TEXT("Failed to set x264 profile: %s"), curProfile.Array()); Free(lpProfile); } x264 = x264_encoder_open(¶mData); if(!x264) CrashError(TEXT("Could not initialize x264")); Log(TEXT("------------------------------------------")); Log(TEXT("%s"), GetInfoString().Array()); Log(TEXT("------------------------------------------")); DataPacket packet; GetHeaders(packet); }
int main(int argc, char **argv) { int ret = 0; int y_size = 0; int i = 0; int j = 0; //Encode 50 frame //if set 0, encode all frame int frame_num = 50; int csp = X264_CSP_I420; int width = 640; int height = 360; int i_nal = 0; x264_nal_t *p_nals = NULL; x264_t *p_handle = NULL; x264_picture_t *p_pic_in = (x264_picture_t *) malloc(sizeof(x264_picture_t)); x264_picture_t *p_pic_out = (x264_picture_t *) malloc(sizeof(x264_picture_t)); x264_param_t *p_param = (x264_param_t *) malloc(sizeof(x264_param_t)); //FILE* fp_src = fopen("../cuc_ieschool_640x360_yuv444p.yuv", "rb"); FILE *fp_src = fopen("../cuc_ieschool_640x360_yuv420p.yuv", "rb"); FILE *fp_dst = fopen("cuc_ieschool.h264", "wb"); //Check if ((NULL == fp_src) || (NULL == fp_dst)) { lwlog_err("Open files error."); return -1; } x264_param_default(p_param); p_param->i_width = width; p_param->i_height = height; /* //Param p_param->i_log_level = X264_LOG_DEBUG; p_param->i_threads = X264_SYNC_LOOKAHEAD_AUTO; p_param->i_frame_total = 0; p_param->i_keyint_max = 10; p_param->i_bframe = 5; p_param->b_open_gop = 0; p_param->i_bframe_pyramid = 0; p_param->rc.i_qp_constant=0; p_param->rc.i_qp_max=0; p_param->rc.i_qp_min=0; p_param->i_bframe_adaptive = X264_B_ADAPT_TRELLIS; p_param->i_fps_den = 1; p_param->i_fps_num = 25; p_param->i_timebase_den = p_param->i_fps_num; p_param->i_timebase_num = p_param->i_fps_den; */ p_param->i_csp = csp; x264_param_apply_profile(p_param, x264_profile_names[5]); p_handle = x264_encoder_open(p_param); x264_picture_init(p_pic_out); x264_picture_alloc(p_pic_in, csp, p_param->i_width, p_param->i_height); //ret = x264_encoder_headers(p_handle, &p_nals, &i_nal); y_size = p_param->i_width * p_param->i_height; //detect frame number if (0 == frame_num) { fseek(fp_src, 0, SEEK_END); switch (csp) { case X264_CSP_I444: frame_num = ftell(fp_src) / (y_size * 3); break; case X264_CSP_I420: frame_num = ftell(fp_src) / (y_size * 3 / 2); break; default: lwlog_err("Colorspace Not Support"); return -1; } fseek(fp_src, 0, SEEK_SET); } //Loop to Encode for (i = 0; i < frame_num; ++i) { switch (csp) { case X264_CSP_I444: { fread(p_pic_in->img.plane[0], y_size, 1, fp_src); //Y fread(p_pic_in->img.plane[1], y_size, 1, fp_src); //U fread(p_pic_in->img.plane[2], y_size, 1, fp_src); //V break; } case X264_CSP_I420: { fread(p_pic_in->img.plane[0], y_size, 1, fp_src); //Y fread(p_pic_in->img.plane[1], y_size / 4, 1, fp_src); //U fread(p_pic_in->img.plane[2], y_size / 4, 1, fp_src); //V break; } default: { lwlog_err("Colorspace Not Support.\n"); return -1; } } p_pic_in->i_pts = i; ret = x264_encoder_encode(p_handle, &p_nals, &i_nal, p_pic_in, p_pic_out); if (ret < 0) { lwlog_err("x264_encoder_encode error"); return -1; } lwlog_info("Succeed encode frame: %5d\n", i); for (j = 0; j < i_nal; ++j) { fwrite(p_nals[j].p_payload, 1, p_nals[j].i_payload, fp_dst); } } i = 0; //flush encoder while (1) { ret = x264_encoder_encode(p_handle, &p_nals, &i_nal, NULL, p_pic_out); if (0 == ret) { break; } lwlog_info("Flush 1 frame."); for (j = 0; j < i_nal; ++j) { fwrite(p_nals[j].p_payload, 1, p_nals[j].i_payload, fp_dst); } ++i; } x264_picture_clean(p_pic_in); x264_encoder_close(p_handle); p_handle = NULL; free(p_pic_in); free(p_pic_out); free(p_param); fclose(fp_src); fclose(fp_dst); return 0; }
int init_param(x264_param_t * x264_param, int width, int height, int fps, int bitrate) { x264_param_default(x264_param); x264_param_default_preset(x264_param, "medium", NULL ); x264_param_default_preset(x264_param, "veryfast", "zerolatency"); //x264_param_default_preset(x264_param_, "veryfast", NULL); //x264_param_default_preset(x264_param_,"superfast","zerolatency"); // CPU flags //x264_param_->i_threads = X264_THREADS_AUTO; x264_param->i_threads = X264_SYNC_LOOKAHEAD_AUTO; // Video Properties x264_param->i_csp = X264_CSP_I420; x264_param->i_width = width; x264_param->i_height = height; //x264_param_->i_frame_total = 0; // Bitstream parameters //x264_param_->i_bframe = 5; //x264_param_->b_open_gop = 0; //x264_param_->i_bframe_pyramid = 0; //x264_param_->i_bframe_adaptive = X264_B_ADAPT_TRELLIS; //x264_param_->i_keyint_min = 0; //x264_param_->i_keyint_max = fps*10; // Rate control parameters //x264_param_->rc.i_qp_min = 0; //x264_param_->rc.i_qp_max = 20; //x264_param_->rc.i_qp_constant = 0; //x264_param_->rc.i_bitrate = 1024 * 100; //x264_param_->rc.i_rc_method = X264_RC_CRF; //x264_param_->rc.f_rf_constant = 22.0+float(10-5); // muxing parameters x264_param->b_annexb = 1; x264_param->b_repeat_headers = 1; //x264_param_->i_fps_den = 1; //* 帧率分母 //x264_param_->i_fps_num = 10;//* 帧率分子 //x264_param_->i_timebase_den = x264_param_->i_fps_num; //x264_param_->i_timebase_num = x264_param_->i_fps_den; //x264_param_->b_vfr_input = 0; // OBS x264_param->i_fps_num = fps; x264_param->i_keyint_max = fps * 2; //x264_param_->b_deterministic = false; //x264_param_->b_vfr_input = 0; //x264_param_->i_fps_num =fps;//数值由客户端传下来,一般是15fps //x264_param_->i_timebase_num = 1; //x264_param_->i_timebase_den = 1000; //x264_param_->rc.i_qp_min = 16; //x264_param_->rc.i_qp_max = 20; //x264_param_->rc.i_qp_constant = 16; x264_param->rc.i_rc_method = X264_RC_CRF; x264_param->rc.f_rf_constant = (float)bitrate; x264_param_apply_profile(x264_param, "main"); }