- Query GPU caps for B-frame support and warn if unsupported. - Make `-max_b_frames` optional - Drop explicit `-pa_lookahead_buffer_depth` requirement in adaptive mode.
Unified · Split
| @@ -468,26 +468,61 @@ static av_cold int amf_encode_init_h264(AVCodecContext *avctx) · 467 unmodified lines | |||
| 468 | } | 468 | } |
| 469 | 469 | ||
| 470 | // B-Frames | 470 | // B-Frames |
| 471 | if (ctx->max_consecutive_b_frames != -1) { | 471 | AMFVariantStruct is_adaptive_b_frames = { 0 }; |
| 472 | AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_MAX_CONSECUTIVE_BPICTURES, ctx->max_consecutive_b_frames); | 472 | res = ctx->encoder->pVtbl->GetProperty(ctx->encoder, AMF_VIDEO_ENCODER_ADAPTIVE_MINIGOP, &is_adaptive_b_frames); |
| 473 | if (ctx->max_b_frames != -1) { | 473 | if (ctx->max_consecutive_b_frames != -1 || ctx->max_b_frames != -1 || is_adaptive_b_frames.boolValue == true) { |
| 474 | AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_B_PIC_PATTERN, ctx->max_b_frames); | 474 | |
| 475 | if (res != AMF_OK) { | 475 | //Get the capability of encoder |
| 476 | res = ctx->encoder->pVtbl->GetProperty(ctx->encoder, AMF_VIDEO_ENCODER_B_PIC_PATTERN, &var); | 476 | AMFCaps *encoder_caps = NULL; |
| 477 | av_log(ctx, AV_LOG_WARNING, "B-frames=%d is not supported by this GPU, switched to %d\n", | 477 | ctx->encoder->pVtbl->GetCaps(ctx->encoder, &encoder_caps); |
| 478 | ctx->max_b_frames, (int)var.int64Value); | 478 | if (encoder_caps != NULL) |
| 479 | ctx->max_b_frames = (int)var.int64Value; | 479 | { |
| 480 | res = encoder_caps->pVtbl->GetProperty(encoder_caps, AMF_VIDEO_ENCODER_CAP_BFRAMES, &var); | ||
| 481 | if (res == AMF_OK) { | ||
| 482 | |||
| 483 | //encoder supports H.264 B-frame | ||
| 484 | if(var.boolValue == true){ | ||
| 485 | //adaptive b-frames is higher priority than max_b_frames | ||
| 486 | if (is_adaptive_b_frames.boolValue == true) | ||
| 487 | { | ||
| 488 | //force AMF_VIDEO_ENCODER_MAX_CONSECUTIVE_BPICTURES to 3 | ||
| 489 | AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_MAX_CONSECUTIVE_BPICTURES, 3); | ||
| 490 | |||
| 491 | if(ctx->pa_lookahead_buffer_depth < 1) | ||
| 492 | { | ||
| 493 | //force AMF_PA_LOOKAHEAD_BUFFER_DEPTH to 1 if not set or smaller than 1 | ||
| 494 | AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_PA_LOOKAHEAD_BUFFER_DEPTH, 1); | ||
| 495 | } | ||
| 496 | } | ||
| 497 | else { | ||
| 498 | if (ctx->max_b_frames != -1) { | ||
| 499 | //in case user sets B-frames | ||
| 500 | AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_B_PIC_PATTERN, ctx->max_b_frames); | ||
| 501 | if (res != AMF_OK) { | ||
| 502 | res = ctx->encoder->pVtbl->GetProperty(ctx->encoder, AMF_VIDEO_ENCODER_B_PIC_PATTERN, &var); | ||
| 503 | av_log(ctx, AV_LOG_WARNING, "B-frames=%d is not supported by this GPU, switched to %d\n", ctx->max_b_frames, (int)var.int64Value); | ||
| 504 | ctx->max_b_frames = (int)var.int64Value; | ||
| 505 | } | ||
| 506 | AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_MAX_CONSECUTIVE_BPICTURES, ctx->max_b_frames); | ||
| 507 | } | ||
| 508 | } | ||
| 509 | |||
| 510 | } | ||
| 511 | //encoder doesn't support H.264 B-frame | ||
| 512 | else { | ||
| 513 | av_log(ctx, AV_LOG_WARNING, "The current GPU in use does not support H.264 B-frame encoding, there will be no B-frame in bitstream.\n"); | ||
| 514 | } | ||
| 515 | } else { | ||
| 516 | //Can't get the capability of encoder | ||
| 517 | av_log(ctx, AV_LOG_WARNING, "Unable to get H.264 B-frame capability.\n"); | ||
| 518 | av_log(ctx, AV_LOG_WARNING, "There will be no B-frame in bitstream.\n"); | ||
| 480 | } | 519 | } |
| 481 | if (ctx->max_consecutive_b_frames < ctx->max_b_frames) { | 520 | |
| 482 | av_log(ctx, AVERROR_BUG, "Maxium B frames needs to be greater than the specified B frame count.\n"); | 521 | encoder_caps->pVtbl->Release(encoder_caps); |
| 483 | } | 522 | encoder_caps = NULL; |
| 484 | } | ||
| 485 | } | ||
| 486 | else { | ||
| 487 | if (ctx->max_b_frames != -1) { | ||
| 488 | av_log(ctx, AVERROR_BUG, "Maxium number of B frames needs to be specified.\n"); | ||
| 489 | } | 523 | } |
| 490 | } | 524 | } |
| 525 | |||
| 491 | res = ctx->encoder->pVtbl->GetProperty(ctx->encoder, AMF_VIDEO_ENCODER_B_PIC_PATTERN, &var); | 526 | res = ctx->encoder->pVtbl->GetProperty(ctx->encoder, AMF_VIDEO_ENCODER_B_PIC_PATTERN, &var); |
| 492 | if ((int)var.int64Value) { | 527 | if ((int)var.int64Value) { |
| 493 | AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_B_PIC_DELTA_QP, ctx->b_frame_delta_qp); | 528 | AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_B_PIC_DELTA_QP, ctx->b_frame_delta_qp); |