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

Michael Niedermayer michaelni at gmx.at
Sat Oct 12 18:44:32 CEST 2013


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;
+
+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,
+};
+
+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



More information about the ffmpeg-devel mailing list