[FFmpeg-devel] [PATCH] HWAccel infrastructure (take 5)

Michael Niedermayer michaelni
Fri Feb 20 13:45:52 CET 2009


On Fri, Feb 20, 2009 at 09:51:37AM +0100, Gwenole Beauchesne wrote:
> Hi,
>
> On Thu, 19 Feb 2009, Michael Niedermayer wrote:
>
>>> +AVHWAccel *ff_query_hwaccel_codec(AVCodecContext *avctx, enum CodecID 
>>> codec_id)
>>> +{
>>> +    AVHWAccel *hwaccel;
>>> +    AVHWAccel *hwaccels[PIX_FMT_NB] = { NULL, };
>>> +    enum PixelFormat pix_fmts[PIX_FMT_NB + 1];
>>> +    int pix_fmt, n_pix_fmts = 0;
>>> +
>>
>>> +    /* The user shall override ::get_format() with something sensible 
>>> enough */
>>> +    if (!avctx->get_format || avctx->get_format == 
>>> avcodec_default_get_format)
>>> +        return NULL;
>>
>> avctx->get_format being NULL seems invalid, so no need to check for it
>> also i suspect it would be cleaner to make avcodec_default_get_format()
>> skip hw-accel formats.
>
> Implemented with an ff_is_hwaccel_pix_fmt() function. That's intentionally 
> internal because users are expected to handle the HW accelerated pix_fmt 
> specifically anyway. IMO, this is only useful for lavc.
>
> New patch attached with the following changes:
> * Filter out HW accelerated formats in avcodec_default_get_format().
> * Add ff_is_hwaccel_pix_fmt(() to detect hardware accelerated pix_fmts.
> * Cosmetics and documentation improvements.

[...]

> diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h
> index 62e4e47..129e15d 100644
> --- a/libavcodec/avcodec.h
> +++ b/libavcodec/avcodec.h
> @@ -2315,6 +2315,13 @@ typedef struct AVCodecContext {
>       * - decoding: unused.
>       */
>      float rc_min_vbv_overflow_use;
> +
> +    /**
> +     * Hardware accelerator in use
> +     * - encoding: unused.
> +     * - decoding: Set by libavcodec
> +     */
> +    struct AVHWAccel *hwaccel;
>  } AVCodecContext;
>  
>  /**

hunk ok


[...]
> +    /**
> +     * Called at the beginning of each frame or field picture.
> +     *
> +     * Meaningful frame information (codec specific) is guaranteed to
> +     * be parsed at this point. This function is mandatory.
> +     *
> +     * Note that \p buf can be NULL along with \p buf_size set to 0.
> +     * Otherwise, this means the whole frame is available at this point.
> +     *
> +     * @param avctx the codec context
> +     * @param buf the frame data buffer base
> +     * @param buf_size the size of the frame in bytes
> +     * @return zero if successful, a negative value otherwise
> +     */
> +    int (*start_frame)(AVCodecContext *avctx, const uint8_t *buf, uint32_t buf_size);

dont you want the current AVFrame as well? just a question ...


[...]
> @@ -3166,4 +3254,16 @@ int av_parse_video_frame_rate(AVRational *frame_rate, const char *str);
>  #define AVERROR_NOENT       AVERROR(ENOENT)  /**< No such file or directory. */
>  #define AVERROR_PATCHWELCOME    -MKTAG('P','A','W','E') /**< Not yet implemented in FFmpeg. Patches welcome. */
>  
> +/**
> + * Registers the hardware accelerator \p hwaccel.
> + */
> +void av_register_hwaccel(AVHWAccel *hwaccel);
> +
> +/**
> + * If hwaccel is NULL, returns the first registered hardware accelerator,
> + * if hwaccel is non-NULL, returns the next registered hardware accelerator
> + * after hwaccel, or NULL if hwaccel is the last one.
> + */
> +AVHWAccel *av_hwaccel_next(AVHWAccel *hwaccel);
> +
>  #endif /* AVCODEC_AVCODEC_H */
> diff --git a/libavcodec/error_resilience.c b/libavcodec/error_resilience.c
> index a196326..c21bc70 100644
> --- a/libavcodec/error_resilience.c
> +++ b/libavcodec/error_resilience.c
> @@ -680,6 +680,7 @@ void ff_er_frame_end(MpegEncContext *s){
>      Picture *pic= s->current_picture_ptr;
>  
>      if(!s->error_recognition || s->error_count==0 || s->avctx->lowres ||
> +       s->avctx->hwaccel ||
>         s->avctx->codec->capabilities&CODEC_CAP_HWACCEL_VDPAU ||
>         s->error_count==3*s->mb_width*(s->avctx->skip_top + s->avctx->skip_bottom)) return;
>  
> diff --git a/libavcodec/h263dec.c b/libavcodec/h263dec.c
> index 4cd2ce8..1eb7f9d 100644
> --- a/libavcodec/h263dec.c
> +++ b/libavcodec/h263dec.c
> @@ -25,6 +25,7 @@
>   * H.263 decoder.
>   */
>  
> +#include "internal.h"
>  #include "avcodec.h"
>  #include "dsputil.h"
>  #include "mpegvideo.h"

3 hunks ok


[...]
> diff --git a/libavcodec/imgconvert.c b/libavcodec/imgconvert.c
> index abc253e..edcc6d9 100644
> --- a/libavcodec/imgconvert.c
> +++ b/libavcodec/imgconvert.c
> @@ -57,6 +57,7 @@ typedef struct PixFmtInfo {
>      uint8_t color_type;      /**< color type (see FF_COLOR_xxx constants) */
>      uint8_t pixel_type;      /**< pixel storage type (see FF_PIXEL_xxx constants) */
>      uint8_t is_alpha : 1;    /**< true if alpha can be specified */
> +    uint8_t is_hwaccel : 1;  /**< true if this is an HW accelerated format */
>      uint8_t x_chroma_shift;  /**< X chroma subsampling factor is 2 ^ shift */
>      uint8_t y_chroma_shift;  /**< Y chroma subsampling factor is 2 ^ shift */
>      uint8_t depth;           /**< bit depth of the color components */
> @@ -263,24 +264,31 @@ static const PixFmtInfo pix_fmt_info[PIX_FMT_NB] = {
>      },
>      [PIX_FMT_XVMC_MPEG2_MC] = {
>          .name = "xvmcmc",
> +        .is_hwaccel = 1,
>      },
>      [PIX_FMT_XVMC_MPEG2_IDCT] = {
>          .name = "xvmcidct",
> +        .is_hwaccel = 1,
>      },
>      [PIX_FMT_VDPAU_MPEG1] = {
>          .name = "vdpau_mpeg1",
> +        .is_hwaccel = 1,
>      },
>      [PIX_FMT_VDPAU_MPEG2] = {
>          .name = "vdpau_mpeg2",
> +        .is_hwaccel = 1,
>      },
>      [PIX_FMT_VDPAU_H264] = {
>          .name = "vdpau_h264",
> +        .is_hwaccel = 1,
>      },
>      [PIX_FMT_VDPAU_WMV3] = {
>          .name = "vdpau_wmv3",
> +        .is_hwaccel = 1,
>      },
>      [PIX_FMT_VDPAU_VC1] = {
>          .name = "vdpau_vc1",
> +        .is_hwaccel = 1,
>      },
>      [PIX_FMT_UYYVYY411] = {
>          .name = "uyyvyy411",

2 hunks ok


> @@ -443,6 +451,12 @@ void avcodec_pix_fmt_string (char *buf, int buf_size, int pix_fmt)
>      }
>  }
>  
> +int ff_is_hwaccel_pix_fmt(enum PixelFormat pix_fmt)
> +{
> +    return pix_fmt >= 0 && pix_fmt < PIX_FMT_NB &&
> +        pix_fmt_info[pix_fmt].is_hwaccel;
> +}
> +

the >= < checks seem useless for an internal function


>  int ff_set_systematic_pal(uint32_t pal[256], enum PixelFormat pix_fmt){
>      int i;
>  
> diff --git a/libavcodec/internal.h b/libavcodec/internal.h
> index a8bed35..e1b3b0d 100644
> --- a/libavcodec/internal.h
> +++ b/libavcodec/internal.h
> @@ -24,6 +24,9 @@
>  #ifndef AVCODEC_INTERNAL_H
>  #define AVCODEC_INTERNAL_H
>  
> +#include <stdint.h>
> +#include "avcodec.h"
> +
>  /**
>   * Logs a generic warning message about a missing feature.
>   * @param[in] avc a pointer to an arbitrary struct of which the first field is

hunk ok

[...]
> diff --git a/libavcodec/mpeg12.c b/libavcodec/mpeg12.c
> index 6cf0335..c14cd6e 100644
> --- a/libavcodec/mpeg12.c
> +++ b/libavcodec/mpeg12.c
> @@ -26,6 +26,7 @@
>   */
>  
>  //#define DEBUG
> +#include "internal.h"
>  #include "avcodec.h"
>  #include "dsputil.h"
>  #include "mpegvideo.h"

hunk ok


[...]
> diff --git a/libavcodec/mpegvideo.c b/libavcodec/mpegvideo.c
> index 2eec211..c213c82 100644
> --- a/libavcodec/mpegvideo.c
> +++ b/libavcodec/mpegvideo.c
> @@ -955,7 +955,8 @@ void MPV_frame_end(MpegEncContext *s)
>      //just to make sure that all data is rendered.
>      if(CONFIG_MPEG_XVMC_DECODER && s->avctx->xvmc_acceleration){
>          ff_xvmc_field_end(s);
> -    }else if(!(s->avctx->codec->capabilities&CODEC_CAP_HWACCEL_VDPAU)
> +    }else if(!s->avctx->hwaccel
> +       && !(s->avctx->codec->capabilities&CODEC_CAP_HWACCEL_VDPAU)
>         && s->unrestricted_mv
>         && s->current_picture.reference
>         && !s->intra_only
> diff --git a/libavcodec/utils.c b/libavcodec/utils.c
> index 215029d..90a23c3 100644
> --- a/libavcodec/utils.c
> +++ b/libavcodec/utils.c
> @@ -391,7 +391,9 @@ int avcodec_default_execute(AVCodecContext *c, int (*func)(AVCodecContext *c2, v
>      return 0;
>  }
>  
> -enum PixelFormat avcodec_default_get_format(struct AVCodecContext *s, const enum PixelFormat * fmt){
> +enum PixelFormat avcodec_default_get_format(struct AVCodecContext *s, const enum PixelFormat *fmt){
> +    while (*fmt != PIX_FMT_NONE && ff_is_hwaccel_pix_fmt(*fmt))
> +        ++fmt;
>      return fmt[0];
>  }
>  

2 hunks ok


[...]
> +AVHWAccel *ff_query_hwaccel_codec(AVCodecContext *avctx, enum CodecID codec_id)
> +{
> +    AVHWAccel *hwaccel;
> +    AVHWAccel *hwaccels[PIX_FMT_NB] = { NULL, };
> +    enum PixelFormat pix_fmts[PIX_FMT_NB + 1];
> +    int pix_fmt, n_pix_fmts = 0;
> +
> +    for (hwaccel = first_hwaccel; hwaccel; hwaccel = hwaccel->next) {
> +        if (hwaccel->id == codec_id) {
> +            hwaccels[hwaccel->pix_fmt] = hwaccel;
> +            pix_fmts[n_pix_fmts++] = hwaccel->pix_fmt;
> +        }
> +    }
> +    if (n_pix_fmts == 0)
> +        return NULL;
> +    pix_fmts[n_pix_fmts] = PIX_FMT_NONE;
> +

> +    /* The default ::get_format() filters out HW accelerated formats */
> +    if ((pix_fmt = avctx->get_format(avctx, pix_fmts)) != PIX_FMT_NONE)
> +        return hwaccels[pix_fmt];
> +    return NULL;
> +}

the PIX_FMT_NONE check seems useless using pix_fmt+1 as index seems to achive
the same

[...]
-- 
Michael     GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB

The educated differ from the uneducated as much as the living from the
dead. -- Aristotle 
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: Digital signature
URL: <http://lists.mplayerhq.hu/pipermail/ffmpeg-devel/attachments/20090220/2a5405e0/attachment.pgp>



More information about the ffmpeg-devel mailing list