问题描述
任务:
我正在以30 FPS录制屏幕并将其保存到FLV文件。屏幕图像是使用Windows中的dxgi API获取的。然后使用libx264将这些图像编码为视频。然后将视频数据存储在FLV容器中。
问题/问题:
在任何视频播放器中播放视频时,速度都很慢。帧速率信息显示为30 FPS,但播放时感觉为15 FPS。
详细信息:
整个软件的伪代码:
FPS = 30
target_time_for_each_frame = 1/FPS;
timestamp = 0;
while (true)
{
start_time = current_time();
image = capture_screen();
video_data = encode(image);
writetoFLV(video_data,timestamp);
timestamp += target_time_for_each_frame;
end_time = current_time();
time_taken_for_current_frame = (end_time - start_time)
// put the app to sleep to take screenshots only at 1/FPS or 33ms intervals. (delaying)
if (time_taken_for_current_frame < target_time_for_each_frame)
{
sleep(target_time_for_each_frame - time_taken_for_current_frame)
}
}
我正在使用以下参数进行编码:
void init_encoder()
{
x264_param_default_preset(¶m,"veryfast",0);
param.i_width = 1920;
param.i_height = 1080;
param.i_fps_num = 30;
param.i_fps_den = 1;
param.i_timebase_num = param.i_fps_den;
param.i_timebase_den = param.i_fps_num;
param.rc.i_bitrate = 2500;
param.i_bframe = 0;
param.rc.i_rc_method = X264_RC_ABR;
param.rc.f_rf_constant = 0;
//param.rc.b_filler = true;
param.rc.i_vbv_max_bitrate = param.rc.i_bitrate;
param.rc.i_vbv_buffer_size = param.rc.i_bitrate;
param.b_repeat_headers = 0;
param.b_annexb = 1;
x264_param_apply_profile(¶m,0);
}
为FLV文件提供的时间戳是正确的:
timestamp += (1/30) // It is increased by 33 ms every loop
int encodeYUV(uint8_t* data)
{
// convert BGRA to YUV using FFmpeg
BGRA.data[0] = data;
sws_scale(sws,BGRA.data,BGRA.linesize,param.i_height,picIn.img.plane,picIn.img.i_stride);
nal_size = x264_encoder_encode(h,&nals,&nal_count,&picIn,&picOut);
picIn.i_pts += 1; // pts += 1 because timebase_num = 1,timebase_den = 30. So it increases by 33 ms
return 0;
}
每个循环(pts + = 1000)将pts增大到一个很高的值,使播放非常像素化,并且播放速度非常快,有时会一次又一次重复同一帧。
在出现此问题之前,我将调音用作“ zerolatency”,并且回放效果很好。但是视频质量不好,所以我不得不删除它。当我删除它时,这些问题就来了。
建议不要使用我正在使用的参数来录制视频,但是它们对于实时流媒体很有用。我的主要目的是屏幕共享应用程序。我将其用作屏幕录像机只是为了测试它是否有效。
我不确定问题是否出在我增加PTS或时间戳的方式上,还是我在应用中编写了延迟(正确设置FPS上限)的方式。确实感觉到该问题仅与这些因素(x264 PTS或FLV时间戳或延迟代码)有关。
任何提示将不胜感激。
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)