为什么在我使用 ffmpeg 的英特尔 qsv 中将一帧设置为关键帧后,每个编码帧的大小都会增加
Why does every encoded frame's size increase after I had use to set one frame to be key in intel qsv of ffmpeg
我使用intel的qsv在ffmpeg中编码h264视频。我的 av 编解码器上下文设置如下所示:
m_ctx->width = m_width;
m_ctx->height = m_height;
m_ctx->time_base = { 1, (int)fps };
m_ctx->qmin = 10;
m_ctx->qmax = 35;
m_ctx->gop_size = 3000;
m_ctx->max_b_frames = 0;
m_ctx->has_b_frames = false;
m_ctx->refs = 2;
m_ctx->slices = 0;
m_ctx->codec_id = m_encoder->id;
m_ctx->codec_type = AVMEDIA_TYPE_VIDEO;
m_ctx->pix_fmt = m_h264InputFormat;
m_ctx->compression_level = 4;
m_ctx->flags &= ~AV_CODEC_FLAG_CLOSED_GOP;
AVDictionary *param = nullptr;
av_dict_set(¶m, "idr_interval", "0", 0);
av_dict_set(¶m, "async_depth", "1", 0);
av_dict_set(¶m, "forced_idr", "1", 0);
并且在编码中,当需要关键帧时,我将 AVFrame 设置为 AV_PICTURE_TYPE_I:
if(key_frame){
encodeFrame->pict_type = AV_PICTURE_TYPE_I;
}else{
encodeFrame->pict_type = AV_PICTURE_TYPE_NONE;
}
avcodec_send_frame(m_ctx, encodeFrame);
avcodec_receive_packet(m_ctx, m_packet);
std::cerr<<"packet size is "<<m_packet->size<<",is key frame "<<key_frame<<std::endl;
奇怪的现象是,如果我将一帧设置为AV_PICTURE_TYPE_I,那么关键帧之后的每个编码帧的大小都会增加。如果我把h264编码器改成x264就可以了
在我调用“encodeFrame->pict_type = AV_PICTURE_TYPE_I”之前数据包大小如下:
packet size is 26839
packet size is 2766
packet size is 2794
packet size is 2193
packet size is 1820
packet size is 2542
packet size is 2024
packet size is 1692
packet size is 2095
packet size is 2550
packet size is 1685
packet size is 1800
packet size is 2276
packet size is 1813
packet size is 2206
packet size is 2745
packet size is 2334
packet size is 2623
packet size is 2055
如果我调用“encodeFrame->pict_type = AV_PICTURE_TYPE_I”,那么数据包大小如下:
packet size is 23720,is key frame 1
packet size is 23771,is key frame 0
packet size is 23738,is key frame 0
packet size is 23752,is key frame 0
packet size is 23771,is key frame 0
packet size is 23763,is key frame 0
packet size is 23715,is key frame 0
packet size is 23686,is key frame 0
packet size is 23829,is key frame 0
packet size is 23774,is key frame 0
packet size is 23850,is key frame 0
FFMPEG 在编码下一帧时不重置 mfxEncodeCtrl 的 FrameType,它导致关键帧之后的每一帧都是 IDR 帧
我使用intel的qsv在ffmpeg中编码h264视频。我的 av 编解码器上下文设置如下所示:
m_ctx->width = m_width;
m_ctx->height = m_height;
m_ctx->time_base = { 1, (int)fps };
m_ctx->qmin = 10;
m_ctx->qmax = 35;
m_ctx->gop_size = 3000;
m_ctx->max_b_frames = 0;
m_ctx->has_b_frames = false;
m_ctx->refs = 2;
m_ctx->slices = 0;
m_ctx->codec_id = m_encoder->id;
m_ctx->codec_type = AVMEDIA_TYPE_VIDEO;
m_ctx->pix_fmt = m_h264InputFormat;
m_ctx->compression_level = 4;
m_ctx->flags &= ~AV_CODEC_FLAG_CLOSED_GOP;
AVDictionary *param = nullptr;
av_dict_set(¶m, "idr_interval", "0", 0);
av_dict_set(¶m, "async_depth", "1", 0);
av_dict_set(¶m, "forced_idr", "1", 0);
并且在编码中,当需要关键帧时,我将 AVFrame 设置为 AV_PICTURE_TYPE_I:
if(key_frame){
encodeFrame->pict_type = AV_PICTURE_TYPE_I;
}else{
encodeFrame->pict_type = AV_PICTURE_TYPE_NONE;
}
avcodec_send_frame(m_ctx, encodeFrame);
avcodec_receive_packet(m_ctx, m_packet);
std::cerr<<"packet size is "<<m_packet->size<<",is key frame "<<key_frame<<std::endl;
奇怪的现象是,如果我将一帧设置为AV_PICTURE_TYPE_I,那么关键帧之后的每个编码帧的大小都会增加。如果我把h264编码器改成x264就可以了
在我调用“encodeFrame->pict_type = AV_PICTURE_TYPE_I”之前数据包大小如下:
packet size is 26839
packet size is 2766
packet size is 2794
packet size is 2193
packet size is 1820
packet size is 2542
packet size is 2024
packet size is 1692
packet size is 2095
packet size is 2550
packet size is 1685
packet size is 1800
packet size is 2276
packet size is 1813
packet size is 2206
packet size is 2745
packet size is 2334
packet size is 2623
packet size is 2055
如果我调用“encodeFrame->pict_type = AV_PICTURE_TYPE_I”,那么数据包大小如下:
packet size is 23720,is key frame 1
packet size is 23771,is key frame 0
packet size is 23738,is key frame 0
packet size is 23752,is key frame 0
packet size is 23771,is key frame 0
packet size is 23763,is key frame 0
packet size is 23715,is key frame 0
packet size is 23686,is key frame 0
packet size is 23829,is key frame 0
packet size is 23774,is key frame 0
packet size is 23850,is key frame 0
FFMPEG 在编码下一帧时不重置 mfxEncodeCtrl 的 FrameType,它导致关键帧之后的每一帧都是 IDR 帧