[FFmpeg-devel,3/3] lavc/qsvdec: expose frame pic_type

Submitted by Zhong Li on March 22, 2018, 3:05 p.m.

Details

Message ID 1521731134-24618-3-git-send-email-zhong.li@intel.com
State New
Headers show

Commit Message

Zhong Li March 22, 2018, 3:05 p.m.
Currently pict_type are unset.
Add an extra param to fetch the picture type from qsv decoder

v2: remove the key_frame setting because the judgement “key frame is equal
to IDR frame” only suitable for H264.
For HEVC, all IRAP frames are key frames, and other codecs have no IDR
frame.

Signed-off-by: ChaoX A Liu <chaox.a.liu@intel.com>
Signed-off-by: Zhong Li <zhong.li@intel.com>
---
 libavcodec/qsv.c          | 24 ++++++++++++++++++++++++
 libavcodec/qsv_internal.h |  4 ++++
 libavcodec/qsvdec.c       |  6 ++++++
 3 files changed, 34 insertions(+)

Patch hide | download patch | download mbox

diff --git a/libavcodec/qsv.c b/libavcodec/qsv.c
index 5217adf..2362e55 100644
--- a/libavcodec/qsv.c
+++ b/libavcodec/qsv.c
@@ -195,6 +195,30 @@  int ff_qsv_find_surface_idx(QSVFramesContext *ctx, QSVFrame *frame)
     return AVERROR_BUG;
 }
 
+enum AVPictureType ff_qsv_map_pictype(int mfx_pic_type)
+{
+    enum AVPictureType type = AV_PICTURE_TYPE_NONE;
+    switch (mfx_pic_type & 0x7) {
+        case MFX_FRAMETYPE_I:
+            if (mfx_pic_type & MFX_FRAMETYPE_S)
+                type = AV_PICTURE_TYPE_SI;
+            else
+                type = AV_PICTURE_TYPE_I;
+            break;
+        case MFX_FRAMETYPE_B:
+            type = AV_PICTURE_TYPE_B;
+            break;
+        case MFX_FRAMETYPE_P:
+             if (mfx_pic_type & MFX_FRAMETYPE_S)
+                type = AV_PICTURE_TYPE_SP;
+            else
+                type = AV_PICTURE_TYPE_P;
+            break;
+    }
+
+    return type;
+}
+
 static int qsv_load_plugins(mfxSession session, const char *load_plugins,
                             void *logctx)
 {
diff --git a/libavcodec/qsv_internal.h b/libavcodec/qsv_internal.h
index c030550..b576f53f 100644
--- a/libavcodec/qsv_internal.h
+++ b/libavcodec/qsv_internal.h
@@ -52,6 +52,9 @@  typedef struct QSVFrame {
     mfxFrameSurface1 surface;
     mfxEncodeCtrl enc_ctrl;
 
+    mfxExtDecodedFrameInfo dec_info;
+    mfxExtBuffer *ext_param;
+
     int queued;
     int used;
 
@@ -86,6 +89,7 @@  int ff_qsv_codec_id_to_mfx(enum AVCodecID codec_id);
 int ff_qsv_profile_to_mfx(enum AVCodecID codec_id, int profile);
 
 int ff_qsv_map_pixfmt(enum AVPixelFormat format, uint32_t *fourcc);
+enum AVPictureType ff_qsv_map_pictype(int mfx_pic_type);
 
 int ff_qsv_init_internal_session(AVCodecContext *avctx, mfxSession *session,
                                  const char *load_plugins);
diff --git a/libavcodec/qsvdec.c b/libavcodec/qsvdec.c
index e0c5579..63e2733 100644
--- a/libavcodec/qsvdec.c
+++ b/libavcodec/qsvdec.c
@@ -232,6 +232,11 @@  static int alloc_frame(AVCodecContext *avctx, QSVContext *q, QSVFrame *frame)
 
         frame->surface.Data.MemId = &q->frames_ctx.mids[ret];
     }
+    frame->surface.Data.ExtParam = &frame->ext_param;
+    frame->surface.Data.NumExtParam = 1;
+    frame->ext_param = (mfxExtBuffer*)&frame->dec_info;
+    frame->dec_info.Header.BufferId = MFX_EXTBUFF_DECODED_FRAME_INFO;
+    frame->dec_info.Header.BufferSz = sizeof(frame->dec_info);
 
     frame->used = 1;
 
@@ -418,6 +423,7 @@  FF_ENABLE_DEPRECATION_WARNINGS
             outsurf->Info.PicStruct & MFX_PICSTRUCT_FIELD_TFF;
         frame->interlaced_frame =
             !(outsurf->Info.PicStruct & MFX_PICSTRUCT_PROGRESSIVE);
+        frame->pict_type = ff_qsv_map_pictype(out_frame->dec_info.FrameType);
 
         /* update the surface properties */
         if (avctx->pix_fmt == AV_PIX_FMT_QSV)