#if QSV_HAVE_CO2
mfxExtCodingOption2 *co2 = (mfxExtCodingOption2*)coding_opts[1];
#endif
+#if QSV_HAVE_CO3
+ mfxExtCodingOption3 *co3 = (mfxExtCodingOption3*)coding_opts[2];
+#endif
av_log(avctx, AV_LOG_VERBOSE, "profile: %s; level: %"PRIu16"\n",
print_profile(info->CodecProfile), info->CodecLevel);
#endif
) {
av_log(avctx, AV_LOG_VERBOSE,
- "BufferSizeInKB: %"PRIu16"; InitialDelayInKB: %"PRIu16"; TargetKbps: %"PRIu16"; MaxKbps: %"PRIu16"\n",
- info->BufferSizeInKB, info->InitialDelayInKB, info->TargetKbps, info->MaxKbps);
+ "BufferSizeInKB: %"PRIu16"; InitialDelayInKB: %"PRIu16"; TargetKbps: %"PRIu16"; MaxKbps: %"PRIu16"; BRCParamMultiplier: %"PRIu16"\n",
+ info->BufferSizeInKB, info->InitialDelayInKB, info->TargetKbps, info->MaxKbps, info->BRCParamMultiplier);
} else if (info->RateControlMethod == MFX_RATECONTROL_CQP) {
av_log(avctx, AV_LOG_VERBOSE, "QPI: %"PRIu16"; QPP: %"PRIu16"; QPB: %"PRIu16"\n",
info->QPI, info->QPP, info->QPB);
#if QSV_HAVE_AVBR
else if (info->RateControlMethod == MFX_RATECONTROL_AVBR) {
av_log(avctx, AV_LOG_VERBOSE,
- "TargetKbps: %"PRIu16"; Accuracy: %"PRIu16"; Convergence: %"PRIu16"\n",
- info->TargetKbps, info->Accuracy, info->Convergence);
+ "TargetKbps: %"PRIu16"; Accuracy: %"PRIu16"; Convergence: %"PRIu16"; BRCParamMultiplier: %"PRIu16"\n",
+ info->TargetKbps, info->Accuracy, info->Convergence, info->BRCParamMultiplier);
}
#endif
#if QSV_HAVE_LA
#endif
) {
av_log(avctx, AV_LOG_VERBOSE,
- "TargetKbps: %"PRIu16"; LookAheadDepth: %"PRIu16"\n",
- info->TargetKbps, co2->LookAheadDepth);
+ "TargetKbps: %"PRIu16"; LookAheadDepth: %"PRIu16"; BRCParamMultiplier: %"PRIu16"\n",
+ info->TargetKbps, co2->LookAheadDepth, info->BRCParamMultiplier);
}
#endif
#if QSV_HAVE_ICQ
info->ICQQuality, co2->LookAheadDepth);
}
#endif
-
+#if QSV_HAVE_QVBR
+ else if (info->RateControlMethod == MFX_RATECONTROL_QVBR) {
+ av_log(avctx, AV_LOG_VERBOSE, "QVBRQuality: %"PRIu16"\n",
+ co3->QVBRQuality);
+ }
+#endif
av_log(avctx, AV_LOG_VERBOSE, "NumSlice: %"PRIu16"; NumRefFrame: %"PRIu16"\n",
info->NumSlice, info->NumRefFrame);
av_log(avctx, AV_LOG_VERBOSE, "RateDistortionOpt: %s\n",
av_log(avctx, AV_LOG_VERBOSE, "\n");
#endif
+#if QSV_HAVE_VDENC
+ av_log(avctx, AV_LOG_VERBOSE, "VDENC: %s\n", print_threestate(info->LowPower));
+#endif
+
#if QSV_VERSION_ATLEAST(1, 8)
av_log(avctx, AV_LOG_VERBOSE,
"RepeatPPS: %s; NumMbPerSlice: %"PRIu16"; LookAheadDS: ",
}
#endif
#if QSV_HAVE_ICQ
- else if (avctx->global_quality > 0) {
+ else if (avctx->global_quality > 0 && !avctx->rc_max_rate) {
rc_mode = MFX_RATECONTROL_ICQ;
rc_desc = "intelligent constant quality (ICQ)";
}
rc_mode = MFX_RATECONTROL_AVBR;
rc_desc = "average variable bitrate (AVBR)";
}
+#endif
+#if QSV_HAVE_QVBR
+ else if (avctx->global_quality > 0) {
+ rc_mode = MFX_RATECONTROL_QVBR;
+ rc_desc = "constant quality with VBR algorithm (QVBR)";
+ }
#endif
else {
rc_mode = MFX_RATECONTROL_VBR;
avctx->sw_pix_fmt : avctx->pix_fmt;
const AVPixFmtDescriptor *desc;
float quant;
+ int target_bitrate_kbps, max_bitrate_kbps, brc_param_multiplier;
+ int buffer_size_in_kilobytes, initial_delay_in_kilobytes;
int ret;
mfxVersion ver;
}
}
+#if QSV_HAVE_VDENC
+ q->param.mfx.LowPower = q->low_power ? MFX_CODINGOPTION_ON : MFX_CODINGOPTION_OFF;
+#endif
q->param.mfx.CodecProfile = q->profile;
q->param.mfx.TargetUsage = avctx->compression_level;
q->param.mfx.GopPicSize = FFMAX(0, avctx->gop_size);
if (ret < 0)
return ret;
+ //libmfx BRC parameters are 16 bits thus maybe overflow, then BRCParamMultiplier is needed
+ buffer_size_in_kilobytes = avctx->rc_buffer_size / 8000;
+ initial_delay_in_kilobytes = avctx->rc_initial_buffer_occupancy / 1000;
+ target_bitrate_kbps = avctx->bit_rate / 1000;
+ max_bitrate_kbps = avctx->rc_max_rate / 1000;
+ brc_param_multiplier = (FFMAX(FFMAX3(target_bitrate_kbps, max_bitrate_kbps, buffer_size_in_kilobytes),
+ initial_delay_in_kilobytes) + 0x10000) / 0x10000;
+
switch (q->param.mfx.RateControlMethod) {
case MFX_RATECONTROL_CBR:
case MFX_RATECONTROL_VBR:
#if QSV_HAVE_VCM
case MFX_RATECONTROL_VCM:
#endif
- q->param.mfx.BufferSizeInKB = avctx->rc_buffer_size / 8000;
- q->param.mfx.InitialDelayInKB = avctx->rc_initial_buffer_occupancy / 1000;
- q->param.mfx.TargetKbps = avctx->bit_rate / 1000;
- q->param.mfx.MaxKbps = avctx->rc_max_rate / 1000;
+#if QSV_HAVE_QVBR
+ case MFX_RATECONTROL_QVBR:
+#endif
+ q->param.mfx.BufferSizeInKB = buffer_size_in_kilobytes / brc_param_multiplier;
+ q->param.mfx.InitialDelayInKB = initial_delay_in_kilobytes / brc_param_multiplier;
+ q->param.mfx.TargetKbps = target_bitrate_kbps / brc_param_multiplier;
+ q->param.mfx.MaxKbps = max_bitrate_kbps / brc_param_multiplier;
+ q->param.mfx.BRCParamMultiplier = brc_param_multiplier;
+#if QSV_HAVE_QVBR
+ if (q->param.mfx.RateControlMethod == MFX_RATECONTROL_QVBR)
+ q->extco3.QVBRQuality = av_clip(avctx->global_quality, 0, 51);
+#endif
break;
case MFX_RATECONTROL_CQP:
quant = avctx->global_quality / FF_QP2LAMBDA;
break;
#if QSV_HAVE_AVBR
case MFX_RATECONTROL_AVBR:
- q->param.mfx.TargetKbps = avctx->bit_rate / 1000;
+ q->param.mfx.TargetKbps = target_bitrate_kbps / brc_param_multiplier;
q->param.mfx.Convergence = q->avbr_convergence;
q->param.mfx.Accuracy = q->avbr_accuracy;
+ q->param.mfx.BRCParamMultiplier = brc_param_multiplier;
break;
#endif
#if QSV_HAVE_LA
case MFX_RATECONTROL_LA:
- q->param.mfx.TargetKbps = avctx->bit_rate / 1000;
+ q->param.mfx.TargetKbps = target_bitrate_kbps / brc_param_multiplier;
q->extco2.LookAheadDepth = q->look_ahead_depth;
+ q->param.mfx.BRCParamMultiplier = brc_param_multiplier;
break;
#if QSV_HAVE_ICQ
case MFX_RATECONTROL_LA_ICQ:
}
#endif
}
+#if QSV_HAVE_CO3
+ q->extco3.Header.BufferId = MFX_EXTBUFF_CODING_OPTION3;
+ q->extco3.Header.BufferSz = sizeof(q->extco3);
+ q->extparam_internal[q->nb_extparam_internal++] = (mfxExtBuffer *)&q->extco3;
+#endif
}
if (!check_enc_param(avctx,q)) {
return ff_qsv_print_error(avctx, ret,
"Error calling GetVideoParam");
- q->packet_size = q->param.mfx.BufferSizeInKB * 1000;
+ q->packet_size = q->param.mfx.BufferSizeInKB * q->param.mfx.BRCParamMultiplier * 1000;
// for qsv mjpeg the return value maybe 0 so alloc the buffer
if (q->packet_size == 0)
.Header.BufferSz = sizeof(co2),
};
#endif
+#if QSV_HAVE_CO3
+ mfxExtCodingOption3 co3 = {
+ .Header.BufferId = MFX_EXTBUFF_CODING_OPTION3,
+ .Header.BufferSz = sizeof(co3),
+ };
+#endif
mfxExtBuffer *ext_buffers[] = {
(mfxExtBuffer*)&extradata,
(mfxExtBuffer*)&co,
#if QSV_HAVE_CO2
(mfxExtBuffer*)&co2,
+#endif
+#if QSV_HAVE_CO3
+ (mfxExtBuffer*)&co3,
#endif
};
return ff_qsv_print_error(avctx, ret,
"Error calling GetVideoParam");
- q->packet_size = q->param.mfx.BufferSizeInKB * 1000;
+ q->packet_size = q->param.mfx.BufferSizeInKB * q->param.mfx.BRCParamMultiplier * 1000;
if (!extradata.SPSBufSize || (need_pps && !extradata.PPSBufSize)) {
av_log(avctx, AV_LOG_ERROR, "No extradata returned from libmfx.\n");
new_pkt.pts = av_rescale_q(bs->TimeStamp, (AVRational){1, 90000}, avctx->time_base);
new_pkt.size = bs->DataLength;
- if (bs->FrameType & MFX_FRAMETYPE_IDR ||
- bs->FrameType & MFX_FRAMETYPE_xIDR)
+ if (bs->FrameType & MFX_FRAMETYPE_IDR || bs->FrameType & MFX_FRAMETYPE_xIDR) {
new_pkt.flags |= AV_PKT_FLAG_KEY;
-
- if (bs->FrameType & MFX_FRAMETYPE_I || bs->FrameType & MFX_FRAMETYPE_xI)
+ pict_type = AV_PICTURE_TYPE_I;
+ } else if (bs->FrameType & MFX_FRAMETYPE_I || bs->FrameType & MFX_FRAMETYPE_xI)
pict_type = AV_PICTURE_TYPE_I;
else if (bs->FrameType & MFX_FRAMETYPE_P || bs->FrameType & MFX_FRAMETYPE_xP)
pict_type = AV_PICTURE_TYPE_P;
else if (bs->FrameType & MFX_FRAMETYPE_B || bs->FrameType & MFX_FRAMETYPE_xB)
pict_type = AV_PICTURE_TYPE_B;
- else
- av_assert0(!"Uninitialized pict_type!");
+ else if (bs->FrameType == MFX_FRAMETYPE_UNKNOWN) {
+ pict_type = AV_PICTURE_TYPE_NONE;
+ av_log(avctx, AV_LOG_WARNING, "Unknown FrameType, set pict_type to AV_PICTURE_TYPE_NONE.\n");
+ } else {
+ av_log(avctx, AV_LOG_ERROR, "Invalid FrameType:%d.\n", bs->FrameType);
+ return AVERROR_INVALIDDATA;
+ }
#if FF_API_CODED_FRAME
FF_DISABLE_DEPRECATION_WARNINGS