Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | RSS feed

  1. /*
  2.  * Copyright (c) 2012 Clément Bœsch
  3.  *
  4.  * This file is part of FFmpeg.
  5.  *
  6.  * FFmpeg is free software; you can redistribute it and/or
  7.  * modify it under the terms of the GNU Lesser General Public
  8.  * License as published by the Free Software Foundation; either
  9.  * version 2.1 of the License, or (at your option) any later version.
  10.  *
  11.  * FFmpeg is distributed in the hope that it will be useful,
  12.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  14.  * Lesser General Public License for more details.
  15.  *
  16.  * You should have received a copy of the GNU Lesser General Public
  17.  * License along with FFmpeg; if not, write to the Free Software
  18.  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  19.  */
  20.  
  21. /**
  22.  * @file
  23.  * VPlayer subtitles format demuxer
  24.  */
  25.  
  26. #include "avformat.h"
  27. #include "internal.h"
  28. #include "subtitles.h"
  29.  
  30. typedef struct {
  31.     FFDemuxSubtitlesQueue q;
  32. } VPlayerContext;
  33.  
  34. static int vplayer_probe(AVProbeData *p)
  35. {
  36.     char c;
  37.     const unsigned char *ptr = p->buf;
  38.  
  39.     if (sscanf(ptr, "%*d:%*d:%*d.%*d%c", &c) == 1 && strchr(": =", c))
  40.         return AVPROBE_SCORE_MAX;
  41.     return 0;
  42. }
  43.  
  44. static int64_t read_ts(char **line)
  45. {
  46.     char c;
  47.     int hh, mm, ss, ms, len;
  48.  
  49.     if (sscanf(*line, "%d:%d:%d.%d%c%n",
  50.                &hh, &mm, &ss, &ms, &c, &len) >= 5) {
  51.         *line += len;
  52.         return (hh*3600LL + mm*60LL + ss) * 100LL + ms;
  53.     }
  54.     return AV_NOPTS_VALUE;
  55. }
  56.  
  57. static int vplayer_read_header(AVFormatContext *s)
  58. {
  59.     VPlayerContext *vplayer = s->priv_data;
  60.     AVStream *st = avformat_new_stream(s, NULL);
  61.  
  62.     if (!st)
  63.         return AVERROR(ENOMEM);
  64.     avpriv_set_pts_info(st, 64, 1, 100);
  65.     st->codec->codec_type = AVMEDIA_TYPE_SUBTITLE;
  66.     st->codec->codec_id   = AV_CODEC_ID_VPLAYER;
  67.  
  68.     while (!url_feof(s->pb)) {
  69.         char line[4096];
  70.         char *p = line;
  71.         const int64_t pos = avio_tell(s->pb);
  72.         int len = ff_get_line(s->pb, line, sizeof(line));
  73.         int64_t pts_start;
  74.  
  75.         if (!len)
  76.             break;
  77.  
  78.         line[strcspn(line, "\r\n")] = 0;
  79.  
  80.         pts_start = read_ts(&p);
  81.         if (pts_start != AV_NOPTS_VALUE) {
  82.             AVPacket *sub;
  83.  
  84.             sub = ff_subtitles_queue_insert(&vplayer->q, p, strlen(p), 0);
  85.             if (!sub)
  86.                 return AVERROR(ENOMEM);
  87.             sub->pos = pos;
  88.             sub->pts = pts_start;
  89.             sub->duration = -1;
  90.         }
  91.     }
  92.  
  93.     ff_subtitles_queue_finalize(&vplayer->q);
  94.     return 0;
  95. }
  96.  
  97. static int vplayer_read_packet(AVFormatContext *s, AVPacket *pkt)
  98. {
  99.     VPlayerContext *vplayer = s->priv_data;
  100.     return ff_subtitles_queue_read_packet(&vplayer->q, pkt);
  101. }
  102.  
  103. static int vplayer_read_seek(AVFormatContext *s, int stream_index,
  104.                              int64_t min_ts, int64_t ts, int64_t max_ts, int flags)
  105. {
  106.     VPlayerContext *vplayer = s->priv_data;
  107.     return ff_subtitles_queue_seek(&vplayer->q, s, stream_index,
  108.                                    min_ts, ts, max_ts, flags);
  109. }
  110.  
  111. static int vplayer_read_close(AVFormatContext *s)
  112. {
  113.     VPlayerContext *vplayer = s->priv_data;
  114.     ff_subtitles_queue_clean(&vplayer->q);
  115.     return 0;
  116. }
  117.  
  118. AVInputFormat ff_vplayer_demuxer = {
  119.     .name           = "vplayer",
  120.     .long_name      = NULL_IF_CONFIG_SMALL("VPlayer subtitles"),
  121.     .priv_data_size = sizeof(VPlayerContext),
  122.     .read_probe     = vplayer_probe,
  123.     .read_header    = vplayer_read_header,
  124.     .read_packet    = vplayer_read_packet,
  125.     .read_seek2     = vplayer_read_seek,
  126.     .read_close     = vplayer_read_close,
  127.     .extensions     = "txt",
  128. };
  129.