[FFmpeg-devel] [PATCH 1/2] avcodec: Add interface to motion estimation
Michael Niedermayer
michaelni at gmx.at
Sun Aug 30 04:23:58 CEST 2015
From: Michael Niedermayer <michael at niedermayer.cc>
This is needed for vf_mcfps, no codec related structs are part of the
public interface
Signed-off-by: Michael Niedermayer <michael at niedermayer.cc>
---
libavcodec/Makefile | 2 +-
libavcodec/avme.c | 138 +++++++++++++++++++++++++++++++++++++++++++++++++
libavcodec/avme.h | 30 +++++++++++
libavcodec/internal.h | 2 +
libavcodec/snow.c | 30 +++++++++++
libavcodec/version.h | 2 +-
6 files changed, 202 insertions(+), 2 deletions(-)
create mode 100644 libavcodec/avme.c
create mode 100644 libavcodec/avme.h
diff --git a/libavcodec/Makefile b/libavcodec/Makefile
index 407c6c3..43079b6 100644
--- a/libavcodec/Makefile
+++ b/libavcodec/Makefile
@@ -468,7 +468,7 @@ OBJS-$(CONFIG_SMC_DECODER) += smc.o
OBJS-$(CONFIG_SMVJPEG_DECODER) += smvjpegdec.o
OBJS-$(CONFIG_SNOW_DECODER) += snowdec.o snow.o snow_dwt.o
OBJS-$(CONFIG_SNOW_ENCODER) += snowenc.o snow.o snow_dwt.o \
- h263.o ituh263enc.o
+ h263.o ituh263enc.o avme.o
OBJS-$(CONFIG_SOL_DPCM_DECODER) += dpcm.o
OBJS-$(CONFIG_SONIC_DECODER) += sonic.o
OBJS-$(CONFIG_SONIC_ENCODER) += sonic.o
diff --git a/libavcodec/avme.c b/libavcodec/avme.c
new file mode 100644
index 0000000..36a1e57
--- /dev/null
+++ b/libavcodec/avme.c
@@ -0,0 +1,138 @@
+/*
+ * Copyright (C) 2015 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 "libavutil/avassert.h"
+
+#include "avcodec.h"
+#include "avme.h"
+#include "internal.h"
+
+typedef struct AVMEContext {
+ AVCodecContext *avctx;
+ uint8_t *outbuf;
+ int outbuf_size;
+} AVMEContext;
+
+AVMEContext *av_me_init(int width, int height, enum AVPixelFormat pix_fmt, AVDictionary *dict)
+{
+ AVMEContext *c = av_mallocz(sizeof(*c));
+ AVCodecContext *avctx_enc;
+ AVDictionary *opts = NULL;
+ AVDictionaryEntry *e;
+ AVCodec *enc = avcodec_find_encoder(AV_CODEC_ID_SNOW);
+ int ret;
+
+ if (!c)
+ return NULL;
+
+ if (!enc) {
+ av_log(NULL, AV_LOG_ERROR, "SNOW encoder not found.\n");
+ ret = AVERROR(EINVAL);
+ goto fail;
+ }
+
+ av_dict_copy(&opts, dict, 0);
+
+ if (!(c->avctx = avcodec_alloc_context3(NULL))) {
+ ret = AVERROR(ENOMEM);
+ goto fail;
+ }
+
+ avctx_enc = c->avctx;
+ avctx_enc->width = width;
+ avctx_enc->height = height;
+ avctx_enc->time_base = (AVRational){1,25};
+
+ e = av_dict_get(dict, "g", NULL, 0);
+ if (e) {
+ avctx_enc->gop_size = atoi(e->value);
+ } else
+ avctx_enc->gop_size = INT_MAX;
+
+ avctx_enc->max_b_frames = 0;
+ avctx_enc->pix_fmt = pix_fmt;
+ avctx_enc->flags = CODEC_FLAG_QSCALE | CODEC_FLAG_LOW_DELAY;
+ if (av_dict_get(dict, "qpel", NULL, 0))
+ avctx_enc->flags |= CODEC_FLAG_QPEL;
+ avctx_enc->strict_std_compliance = FF_COMPLIANCE_EXPERIMENTAL;
+ avctx_enc->global_quality = 12;
+ avctx_enc->me_method = ME_ITER;
+// avctx_enc->dia_size = 16;
+ avctx_enc->mb_decision = FF_MB_DECISION_RD;
+ avctx_enc->scenechange_threshold = 2000000000;
+ avctx_enc->me_sub_cmp =
+ avctx_enc->me_cmp = FF_CMP_SATD;
+ avctx_enc->mb_cmp = FF_CMP_SSE;
+
+ av_dict_set(&opts, "no_bitstream", "1", 0);
+ av_dict_set(&opts, "intra_penalty", "500", 0);
+ ret = avcodec_open2(avctx_enc, enc, &opts);
+ av_dict_free(&opts);
+ if (ret < 0)
+ goto fail;
+ av_assert0(avctx_enc->codec);
+
+ c->outbuf_size = (width + 16) * (height + 16) * 10;
+ if (!(c->outbuf = av_malloc(c->outbuf_size)))
+ goto fail;
+
+ return c;
+fail:
+ av_me_free(&c);
+
+ return NULL;
+}
+
+int av_me_add_frame(struct AVMEContext *c, AVFrame *frame, int refonly)
+{
+ int ret;
+ AVPacket pkt = {0};
+ int got_pkt_ptr;
+
+ av_init_packet(&pkt);
+ pkt.data = c->outbuf;
+ pkt.size = c->outbuf_size;
+
+ ret = avcodec_encode_video2(c->avctx, &pkt, frame, &got_pkt_ptr);
+ av_free_packet(&pkt);
+
+ return ret;
+}
+
+int av_me_get_mvs(struct AVMEContext *c, int16_t (*mvs)[2], int8_t *refs, int width, int height)
+{
+ switch (c->avctx->codec_id) {
+ case AV_CODEC_ID_SNOW:
+ return ff_get_mvs_snow(c->avctx, mvs, refs, width, height);
+ default:
+ return AVERROR(EINVAL);
+ }
+}
+
+void av_me_free(struct AVMEContext **c)
+{
+ if (*c) {
+ avcodec_close((*c)->avctx);
+ av_freep(&(*c)->avctx);
+ av_freep(&(*c)->outbuf);
+ (*c)->outbuf_size = 0;
+ }
+ av_freep(c);
+}
diff --git a/libavcodec/avme.h b/libavcodec/avme.h
new file mode 100644
index 0000000..d85144c
--- /dev/null
+++ b/libavcodec/avme.h
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2015 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 "libavutil/dict.h"
+#include "libavutil/frame.h"
+
+struct AVMEContext *av_me_init(int width, int height, enum AVPixelFormat pix_fmt, AVDictionary *dict);
+
+int av_me_add_frame(struct AVMEContext *c, AVFrame *frame, int refonly);
+
+int av_me_get_mvs(struct AVMEContext *c, int16_t (*mvs)[2], int8_t *refs, int width, int height);
+
+void av_me_free(struct AVMEContext **c);
diff --git a/libavcodec/internal.h b/libavcodec/internal.h
index f93a196..da3c6aa 100644
--- a/libavcodec/internal.h
+++ b/libavcodec/internal.h
@@ -303,4 +303,6 @@ int ff_decode_frame_props(AVCodecContext *avctx, AVFrame *frame);
int ff_side_data_set_encoder_stats(AVPacket *pkt, int quality, int64_t *error, int error_count, int pict_type);
+int ff_get_mvs_snow(AVCodecContext *avctx, int16_t (*mvs)[2], int8_t *refs, int w, int h);
+
#endif /* AVCODEC_INTERNAL_H */
diff --git a/libavcodec/snow.c b/libavcodec/snow.c
index fc2e727..de4d816 100644
--- a/libavcodec/snow.c
+++ b/libavcodec/snow.c
@@ -731,3 +731,33 @@ av_cold void ff_snow_common_end(SnowContext *s)
av_frame_free(&s->mconly_picture);
av_frame_free(&s->current_picture);
}
+
+int ff_get_mvs_snow(AVCodecContext *avctx, int16_t (*mvs)[2], int8_t *refs, int w, int h)
+{
+ SnowContext *s = avctx->priv_data;
+ const int b_width = s->b_width << s->block_max_depth;
+ const int b_height = s->b_height << s->block_max_depth;
+ const int b_stride= b_width;
+ int x, y;
+
+ if (w != b_width || h != b_height) {
+ av_log(avctx, AV_LOG_ERROR, "mvs array dimensions mismatch %dx%d != %dx%d\n",
+ w, h, b_width, b_height);
+ return AVERROR(EINVAL);
+ }
+
+ for (y=0; y<h; y++) {
+ for (x=0; x<w; x++) {
+ BlockNode *bn= &s->block[x + y*b_stride];
+ if (bn->type) {
+ refs[x + y*w] = -1;
+ } else {
+ refs[x + y*w] = bn->ref;
+ mvs[x + y*w][0] = bn->mx;
+ mvs[x + y*w][1] = bn->my;
+ }
+ }
+ }
+
+ return 0;
+}
diff --git a/libavcodec/version.h b/libavcodec/version.h
index e098dde..6dbeeff 100644
--- a/libavcodec/version.h
+++ b/libavcodec/version.h
@@ -29,7 +29,7 @@
#include "libavutil/version.h"
#define LIBAVCODEC_VERSION_MAJOR 56
-#define LIBAVCODEC_VERSION_MINOR 59
+#define LIBAVCODEC_VERSION_MINOR 60
#define LIBAVCODEC_VERSION_MICRO 100
#define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \
--
1.7.9.5
More information about the ffmpeg-devel
mailing list