On 15.01.2019 23:05, michael.di...@xaymar.com wrote:
From: Michael Fabian 'Xaymar' Dirks <i...@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 <i...@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
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel

Reply via email to