[FFmpeg-devel] [PATCH] lavc/vaapi_h26[45]: add crop info support in vaapi_h26[4, 5]

wm4 nfxjfg at googlemail.com
Wed Nov 30 11:18:32 EET 2016


On Wed, 30 Nov 2016 10:20:54 +0800
Jun Zhao <mypopydev at gmail.com> wrote:

> From 20bedd18213420c77d5e8a26fbe741d8d204ac10 Mon Sep 17 00:00:00 2001
> From: Jun Zhao <jun.zhao at intel.com>
> Date: Tue, 29 Nov 2016 14:14:25 +0800
> Subject: [PATCH] lavc/vaapi_h26[45]: add crop info support in vaapi_h26[4,5]
> 
> add crop information support in vaapi_h26[4,5] hwaccel decode,
> and align h264/hevc software decoder. After this fix, FATE test
> h264-conformance-cvfc1_sony_c/hevc-conformance-CONFWIN_A_Sony_1
> will pass in i965/SKL.
> 
> Signed-off-by: Wang, Yi A <yi.a.wang at intel.com>
> Signed-off-by: Jun Zhao <jun.zhao at intel.com>
> ---
>  libavcodec/h264dec.c        | 13 +++++++++++++
>  libavcodec/hevc_refs.c      |  7 +++++++
>  libavutil/hwcontext.h       |  6 ++++++
>  libavutil/hwcontext_vaapi.c |  1 +
>  4 files changed, 27 insertions(+)
> 
> diff --git a/libavcodec/h264dec.c b/libavcodec/h264dec.c
> index ed0b724..2e7692c 100644
> --- a/libavcodec/h264dec.c
> +++ b/libavcodec/h264dec.c
> @@ -54,6 +54,7 @@
>  #include "rectangle.h"
>  #include "thread.h"
>  #include "vdpau_compat.h"
> +#include "libavutil/hwcontext.h"
>  
>  static int h264_decode_end(AVCodecContext *avctx);
>  
> @@ -1012,6 +1013,18 @@ static int output_frame(H264Context *h, AVFrame *dst, H264Picture *srcp)
>                        (srcp->crop_top  >> vshift) * dst->linesize[i];
>          dst->data[i] += off;
>      }
> +
> +    /* HWAccel always used data[0-3] in avframe */
> +    for (i = 0; i < 3; i++) {
> +        if (dst->hw_frames_ctx) {
> +            int hshift = (i > 0) ? desc->log2_chroma_w : 0;
> +            int vshift = (i > 0) ? desc->log2_chroma_h : 0;
> +            AVHWFramesContext *ctx = (AVHWFramesContext*)dst->hw_frames_ctx->data;
> +            ctx->top_offset[i] = srcp->crop_top  >> vshift;
> +            ctx->left_offset[i] = (srcp->crop_left >> hshift) << h->pixel_shift;
> +        }
> +    }
> +
>      return 0;
>  }
>  
> diff --git a/libavcodec/hevc_refs.c b/libavcodec/hevc_refs.c
> index 611ad45..a184de2 100644
> --- a/libavcodec/hevc_refs.c
> +++ b/libavcodec/hevc_refs.c
> @@ -28,6 +28,7 @@
>  #include "thread.h"
>  #include "hevc.h"
>  
> +#include "libavutil/hwcontext.h"
>  void ff_hevc_unref_frame(HEVCContext *s, HEVCFrame *frame, int flags)
>  {
>      /* frame->frame can be NULL if context init failed */
> @@ -222,7 +223,13 @@ int ff_hevc_output_frame(HEVCContext *s, AVFrame *out, int flush)
>                  int off = ((frame->window.left_offset >> hshift) << pixel_shift) +
>                            (frame->window.top_offset   >> vshift) * dst->linesize[i];
>                  dst->data[i] += off;
> +                if (out->hw_frames_ctx) {
> +                    AVHWFramesContext *ctx = (AVHWFramesContext*)out->hw_frames_ctx->data;
> +                    ctx->top_offset[i] = frame->window.top_offset >> vshift;
> +                    ctx->left_offset[i] = (frame->window.left_offset >> hshift) << pixel_shift;
> +                }
>              }
> +
>              av_log(s->avctx, AV_LOG_DEBUG,
>                     "Output frame with POC %d.\n", frame->poc);
>              return 1;
> diff --git a/libavutil/hwcontext.h b/libavutil/hwcontext.h
> index 785da09..0d666c3 100644
> --- a/libavutil/hwcontext.h
> +++ b/libavutil/hwcontext.h
> @@ -220,6 +220,12 @@ typedef struct AVHWFramesContext {
>       * Must be set by the user before calling av_hwframe_ctx_init().
>       */
>      int width, height;
> +
> +    /**
> +     * The top and left offset of the frames
> +     */
> +    int top_offset[AV_NUM_DATA_POINTERS];
> +    int left_offset[AV_NUM_DATA_POINTERS];
>  } AVHWFramesContext;
>  
>  /**
> diff --git a/libavutil/hwcontext_vaapi.c b/libavutil/hwcontext_vaapi.c
> index 6176bdc..fa026cc 100644
> --- a/libavutil/hwcontext_vaapi.c
> +++ b/libavutil/hwcontext_vaapi.c
> @@ -781,6 +781,7 @@ static int vaapi_map_frame(AVHWFramesContext *hwfc,
>      for (i = 0; i < map->image.num_planes; i++) {
>          dst->data[i] = (uint8_t*)address + map->image.offsets[i];
>          dst->linesize[i] = map->image.pitches[i];
> +        dst->data[i] += hwfc->top_offset[i] * dst->linesize[i] + hwfc->left_offset[i];
>      }
>      if (
>  #ifdef VA_FOURCC_YV16

That's an interesting approach. I don't mind this being pushed, but in
the end I think it would be better to have proper crop info in AVFrame
(this would also get rid of annoyances like unaligned data pointers
with software decoded frames).



More information about the ffmpeg-devel mailing list