aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNicolas George <nicolas.george@normalesup.org>2012-06-17 21:11:49 +0200
committerNicolas George <nicolas.george@normalesup.org>2012-06-21 20:52:56 +0200
commit9e63c30daa8bfde52c534027ce984e8cf3f200c3 (patch)
treecedfd0acfd227d62e7b8e037581fc2b1bf17e716
parent14ac47fcc79b3c587af65e21be1da314882eeed0 (diff)
downloadffmpeg-9e63c30daa8bfde52c534027ce984e8cf3f200c3.tar.gz
lavf: add a real SRT muxer.
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.
-rw-r--r--libavformat/Makefile2
-rw-r--r--libavformat/rawenc.c12
-rw-r--r--libavformat/srtenc.c99
3 files changed, 100 insertions, 13 deletions
diff --git a/libavformat/Makefile b/libavformat/Makefile
index 74257392cd..9032654ae5 100644
--- a/libavformat/Makefile
+++ b/libavformat/Makefile
@@ -313,7 +313,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 3745620133..8be3cc999e 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 0000000000..b8fc8fac7e
--- /dev/null
+++ b/libavformat/srtenc.c
@@ -0,0 +1,99 @@
+/*
+ * SubRip subtitle muxer
+ * Copyright (c) 2012 Nicolas George <nicolas.george@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,
+};