开发平台 :
Mac OS X EI Capitan 10.11.4
Xcode Version 7.3 iOS 9.3
代码 :
// x264 参数
double crf = 23;
int qmin = 12;// 最小的量化因子。取值范围0-69。
int qmax = 18;// 最大的量化因子。取值范围13-69。
int keyint = 16;
int scenecut = 0;
// slow
// ultrafast
// superfast
av_opt_set(codec_ctx->priv_data,
"preset",
"ultrafast",
0);
// zerolatency
// stillimage,fastdecode,zerolatency
av_opt_set(codec_ctx->priv_data,
"tune",
"stillimage,fastdecode,zerolatency",
0);
av_opt_set(codec_ctx->priv_data,
"profile",
"baseline",
0);
char x264opts[512] = { 0 };
sprintf(x264opts,
"crf=%f:scenecut=%d",
crf,
scenecut);
av_opt_set(codec_ctx->priv_data,
"x264opts",
x264opts,
0);
codec_ctx->codec_id = codec_id;
codec_ctx->codec_type = AVMEDIA_TYPE_VIDEO;
codec_ctx->pix_fmt = PIX_FMT_YUV420P;
codec_ctx->width = in_width;
codec_ctx->height = in_height;
codec_ctx->bit_rate = bit_rate;// 比特率
codec_ctx->time_base = (AVRational){ 1, in_frames_per_secs };
codec_ctx->qcompress = 1;// x264 参数 qcomp
codec_ctx->qblur = 1;
codec_ctx->qmin = qmin;// 最小量化系数
codec_ctx->qmax = qmax;// 最大量化系数
codec_ctx->keyint_min = 2;// 关键帧的最小间隔帧数
codec_ctx->gop_size = keyint;// 关键帧的最大间隔帧数,x264 参数 keyint
codec_ctx->scenechange_threshold = scenecut;// 场景变化检测阈值
codec_ctx->max_b_frames = 0;// optional param 可选参数,禁用B帧,,设置 x264 参数 profile 值为 baseline 时,此参数失效
codec_ctx->thread_count = 1;
codec_ctx->ticks_per_frame = 2;
/*
codec_ctx->rc_max_rate = 700;// 最大码流,x264单位kbps,ffmpeg单位bps,x264 参数 vbv-maxrate
codec_ctx->rc_min_rate = 300;// 最小码流
codec_ctx->rc_buffer_size = codec_ctx->rc_max_rate + codec_ctx->rc_min_rate;// x264 参数 vbv-bufsize
*/
codec_ctx->max_qdiff = 6;// 固定量化器因子允许的最大偏差,取值范围0-69,x264 参数 qpstep
codec_ctx->me_range = 5;
codec_ctx->refs = 3;// 运动补偿,x264 参数 ref
codec_ctx->rc_strategy = FF_RC_STRATEGY_XVID;// 码率控制策略,宏定义,查API
codec_ctx->dct_algo = FF_DCT_AUTO;
codec_ctx->idct_algo = FF_IDCT_AUTO;
codec_ctx->profile = FF_PROFILE_H264_BASELINE;
codec_ctx->codec_tag = 0;
}
if(oformat->flags & AVFMT_GLOBALHEADER) {
codec_ctx->flags |= CODEC_FLAG_GLOBAL_HEADER;
}
av_error = avcodec_open2(codec_ctx, codec, NULL);
if (0 != av_error) {
goto fail_label;
}
g_out_fmt_ctx = fmt_ctx;
g_video_codec_ctx = codec_ctx;
video_stream_index = fmt_ctx->nb_streams - 1;
ret = 0;
fail_label:
if (0 != ret) {
printf("%s", "fail");
if (codec_ctx) {
avcodec_close(codec_ctx);
codec_ctx = NULL;
}
if (fmt_ctx) {
avformat_free_context(fmt_ctx);
fmt_ctx = NULL;
}
}
else {
printf("%s", "success");
}
codec_ctx = NULL;
stream = NULL;
codec = NULL;
}
void test_release_mw_recorder_controller()
{
video_stream_index = -1;
if (g_video_codec_ctx) {
avcodec_close(g_video_codec_ctx);
g_video_codec_ctx = NULL;
}
if (g_out_fmt_ctx) {
avformat_free_context(g_out_fmt_ctx);
g_out_fmt_ctx = NULL;
}
}
(void)click_init_h264:(id)sender
{
NSString *format_name = @"flv";// flv、aac
NSArray *doc_paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *doc_path = [doc_paths objectAtIndex:0];
NSString *filename = [doc_path stringByAppendingPathComponent:[NSString stringWithFormat:@"test_ffmpeg_encoder.%@", format_name]];
const char *format_name_str = format_name.UTF8String;
const char *filename_str = filename.UTF8String;
test_init_mw_recorder_controller(format_name_str, filename_str);
}-
(void)click_release_h264:(id)sender
{
test_release_mw_recorder_controller();
}使用 Instruments 进行内存 leak 检测时,在调用 click_init_h264 方法后,就会出现
7个x264_malloc方法调用的memory leak的情况。
Instruments截图--->>>
所以想请求各位有使用FFmpeg进行视频编码的高手,这是什么问题。是我的设置参数有问题,还是步骤有问题。请指点一下小弟。(小弟刚学FFmpeg,想写个iOS录制视频的例子,使用x264库进行视频编码,aac进行音频编码。现在可以正常编码,录制的视频也可以播。现在就差这个memory leak一直找不到解决办法)。
FFmpeg打印x264配置信息 :
[libx264 @ 0x110060800] using cpu capabilities: MMX2 SSE2Fast SSSE3 SSE4.2 AVX FMA3 AVX2 LZCNT BMI2
[libx264 @ 0x110060800] profile Constrained Baseline, level 2.2
[libx264 @ 0x110060800] 264 - core 148 - H.264/MPEG-4 AVC codec - Copyleft 2003-2016 - http://www.videolan.org/x264.html - options: cabac=0 ref=3 deblock=0:-3:-3 analyse=0:0 me=dia subme=0 psy=1 psy_rd=2.00:0.70 mixed_ref=0 me_range=5 chroma_me=1 trellis=0 8x8dct=0 cqm=0 deadzone=21,11 fast_pskip=1 chroma_qp_offset=0 threads=5 lookahead_threads=5 sliced_threads=1 slices=5 nr=0 decimate=1 interlaced=0 bluray_compat=0 constrained_intra=0 bframes=0 weightp=0 keyint=6 keyint_min=2 scenecut=0 intra_refresh=0 rc=crf mbtree=0 crf=23.0 qcomp=1.00 qpmin=12 qpmax=18 qpstep=8 ip_ratio=1.40 aq=0
我自己找到了一些规律,不懂是否正确。
已找到泄露的调用 av_error = avcodec_open2(codec_ctx, codec, NULL); 这句一调用就有x264_malloc memory leak 出来了。
而且是泄露的个数是可以计算出来,是codec_ctx->qmax - codec_ctx->qmin + 1个泄露。所以在想是不是x264设置参数的问题导致。
求大神。