00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "avformat.h"
00023 #include "internal.h"
00024 #include "libavutil/intreadwrite.h"
00025
00026 static int srt_probe(AVProbeData *p)
00027 {
00028 unsigned char *ptr = p->buf;
00029 int i, v, num = 0;
00030
00031 if (AV_RB24(ptr) == 0xEFBBBF)
00032 ptr += 3;
00033
00034 for (i=0; i<2; i++) {
00035 if (num == i && sscanf(ptr, "%*d:%*2d:%*2d%*1[,.]%*3d --> %*d:%*2d:%*2d%*1[,.]%3d", &v) == 1)
00036 return AVPROBE_SCORE_MAX;
00037 num = atoi(ptr);
00038 ptr += strcspn(ptr, "\n") + 1;
00039 }
00040 return 0;
00041 }
00042
00043 static int srt_read_header(AVFormatContext *s)
00044 {
00045 AVStream *st = avformat_new_stream(s, NULL);
00046 if (!st)
00047 return -1;
00048 avpriv_set_pts_info(st, 64, 1, 1000);
00049 st->codec->codec_type = AVMEDIA_TYPE_SUBTITLE;
00050 st->codec->codec_id = CODEC_ID_SRT;
00051 return 0;
00052 }
00053
00054 static int64_t get_pts(const char *buf)
00055 {
00056 int i, v, hour, min, sec, hsec;
00057
00058 for (i=0; i<2; i++) {
00059 if (sscanf(buf, "%d:%2d:%2d%*1[,.]%3d --> %*d:%*2d:%*2d%*1[,.]%3d",
00060 &hour, &min, &sec, &hsec, &v) == 5) {
00061 min += 60*hour;
00062 sec += 60*min;
00063 return sec*1000+hsec;
00064 }
00065 buf += strcspn(buf, "\n") + 1;
00066 }
00067 return AV_NOPTS_VALUE;
00068 }
00069
00070 static inline int is_eol(char c)
00071 {
00072 return c == '\r' || c == '\n';
00073 }
00074
00075 static int srt_read_packet(AVFormatContext *s, AVPacket *pkt)
00076 {
00077 char buffer[2048], *ptr = buffer, *ptr2;
00078 int64_t pos = avio_tell(s->pb);
00079 int res = AVERROR_EOF;
00080
00081 do {
00082 ptr2 = ptr;
00083 ptr += ff_get_line(s->pb, ptr, sizeof(buffer)+buffer-ptr);
00084 } while (!is_eol(*ptr2) && !url_feof(s->pb) && ptr-buffer<sizeof(buffer)-1);
00085
00086 if (buffer[0] && !(res = av_new_packet(pkt, ptr-buffer))) {
00087 memcpy(pkt->data, buffer, pkt->size);
00088 pkt->flags |= AV_PKT_FLAG_KEY;
00089 pkt->pos = pos;
00090 pkt->pts = pkt->dts = get_pts(pkt->data);
00091 }
00092 return res;
00093 }
00094
00095 AVInputFormat ff_srt_demuxer = {
00096 .name = "srt",
00097 .long_name = NULL_IF_CONFIG_SMALL("SubRip subtitle format"),
00098 .read_probe = srt_probe,
00099 .read_header = srt_read_header,
00100 .read_packet = srt_read_packet,
00101 .flags = AVFMT_GENERIC_INDEX,
00102 };