为什么编解码器 x264/x265 会忽略输入帧的 pts 和 dts?
Why codecs x264/x265 ignores pts and dts of input frame?
我正在尝试使用 libx265(之前尝试过 libx264)对来自网络摄像头的图像进行编码...
由于进入矩阵的光量不同,网络摄像头无法以稳定的 FPS 拍摄,并且,结果,不同的延迟。因此,我计算传入帧的 fps 和 dts,并为 x265_image
对象的相应参数设置这些值,并将编码器 fpsNum
初始化为 1000,将 fpsDenom
初始化为 1(对于毫秒时基)。
问题是编码器忽略了输入图像的 pts 和 dts 并以 1000 fps 编码!使用时基的相同技巧可以使用 libvpx 生成平滑的记录。为什么它不适用于 x264/x265 编解码器?
下面是参数初始化:
...
error = (x265_param_default_preset(param, "fast", "zerolatency") != 0);
if(!error){
param->sourceWidth = width;
param->sourceHeight = height;
param->frameNumThreads = 1;
param->fpsNum = 1000;
param->fpsDenom = 1;
// Intra refres:
param->keyframeMax = 15;
param->intraRefine = 1;
// Rate control:
param->rc.rateControlMode = X265_RC_CQP;
param->rc.rfConstant = 12;
param->rc.rfConstantMax = 48;
// For streaming:
param->bRepeatHeaders = 1;
param->bAnnexB = 1;
encoder = x265_encoder_open(param);
...
}
...
这里是加框功能:
bool hevc::Push(unsigned char *data){
if(!error){
std::lock_guard<std::mutex> lock(m_framestack);
if( timer > 0){
framestack.back()->dts = clock() - timer;
timer+= framestack.back()->dts;
}
else{timer = clock();}
x265_picture *picture = x265_picture_alloc();
if( picture){
x265_picture_init(param, picture);
picture->height = param->sourceHeight;
picture->stride[0] = param->sourceWidth;
picture->stride[1] = picture->stride[2] = picture->stride[0] / 2;
picture->planes[0] = new char[ luma_size];
picture->planes[1] = new char[chroma_size];
picture->planes[2] = new char[chroma_size];
colorspaces::BGRtoI420(param->sourceWidth, param->sourceHeight, data, (byte*)picture->planes[0], (byte*)picture->planes[1], (byte*)picture->planes[2]);
picture->pts = picture->dts = 0;
framestack.emplace_back(picture);
}
else{error = true;}
}
return !error;
}
全局 PTS 在 x265_encoder_encode
调用后立即增加:
pts+= pic_in->dts;
并设置为来自 framestack
队列的新图像的点,当涉及到编码器时。
x265/x264 编解码器能否以可变 fps 进行编码?是的话怎么配置?
我不知道 x265,但在 x264 中要编码可变帧率 (VFR) 视频,您应该启用 x264_param_t.b_vfr_input 选项,该选项已被您的 zerolatency 调整禁用(VFR 编码需要 1 帧延迟)。此外,至少在 x264 中,时基应该在 i_timebase_num/i_timebase_den 和 i_fps_num/i_fps_den 中以达到平均 fps(如果您不知道 fps,则保持默认的 25/1),否则您将破坏速率控制。
我正在尝试使用 libx265(之前尝试过 libx264)对来自网络摄像头的图像进行编码...
由于进入矩阵的光量不同,网络摄像头无法以稳定的 FPS 拍摄,并且,结果,不同的延迟。因此,我计算传入帧的 fps 和 dts,并为 x265_image
对象的相应参数设置这些值,并将编码器 fpsNum
初始化为 1000,将 fpsDenom
初始化为 1(对于毫秒时基)。
问题是编码器忽略了输入图像的 pts 和 dts 并以 1000 fps 编码!使用时基的相同技巧可以使用 libvpx 生成平滑的记录。为什么它不适用于 x264/x265 编解码器?
下面是参数初始化:
...
error = (x265_param_default_preset(param, "fast", "zerolatency") != 0);
if(!error){
param->sourceWidth = width;
param->sourceHeight = height;
param->frameNumThreads = 1;
param->fpsNum = 1000;
param->fpsDenom = 1;
// Intra refres:
param->keyframeMax = 15;
param->intraRefine = 1;
// Rate control:
param->rc.rateControlMode = X265_RC_CQP;
param->rc.rfConstant = 12;
param->rc.rfConstantMax = 48;
// For streaming:
param->bRepeatHeaders = 1;
param->bAnnexB = 1;
encoder = x265_encoder_open(param);
...
}
...
这里是加框功能:
bool hevc::Push(unsigned char *data){
if(!error){
std::lock_guard<std::mutex> lock(m_framestack);
if( timer > 0){
framestack.back()->dts = clock() - timer;
timer+= framestack.back()->dts;
}
else{timer = clock();}
x265_picture *picture = x265_picture_alloc();
if( picture){
x265_picture_init(param, picture);
picture->height = param->sourceHeight;
picture->stride[0] = param->sourceWidth;
picture->stride[1] = picture->stride[2] = picture->stride[0] / 2;
picture->planes[0] = new char[ luma_size];
picture->planes[1] = new char[chroma_size];
picture->planes[2] = new char[chroma_size];
colorspaces::BGRtoI420(param->sourceWidth, param->sourceHeight, data, (byte*)picture->planes[0], (byte*)picture->planes[1], (byte*)picture->planes[2]);
picture->pts = picture->dts = 0;
framestack.emplace_back(picture);
}
else{error = true;}
}
return !error;
}
全局 PTS 在 x265_encoder_encode
调用后立即增加:
pts+= pic_in->dts;
并设置为来自 framestack
队列的新图像的点,当涉及到编码器时。
x265/x264 编解码器能否以可变 fps 进行编码?是的话怎么配置?
我不知道 x265,但在 x264 中要编码可变帧率 (VFR) 视频,您应该启用 x264_param_t.b_vfr_input 选项,该选项已被您的 zerolatency 调整禁用(VFR 编码需要 1 帧延迟)。此外,至少在 x264 中,时基应该在 i_timebase_num/i_timebase_den 和 i_fps_num/i_fps_den 中以达到平均 fps(如果您不知道 fps,则保持默认的 25/1),否则您将破坏速率控制。