[FFmpeg-devel] [PATCH] matroskadec: Fix up SRT subtitles to permit decoding.

Philip Langdale philipl at overt.org
Sun May 20 23:43:52 CEST 2012


Just like SSA/ASS subtitles, SRT titles have their timecodes
transferred into the container metadata when stored in Matroska.

Unlike SSA/ASS, there is currently no fix up step when demuxing
to reconstruct the full subtitle stream. This change introduces an
equivalent fixup for SRT.

Signed-off-by: Philip Langdale <philipl at overt.org>
---
 libavformat/matroskadec.c |   29 +++++++++++++++++++++++++++++
 1 file changed, 29 insertions(+)

diff --git a/libavformat/matroskadec.c b/libavformat/matroskadec.c
index e8f70f9..9b9ddc6 100644
--- a/libavformat/matroskadec.c
+++ b/libavformat/matroskadec.c
@@ -1167,6 +1167,33 @@ static void matroska_fix_ass_packet(MatroskaDemuxContext *matroska,
     }
 }
 
+static void matroska_fix_srt_packet(MatroskaDemuxContext *matroska,
+                                    AVPacket *pkt, uint64_t display_duration)
+{
+    char *line, *ptr = pkt->data, *end = ptr+pkt->size;
+    int64_t end_pts = pkt->pts + display_duration;
+    int sc = matroska->time_scale * pkt->pts / 1000000;
+    int ec = matroska->time_scale * end_pts  / 1000000;
+    int sh, sm, ss, eh, em, es, len;
+    sh = sc/3600000;  sc -= 3600000*sh;
+    sm = sc/  60000;  sc -=   60000*sm;
+    ss = sc/   1000;  sc -=    1000*ss;
+    eh = ec/3600000;  ec -= 3600000*eh;
+    em = ec/  60000;  ec -=   60000*em;
+    es = ec/   1000;  ec -=    1000*es;
+    len = 50 + end-ptr + FF_INPUT_BUFFER_PADDING_SIZE;
+    if (!(line = av_malloc(len)))
+        return;
+    // It's not worth the effort to calculate the subtitle index, as
+    // the decoder doesn't need or use it in practice.
+    snprintf(line, len,
+             "%02d:%02d:%02d,%03d --> %02d:%02d:%02d,%03d\r\n%s\r\n",
+             sh, sm, ss, sc, eh, em, es, ec, ptr);
+    av_free(pkt->data);
+    pkt->data = line;
+    pkt->size = strlen(line);
+}
+
 static int matroska_merge_packets(AVPacket *out, AVPacket *in)
 {
     int ret = av_grow_packet(out, in->size);
@@ -2084,6 +2111,8 @@ static int matroska_parse_block(MatroskaDemuxContext *matroska, uint8_t *data,
 
                 if (st->codec->codec_id == CODEC_ID_SSA)
                     matroska_fix_ass_packet(matroska, pkt, duration);
+                else if (st->codec->codec_id == CODEC_ID_SRT)
+                    matroska_fix_srt_packet(matroska, pkt, duration);
 
                 if (matroska->prev_pkt &&
                     timecode != AV_NOPTS_VALUE &&
-- 
1.7.9.5



More information about the ffmpeg-devel mailing list