File: subtitles.cpp

package info (click to toggle)
ogmtools 1%3A1.5-3
  • links: PTS
  • area: main
  • in suites: jessie, jessie-kfreebsd, lenny, squeeze, wheezy
  • size: 1,376 kB
  • ctags: 1,421
  • sloc: cpp: 8,003; ansic: 5,865; sh: 3,227; makefile: 136
file content (153 lines) | stat: -rw-r--r-- 3,896 bytes parent folder | download | duplicates (7)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
/*
  ogmmerge -- utility for splicing together ogg bitstreams
  from component media subtypes

  subtitles.cpp
  subtitle queueing and checking helper class

  Written by Moritz Bunkus <moritz@bunkus.org>
  Based on Xiph.org's 'oggmerge' found in their CVS repository
  See http://www.xiph.org

  Distributed under the GPL
  see the file COPYING for details
  or visit http://www.gnu.org/copyleft/gpl.html
*/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "ogmmerge.h"
#include "subtitles.h"

subtitles_c::subtitles_c() {
  first = NULL;
  last = NULL;
}

subtitles_c::~subtitles_c() {
  sub_t *current = first;
  
  while (current != NULL) {
    if (current->subs != NULL)
      free(current->subs);
    last = current;
    current = current->next;
    free(last);
  }
}
    
void subtitles_c::add(ogg_int64_t nstart, ogg_int64_t nend, char *nsubs) {
  sub_t *s;
  
  s = (sub_t *)malloc(sizeof(sub_t));
  if (s == NULL)
    die("malloc");
  s->subs = strdup(nsubs);
  s->start = nstart;
  s->end = nend;
  s->next = NULL;
  
  if (last == NULL) {
    first = s;
    last = s;
  } else {
    last->next = s;
    last = s;
  }
}

int subtitles_c::check() {
  sub_t *current;
  int error = 0;
  char *c;
  
  current = first;
  while ((current != NULL) && (current->next != NULL)) {
    if (current->end > current->next->start) {
      if (verbose) {
        char short_subs[21];
        
        memset(short_subs, 0, 21);
        strncpy(short_subs, current->subs, 20);
        for (c = short_subs; *c != 0; c++)
          if (*c == '\n')
            *c = ' ';
        fprintf(stdout, "subtitles: Warning: current entry ends after "
                "the next one starts. This end: %02lld:%02lld:%02lld,%03lld"
                "  next start: %02lld:%02lld:%02lld,%03lld  (\"%s\"...)\n",
                current->end / (60 * 60 * 1000),
                (current->end / (60 * 1000)) % 60,
                (current->end / 1000) % 60,
                current->end % 1000,
                current->next->start / (60 * 60 * 1000),
                (current->next->start / (60 * 1000)) % 60,
                (current->next->start / 1000) % 60,
                current->next->start % 1000,
                short_subs);
      }
      current->end = current->next->start - 1;
    }
    current = current->next;
  }
  
  current = first;
  while (current != NULL) {
    if (current->start > current->end) {
      error = 1;
      if (verbose) {
        char short_subs[21];
        
        memset(short_subs, 0, 21);
        strncpy(short_subs, current->subs, 20);
        for (c = short_subs; *c != 0; c++)
          if (*c == '\n')
            *c = ' ';
        fprintf(stdout, "subtitles: Warning: after fixing the time the "
                "current entry begins after it ends. This start: "
                "%02lld:%02lld:%02lld,%03lld  this end: %02lld:%02lld:"
                "%02lld,%03lld  (\"%s\"...)\n",
                current->start / (60 * 60 * 1000),
                (current->start / (60 * 1000)) % 60,
                (current->start / 1000) % 60,
                current->start % 1000,
                current->end / (60 * 60 * 1000),
                (current->end / (60 * 1000)) % 60,
                (current->end / 1000) % 60,
                current->end % 1000,
                short_subs);
       }
    }
    current = current->next;
  }
  
  return error;
}

void subtitles_c::process(textsubs_packetizer_c *p) {
  sub_t *current;
  
  while ((current = get_next()) != NULL) {
    p->process(current->start, current->end, current->subs,
               (first == NULL ? 1 : 0));
    free(current->subs);
    free(current);
  }
}

sub_t *subtitles_c::get_next() {
  sub_t *current;
  
  if (first == NULL)
    return NULL;
  
  current = first;
  if (first == last) {
    first = NULL;
    last = NULL;
  } else
    first = first->next;
  
  return current;
}