[FFmpeg-devel] [PATCH] amfenc: Add support for pict_type field

Michael Dirks michael.dirks at xaymar.com
Wed Jan 16 00:41:42 EET 2019


On 15.01.2019 23:05, michael.dirks at xaymar.com wrote:
> From: Michael Fabian 'Xaymar' Dirks <info at xaymar.com>
>
> Adds support for the pict_type field in AVFrame to amf_h264 and amf_h265 simultaneously. This field is needed in cases where the application wishes to override the frame type with another one, such as forcefully inserting a key frame for chapter markers or similar.
>
> Additionally this abuses AV_PICTURE_TYPE_S for marking Skip frames, a special type of frame in AVC, SVC and HEVC which is a flag for the decoder to repeat the last frame.
>
> Signed-off-by: Michael Fabian 'Xaymar' Dirks <info at xaymar.com>
> ---
>   Changelog           |  1 +
>   libavcodec/amfenc.c | 46 +++++++++++++++++++++++++++++++++++++++++++++
>   2 files changed, 47 insertions(+)
>
> diff --git a/Changelog b/Changelog
> index 1cd53916cb..4fc48ba210 100644
> --- a/Changelog
> +++ b/Changelog
> @@ -15,6 +15,7 @@ version <next>:
>   - hymt decoder
>   - anlmdn filter
>   - maskfun filter
> +- AMF now supports AVFrame->pict_type override
>   
>   
>   version 4.1:
> diff --git a/libavcodec/amfenc.c b/libavcodec/amfenc.c
> index 384d8efc92..3be9ff9ee2 100644
> --- a/libavcodec/amfenc.c
> +++ b/libavcodec/amfenc.c
> @@ -680,6 +680,52 @@ int ff_amf_send_frame(AVCodecContext *avctx, const AVFrame *frame)
>               break;
>           }
>   
> +        // Override Picture Type for Frame
> +        if (avctx->codec->id == AV_CODEC_ID_H264) {
> +            switch (frame->pict_type) {
> +            case AV_PICTURE_TYPE_I:
> +                AMF_ASSIGN_PROPERTY_INT64(res, surface, AMF_VIDEO_ENCODER_FORCE_PICTURE_TYPE, AMF_VIDEO_ENCODER_PICTURE_TYPE_I);
> +                break;
> +            case AV_PICTURE_TYPE_P:
> +                AMF_ASSIGN_PROPERTY_INT64(res, surface, AMF_VIDEO_ENCODER_FORCE_PICTURE_TYPE, AMF_VIDEO_ENCODER_PICTURE_TYPE_P);
> +                break;
> +            case AV_PICTURE_TYPE_B:
> +                AMF_ASSIGN_PROPERTY_INT64(res, surface, AMF_VIDEO_ENCODER_FORCE_PICTURE_TYPE, AMF_VIDEO_ENCODER_PICTURE_TYPE_B);
> +                break;
> +            case AV_PICTURE_TYPE_S:
> +                AMF_ASSIGN_PROPERTY_INT64(res, surface, AMF_VIDEO_ENCODER_FORCE_PICTURE_TYPE, AMF_VIDEO_ENCODER_PICTURE_TYPE_SKIP);
> +                break;
> +            default:
> +                AMF_ASSIGN_PROPERTY_INT64(res, surface, AMF_VIDEO_ENCODER_FORCE_PICTURE_TYPE, AMF_VIDEO_ENCODER_PICTURE_TYPE_NONE);
> +                break;
> +            }
> +            // Keyframe overrides previous assignment.
> +            if (frame->key_frame) {
> +                AMF_ASSIGN_PROPERTY_INT64(res, surface, AMF_VIDEO_ENCODER_FORCE_PICTURE_TYPE, AMF_VIDEO_ENCODER_PICTURE_TYPE_IDR);
> +            }
> +        } else if (avctx->codec->id == AV_CODEC_ID_HEVC) {
> +            switch (frame->pict_type) {
> +            case AV_PICTURE_TYPE_I:
> +                AMF_ASSIGN_PROPERTY_INT64(res, surface, AMF_VIDEO_ENCODER_HEVC_FORCE_PICTURE_TYPE, AMF_VIDEO_ENCODER_HEVC_PICTURE_TYPE_I);
> +                break;
> +            case AV_PICTURE_TYPE_P:
> +                AMF_ASSIGN_PROPERTY_INT64(res, surface, AMF_VIDEO_ENCODER_HEVC_FORCE_PICTURE_TYPE, AMF_VIDEO_ENCODER_HEVC_PICTURE_TYPE_P);
> +                break;
> +            case AV_PICTURE_TYPE_B:
> +                av_log(ctx, AV_LOG_WARNING, "Ignoring B-Frame, unsupported by AMD AMF H.265 Encoder.");
> +                break;
> +            case AV_PICTURE_TYPE_S:
> +                AMF_ASSIGN_PROPERTY_INT64(res, surface, AMF_VIDEO_ENCODER_HEVC_FORCE_PICTURE_TYPE, AMF_VIDEO_ENCODER_HEVC_PICTURE_TYPE_SKIP);
> +                break;
> +            default:
> +                AMF_ASSIGN_PROPERTY_INT64(res, surface, AMF_VIDEO_ENCODER_HEVC_FORCE_PICTURE_TYPE, AMF_VIDEO_ENCODER_HEVC_PICTURE_TYPE_NONE);
> +                break;
> +            }
> +            // Keyframe overrides previous assignment.
> +            if (frame->key_frame) {
> +                AMF_ASSIGN_PROPERTY_INT64(res, surface, AMF_VIDEO_ENCODER_HEVC_FORCE_PICTURE_TYPE, AMF_VIDEO_ENCODER_HEVC_PICTURE_TYPE_IDR);
> +            }
> +        }
>   
>           // submit surface
>           res = ctx->encoder->pVtbl->SubmitInput(ctx->encoder, (AMFData*)surface);
This patch has been tested with the small tool I wrote here: 
https://github.com/Xaymar/ffmpeg-test. It works in both H264 and H265 
and produces the correct sequence of IDR, I, P and Skip frames - 
including the visual corruption that AMD's Skip frames have.

Michael Fabian Dirks


More information about the ffmpeg-devel mailing list