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 AVERROR(ENOMEM);
00048 avpriv_set_pts_info(st, 64, 1, 1000);
00049 st->codec->codec_type = AVMEDIA_TYPE_SUBTITLE;
00050 st->codec->codec_id = AV_CODEC_ID_SRT;
00051 return 0;
00052 }
00053
00054 static int64_t get_pts(const char *buf, int *duration)
00055 {
00056 int i, hour, min, sec, hsec;
00057 int he, me, se, mse;
00058
00059 for (i=0; i<2; i++) {
00060 int64_t start, end;
00061 if (sscanf(buf, "%d:%2d:%2d%*1[,.]%3d --> %d:%2d:%2d%*1[,.]%3d",
00062 &hour, &min, &sec, &hsec, &he, &me, &se, &mse) == 8) {
00063 min += 60*hour;
00064 sec += 60*min;
00065 start = sec*1000+hsec;
00066 me += 60*he;
00067 se += 60*me;
00068 end = se*1000+mse;
00069 *duration = end - start;
00070 return start;
00071 }
00072 buf += strcspn(buf, "\n") + 1;
00073 }
00074 return AV_NOPTS_VALUE;
00075 }
00076
00077 static inline int is_eol(char c)
00078 {
00079 return c == '\r' || c == '\n';
00080 }
00081
00082 static int srt_read_packet(AVFormatContext *s, AVPacket *pkt)
00083 {
00084 char buffer[2048], *ptr = buffer, *ptr2;
00085 int64_t pos = avio_tell(s->pb);
00086 int res = AVERROR_EOF;
00087
00088 do {
00089 ptr2 = ptr;
00090 ptr += ff_get_line(s->pb, ptr, sizeof(buffer)+buffer-ptr);
00091 } while (!is_eol(*ptr2) && !url_feof(s->pb) && ptr-buffer<sizeof(buffer)-1);
00092
00093 if (buffer[0] && !(res = av_new_packet(pkt, ptr-buffer))) {
00094 memcpy(pkt->data, buffer, pkt->size);
00095 pkt->flags |= AV_PKT_FLAG_KEY;
00096 pkt->pos = pos;
00097 pkt->pts = pkt->dts = get_pts(pkt->data, &(pkt->duration));
00098 }
00099 return res;
00100 }
00101
00102 AVInputFormat ff_srt_demuxer = {
00103 .name = "srt",
00104 .long_name = NULL_IF_CONFIG_SMALL("SubRip subtitle"),
00105 .read_probe = srt_probe,
00106 .read_header = srt_read_header,
00107 .read_packet = srt_read_packet,
00108 .flags = AVFMT_GENERIC_INDEX,
00109 };