[FFmpeg-devel] [PATCH]Addedd Kate demuxer and decoder

Hima Dangi hima.dangi565 at gmail.com
Tue Oct 21 18:32:35 CEST 2014


diff --git a/libavformat/Makefile b/libavformat/Makefile
index 86064ea..4d41283 100644
--- a/libavformat/Makefile
+++ b/libavformat/Makefile
@@ -433,6 +433,7 @@ OBJS-$(CONFIG_VOBSUB_DEMUXER)            += subtitles.o
# mpeg demuxer is in the
 OBJS-$(CONFIG_VOC_DEMUXER)               += vocdec.o voc.o
 OBJS-$(CONFIG_VOC_MUXER)                 += vocenc.o voc.o
 OBJS-$(CONFIG_VPLAYER_DEMUXER)           += vplayerdec.o subtitles.o
+OBJS-$(CONFIG_KATE_DEMUXER)              += katedec.o subtitles.o
 OBJS-$(CONFIG_VQF_DEMUXER)               += vqf.o
 OBJS-$(CONFIG_W64_DEMUXER)               += wavdec.o w64.o pcm.o
 OBJS-$(CONFIG_W64_MUXER)                 += wavenc.o w64.o
diff --git a/libavformat/allformats.c b/libavformat/allformats.c
index d54ed9b..6e16031 100644
--- a/libavformat/allformats.c
+++ b/libavformat/allformats.c
@@ -320,7 +320,7 @@ void av_register_all(void)
     REGISTER_DEMUXER (XWMA,             xwma);
     REGISTER_DEMUXER (YOP,              yop);
     REGISTER_MUXDEMUX(YUV4MPEGPIPE,     yuv4mpegpipe);
-
+    REGISTER_DEMUXER (KATE,             kate);
     /* image demuxers */
     REGISTER_DEMUXER (IMAGE_BMP_PIPE,        image_bmp_pipe);
     REGISTER_DEMUXER (IMAGE_DPX_PIPE,        image_dpx_pipe);
diff --git a/libavformat/katedec.c b/libavformat/katedec.c
new file mode 100644
index 0000000..7b4ced3
--- /dev/null
+++ b/libavformat/katedec.c
@@ -0,0 +1,158 @@
+
+
+/**
+ * @file
+ * Kate subtitles format demuxer
+ */
+
+#include "avformat.h"
+#include "internal.h"
+#include "subtitles.h"
+#include "libavutil/bprint.h"
+#include "libavutil/intreadwrite.h"
+
+
+typedef struct {
+    FFDemuxSubtitlesQueue q;
+} KateContext;
+
+static int kate_probe(AVProbeData *p)
+{
+    int v1,v2,v3,v4,v5,v6;
+    const char *ptr = p->buf;
+    const char *find;
+    if(strstr(ptr,"kate {"))
+    {
+
+      find=strstr(ptr,"event {");
+      while(strcmp(find,"\n")==0 || strcmp(find," ")==0)
+       find++;
+      if (  sscanf(find," %2d:%2d:%2d -->
%2d:%2d:%2d",&v1,&v2,&v3,&v4,&v5,&v6 )>=4)
+      return AVPROBE_SCORE_MAX;
+      else
+      return 0;
+     }
+     else
+     return 0;
+}
+
+static int64_t get_pts_start(const char **buf)
+{
+
+        int hh1, mm1, ss1;
+        int hh2, mm2, ss2;
+        const char *find = strstr(*buf,"event");
+        while(strcmp(find,"\n")|| strcmp(find," "))
+        find++;
+        if(sscanf(find,  "%2d:%2d:%2d --> %2d:%2d:%2d",&hh1, &mm1,
&ss1,&hh2, &mm2, &ss2)>=6)
+        {
+            int64_t start = (hh1*3600LL + mm1*60LL + ss1) * 1000LL;
+            *buf += ff_subtitles_next_line(*buf);
+            return start;
+        }
+       *buf += ff_subtitles_next_line(*buf);
+      return AV_NOPTS_VALUE;
+}
+
+static int64_t get_pts_end(const char **buf)
+{
+
+        int hh1, mm1, ss1;
+        int hh2, mm2, ss2;
+        const char *find = strstr(*buf,"event");
+        while(strcmp(find,"\n") || strcmp(find," "))
+        find++;
+        if(sscanf(find,  "%2d:%2d:%2d --> %2d:%2d:%2d",&hh1, &mm1,
&ss1,&hh2, &mm2, &ss2)>=6)
+        {
+            int64_t end = (hh2*3600LL + mm2*60LL + ss2) * 1000LL;

+            *buf += ff_subtitles_next_line(*buf);
+            return end;
+        }
+       *buf += ff_subtitles_next_line(*buf);
+      return AV_NOPTS_VALUE;
+}
+
+static int kate_read_header(AVFormatContext *s)
+{
+    KateContext *kate = s->priv_data;
+    AVStream *st = avformat_new_stream(s, NULL);
+     int64_t pts_start;
+        int64_t pts_end;
+        int64_t duration;
+    if (!st)
+        return AVERROR(ENOMEM);
+    avpriv_set_pts_info(st, 64, 1, 100);
+    st->codec->codec_type = AVMEDIA_TYPE_SUBTITLE;
+    st->codec->codec_id   = AV_CODEC_ID_TEXT;
+
+
+
+    while (!avio_feof(s->pb))
+     {
+        char line[4096];
+        const char *p = line;
+        const int64_t pos = avio_tell(s->pb);
+        int len = ff_get_line(s->pb, line, sizeof(line));
+
+        AVPacket *sub;
+
+
+
+        if (!len)
+            break;
+
+        line[strcspn(line, "\r\n")] = 0;
+
+        pts_start = get_pts_start(&p);
+        pts_end = get_pts_end(&p);
+        if (pts_start != AV_NOPTS_VALUE && pts_end !=AV_NOPTS_VALUE)
+        {
+            duration= pts_end- pts_start;
+
+
+            sub = ff_subtitles_queue_insert(&kate->q, p, strlen(p), 0);
+            if (!sub)
+                return AVERROR(ENOMEM);
+            sub->pos = pos;
+            sub->pts = pts_start;
+            sub->duration = duration;
+
+        }
+    }
+
+    ff_subtitles_queue_finalize(&kate->q);
+    return 0;
+}
+
+static int kate_read_packet(AVFormatContext *s, AVPacket *pkt)
+{
+    KateContext *kate = s->priv_data;
+    return ff_subtitles_queue_read_packet(&kate->q, pkt);
+}
+
+static int kate_read_seek(AVFormatContext *s, int stream_index,
+                             int64_t min_ts, int64_t ts, int64_t max_ts,
int flags)
+{
+    KateContext *kate = s->priv_data;
+    return ff_subtitles_queue_seek(&kate->q, s, stream_index,
+                                   min_ts, ts, max_ts, flags);
+}
+
+static int kate_read_close(AVFormatContext *s)
+{
+    KateContext *kate = s->priv_data;
+    ff_subtitles_queue_clean(&kate->q);
+    return 0;
+}
+
+AVInputFormat ff_kate_demuxer = {
+    .name           = "kate",
+    .long_name      = NULL_IF_CONFIG_SMALL("Kate subtitles"),
+    .priv_data_size = sizeof(KateContext),
+    .read_probe     = kate_probe,
+    .read_header    = kate_read_header,
+    .read_packet    = kate_read_packet,
+    .read_seek2     = kate_read_seek,
+    .read_close     = kate_read_close,
+    .extensions     = "txt",
+};


More information about the ffmpeg-devel mailing list