[FFmpeg-devel] [PATCH] libavformat/keyframes: output keyframe indexes
Jonathan Viney
jonathan.viney at gmail.com
Sun May 3 16:35:45 CEST 2015
Hi,
First patch here. I wrote this format to be able to get the keyframe
indexes faster than seemed possible with ffprobe, and also to get more
familiar with ffmpeg.
ffmpeg -i input.mkv -c copy -f keyframes -keyframes_filename keyframes.txt
/dev/null
Could something like this be included in ffmpeg? Or is this already
achievable with the current code?
Cheers,
-Jonathan.
---
libavformat/Makefile | 1 +
libavformat/allformats.c | 1 +
libavformat/keyframes.c | 96
++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 98 insertions(+)
create mode 100644 libavformat/keyframes.c
diff --git a/libavformat/Makefile b/libavformat/Makefile
index 8d9a770..b78a753 100644
--- a/libavformat/Makefile
+++ b/libavformat/Makefile
@@ -221,6 +221,7 @@ OBJS-$(CONFIG_IVF_MUXER) += ivfenc.o
OBJS-$(CONFIG_JACOSUB_DEMUXER) += jacosubdec.o subtitles.o
OBJS-$(CONFIG_JACOSUB_MUXER) += jacosubenc.o rawenc.o
OBJS-$(CONFIG_JV_DEMUXER) += jvdec.o
+OBJS-$(CONFIG_KEYFRAMES_MUXER) += keyframes.o
OBJS-$(CONFIG_LATM_DEMUXER) += rawdec.o
OBJS-$(CONFIG_LATM_MUXER) += latmenc.o rawenc.o
OBJS-$(CONFIG_LMLM4_DEMUXER) += lmlm4.o
diff --git a/libavformat/allformats.c b/libavformat/allformats.c
index e6a9d01..f1da759 100644
--- a/libavformat/allformats.c
+++ b/libavformat/allformats.c
@@ -164,6 +164,7 @@ void av_register_all(void)
REGISTER_MUXDEMUX(IVF, ivf);
REGISTER_MUXDEMUX(JACOSUB, jacosub);
REGISTER_DEMUXER (JV, jv);
+ REGISTER_MUXER (KEYFRAMES, keyframes);
REGISTER_MUXDEMUX(LATM, latm);
REGISTER_DEMUXER (LMLM4, lmlm4);
REGISTER_DEMUXER (LOAS, loas);
diff --git a/libavformat/keyframes.c b/libavformat/keyframes.c
new file mode 100644
index 0000000..da6e054
--- /dev/null
+++ b/libavformat/keyframes.c
@@ -0,0 +1,96 @@
+/*
+ * Output keyframe indexes.
+ *
+ * Copyright (c) 2015 Jonathan Viney
+ *
+ * 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 "avformat.h"
+#include "libavutil/opt.h"
+
+typedef struct {
+ const AVClass *class;
+ int frame_count;
+ char *filename;
+ FILE *file;
+} KeyFramesContext;
+
+av_cold static int kf_init(AVFormatContext *s)
+{
+ KeyFramesContext *kf = s->priv_data;
+
+ kf->file = fopen(kf->filename, "w");
+
+ if (kf->file) {
+ av_log(s, AV_LOG_ERROR, "failed opening key frames file: %s\n",
kf->filename);
+ return -1;
+ }
+
+ return 0;
+}
+
+static int kf_write_packet(struct AVFormatContext *s, AVPacket *pkt)
+{
+ KeyFramesContext *kf = s->priv_data;
+
+ if (pkt->flags & AV_PKT_FLAG_KEY) {
+ av_log(s, AV_LOG_DEBUG, "key frame at index %d\n",
kf->frame_count);
+
+ if (fprintf(kf->file, "%d\n", kf->frame_count) < 0) {
+ av_log(s, AV_LOG_ERROR, "failed writing to key frames file\n");
+ return -1;
+ }
+ }
+
+ kf->frame_count++;
+
+ return 0;
+}
+
+av_cold static int kf_uninit(AVFormatContext *s)
+{
+ KeyFramesContext *kf = s->priv_data;
+ fclose(kf->file);
+ kf->file = NULL;
+ return 0;
+}
+
+#define OFFSET(x) offsetof(KeyFramesContext, x)
+static const AVOption options[] = {
+ { "keyframes_filename", "output file for key frame indexes",
OFFSET(filename), AV_OPT_TYPE_STRING, { .str = "keyframes.txt" }, CHAR_MIN,
CHAR_MAX, AV_OPT_FLAG_ENCODING_PARAM },
+ { NULL }
+};
+
+static const AVClass keyframes_class = {
+ .class_name = "keyframes",
+ .item_name = av_default_item_name,
+ .option = options,
+ .version = LIBAVUTIL_VERSION_INT,
+};
+
+AVOutputFormat ff_keyframes_muxer = {
+ .name = "keyframes",
+ .long_name = NULL_IF_CONFIG_SMALL("Output keyframe indexes."),
+ .priv_data_size = sizeof(KeyFramesContext),
+ .flags = AVFMT_NOFILE | AVFMT_GLOBALHEADER,
+ .video_codec = AV_CODEC_ID_RAWVIDEO,
+ .write_header = kf_init,
+ .write_packet = kf_write_packet,
+ .write_trailer = kf_uninit,
+ .priv_class = &keyframes_class
+};
--
2.3.7
More information about the ffmpeg-devel
mailing list