diff mbox

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

Message ID 6fc5c751-fe57-f1da-b793-f6f130472608@gmail.com
State New
Headers show

Commit Message

Jun Zhao Nov. 30, 2016, 2:20 a.m. UTC
From 20bedd18213420c77d5e8a26fbe741d8d204ac10 Mon Sep 17 00:00:00 2001
From: Jun Zhao <jun.zhao@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@intel.com>
Signed-off-by: Jun Zhao <jun.zhao@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(+)

Comments

wm4 Nov. 30, 2016, 9:18 a.m. UTC | #1
On Wed, 30 Nov 2016 10:20:54 +0800
Jun Zhao <mypopydev@gmail.com> wrote:

> From 20bedd18213420c77d5e8a26fbe741d8d204ac10 Mon Sep 17 00:00:00 2001
> From: Jun Zhao <jun.zhao@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@intel.com>
> Signed-off-by: Jun Zhao <jun.zhao@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).
Mark Thompson Nov. 30, 2016, 11:08 a.m. UTC | #2
On 30/11/16 02:20, Jun Zhao wrote:
> From 20bedd18213420c77d5e8a26fbe741d8d204ac10 Mon Sep 17 00:00:00 2001
> From: Jun Zhao <jun.zhao@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@intel.com>
> Signed-off-by: Jun Zhao <jun.zhao@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(+)

No.  Top/left cropping needs a more general approach, not hacks in specific decoders/hwcontexts.

