From: Michael Niedermayer <mich...@niedermayer.cc> This is needed for vf_mcfps, no codec related structs are part of the public interface
Signed-off-by: Michael Niedermayer <mich...@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 <michae...@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 <michae...@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 _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel