[FFmpeg-devel] [PATCH v5 4/4] lavc, doc, configure: add avs2 video decoder

Steven Liu lingjiujianke at gmail.com
Tue Jul 3 06:38:03 EEST 2018


hwren <hwrenx at 126.com> 于2018年7月3日周二 上午10:34写道:
>
> Signed-off-by: hwren <hwrenx at 126.com>
> ---
>  Changelog              |   1 +
>  configure              |   4 ++
>  doc/decoders.texi      |  10 +++
>  doc/general.texi       |   8 +++
>  libavcodec/Makefile    |   1 +
>  libavcodec/allcodecs.c |   1 +
>  libavcodec/libdavs2.c  | 172 +++++++++++++++++++++++++++++++++++++++++++++++++
>  7 files changed, 197 insertions(+)
>  create mode 100644 libavcodec/libdavs2.c
>
> diff --git a/Changelog b/Changelog
> index d8e2811..ec65f43 100644
> --- a/Changelog
> +++ b/Changelog
> @@ -13,6 +13,7 @@ version <next>:
>  - adeclip filter
>  - libtensorflow backend for DNN based filters like srcnn
>  - vc1 decoder is now bit-exact
> +- AVS2 video decoder via libdavs2
>
>
>  version 4.0:
> diff --git a/configure b/configure
> index 0e8e8a6..059812f 100755
> --- a/configure
> +++ b/configure
> @@ -226,6 +226,7 @@ External library support:
>    --enable-libcelt         enable CELT decoding via libcelt [no]
>    --enable-libcdio         enable audio CD grabbing with libcdio [no]
>    --enable-libcodec2       enable codec2 en/decoding using libcodec2 [no]
> +  --enable-libdavs2        enable AVS2 decoding via libdavs2 [no]
>    --enable-libdc1394       enable IIDC-1394 grabbing using libdc1394
>                             and libraw1394 [no]
>    --enable-libfdk-aac      enable AAC de/encoding via libfdk-aac [no]
> @@ -1638,6 +1639,7 @@ EXTERNAL_LIBRARY_GPL_LIST="
>      avisynth
>      frei0r
>      libcdio
> +    libdavs2
>      librubberband
>      libvidstab
>      libx264
> @@ -3048,6 +3050,7 @@ libaom_av1_encoder_deps="libaom"
>  libcelt_decoder_deps="libcelt"
>  libcodec2_decoder_deps="libcodec2"
>  libcodec2_encoder_deps="libcodec2"
> +libdavs2_decoder_deps="libdavs2"
>  libfdk_aac_decoder_deps="libfdk_aac"
>  libfdk_aac_encoder_deps="libfdk_aac"
>  libfdk_aac_encoder_select="audio_frame_queue"
> @@ -6001,6 +6004,7 @@ enabled libcelt           && require libcelt celt/celt.h celt_decode -lcelt0 &&
>                                 die "ERROR: libcelt must be installed and version must be >= 0.11.0."; }
>  enabled libcaca           && require_pkg_config libcaca caca caca.h caca_create_canvas
>  enabled libcodec2         && require libcodec2 codec2/codec2.h codec2_create -lcodec2
> +enabled libdavs2          && require_pkg_config libdavs2 "davs2 >= 1.4.95" davs2.h davs2_decoder_open
>  enabled libdc1394         && require_pkg_config libdc1394 libdc1394-2 dc1394/dc1394.h dc1394_new
>  enabled libdrm            && require_pkg_config libdrm libdrm xf86drm.h drmGetVersion
>  enabled libfdk_aac        && { check_pkg_config libfdk_aac fdk-aac "fdk-aac/aacenc_lib.h" aacEncOpen ||
> diff --git a/doc/decoders.texi b/doc/decoders.texi
> index 8f07bc1..f119917 100644
> --- a/doc/decoders.texi
> +++ b/doc/decoders.texi
> @@ -47,6 +47,16 @@ top-field-first is assumed
>
>  @end table
>
> + at section libdavs2
> +
> +AVS2/IEEE 1857.4 video decoder wrapper.
> +
> +This decoder allows libavcodec to decode AVS2 streams with libdavs2 library.
> +Using it requires the presence of the libdavs2 headers and library during
> +configuration. You need to explicitly configure the build with @code{--enable-libdavs2}.
> +
> +libdavs2 uses GPLv2, so you may also need to add @code{--enable-gpl} while configuring.
> +
>  @c man end VIDEO DECODERS
>
>  @chapter Audio Decoders
> diff --git a/doc/general.texi b/doc/general.texi
> index 8c3a04b..7e89e95 100644
> --- a/doc/general.texi
> +++ b/doc/general.texi
> @@ -17,6 +17,14 @@ for more formats. None of them are used by default, their use has to be
>  explicitly requested by passing the appropriate flags to
>  @command{./configure}.
>
> + at section libdavs2
> +
> +FFmpeg can make use of the libdavs2 library for AVS2 decoding.
> +
> +Go to @url{https://github.com/pkuvcl/davs2} and follow the instructions for
> +installing the library. Then pass @code{--enable-libdavs2} to configure to
> +enable it.
> +
>  @section Alliance for Open Media libaom
>
>  FFmpeg can make use of the libaom library for AV1 decoding.
> diff --git a/libavcodec/Makefile b/libavcodec/Makefile
> index 6b6d6de..5135b97 100644
> --- a/libavcodec/Makefile
> +++ b/libavcodec/Makefile
> @@ -944,6 +944,7 @@ OBJS-$(CONFIG_LIBAOM_AV1_ENCODER)         += libaomenc.o
>  OBJS-$(CONFIG_LIBCELT_DECODER)            += libcelt_dec.o
>  OBJS-$(CONFIG_LIBCODEC2_DECODER)          += libcodec2.o codec2utils.o
>  OBJS-$(CONFIG_LIBCODEC2_ENCODER)          += libcodec2.o codec2utils.o
> +OBJS-$(CONFIG_LIBDAVS2_DECODER)           += libdavs2.o
>  OBJS-$(CONFIG_LIBFDK_AAC_DECODER)         += libfdk-aacdec.o
>  OBJS-$(CONFIG_LIBFDK_AAC_ENCODER)         += libfdk-aacenc.o
>  OBJS-$(CONFIG_LIBGSM_DECODER)             += libgsmdec.o
> diff --git a/libavcodec/allcodecs.c b/libavcodec/allcodecs.c
> index 90d170b..a59b601 100644
> --- a/libavcodec/allcodecs.c
> +++ b/libavcodec/allcodecs.c
> @@ -667,6 +667,7 @@ extern AVCodec ff_libaom_av1_encoder;
>  extern AVCodec ff_libcelt_decoder;
>  extern AVCodec ff_libcodec2_encoder;
>  extern AVCodec ff_libcodec2_decoder;
> +extern AVCodec ff_libdavs2_decoder;
>  extern AVCodec ff_libfdk_aac_encoder;
>  extern AVCodec ff_libfdk_aac_decoder;
>  extern AVCodec ff_libgsm_encoder;
> diff --git a/libavcodec/libdavs2.c b/libavcodec/libdavs2.c
> new file mode 100644
> index 0000000..9eea84c
> --- /dev/null
> +++ b/libavcodec/libdavs2.c
> @@ -0,0 +1,172 @@
> +/*
> + * AVS2 decoding using the davs2 library
> + *
> + * Copyright (C) 2018 Yiqun Xu, <yiqun.xu at vipl.ict.ac.cn>
> + *                    Falei Luo, <falei.luo at gmail.com>
> + *                    Huiwen Ren, <hwrenx at gmail.com>
> + *
> + * 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 "libavutil/avassert.h"
> +#include "libavutil/common.h"
> +#include "libavutil/avutil.h"
> +#include "avcodec.h"
> +#include "libavutil/imgutils.h"
> +#include "internal.h"
> +
> +#include <davs2.h>
> +
> +typedef struct DAVS2Context {
> +    void *decoder;
> +
> +    AVFrame *frame;
> +    davs2_param_t    param;      // decoding parameters
> +    davs2_packet_t   packet;     // input bitstream
> +
> +    int decoded_frames;
> +
> +    davs2_picture_t  out_frame;  // output data, frame data
> +    davs2_seq_info_t headerset;  // output data, sequence header
> +
> +}DAVS2Context;
> +
> +static av_cold int davs2_init(AVCodecContext *avctx)
> +{
> +    DAVS2Context *cad = avctx->priv_data;
> +
> +    /* init the decoder */
> +    cad->param.threads      = avctx->thread_count;
> +    cad->param.i_info_level = 0;
> +    cad->decoder            = davs2_decoder_open(&cad->param);
> +
what about add a davs2_decoder_open failed check, if open failed,
return an error.

> +    av_log(avctx, AV_LOG_VERBOSE, "decoder created. %p\n", cad->decoder);
> +    return 0;
> +}
> +
> +static int davs2_dump_frames(AVCodecContext *avctx, davs2_picture_t *pic,
> +                             davs2_seq_info_t *headerset, int ret_type, AVFrame *frame)
> +{
> +    DAVS2Context *cad    = avctx->priv_data;
> +    int bytes_per_sample = pic->bytes_per_sample;
> +    int plane = 0;
> +    int line  = 0;
> +
> +    if (!headerset)
> +        return 0;
> +
> +    if (!pic || ret_type == DAVS2_GOT_HEADER) {
> +        avctx->width     = headerset->horizontal_size;
> +        avctx->height    = headerset->vertical_size;
> +        avctx->pix_fmt   = headerset->output_bitdepth == 10 ?
> +                           AV_PIX_FMT_YUV420P10 : AV_PIX_FMT_YUV420P;
> +
> +        avctx->framerate = av_d2q(headerset->frame_rate,4096);
> +        return 0;
> +    }
> +
> +    for (plane = 0; plane < 3; ++plane) {
> +        int size_line = pic->widths[plane] * bytes_per_sample;
> +        frame->buf[plane]  = av_buffer_alloc(size_line * pic->lines[plane]);
> +
> +        if (!frame->buf[plane]){
> +            av_log(avctx, AV_LOG_ERROR, "dump error: alloc failed.\n");
> +            return AVERROR(EINVAL);
> +        }
> +
> +        frame->data[plane]     = frame->buf[plane]->data;
> +        frame->linesize[plane] = pic->widths[plane];
> +
> +        for (line = 0; line < pic->lines[plane]; ++line)
> +            memcpy(frame->data[plane] + line * size_line,
> +                   pic->planes[plane] + line * pic->strides[plane],
> +                   pic->widths[plane] * bytes_per_sample);
> +    }
> +
> +    frame->width     = cad->headerset.horizontal_size;
> +    frame->height    = cad->headerset.vertical_size;
> +    frame->pts       = cad->out_frame.pts;
> +    frame->pict_type = pic->type;
> +    frame->format    = avctx->pix_fmt;
> +
> +    cad->decoded_frames++;
> +    return 1;
> +}
> +
> +static av_cold int davs2_end(AVCodecContext *avctx)
> +{
> +    DAVS2Context *cad = avctx->priv_data;
> +
> +    /* close the decoder */
> +    if (cad->decoder) {
> +        davs2_decoder_close(cad->decoder);
> +        cad->decoder = NULL;
> +    }
> +
> +    return 0;
> +}
> +
> +static int davs2_decode_frame(AVCodecContext *avctx, void *data,
> +                              int *got_frame, AVPacket *avpkt)
> +{
> +    DAVS2Context *cad      = avctx->priv_data;
> +    int           buf_size = avpkt->size;
> +    uint8_t      *buf_ptr  = avpkt->data;
> +    AVFrame      *frame    = data;
> +    int           ret      = DAVS2_DEFAULT;
> +
> +    if (!buf_size) {
> +        return 0;
> +    }
> +
> +    cad->packet.data = buf_ptr;
> +    cad->packet.len  = buf_size;
> +    cad->packet.pts  = avpkt->pts;
> +    cad->packet.dts  = avpkt->dts;
> +
> +    ret = davs2_decoder_send_packet(cad->decoder, &cad->packet);
> +
> +
> +    if (ret == DAVS2_ERROR) {
only and DAVS2_ERROR? Do there have other error value min than 0?
> +        av_log(avctx, AV_LOG_ERROR, "Decoder error: can't read packet\n");
> +        return AVERROR(EINVAL);
> +    }
> +
> +    ret = davs2_decoder_recv_frame(cad->decoder, &cad->headerset, &cad->out_frame);
> +
> +    if (ret != DAVS2_DEFAULT) {
> +        *got_frame = davs2_dump_frames(avctx, &cad->out_frame, &cad->headerset, ret, frame);
> +        davs2_decoder_frame_unref(cad->decoder, &cad->out_frame);
> +    }
> +
> +    return buf_size;
> +}
> +
> +AVCodec ff_libdavs2_decoder = {
> +    .name           = "libdavs2",
> +    .long_name      = NULL_IF_CONFIG_SMALL("Decoder for AVS2/IEEE 1857.4"),
> +    .type           = AVMEDIA_TYPE_VIDEO,
> +    .id             = AV_CODEC_ID_AVS2,
> +    .priv_data_size = sizeof(DAVS2Context),
> +    .init           = davs2_init,
> +    .close          = davs2_end,
> +    .decode         = davs2_decode_frame,
> +    .capabilities   =  AV_CODEC_CAP_DELAY,//AV_CODEC_CAP_DR1 |
> +    .pix_fmts       = (const enum AVPixelFormat[]) { AV_PIX_FMT_YUV420P, AV_PIX_FMT_YUV420P10,
> +                                                     AV_PIX_FMT_NONE },
> +    .wrapper_name   = "libdavs2",
> +};
> --
> 2.7.4
>
> _______________________________________________
> ffmpeg-devel mailing list
> ffmpeg-devel at ffmpeg.org
> http://ffmpeg.org/mailman/listinfo/ffmpeg-devel


More information about the ffmpeg-devel mailing list