[x264-devel] h.264 encoding live stream from a web cam

i-love-spam i-love-spam at yandex.ru
Mon Aug 24 00:36:06 CEST 2009


Hello,

I trying to encode from a web cam and I have a couple of problems/questions:

0) it seems that my cpu can't do real time encoding of web cam video. Is my cpu no good, is that property of video from a so-so quality web cam (mosquito noise etc) or it's my config of x264 isn't good (I'll post the code at the bottom of the message)?
10fps at CIF takes 30% cpu on a dual core athlon 64 x2 3800+ (I manually limit to 10fps for testing).
if I try to use 640x480 then I already can't do real time encoding even if I enable threading.
I'm getting approximately 8.5fps with 95+% of cpu load (both cores).
I'm using ffmpeg built with x264. From all the post all over the web I'm seeing that most of the users transcode a DVD movie in half duration of the movie itself; so I just wanted to make sure that my results aren't totally broken.

1) x264 and threading: I enabled threading and it works, but I have one major complain about that.
I'm getting 8fps and for each frame it seems that there is a thread started and terminated, so that in debugger of visual studio I see tons of useless messages like:
..
The thread 'Win32 Thread' (0x1ba4) has exited with code 0 (0x0).
The thread 'Win32 Thread' (0x1258) has exited with code 0 (0x0).
The thread 'Win32 Thread' (0xd08) has exited with code 0 (0x0).
..
Can I make x264 not terminate, and keep the thread and use mutexes or events to signal new tasks? If there is not such code in x264, can you direct me where should I look for threading code so I change it for my build, otherwise x264 makes my debug output unreadable.

and one small question: what's that project direct264 and what's the difference? It seems that x264 doesn't compile out of the box on MSVC, unlike direct264

thanks


