LCOV - code coverage report
Current view: top level - libavformat - pjsdec.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 46 52 88.5 %
Date: 2017-12-18 06:23:41 Functions: 5 6 83.3 %

          Line data    Source code
       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             :  * PJS (Phoenix Japanimation Society) subtitles format demuxer
      24             :  *
      25             :  * @see http://subs.com.ru/page.php?al=pjs
      26             :  */
      27             : 
      28             : #include "avformat.h"
      29             : #include "internal.h"
      30             : #include "subtitles.h"
      31             : 
      32             : typedef struct {
      33             :     FFDemuxSubtitlesQueue q;
      34             : } PJSContext;
      35             : 
      36        6130 : static int pjs_probe(AVProbeData *p)
      37             : {
      38             :     char c;
      39             :     int64_t start, end;
      40        6130 :     const unsigned char *ptr = p->buf;
      41             : 
      42        6130 :     if (sscanf(ptr, "%"SCNd64",%"SCNd64",%c", &start, &end, &c) == 3) {
      43           1 :         size_t q1pos = strcspn(ptr, "\"");
      44           1 :         size_t q2pos = q1pos + strcspn(ptr + q1pos + 1, "\"") + 1;
      45           1 :         if (strcspn(ptr, "\r\n") > q2pos)
      46           1 :             return AVPROBE_SCORE_MAX;
      47             :     }
      48        6129 :     return 0;
      49             : }
      50             : 
      51           3 : static int64_t read_ts(char **line, int *duration)
      52             : {
      53             :     int64_t start, end;
      54             : 
      55           3 :     if (sscanf(*line, "%"SCNd64",%"SCNd64, &start, &end) == 2) {
      56           3 :         *line += strcspn(*line, "\"");
      57           3 :         *line += !!**line;
      58           3 :         *duration = end - start;
      59           3 :         return start;
      60             :     }
      61           0 :     return AV_NOPTS_VALUE;
      62             : }
      63             : 
      64           1 : static int pjs_read_header(AVFormatContext *s)
      65             : {
      66           1 :     PJSContext *pjs = s->priv_data;
      67           1 :     AVStream *st = avformat_new_stream(s, NULL);
      68           1 :     int res = 0;
      69             : 
      70           1 :     if (!st)
      71           0 :         return AVERROR(ENOMEM);
      72           1 :     avpriv_set_pts_info(st, 64, 1, 10);
      73           1 :     st->codecpar->codec_type = AVMEDIA_TYPE_SUBTITLE;
      74           1 :     st->codecpar->codec_id   = AV_CODEC_ID_PJS;
      75             : 
      76           5 :     while (!avio_feof(s->pb)) {
      77             :         char line[4096];
      78           4 :         char *p = line;
      79           4 :         const int64_t pos = avio_tell(s->pb);
      80           4 :         int len = ff_get_line(s->pb, line, sizeof(line));
      81             :         int64_t pts_start;
      82             :         int duration;
      83             : 
      84           4 :         if (!len)
      85           1 :             break;
      86             : 
      87           3 :         line[strcspn(line, "\r\n")] = 0;
      88             : 
      89           3 :         pts_start = read_ts(&p, &duration);
      90           3 :         if (pts_start != AV_NOPTS_VALUE) {
      91             :             AVPacket *sub;
      92             : 
      93           3 :             p[strcspn(p, "\"")] = 0;
      94           3 :             sub = ff_subtitles_queue_insert(&pjs->q, p, strlen(p), 0);
      95           3 :             if (!sub)
      96           0 :                 return AVERROR(ENOMEM);
      97           3 :             sub->pos = pos;
      98           3 :             sub->pts = pts_start;
      99           3 :             sub->duration = duration;
     100             :         }
     101             :     }
     102             : 
     103           1 :     ff_subtitles_queue_finalize(s, &pjs->q);
     104           1 :     return res;
     105             : }
     106             : 
     107           4 : static int pjs_read_packet(AVFormatContext *s, AVPacket *pkt)
     108             : {
     109           4 :     PJSContext *pjs = s->priv_data;
     110           4 :     return ff_subtitles_queue_read_packet(&pjs->q, pkt);
     111             : }
     112             : 
     113           0 : static int pjs_read_seek(AVFormatContext *s, int stream_index,
     114             :                          int64_t min_ts, int64_t ts, int64_t max_ts, int flags)
     115             : {
     116           0 :     PJSContext *pjs = s->priv_data;
     117           0 :     return ff_subtitles_queue_seek(&pjs->q, s, stream_index,
     118             :                                    min_ts, ts, max_ts, flags);
     119             : }
     120             : 
     121           1 : static int pjs_read_close(AVFormatContext *s)
     122             : {
     123           1 :     PJSContext *pjs = s->priv_data;
     124           1 :     ff_subtitles_queue_clean(&pjs->q);
     125           1 :     return 0;
     126             : }
     127             : 
     128             : AVInputFormat ff_pjs_demuxer = {
     129             :     .name           = "pjs",
     130             :     .long_name      = NULL_IF_CONFIG_SMALL("PJS (Phoenix Japanimation Society) subtitles"),
     131             :     .priv_data_size = sizeof(PJSContext),
     132             :     .read_probe     = pjs_probe,
     133             :     .read_header    = pjs_read_header,
     134             :     .read_packet    = pjs_read_packet,
     135             :     .read_seek2     = pjs_read_seek,
     136             :     .read_close     = pjs_read_close,
     137             :     .extensions     = "pjs",
     138             : };

Generated by: LCOV version 1.13