On Tue, 2 Feb 2016 19:51:53 +0000
Mark Thompson <s...@jkqxz.net> wrote:

> On 01/02/16 15:58, wm4 wrote:
> > On Sat, 30 Jan 2016 22:11:52 +0000
> > Mark Thompson <s...@jkqxz.net> wrote:
> >   
> >> ---
> >>  configure                  |   5 +
> >>  libavcodec/Makefile        |   1 +
> >>  libavcodec/vaapi_support.c | 710 
> >> +++++++++++++++++++++++++++++++++++++++++++++
> >>  libavcodec/vaapi_support.h | 122 ++++++++
> >>  4 files changed, 838 insertions(+)
> >>  create mode 100644 libavcodec/vaapi_support.c
> >>  create mode 100644 libavcodec/vaapi_support.h
> >>
> >> diff --git a/configure b/configure
> >> index dba8180..e7f53af 100755
> >> --- a/configure
> >> +++ b/configure
> >> @@ -2037,6 +2037,7 @@ CONFIG_EXTRA="
> >>      texturedsp
> >>      texturedspenc
> >>      tpeldsp
> >> +    vaapi_recent
> >>      videodsp
> >>      vp3dsp
> >>      vp56dsp
> >> @@ -5768,6 +5769,10 @@ enabled vaapi &&
> >>      check_lib va/va.h vaInitialize -lva ||
> >>      disable vaapi
> >>
> >> +enabled vaapi &&
> >> +    check_code cc va/va.h "vaCreateSurfaces(0, 0, 0, 0, 0, 0, 0, 0)" &&
> >> +    enable vaapi_recent
> >> +
> >>  enabled vaapi && enabled xlib &&
> >>      check_lib2 "va/va.h va/va_x11.h" vaGetDisplay -lva -lva-x11 &&
> >>      enable vaapi_x11
> >> diff --git a/libavcodec/Makefile b/libavcodec/Makefile
> >> index de957d8..045d118 100644
> >> --- a/libavcodec/Makefile
> >> +++ b/libavcodec/Makefile
> >> @@ -719,6 +719,7 @@ OBJS-$(CONFIG_ADPCM_YAMAHA_ENCODER)       += 
> >> adpcmenc.o adpcm_data.o
> >>  OBJS-$(CONFIG_D3D11VA)                    += dxva2.o
> >>  OBJS-$(CONFIG_DXVA2)                      += dxva2.o
> >>  OBJS-$(CONFIG_VAAPI)                      += vaapi.o
> >> +OBJS-$(CONFIG_VAAPI_RECENT)               += vaapi_support.o
> >>  OBJS-$(CONFIG_VDA)                        += vda.o videotoolbox.o
> >>  OBJS-$(CONFIG_VIDEOTOOLBOX)               += videotoolbox.o
> >>  OBJS-$(CONFIG_VDPAU)                      += vdpau.o
> >> diff --git a/libavcodec/vaapi_support.c b/libavcodec/vaapi_support.c
> >> new file mode 100644
> >> index 0000000..2e22f98
> >> --- /dev/null
> >> +++ b/libavcodec/vaapi_support.c
> >> @@ -0,0 +1,710 @@
> >> +/*
> >> + * VAAPI helper functions.
> >> + *
> >> + * Copyright (C) 2016 Mark Thompson <m...@jkqxz.net>
> >> + *
> >> + * This file is part of FFmpeg.
> >> + *
> >> + * FFmpeg is free software; you can redistribute it and/or
> >> + * modify it under the terms of the GNU Lesser General Public
> >> + * License as published by the Free Software Foundation; either
> >> + * version 2.1 of the License, or (at your option) any later version.
> >> + *
> >> + * FFmpeg is distributed in the hope that it will be useful,
> >> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> >> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> >> + * Lesser General Public License for more details.
> >> + *
> >> + * You should have received a copy of the GNU Lesser General Public
> >> + * License along with FFmpeg; if not, write to the Free Software
> >> + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 
> >> 02110-1301 USA
> >> + */
> >> +
> >> +#include "vaapi_support.h"
> >> +
> >> +#include "libavutil/avassert.h"
> >> +#include "libavutil/imgutils.h"
> >> +#include "libavutil/pixfmt.h"
> >> +
> >> +
> >> +static AVClass vaapi_class = {
> >> +    .class_name = "vaapi",
> >> +    .item_name  = av_default_item_name,
> >> +    .version    = LIBAVUTIL_VERSION_INT,
> >> +};
> >> +static AVClass *vaapi_log = &vaapi_class;  
> > 
> > We've talked about it on IRC. So the idea was matching
> > AVVAAPIHardwareContext with vaapi_context, which is why the first
> > member of AVVAAPIHardwareContext can't be AVClass. I think trying to
> > somehow make these structs compatible should be given up, and instead
> > the struct should have a vaapi_context pointer field instead.  
> 
> Yes.
> 
> > Also, I'm very worried about how this patch in general with combine
> > with the API Libav is planning to add:
> > 
> > https://lists.libav.org/pipermail/libav-devel/2016-January/074490.html
> > 
> > To make this clear, above patch series:
> > - extends the buffer pool to make it useful for the hwdec case (where
> >   you need to free the hw context when the final AVFrame is unreffed)
> > - create a common API for hwaccel contexts, which overlaps with this
> >   patch to some degree, but not fully
> > - adds a hwaccel context field to AVFrame
> > - the hwaccel context is refcounted
> > - adds helper for reading back data from hwaccel AVFrames in an
> >   API-independent way
> > 
> > I'm not sure what to make out of this mess. Any ideas? I don't really
> > want to hold this patch series back either. There is not much reason to
> > refactor the whole API 1 week after it has been added either.  
> 
> I'm not sure how to respond usefully to all of that, it adds a lot of new 
> things all over the place.
> 
> It looks like it has most of the elements needed here, though I would need to 
> examine it more carefully to be sure.  (I don't see a way to do the 
> "enumerate all of a set of frames for something which requires all render 
> targets in advance" operation, but maybe I haven't looked hard enough.)
> 

The newer patches have something for this, I think. At least partially.

> ...
> >> +    err = 0;
> >> +    if(0) {
> >> +    fail:  
> > 
> > This looks funny. My personal preference is avoiding such tricks, but
> > maybe it's not important.  
> 
> I think this unwinding was more complex at some previous iteration.  The 
> failure case can be moved below the return now, though I still think it's 
> nice to have exactly one lock/unlock pair to be sure that that is correct.

If you think so... I still think it could be more readable, but I don't
want to force you. In general, gotos should be lined up at the end of a
function for cleanup, and "if (0)" looks like a WTF.

> >> +        if(surface) {
> >> +            if(surface->id)
> >> +                vaDestroySurfaces(hw_ctx->display, &surface->id, 1);
> >> +            av_free(surface);
> >> +        }
> >> +        if(frame)
> >> +            av_frame_free(&frame);
> >> +        for(--i; i >= 0; i--)
> >> +            av_frame_free(&pool->frames[i]);
> >> +    }
> >> +
> >> +    av_vaapi_unlock_hardware_context(hw_ctx);
> >> +    return err;
> >> +}
> >> +
> >> +int av_vaapi_surface_pool_uninit(AVVAAPISurfacePool *pool)
> >> +
> >> +{
> >> +    int i;
> >> +
> >> +    av_vaapi_lock_hardware_context(pool->hardware_context);
> >> +
> >> +    for(i = 0; i < FF_ARRAY_ELEMS(pool->frames); i++) {
> >> +        if(pool->frames[i])
> >> +            av_frame_free(&pool->frames[i]);
> >> +    }
> >> +
> >> +    av_vaapi_unlock_hardware_context(pool->hardware_context);
> >> +
> >> +    return 0;
> >> +}
> >> +
> >> +int av_vaapi_surface_pool_get(AVVAAPISurfacePool *pool, AVFrame *target)
> >> +{
> >> +    AVFrame *frame = 0;
> >> +    int i, err;
> >> +
> >> +    av_vaapi_lock_hardware_context(pool->hardware_context);
> >> +
> >> +    for(i = 0; i < FF_ARRAY_ELEMS(pool->frames); i++) {
> >> +        if(!pool->frames[i])
> >> +            break;
> >> +
> >> +        if(av_buffer_get_ref_count(pool->frames[i]->buf[0]) == 1) {
> >> +            frame = pool->frames[i];
> >> +            break;
> >> +        }
> >> +    }
> >> +
> >> +    if(frame) {
> >> +        target->data[3] = frame->data[3];
> >> +        target->buf[0] = av_buffer_ref(frame->buf[0]);
> >> +        target->buf[1] = av_buffer_ref(frame->buf[1]);
> >> +        if(!target->buf[0] || !target->buf[1])
> >> +            err = AVERROR(ENOMEM);
> >> +        else
> >> +            err = 0;
> >> +    } else {
> >> +        err = AVERROR(ENOMEM);
> >> +    }
> >> +
> >> +    av_vaapi_unlock_hardware_context(pool->hardware_context);
> >> +
> >> +    return err;
> >> +}
> >> +
> >> +int av_vaapi_map_frame(AVFrame *frame, int get)
> >> +{
> >> +    AVVAAPISurface *surface = vaapi_get_surface(frame);
> >> +    AVVAAPISurfaceConfig *config = vaapi_get_surface_config(frame);
> >> +    AVVAAPIHardwareContext *hw_ctx = surface->hardware_context;
> >> +    VAImage *image = &surface->image;
> >> +    VAStatus vas;
> >> +    int i, err;
> >> +    void *address;
> >> +    // On current Intel drivers, derive gives you memory which is very 
> >> slow
> >> +    // to read (uncached?).  It can be better for write-only cases, but 
> >> for
> >> +    // now play it safe and never use derive.
> >> +    int derive = 0;  
> > 
> > Before the patch gets applied, we also should check if we can get in a
> > "GPU memcpy", and whether this codepath can be enabled. If not, there
> > wouldn't be much of a reason to keep it.  
> 
> Even without it, it has use for the "drawing on frames" case (subtitles?).  I 
> haven't studied how that works in libavfilter at all, but I imagine we want 
> the derive case there to avoid a pointless copy there and back to speed up 
> changing only a few pixel values.
> 
> I guess it could go for now and be added back if/when someone implements 
> that, though.
> 

Then it would have an option. But let's not leave commented code in
there just so it can bitrot.

> ...
> > Looks in general pretty ok to me.
> > 
> > There should be allocation functions for structs which don't have one
> > yet, and a clear warning should be added to the doxygen. (Doxygen
> > should also be added.)  
> 
> If you're happy that this is now plausible, then I will write documentation 
> for the relevant parts.
> 

OK, but there's still the unsolved Libav issue, which might dice up
everything again.

> > One nit: I _think_ we usually add a whitespace between statement and
> > "(", e.g. "if (". (Not for function calls or declarations.)  
> 
> I can sed the spaces in, I guess.
> 
> Thanks for the review!
> 
> - Mark
> 
> _______________________________________________
> ffmpeg-devel mailing list
> ffmpeg-devel@ffmpeg.org
> http://ffmpeg.org/mailman/listinfo/ffmpeg-devel

_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel

Reply via email to