//
//
//  x264 initialization code:
//
//
if ((FourCC(m_szInput)=='024I' || FourCC(m_szInput)=='2VUY') && m_szOutput.compareNoCase(szFmt)==0)
{
	av_log_set_level(AV_LOG_WARN);
	av_log_set_callback(h264_avlog_cb);
	while (true)
	{
		Lock lock(CS);
		Enc->m_pCodec = avcodec_find_encoder(CODEC_ID_H264);
		if (!Enc->m_pCodec)
			break;

		Enc->m_pContext=avcodec_alloc_context();
		Enc->m_pFrame=avcodec_alloc_frame();

		//enable threading:
		Enc->m_pContext->thread_count = 2;
		avcodec_thread_init(Enc->m_pContext, Enc->m_pContext->thread_count);

// Begin make X264 happy code

		Enc->m_pContext->refs = 3; // i_frame_reference
		Enc->m_pContext->me_range = 16; // i_me_range
		Enc->m_pContext->qmin = 10; // i_qp_min
		Enc->m_pContext->qmax = 51; // i_qp_max
		Enc->m_pContext->gop_size = 250; // i_keyint_max
		Enc->m_pContext->keyint_min = 6; // i_keyint_min
		Enc->m_pContext->max_qdiff = 4; // i_qp_step
		Enc->m_pContext->level = -1; // if(avctx->level > 0) x4->params.i_level_idc = avctx->level;
		Enc->m_pContext->scenechange_threshold = 40; // i_scenecut_threshold
		Enc->m_pContext->b_frame_strategy = 1; // i_bframe_adaptive
		Enc->m_pContext->bframebias = 0; // i_bframe_bias
		Enc->m_pContext->flags2 = Enc->m_pContext->flags2 & ~CODEC_FLAG2_BPYRAMID; // clear param->b_bframe_pyramid
		Enc->m_pContext->flags |= CODEC_FLAG_LOOP_FILTER; // set param->b_deblocking_filter
		Enc->m_pContext->deblockalpha = 0; // i_deblocking_filter_alphac0
		Enc->m_pContext->deblockbeta = 0; // i_deblocking_filter_beta
		Enc->m_pContext->coder_type = FF_CODER_TYPE_AC; // b_cabac
		Enc->m_pContext->crf = 23.0; // f_rf_constant
		Enc->m_pContext->i_quant_factor = (float)(-1.0/1.4); // x4->params.rc.f_ip_factor
		Enc->m_pContext->b_quant_factor = (float)1.3; // x4->params.rc.f_pb_factor
		Enc->m_pContext->flags = Enc->m_pContext->flags & ~CODEC_FLAG_PASS1; // clear param->rc.b_stat_write
		Enc->m_pContext->flags = Enc->m_pContext->flags & ~CODEC_FLAG_PASS2; // clear param->rc.b_stat_read
		Enc->m_pContext->max_b_frames = 0;
		Enc->m_pContext->partitions = X264_PART_I4X4 | X264_PART_I8X8 | X264_PART_P8X8 | X264_PART_B8X8;
		Enc->m_pContext->flags2 = Enc->m_pContext->flags2 & ~CODEC_FLAG2_8X8DCT; // set b_transform_8x8 true
		Enc->m_pContext->me_subpel_quality = 7; // i_subpel_refine
		Enc->m_pContext->flags2 = Enc->m_pContext->flags2 | CODEC_FLAG2_MIXED_REFS; // set b_mixed_references
		Enc->m_pContext->trellis = 0; // i_trellis
		Enc->m_pContext->flags2 = Enc->m_pContext->flags2 | CODEC_FLAG2_FASTPSKIP; // set b_fast_pskip
		Enc->m_pContext->chromaoffset = 0; // i_chroma_qp_offset
		Enc->m_pContext->me_cmp |= FF_CMP_CHROMA; // set b_chroma_me
		Enc->m_pContext->directpred = X264_DIRECT_PRED_SPATIAL;
		Enc->m_pContext->me_method = ME_HEX; // set x4->params.analyse.i_me_method = X264_ME_HEX;
		Enc->m_pContext->flags = Enc->m_pContext->flags & ~CODEC_FLAG_PASS1; // clear param->rc.b_stat_write
		Enc->m_pContext->flags2 = Enc->m_pContext->flags2 | CODEC_FLAG2_WPRED; // set b_weighted_bipred
		Enc->m_pContext->flags2 = Enc->m_pContext->flags2 | CODEC_FLAG2_8X8DCT; // set b_transform_8x8
		Enc->m_pContext->trellis = 1; // set i_trellis
		Enc->m_pContext->flags = Enc->m_pContext->flags & ~CODEC_FLAG_PSNR; // clear b_psnr
		Enc->m_pContext->qcompress = (float)0.6;
		Enc->m_pContext->flags2 = Enc->m_pContext->flags2 & ~CODEC_FLAG2_AUD; // clear b_aud
		//Enc->m_pContext->flags = Enc->m_pContext->flags & ~CODEC_FLAG_GLOBAL_HEADER; // b_repeat_headers=1
		Enc->m_pContext->flags = Enc->m_pContext->flags | CODEC_FLAG_GLOBAL_HEADER; // b_repeat_headers=0

// End make X264 happy code

		Enc->m_pContext->pix_fmt = PIX_FMT_YUV420P;
		Enc->m_pContext->time_base.num = 1;
		Enc->m_pContext->time_base.den = 10; // fps
		//assert(m_Size.nHeight && m_Size.nWidth);
		Enc->m_pContext->width = m_Size.nWidth;
		Enc->m_pContext->height = m_Size.nHeight;

		if (!Enc->m_pContext->width)
		{
			LOG_WARN(__FUNCTION__": Dimensions not set, default to CIF");
			Enc->m_pContext->width = CIF_WIDTH;
			Enc->m_pContext->height = CIF_HEIGHT;
		}

		//setVideoSize(m_pContext->width, m_pContext->height);

		int nBitRate=512000;
		SAL_LOG_INFO("%hs: Encode bitrate %d", __FUNCTION__, nBitRate);

		Enc->m_pContext->bit_rate = nBitRate;
		Enc->m_pContext->bit_rate_tolerance = nBitRate / 5;

		/*
			#ifdef WIN32_WCE
			m_pContext->gop_size = 25; //m_pContext->time_base.den * 5; //125; //FPS * 5
			#else
			m_pContext->gop_size = 50; //m_pContext->time_base.den * 5; //125; //FPS * 5
			#endif
		*/

		//assert(m_pCodec);
		int nOpenResult = avcodec_open(Enc->m_pContext, Enc->m_pCodec);


More information about the x264-devel mailing list