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 _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel