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", +}; _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel