[FFmpeg-devel] [PATCH 7/7] lavc: add libopenhevc support

Timothy Gu timothygu99 at gmail.com
Sat Oct 12 22:55:43 CEST 2013


The review is only a review. I am against applying the patch itself.

On Oct 12, 2013 9:46 AM, "Michael Niedermayer" <michaelni at gmx.at> wrote:
>
> Signed-off-by: Michael Niedermayer <michaelni at gmx.at>
> ---
>  configure                |    4 ++
>  libavcodec/Makefile      |    1 +
>  libavcodec/allcodecs.c   |    1 +
>  libavcodec/libopenhevc.c |  127
++++++++++++++++++++++++++++++++++++++++++++++
>  4 files changed, 133 insertions(+)
>  create mode 100644 libavcodec/libopenhevc.c
>
> diff --git a/configure b/configure
> index f419f41..4319968 100755
> --- a/configure
> +++ b/configure
> @@ -217,6 +217,7 @@ External library support:
>    --enable-libopencore-amrnb enable AMR-NB de/encoding via
libopencore-amrnb [no]
>    --enable-libopencore-amrwb enable AMR-WB decoding via
libopencore-amrwb [no]
>    --enable-libopencv       enable video filtering via libopencv [no]
> +  --enable-libopenhevc     enable HEVC decoding via OpenHEVC [no]
>    --enable-libopenjpeg     enable JPEG 2000 de/encoding via OpenJPEG [no]
>    --enable-libopus         enable Opus decoding via libopus [no]
>    --enable-libpulse        enable Pulseaudio input via libpulse [no]
> @@ -1186,6 +1187,7 @@ EXTERNAL_LIBRARY_LIST="
>      libopencore_amrnb
>      libopencore_amrwb
>      libopencv
> +    libopenhevc
>      libopenjpeg
>      libopus
>      libpulse
> @@ -2019,6 +2021,7 @@ libopencore_amrnb_decoder_deps="libopencore_amrnb"
>  libopencore_amrnb_encoder_deps="libopencore_amrnb"
>  libopencore_amrnb_encoder_select="audio_frame_queue"
>  libopencore_amrwb_decoder_deps="libopencore_amrwb"
> +libopenhevc_decoder_deps="libopenhevc"
>  libopenjpeg_decoder_deps="libopenjpeg"
>  libopenjpeg_encoder_deps="libopenjpeg"
>  libopus_decoder_deps="libopus"
> @@ -4249,6 +4252,7 @@ enabled libnut            && require libnut
libnut.h nut_demuxer_init -lnut
>  enabled libopencore_amrnb && require libopencore_amrnb
opencore-amrnb/interf_dec.h Decoder_Interface_init -lopencore-amrnb
>  enabled libopencore_amrwb && require libopencore_amrwb
opencore-amrwb/dec_if.h D_IF_init -lopencore-amrwb
>  enabled libopencv         && require_pkg_config opencv opencv/cxcore.h
cvCreateImageHeader
> +enabled libopenhevc       && require libopenhevc openHevcWrapper.h
libOpenHevcDecode -lLibOpenHevcWrapper -lm
>  enabled libopenjpeg       && { check_lib openjpeg-1.5/openjpeg.h
opj_version -lopenjpeg ||
>                                 check_lib openjpeg.h opj_version
-lopenjpeg ||
>                                 die "ERROR: libopenjpeg not found"; }
> diff --git a/libavcodec/Makefile b/libavcodec/Makefile
> index d46c546..5f98c1a 100644
> --- a/libavcodec/Makefile
> +++ b/libavcodec/Makefile
> @@ -702,6 +702,7 @@ OBJS-$(CONFIG_LIBMP3LAME_ENCODER)         +=
libmp3lame.o mpegaudiodecheader.o
>  OBJS-$(CONFIG_LIBOPENCORE_AMRNB_DECODER)  += libopencore-amr.o
>  OBJS-$(CONFIG_LIBOPENCORE_AMRNB_ENCODER)  += libopencore-amr.o
>  OBJS-$(CONFIG_LIBOPENCORE_AMRWB_DECODER)  += libopencore-amr.o
> +OBJS-$(CONFIG_LIBOPENHEVC_DECODER)        += libopenhevc.o
>  OBJS-$(CONFIG_LIBOPENJPEG_DECODER)        += libopenjpegdec.o
>  OBJS-$(CONFIG_LIBOPENJPEG_ENCODER)        += libopenjpegenc.o
>  OBJS-$(CONFIG_LIBOPUS_DECODER)            += libopusdec.o libopus.o     \
> diff --git a/libavcodec/allcodecs.c b/libavcodec/allcodecs.c
> index e20c9cd..81253b0 100644
> --- a/libavcodec/allcodecs.c
> +++ b/libavcodec/allcodecs.c
> @@ -488,6 +488,7 @@ void avcodec_register_all(void)
>      REGISTER_ENCODER(LIBMP3LAME,        libmp3lame);
>      REGISTER_ENCDEC (LIBOPENCORE_AMRNB, libopencore_amrnb);
>      REGISTER_DECODER(LIBOPENCORE_AMRWB, libopencore_amrwb);
> +    REGISTER_DECODER(LIBOPENHEVC,       libopenhevc);
>      REGISTER_ENCDEC (LIBOPENJPEG,       libopenjpeg);
>      REGISTER_ENCDEC (LIBOPUS,           libopus);
>      REGISTER_ENCDEC (LIBSCHROEDINGER,   libschroedinger);
> diff --git a/libavcodec/libopenhevc.c b/libavcodec/libopenhevc.c
> new file mode 100644
> index 0000000..bebb4b7
> --- /dev/null
> +++ b/libavcodec/libopenhevc.c
> @@ -0,0 +1,127 @@
> +/*
> + * Interface to openHEVC for decoding HEVC
> + * Copyright (c) 2013 Michael Niedermayer <michaelni at gmx.at>
> + *
> + * 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 <openHevcWrapper.h>
> +#include "avcodec.h"
> +#include "internal.h"
> +#include "libavutil/imgutils.h"
> +#include "libavutil/opt.h"
> +
> +typedef struct Context {
> +    OpenHevc_Handle handle;
> +}Context;

More descriptive name

> +
> +static av_cold int openhevc_free(AVCodecContext *avctx)
> +{
> +    Context *c = avctx->priv_data;
> +
> +    libOpenHevcClose(c->handle);
> +    c->handle = NULL;
> +    return 0;
> +}
> +
> +static av_cold int openhevc_init(AVCodecContext *avctx)
> +{
> +    Context *c = avctx->priv_data;
> +
> +    c->handle = libOpenHevcInit(avctx->thread_count);
> +    if (!c->handle) {
> +        av_log(avctx, AV_LOG_ERROR, "libOpenHevcInit failed\n");
> +        return AVERROR_EXTERNAL;
> +    }
> +
> +    libOpenHevcSetNoCropping(c->handle, !!(avctx->flags2 &
CODEC_FLAG2_IGNORE_CROP));
> +
> +    return 0;
> +}
> +
> +static int openhevc_decode(AVCodecContext *avctx,
> +                           void *data, int *got_frame, AVPacket *avpkt)
> +{
> +    Context *c = avctx->priv_data;
> +    AVFrame *picture = data;
> +    int ret;
> +    OpenHevc_Frame openHevcFrame;
> +
> +    ret = libOpenHevcDecode(c->handle, avpkt->data, avpkt->size,
avpkt->pts);
> +    if (ret < 0) {
> +        av_log(avctx, AV_LOG_ERROR, "Failed to decode frame\n");
> +        return AVERROR_EXTERNAL;
> +    }
> +
> +    if (ret) {
> +        const uint8_t *data_ptr_array[4] = {NULL};
> +        int stride_array[4] = {0};
> +
> +        libOpenHevcGetOutput(c->handle, 1, &openHevcFrame);
> +        libOpenHevcGetPictureSize2(c->handle, &openHevcFrame.frameInfo);
> +
> +        if (av_image_check_size(openHevcFrame.frameInfo.nWidth,
openHevcFrame.frameInfo.nHeight, 0, avctx))
> +            return AVERROR_INVALIDDATA;
> +
> +        avctx->pix_fmt = AV_PIX_FMT_YUV420P;
> +        avcodec_set_dimensions(avctx, openHevcFrame.frameInfo.nWidth,
openHevcFrame.frameInfo.nHeight);
> +
> +        if ((ret = ff_get_buffer(avctx, picture, 0)) < 0)
> +            return ret;
> +        picture->sample_aspect_ratio.num =
openHevcFrame.frameInfo.sample_aspect_ratio.num;
> +        picture->sample_aspect_ratio.den =
openHevcFrame.frameInfo.sample_aspect_ratio.den;
> +
> +        data_ptr_array[0] = openHevcFrame.pvY;
> +        data_ptr_array[1] = openHevcFrame.pvU;
> +        data_ptr_array[2] = openHevcFrame.pvV;
> +        stride_array[0] = openHevcFrame.frameInfo.nYPitch;
> +        stride_array[1] = openHevcFrame.frameInfo.nUPitch;
> +        stride_array[2] = openHevcFrame.frameInfo.nVPitch;
> +
> +        av_image_copy(picture->data, picture->linesize, data_ptr_array,
> +                      stride_array, avctx->pix_fmt, picture->width,
picture->height);
> +
> +        *got_frame = 1;
> +    }
> +    return avpkt->size;
> +}
> +

> +#define OFFSET(x) offsetof(struct Context, x)
> +#define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM
> +static const AVOption options[] = {
> +    { NULL },
> +}
> +
> +static const AVClass openhevc_class = {
> +    .class_name = "libopenhevc",
> +    .item_name  = av_default_item_name,
> +    .option     = options,
> +    .version    = LIBAVUTIL_VERSION_INT,
> +};

No need in these. If there is to be some private options in the future,
then they should be added at that time.

> +
> +AVCodec ff_libopenhevc_decoder = {
> +    .name           = "libopenhevc",
> +    .long_name      = NULL_IF_CONFIG_SMALL("libopenhevc HEVC decoder"),
> +    .type           = AVMEDIA_TYPE_VIDEO,
> +    .id             = AV_CODEC_ID_HEVC,
> +    .priv_data_size = sizeof(Context),
> +    .init           = openhevc_init,
> +    .close          = openhevc_free,
> +    .decode         = openhevc_decode,
> +    .capabilities   = CODEC_CAP_DELAY | CODEC_CAP_DR1,
> +    .priv_class     = &openhevc_class,
> +};
> --
> 1.7.9.5
>
> _______________________________________________
> ffmpeg-devel mailing list
> ffmpeg-devel at ffmpeg.org
> http://ffmpeg.org/mailman/listinfo/ffmpeg-devel


More information about the ffmpeg-devel mailing list