[FFmpeg-devel] [PATCH] lavf: add a real SRT muxer.
Nicolas George
nicolas.george at normalesup.org
Sun Jun 17 21:23:11 CEST 2012
This muxer supports CODEC_ID_SRT with the timestamps in the packet data
and CODEC_ID_TEXT with the timestamps in the packet fields.
Makes -scodec copy work from Matroska.
Signed-off-by: Nicolas George <nicolas.george at normalesup.org>
---
libavformat/Makefile | 2 +-
libavformat/rawenc.c | 12 ------
libavformat/srtenc.c | 99 ++++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 100 insertions(+), 13 deletions(-)
create mode 100644 libavformat/srtenc.c
diff --git a/libavformat/Makefile b/libavformat/Makefile
index 5e4f002..2091ffc 100644
--- a/libavformat/Makefile
+++ b/libavformat/Makefile
@@ -309,7 +309,7 @@ OBJS-$(CONFIG_SOX_MUXER) += soxenc.o
OBJS-$(CONFIG_SPDIF_DEMUXER) += spdif.o spdifdec.o
OBJS-$(CONFIG_SPDIF_MUXER) += spdif.o spdifenc.o
OBJS-$(CONFIG_SRT_DEMUXER) += srtdec.o
-OBJS-$(CONFIG_SRT_MUXER) += rawenc.o
+OBJS-$(CONFIG_SRT_MUXER) += srtenc.o
OBJS-$(CONFIG_STR_DEMUXER) += psxstr.o
OBJS-$(CONFIG_SWF_DEMUXER) += swfdec.o
OBJS-$(CONFIG_SWF_MUXER) += swfenc.o
diff --git a/libavformat/rawenc.c b/libavformat/rawenc.c
index 3745620..8be3cc9 100644
--- a/libavformat/rawenc.c
+++ b/libavformat/rawenc.c
@@ -257,18 +257,6 @@ AVOutputFormat ff_rawvideo_muxer = {
};
#endif
-#if CONFIG_SRT_MUXER
-AVOutputFormat ff_srt_muxer = {
- .name = "srt",
- .long_name = NULL_IF_CONFIG_SMALL("SubRip subtitle format"),
- .mime_type = "application/x-subrip",
- .extensions = "srt",
- .write_packet = ff_raw_write_packet,
- .flags = AVFMT_NOTIMESTAMPS,
- .subtitle_codec = CODEC_ID_SRT,
-};
-#endif
-
#if CONFIG_TRUEHD_MUXER
AVOutputFormat ff_truehd_muxer = {
.name = "truehd",
diff --git a/libavformat/srtenc.c b/libavformat/srtenc.c
new file mode 100644
index 0000000..b8fc8fa
--- /dev/null
+++ b/libavformat/srtenc.c
@@ -0,0 +1,99 @@
+/*
+ * SubRip subtitle muxer
+ * Copyright (c) 2012 Nicolas George <nicolas.george at normalesup.org>
+ *
+ * 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 "internal.h"
+#include "libavutil/log.h"
+
+/* TODO: add options for:
+ - character encoding;
+ - LF / CRLF;
+ - byte order mark.
+ */
+
+typedef struct SRTContext{
+ unsigned index;
+} SRTContext;
+
+static int srt_write_header(AVFormatContext *avf)
+{
+ if (avf->nb_streams != 1 ||
+ avf->streams[0]->codec->codec_type != AVMEDIA_TYPE_SUBTITLE) {
+ av_log(avf, AV_LOG_ERROR,
+ "SRT supports only a single subtitles stream.\n");
+ return AVERROR(EINVAL);
+ }
+ if (avf->streams[0]->codec->codec_id != CODEC_ID_TEXT &&
+ avf->streams[0]->codec->codec_id != CODEC_ID_SRT) {
+ av_log(avf, AV_LOG_ERROR,
+ "Unsupported subtitles codec: %s\n",
+ avcodec_get_name(avf->streams[0]->codec->codec_id));
+ return AVERROR(EINVAL);
+ }
+ avpriv_set_pts_info(avf->streams[0], 64, 1, 1000);
+ return 0;
+}
+
+static int srt_write_packet(AVFormatContext *avf, AVPacket *pkt)
+{
+ SRTContext *srt = avf->priv_data;
+ int write_ts = avf->streams[0]->codec->codec_id != CODEC_ID_SRT;
+
+ srt->index++;
+ if (write_ts) {
+ char buf[64];
+ int64_t s = pkt->pts, e, d = pkt->duration;
+ int len;
+
+ if (d <= 0)
+ d = pkt->convergence_duration;
+ if (s == AV_NOPTS_VALUE || d <= 0) {
+ av_log(avf, AV_LOG_ERROR, "Insufficient timestamps.\n");
+ return AVERROR(EINVAL);
+ }
+ e = s + d;
+ len = snprintf(buf, sizeof(buf),
+ "%d\n%02d:%02d:%02d,%03d --> %02d:%02d:%02d,%03d\n",
+ srt->index,
+ (int)(s / 3600000), (int)(s / 60000) % 60,
+ (int)(s / 1000) % 60, (int)(s % 1000),
+ (int)(e / 3600000), (int)(e / 60000) % 60,
+ (int)(e / 1000) % 60, (int)(e % 1000));
+ avio_write(avf->pb, buf, len);
+ }
+ avio_write(avf->pb, pkt->data, pkt->size);
+ if (write_ts)
+ avio_write(avf->pb, "\n\n", 2);
+ avio_flush(avf->pb);
+ return 0;
+}
+
+AVOutputFormat ff_srt_muxer = {
+ .name = "srt",
+ .long_name = NULL_IF_CONFIG_SMALL("SubRip subtitle format"),
+ .mime_type = "application/x-subrip",
+ .extensions = "srt",
+ .priv_data_size = sizeof(SRTContext),
+ .write_header = srt_write_header,
+ .write_packet = srt_write_packet,
+ .flags = AVFMT_VARIABLE_FPS,
+ .subtitle_codec = CODEC_ID_TEXT,
+};
--
1.7.10
More information about the ffmpeg-devel
mailing list