[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