Among other things:
- The hardware frame context is owned by the user, you can't edit it like this from inside the decoder.
- It can't be per-frame-context anyway, because multiple streams can be decoded into the same frame context.
- More components need to be aware of it: the scale filters definitely should be (at <https://git.libav.org/?p=libav.git;a=blob;f=libavfilter/vf_scale_vaapi.c;h=50be68eee07374a78bba1eed8850c3ab9e019fe6;hb=HEAD#l291>, in VAAPI, similarly for the other hardware APIs).  Other components can probably ignore it (with docs saying you should put it through the relevant scale filter if you want correctly-cropped images), but we should make that decision explicitly.
- Messing with pointers/sizes on frame upload/download has issues with APIs which can only transfer whole frames - see the comment at <http://git.videolan.org/?p=ffmpeg.git;a=blob;f=libavutil/hwcontext.h;h=785da090b3fc4b4e91f989370ea4606c79bae823;hb=HEAD#l321>.  (That was written with VDPAU in mind, there are likely others.)

As wm4 notes in another reply, this ends up pointing to some sort of cropping information associated with the AVFrame which all interested components can then read.

I know several people have expressed interest in this problem: given that, it's probably a good idea to have some discussion first and decide roughly what the result should look like before writing a lot of code for it.

Thanks,

- Mark
wm4 Nov. 30, 2016, 1:18 p.m. UTC | #3
On Wed, 30 Nov 2016 11:08:10 +0000
Mark Thompson <sw@jkqxz.net> wrote:

> On 30/11/16 02:20, Jun Zhao wrote:
> > From 20bedd18213420c77d5e8a26fbe741d8d204ac10 Mon Sep 17 00:00:00 2001
> > From: Jun Zhao <jun.zhao@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@intel.com>
> > Signed-off-by: Jun Zhao <jun.zhao@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(+)  
> 
> No.  Top/left cropping needs a more general approach, not hacks in specific decoders/hwcontexts.
> 
> Among other things:
> - The hardware frame context is owned by the user, you can't edit it like this from inside the decoder.
> - It can't be per-frame-context anyway, because multiple streams can be decoded into the same frame context.
> - More components need to be aware of it: the scale filters definitely should be (at <https://git.libav.org/?p=libav.git;a=blob;f=libavfilter/vf_scale_vaapi.c;h=50be68eee07374a78bba1eed8850c3ab9e019fe6;hb=HEAD#l291>, in VAAPI, similarly for the other hardware APIs).  Other components can probably ignore it (with docs saying you should put it through the relevant scale filter if you want correctly-cropped images), but we should make that decision explicitly.
> - Messing with pointers/sizes on frame upload/download has issues with APIs which can only transfer whole frames - see the comment at <http://git.videolan.org/?p=ffmpeg.git;a=blob;f=libavutil/hwcontext.h;h=785da090b3fc4b4e91f989370ea4606c79bae823;hb=HEAD#l321>.  (That was written with VDPAU in mind, there are likely others.)
> 
> As wm4 notes in another reply, this ends up pointing to some sort of cropping information associated with the AVFrame which all interested components can then read.
> 
> I know several people have expressed interest in this problem: given that, it's probably a good idea to have some discussion first and decide roughly what the result should look like before writing a lot of code for it.

I've always argued for having a cropping rectangle directly in AVFrame,
but the idea was never popular.
Michael Niedermayer Nov. 30, 2016, 3:40 p.m. UTC | #4
On Wed, Nov 30, 2016 at 02:18:36PM +0100, wm4 wrote:
> On Wed, 30 Nov 2016 11:08:10 +0000
> Mark Thompson <sw@jkqxz.net> wrote:
> 
> > On 30/11/16 02:20, Jun Zhao wrote:
> > > From 20bedd18213420c77d5e8a26fbe741d8d204ac10 Mon Sep 17 00:00:00 2001
> > > From: Jun Zhao <jun.zhao@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@intel.com>
> > > Signed-off-by: Jun Zhao <jun.zhao@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(+)  
> > 
> > No.  Top/left cropping needs a more general approach, not hacks in specific decoders/hwcontexts.
> > 
> > Among other things:
> > - The hardware frame context is owned by the user, you can't edit it like this from inside the decoder.
> > - It can't be per-frame-context anyway, because multiple streams can be decoded into the same frame context.
> > - More components need to be aware of it: the scale filters definitely should be (at <https://git.libav.org/?p=libav.git;a=blob;f=libavfilter/vf_scale_vaapi.c;h=50be68eee07374a78bba1eed8850c3ab9e019fe6;hb=HEAD#l291>, in VAAPI, similarly for the other hardware APIs).  Other components can probably ignore it (with docs saying you should put it through the relevant scale filter if you want correctly-cropped images), but we should make that decision explicitly.
> > - Messing with pointers/sizes on frame upload/download has issues with APIs which can only transfer whole frames - see the comment at <http://git.videolan.org/?p=ffmpeg.git;a=blob;f=libavutil/hwcontext.h;h=785da090b3fc4b4e91f989370ea4606c79bae823;hb=HEAD#l321>.  (That was written with VDPAU in mind, there are likely others.)
> > 
> > As wm4 notes in another reply, this ends up pointing to some sort of cropping information associated with the AVFrame which all interested components can then read.
> > 
> > I know several people have expressed interest in this problem: given that, it's probably a good idea to have some discussion first and decide roughly what the result should look like before writing a lot of code for it.
> 
> I've always argued for having a cropping rectangle directly in AVFrame,
> but the idea was never popular.

AVFrame had a pan_scan parameter to store one or more croping
rectangles.
That is now available as side data

I remember the intend that this could be used for multiple rectangles
of different sizes for example for storing recommanded display
rectangles for a 4:3 and a 16:9 display device, but it seems only a
single size per frame is supported in the API

[...]
wm4 Nov. 30, 2016, 3:56 p.m. UTC | #5
On Wed, 30 Nov 2016 16:40:53 +0100
Michael Niedermayer <michael@niedermayer.cc> wrote:

> On Wed, Nov 30, 2016 at 02:18:36PM +0100, wm4 wrote:
> > On Wed, 30 Nov 2016 11:08:10 +0000
> > Mark Thompson <sw@jkqxz.net> wrote:
> >   
> > > On 30/11/16 02:20, Jun Zhao wrote:  
> > > > From 20bedd18213420c77d5e8a26fbe741d8d204ac10 Mon Sep 17 00:00:00 2001
> > > > From: Jun Zhao <jun.zhao@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@intel.com>
> > > > Signed-off-by: Jun Zhao <jun.zhao@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(+)    
> > > 
> > > No.  Top/left cropping needs a more general approach, not hacks in specific decoders/hwcontexts.
> > > 
> > > Among other things:
> > > - The hardware frame context is owned by the user, you can't edit it like this from inside the decoder.
> > > - It can't be per-frame-context anyway, because multiple streams can be decoded into the same frame context.
> > > - More components need to be aware of it: the scale filters definitely should be (at <https://git.libav.org/?p=libav.git;a=blob;f=libavfilter/vf_scale_vaapi.c;h=50be68eee07374a78bba1eed8850c3ab9e019fe6;hb=HEAD#l291>, in VAAPI, similarly for the other hardware APIs).  Other components can probably ignore it (with docs saying you should put it through the relevant scale filter if you want correctly-cropped images), but we should make that decision explicitly.
> > > - Messing with pointers/sizes on frame upload/download has issues with APIs which can only transfer whole frames - see the comment at <http://git.videolan.org/?p=ffmpeg.git;a=blob;f=libavutil/hwcontext.h;h=785da090b3fc4b4e91f989370ea4606c79bae823;hb=HEAD#l321>.  (That was written with VDPAU in mind, there are likely others.)
> > > 
> > > As wm4 notes in another reply, this ends up pointing to some sort of cropping information associated with the AVFrame which all interested components can then read.
> > > 
> > > I know several people have expressed interest in this problem: given that, it's probably a good idea to have some discussion first and decide roughly what the result should look like before writing a lot of code for it.  
> > 
> > I've always argued for having a cropping rectangle directly in AVFrame,
> > but the idea was never popular.  
> 
> AVFrame had a pan_scan parameter to store one or more croping
> rectangles.
> That is now available as side data
> 
> I remember the intend that this could be used for multiple rectangles
> of different sizes for example for storing recommanded display
> rectangles for a 4:3 and a 16:9 display device, but it seems only a
> single size per frame is supported in the API
> 
> [...]

This one is very "special" - I don't know if I'd want to further its
existence. What's it used for at all?
Michael Niedermayer Nov. 30, 2016, 5:25 p.m. UTC | #6
On Wed, Nov 30, 2016 at 04:56:01PM +0100, wm4 wrote:
> On Wed, 30 Nov 2016 16:40:53 +0100
> Michael Niedermayer <michael@niedermayer.cc> wrote:
> 
> > On Wed, Nov 30, 2016 at 02:18:36PM +0100, wm4 wrote:
> > > On Wed, 30 Nov 2016 11:08:10 +0000
> > > Mark Thompson <sw@jkqxz.net> wrote:
> > >   
> > > > On 30/11/16 02:20, Jun Zhao wrote:  
> > > > > From 20bedd18213420c77d5e8a26fbe741d8d204ac10 Mon Sep 17 00:00:00 2001
> > > > > From: Jun Zhao <jun.zhao@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@intel.com>
> > > > > Signed-off-by: Jun Zhao <jun.zhao@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(+)    
> > > > 
> > > > No.  Top/left cropping needs a more general approach, not hacks in specific decoders/hwcontexts.
> > > > 
> > > > Among other things:
> > > > - The hardware frame context is owned by the user, you can't edit it like this from inside the decoder.
> > > > - It can't be per-frame-context anyway, because multiple streams can be decoded into the same frame context.
> > > > - More components need to be aware of it: the scale filters definitely should be (at <https://git.libav.org/?p=libav.git;a=blob;f=libavfilter/vf_scale_vaapi.c;h=50be68eee07374a78bba1eed8850c3ab9e019fe6;hb=HEAD#l291>, in VAAPI, similarly for the other hardware APIs).  Other components can probably ignore it (with docs saying you should put it through the relevant scale filter if you want correctly-cropped images), but we should make that decision explicitly.
> > > > - Messing with pointers/sizes on frame upload/download has issues with APIs which can only transfer whole frames - see the comment at <http://git.videolan.org/?p=ffmpeg.git;a=blob;f=libavutil/hwcontext.h;h=785da090b3fc4b4e91f989370ea4606c79bae823;hb=HEAD#l321>.  (That was written with VDPAU in mind, there are likely others.)
> > > > 
> > > > As wm4 notes in another reply, this ends up pointing to some sort of cropping information associated with the AVFrame which all interested components can then read.
> > > > 
> > > > I know several people have expressed interest in this problem: given that, it's probably a good idea to have some discussion first and decide roughly what the result should look like before writing a lot of code for it.  
> > > 
> > > I've always argued for having a cropping rectangle directly in AVFrame,
> > > but the idea was never popular.  
> > 
> > AVFrame had a pan_scan parameter to store one or more croping
> > rectangles.
> > That is now available as side data
> > 
> > I remember the intend that this could be used for multiple rectangles
> > of different sizes for example for storing recommanded display
> > rectangles for a 4:3 and a 16:9 display device, but it seems only a
> > single size per frame is supported in the API
> > 
> > [...]
> 
> This one is very "special" - I don't know if I'd want to further its
> existence. What's it used for at all?

I only know whats written in the specs, i dont remember having
investigated what real world files do with it, and my knowledge of the
specs is many years old so the spec would be a better place than my
memory of it for further research ...

[...]
wm4 Dec. 1, 2016, 11:03 a.m. UTC | #7
On Wed, 30 Nov 2016 18:25:59 +0100
Michael Niedermayer <michael@niedermayer.cc> wrote:

> > > AVFrame had a pan_scan parameter to store one or more croping
> > > rectangles.
> > > That is now available as side data
> > > 
> > > I remember the intend that this could be used for multiple rectangles
> > > of different sizes for example for storing recommanded display
> > > rectangles for a 4:3 and a 16:9 display device, but it seems only a
> > > single size per frame is supported in the API
> > > 
> > > [...]  
> > 
> > This one is very "special" - I don't know if I'd want to further its
> > existence. What's it used for at all?  
> 
> I only know whats written in the specs, i dont remember having
> investigated what real world files do with it, and my knowledge of the
> specs is many years old so the spec would be a better place than my
> memory of it for further research ...

If we're going to have a crop rectangle, lots of code (including many
video filters) will need to be able to interpret them. Considering
this, the pan scan side data is prohibitively complex. Maybe it
accurately reflects some standard (mpeg1/2 apparently?), but I'd say
it's not simple enough for general use.
Jun Zhao Dec. 2, 2016, 8:15 a.m. UTC | #8
On 2016/12/1 19:03, wm4 wrote:
> On Wed, 30 Nov 2016 18:25:59 +0100
> Michael Niedermayer <michael@niedermayer.cc> wrote:
> 
>>>> AVFrame had a pan_scan parameter to store one or more croping
>>>> rectangles.
>>>> That is now available as side data
>>>>
>>>> I remember the intend that this could be used for multiple rectangles
>>>> of different sizes for example for storing recommanded display
>>>> rectangles for a 4:3 and a 16:9 display device, but it seems only a
>>>> single size per frame is supported in the API
>>>>
>>>> [...]  
>>>
>>> This one is very "special" - I don't know if I'd want to further its
>>> existence. What's it used for at all?  
>>
>> I only know whats written in the specs, i dont remember having
>> investigated what real world files do with it, and my knowledge of the
>> specs is many years old so the spec would be a better place than my
>> memory of it for further research ...
> 
> If we're going to have a crop rectangle, lots of code (including many
> video filters) will need to be able to interpret them. Considering
> this, the pan scan side data is prohibitively complex. Maybe it
> accurately reflects some standard (mpeg1/2 apparently?), but I'd say
> it's not simple enough for general use.
> _

I don't think software dec/enc/filter have the crop issue, so I guess
we just need a general solution for HWAccel dec/enc/hwcontext_xxx_filter.
wm4 Dec. 2, 2016, 9:45 a.m. UTC | #9
On Fri, 2 Dec 2016 16:15:10 +0800
Jun Zhao <mypopydev@gmail.com> wrote:

> On 2016/12/1 19:03, wm4 wrote:
> > On Wed, 30 Nov 2016 18:25:59 +0100
> > Michael Niedermayer <michael@niedermayer.cc> wrote:
> >   
> >>>> AVFrame had a pan_scan parameter to store one or more croping
> >>>> rectangles.
> >>>> That is now available as side data
> >>>>
> >>>> I remember the intend that this could be used for multiple rectangles
> >>>> of different sizes for example for storing recommanded display
> >>>> rectangles for a 4:3 and a 16:9 display device, but it seems only a
> >>>> single size per frame is supported in the API
> >>>>
> >>>> [...]    
> >>>
> >>> This one is very "special" - I don't know if I'd want to further its
> >>> existence. What's it used for at all?    
> >>
> >> I only know whats written in the specs, i dont remember having
> >> investigated what real world files do with it, and my knowledge of the
> >> specs is many years old so the spec would be a better place than my
> >> memory of it for further research ...  
> > 
> > If we're going to have a crop rectangle, lots of code (including many
> > video filters) will need to be able to interpret them. Considering
> > this, the pan scan side data is prohibitively complex. Maybe it
> > accurately reflects some standard (mpeg1/2 apparently?), but I'd say
> > it's not simple enough for general use.
> > _  
> 
> I don't think software dec/enc/filter have the crop issue, so I guess
> we just need a general solution for HWAccel dec/enc/hwcontext_xxx_filter.

For software filters, there is the issue that cropping left/right can
make the plane pointers unaligned (e.g. crop 1 pixel -> the pointer is
not aligned to 16 bytes anymore). Which can cause performance issues.
Also, cropping subsampled yuv by non-mod-2 width/height (as jpg
decoding requires it) is really messy.
diff mbox

Patch

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