[FFmpeg-devel] [PATCH 1/2] avcodec: add code that can merge h264 fields into field pairs.
Michael Niedermayer
michaelni at gmx.at
Mon Mar 10 02:58:33 CET 2014
Signed-off-by: Michael Niedermayer <michaelni at gmx.at>
---
libavcodec/Makefile | 3 +-
libavcodec/h264_merge_fields.c | 102 ++++++++++++++++++++++++++++++++++++++++
libavcodec/h264_merge_fields.h | 41 ++++++++++++++++
libavcodec/version.h | 4 +-
4 files changed, 147 insertions(+), 3 deletions(-)
create mode 100644 libavcodec/h264_merge_fields.c
create mode 100644 libavcodec/h264_merge_fields.h
diff --git a/libavcodec/Makefile b/libavcodec/Makefile
index a5df67f..faba518 100644
--- a/libavcodec/Makefile
+++ b/libavcodec/Makefile
@@ -758,7 +758,8 @@ OBJS-$(CONFIG_H264_PARSER) += h264_parser.o h264.o \
cabac.o \
h264_refs.o h264_sei.o h264_direct.o \
h264_loopfilter.o h264_cabac.o \
- h264_cavlc.o h264_ps.o
+ h264_cavlc.o h264_ps.o \
+ h264_merge_fields.o
OBJS-$(CONFIG_HEVC_PARSER) += hevc_parser.o
OBJS-$(CONFIG_MJPEG_PARSER) += mjpeg_parser.o
OBJS-$(CONFIG_MLP_PARSER) += mlp_parser.o mlp.o
diff --git a/libavcodec/h264_merge_fields.c b/libavcodec/h264_merge_fields.c
new file mode 100644
index 0000000..2eceb1e
--- /dev/null
+++ b/libavcodec/h264_merge_fields.c
@@ -0,0 +1,102 @@
+/*
+ *
+ * Copyright (c) 2014 Michael Niedermayer
+ *
+ * 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 "h264_merge_fields.h"
+#include "h264.h"
+
+struct H264MergeFieldsContext {
+ AVCodecParserContext *parser;
+ AVPacket pkt;
+ int is_field;
+ int fnum;
+};
+
+struct H264MergeFieldsContext *avpriv_h264_merge_fields_init(void)
+{
+ struct H264MergeFieldsContext *c = av_mallocz(sizeof(*c));
+ if (!c)
+ return NULL;
+ c->parser = av_parser_init(AV_CODEC_ID_H264);
+ if (!c->parser) {
+ av_free(c);
+ return NULL;
+ }
+ c->parser->flags |= PARSER_FLAG_COMPLETE_FRAMES;
+
+ return c;
+}
+
+void avpriv_h264_merge_fields_free(struct H264MergeFieldsContext **cc)
+{
+ if (cc) {
+ struct H264MergeFieldsContext *c = *cc;
+
+ if (c) {
+ av_free_packet(&c->pkt);
+ av_parser_close(c->parser);
+ c->parser = NULL;
+ }
+ av_freep(cc);
+ }
+}
+
+int avpriv_h264_merge_fields(struct H264MergeFieldsContext *c, AVCodecContext *avctx,
+ AVPacket *pkt)
+{
+ H264Context *h;
+ int prev_field = c->is_field;
+ int prev_fnum = c->fnum;
+ int ret, len, outsize, is_field, fnum;
+ uint8_t *outbuf;
+
+ av_dup_packet(pkt);
+
+ len = av_parser_parse2(c->parser, avctx,
+ &outbuf, &outsize,
+ pkt->data, pkt->size,
+ pkt->pts, pkt->dts, pkt->pos);
+ h = c->parser->priv_data;
+ c->is_field = is_field = (h->picture_structure != PICT_FRAME);
+ c->fnum = fnum = h->frame_num;
+
+ if (c->pkt.size) {
+ if ((!is_field) || (!prev_field) || fnum != prev_fnum) {
+ av_log(avctx, AV_LOG_WARNING, "cannot merge fields, flushing previous packet\n");
+ FFSWAP(AVPacket, *pkt, c->pkt);
+ return 1;
+ }
+ if ((ret = av_grow_packet(&c->pkt, pkt->size))<0)
+ return ret;
+ memcpy(c->pkt.data + c->pkt.size - pkt->size, pkt->data, pkt->size);
+ av_free_packet(pkt);
+ *pkt = c->pkt;
+ memset(&c->pkt, 0, sizeof(c->pkt));
+ return 1;
+ }
+
+ if (is_field) {
+ c->pkt = *pkt;
+ memset(pkt, 0, sizeof(*pkt));
+ return 0;
+ }
+
+ return 1;
+}
\ No newline at end of file
diff --git a/libavcodec/h264_merge_fields.h b/libavcodec/h264_merge_fields.h
new file mode 100644
index 0000000..9698d04
--- /dev/null
+++ b/libavcodec/h264_merge_fields.h
@@ -0,0 +1,41 @@
+/*
+ *
+ * Copyright (c) 2014 Michael Niedermayer
+ *
+ * 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 "avcodec.h"
+
+/**
+ * Allocate and initialize H264MergeFields.
+ */
+struct H264MergeFieldsContext *avpriv_h264_merge_fields_init(void);
+
+/**
+ * Deallocate H264MergeFields.
+ */
+void avpriv_h264_merge_fields_free(struct H264MergeFieldsContext **cc);
+
+/**
+ * Merge the fields from the given input packets.
+ *
+ * @return 0 if no packet is output, 1 if a packet is output, or a negative
+ * error code.
+ */
+int avpriv_h264_merge_fields(struct H264MergeFieldsContext *c, AVCodecContext *avctx,
+ AVPacket *pkt);
diff --git a/libavcodec/version.h b/libavcodec/version.h
index 61a7968..e01d9ef 100644
--- a/libavcodec/version.h
+++ b/libavcodec/version.h
@@ -29,8 +29,8 @@
#include "libavutil/version.h"
#define LIBAVCODEC_VERSION_MAJOR 55
-#define LIBAVCODEC_VERSION_MINOR 52
-#define LIBAVCODEC_VERSION_MICRO 102
+#define LIBAVCODEC_VERSION_MINOR 53
+#define LIBAVCODEC_VERSION_MICRO 100
#define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \
LIBAVCODEC_VERSION_MINOR, \
--
1.7.9.5
More information about the ffmpeg-devel
mailing list