[V3,3/3] lavc/qsvdec: expose frame pic_type

Message ID 1521729713-22225-3-git-send-email-zhong.li@intel.com
State New
Headers show
Series
  • [V2,1/3] lavc/qsvdec: set complete_frame flags for progressive picture
Related show

Commit Message

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

v2: fix the compile error since AV_PICTURE_TYPE_NONE is not existed in libav.
v3: 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 |  3 +++
 libavcodec/qsvdec.c       |  6 ++++++
 3 files changed, 33 insertions(+)

Comments

Maxym Dmytrychenko March 26, 2018, 7:02 p.m. | #1
aside of intend points at  frame->surface..., should be ok

On Thu, Mar 22, 2018 at 3:41 PM, Zhong Li <zhong.li@intel.com> wrote:

> Currently pict_type are unset.
> Add an extra param to fetch the picture type from qsv decoder
>
> v2: fix the compile error since AV_PICTURE_TYPE_NONE is not existed in
> libav.
> v3: 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 |  3 +++
>  libavcodec/qsvdec.c       |  6 ++++++
>  3 files changed, 33 insertions(+)
>
> diff --git a/libavcodec/qsv.c b/libavcodec/qsv.c
> index 96dca14..c7ba642 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 975c8de..07ddc59 100644
> --- a/libavcodec/qsv_internal.h
> +++ b/libavcodec/qsv_internal.h
> @@ -48,6 +48,8 @@ typedef struct QSVMid {
>  typedef struct QSVFrame {
>      AVFrame *frame;
>      mfxFrameSurface1 surface;
> +    mfxExtDecodedFrameInfo dec_info;
> +    mfxExtBuffer *ext_param;
>
>      int queued;
>      int used;
> @@ -83,6 +85,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 8148beb..c0ed4bd 100644
> --- a/libavcodec/qsvdec.c
> +++ b/libavcodec/qsvdec.c
> @@ -235,6 +235,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;
>
> @@ -421,6 +426,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)
> --
> 1.8.3.1
>
> _______________________________________________
> libav-devel mailing list
> libav-devel@libav.org
> https://lists.libav.org/mailman/listinfo/libav-devel
Li, Zhong March 27, 2018, 9:06 a.m. | #2
It is a necessary pipeline step: attach the created buffer to surface, then we can get the frame type from MSDK. 
Refer: https://github.com/Intel-Media-SDK/MediaSDK/blob/master/_studio/mfx_lib/decode/h264/src/mfx_h264_dec_decode.cpp#L1411 

> -----Original Message-----
> From: libav-devel [mailto:libav-devel-bounces@libav.org] On Behalf Of
> Maxym Dmytrychenko
> Sent: Tuesday, March 27, 2018 3:03 AM
> To: libav development <libav-devel@libav.org>
> Cc: Liu, ChaoX A <chaox.a.liu@intel.com>
> Subject: Re: [libav-devel] [PATCH V3 3/3] lavc/qsvdec: expose frame pic_type
> 
> aside of intend points at  frame->surface..., should be ok
> 
> On Thu, Mar 22, 2018 at 3:41 PM, Zhong Li <zhong.li@intel.com> wrote:
> 
> > Currently pict_type are unset.
> > Add an extra param to fetch the picture type from qsv decoder
> >
> > v2: fix the compile error since AV_PICTURE_TYPE_NONE is not existed in
> > libav.
> > v3: 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 |  3 +++
> >  libavcodec/qsvdec.c       |  6 ++++++
> >  3 files changed, 33 insertions(+)
> >
> > diff --git a/libavcodec/qsv.c b/libavcodec/qsv.c index
> > 96dca14..c7ba642 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
> > 975c8de..07ddc59 100644
> > --- a/libavcodec/qsv_internal.h
> > +++ b/libavcodec/qsv_internal.h
> > @@ -48,6 +48,8 @@ typedef struct QSVMid {  typedef struct QSVFrame {
> >      AVFrame *frame;
> >      mfxFrameSurface1 surface;
> > +    mfxExtDecodedFrameInfo dec_info;
> > +    mfxExtBuffer *ext_param;
> >
> >      int queued;
> >      int used;
> > @@ -83,6 +85,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
> > 8148beb..c0ed4bd 100644
> > --- a/libavcodec/qsvdec.c
> > +++ b/libavcodec/qsvdec.c
> > @@ -235,6 +235,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;
> >
> > @@ -421,6 +426,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)
> > --
> > 1.8.3.1

Patch

diff --git a/libavcodec/qsv.c b/libavcodec/qsv.c
index 96dca14..c7ba642 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 975c8de..07ddc59 100644
--- a/libavcodec/qsv_internal.h
+++ b/libavcodec/qsv_internal.h
@@ -48,6 +48,8 @@  typedef struct QSVMid {
 typedef struct QSVFrame {
     AVFrame *frame;
     mfxFrameSurface1 surface;
+    mfxExtDecodedFrameInfo dec_info;
+    mfxExtBuffer *ext_param;
 
     int queued;
     int used;
@@ -83,6 +85,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 8148beb..c0ed4bd 100644
--- a/libavcodec/qsvdec.c
+++ b/libavcodec/qsvdec.c
@@ -235,6 +235,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;
 
@@ -421,6 +426,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)