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;
}
|