Libav 0.7.1
|
00001 /* 00002 * SubRip subtitle demuxer 00003 * Copyright (c) 2010 Aurelien Jacobs <aurel@gnuage.org> 00004 * 00005 * This file is part of Libav. 00006 * 00007 * Libav is free software; you can redistribute it and/or 00008 * modify it under the terms of the GNU Lesser General Public 00009 * License as published by the Free Software Foundation; either 00010 * version 2.1 of the License, or (at your option) any later version. 00011 * 00012 * Libav is distributed in the hope that it will be useful, 00013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00015 * Lesser General Public License for more details. 00016 * 00017 * You should have received a copy of the GNU Lesser General Public 00018 * License along with Libav; if not, write to the Free Software 00019 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 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; /* skip UTF-8 BOM */ 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, AVFormatParameters *ap) 00044 { 00045 AVStream *st = av_new_stream(s, 0); 00046 if (!st) 00047 return -1; 00048 av_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) && !s->pb->eof_reached && 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 };