[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