On Tue, 13 Dec 2011 16:09:33 +0100, Luca Barbato <[email protected]> wrote: > It behaves similarly to image2 muxer > --- > Changelog | 1 + > doc/muxers.texi | 32 ++++++ > libavformat/Makefile | 1 + > libavformat/allformats.c | 1 + > libavformat/segment.c | 273 > ++++++++++++++++++++++++++++++++++++++++++++++ > 5 files changed, 308 insertions(+), 0 deletions(-) > create mode 100644 libavformat/segment.c > > diff --git a/Changelog b/Changelog > index 0d72c53..96b972f 100644 > --- a/Changelog > +++ b/Changelog > @@ -107,6 +107,7 @@ easier to use. The changes are: > - PCM format support in OMA demuxer > - CLJR encoder > - Dxtory capture format decoder > +- Simple segmenting muxer > > > version 0.7: > diff --git a/doc/muxers.texi b/doc/muxers.texi > index 17b1de3..5a609c8 100644 > --- a/doc/muxers.texi > +++ b/doc/muxers.texi > @@ -90,6 +90,7 @@ avconv -i INPUT -c:a pcm_u8 -c:v mpeg2video -f framecrc - > > See also the @ref{crc} muxer. > > +@anchor{image2} > @section image2 > > Image file muxer. > @@ -267,4 +268,35 @@ For example a 3D WebM clip can be created using the > following command line: > avconv -i sample_left_right_clip.mpg -an -c:v libvpx -metadata > STEREO_MODE=left_right -y stereo_clip.webm > @end example > > +@section segment > + > +Basic stream segmenter. > + > +The segmenter muxer outputs streams to a number of separate files of nearly > +fixed duration. Output filename pattern can be set in a fashion similar to > +@ref{image2}. > + > +Every segment starts with a video keyframe, if a video stream is present. > +The segment muxer works best with a single constant frame rate video. > + > +Optionally it can generate a flat list of the created segments, one segment > +per line. > + > +@table @option > +@item segment_format @var{format} > +Override the inner container format, by default it is guessed by the filename > +extension. > +@item segment_time @var{t} > +Set segment duration to @var{t} seconds. > +@item segment_list @var{name} > +Generate also a listfile named @var{name}. > +@item segment_list_size @var{size} > +Overwrite the listfile once it reaches @var{size} entries. > +@end table > + > +@example > +avconv -i in.mkv -c copy -map 0 -f segment -list out.list out%03d.nut > +@end example > + > + > @c man end MUXERS > diff --git a/libavformat/Makefile b/libavformat/Makefile > index 9d2e946..4606e2a 100644 > --- a/libavformat/Makefile > +++ b/libavformat/Makefile > @@ -267,6 +267,7 @@ OBJS-$(CONFIG_SAP_DEMUXER) += sapdec.o > OBJS-$(CONFIG_SAP_MUXER) += sapenc.o rtpenc_chain.o > OBJS-$(CONFIG_SDP_DEMUXER) += rtsp.o > OBJS-$(CONFIG_SEGAFILM_DEMUXER) += segafilm.o > +OBJS-$(CONFIG_SEGMENT_MUXER) += segment.o > OBJS-$(CONFIG_SHORTEN_DEMUXER) += rawdec.o > OBJS-$(CONFIG_SIFF_DEMUXER) += siff.o > OBJS-$(CONFIG_SMACKER_DEMUXER) += smacker.o > diff --git a/libavformat/allformats.c b/libavformat/allformats.c > index fe775f4..2e06f81 100644 > --- a/libavformat/allformats.c > +++ b/libavformat/allformats.c > @@ -197,6 +197,7 @@ void av_register_all(void) > av_register_rdt_dynamic_payload_handlers(); > #endif > REGISTER_DEMUXER (SEGAFILM, segafilm); > + REGISTER_MUXER (SEGMENT, segment); > REGISTER_DEMUXER (SHORTEN, shorten); > REGISTER_DEMUXER (SIFF, siff); > REGISTER_DEMUXER (SMACKER, smacker); > diff --git a/libavformat/segment.c b/libavformat/segment.c > new file mode 100644 > index 0000000..034634f > --- /dev/null > +++ b/libavformat/segment.c > @@ -0,0 +1,273 @@ > +/* > + * Generic segmenter > + * Copyright (c) 2011, Luca Barbato > + * > + * This file is part of Libav. > + * > + * Libav 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. > + * > + * Libav 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 Libav; if not, write to the Free Software > + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 > USA > + */ > + > +#include <strings.h> > +#include <float.h> > + > +#include "avformat.h" > +#include "internal.h" > + > +#include "libavutil/log.h" > +#include "libavutil/opt.h" > +#include "libavutil/avstring.h" > +#include "libavutil/parseutils.h" > +#include "libavutil/mathematics.h" > + > +typedef struct { > + const AVClass *class; /**< Class for private options. */ > + int number; > + AVFormatContext *avf; > + char *format; /**< Set by a private option. */ > + char *list; /**< Set by a private option. */ > + float time; /**< Set by a private option. */ > + int size; /**< Set by a private option. */ > + int64_t offset_time; > + int64_t recording_time; > + int has_video; > + AVIOContext *pb; > +} SegmentContext; > + > +static int segment_header(AVFormatContext *s) > +{ > + SegmentContext *c = s->priv_data; > + AVFormatContext *oc = c->avf; > + int err = 0; > + > + if (av_get_frame_filename(oc->filename, sizeof(oc->filename), > + s->filename, c->number++) < 0) > + return AVERROR(EINVAL); > + > + if ((err = avio_open2(&oc->pb, oc->filename, AVIO_FLAG_WRITE, > + &s->interrupt_callback, NULL)) < 0) > + return err; > + > + if (!oc->priv_data && oc->oformat->priv_data_size > 0) { > + oc->priv_data = av_mallocz(oc->oformat->priv_data_size); > + if (!oc->priv_data) { > + avio_close(oc->pb); > + return AVERROR(ENOMEM); > + } > + if (oc->oformat->priv_class) { > + *(const AVClass**)oc->priv_data = oc->oformat->priv_class; > + av_opt_set_defaults(oc->priv_data); > + } > + } > + > + if ((err = oc->oformat->write_header(oc)) < 0) { > + goto fail; > + } > + > + return 0; > + > +fail: > + avio_close(oc->pb); > + av_freep(&oc->priv_data); > + > + return err; > +} > + > +static int segment_trailer(AVFormatContext *oc) > +{ > + int ret = 0; > + > + if (oc->oformat->write_trailer) > + ret = oc->oformat->write_trailer(oc); > + > + avio_close(oc->pb); > + if (oc->oformat->priv_class) > + av_opt_free(oc->priv_data);
The indentation is off. The rest looks good. -- Anton Khirnov _______________________________________________ libav-devel mailing list [email protected] https://lists.libav.org/mailman/listinfo/libav-devel
