comparison subreader.c @ 7983:8344414c59cf

This patch is to add support for overlapping subtitles, that is subtitles whose start or end happens during another subtitle. After reading the subtitles from the file in sub_read_file(), this patch looks for overlapping subtitles and split them into more non-overlapping subtitles. Salvatore Falco <sfalco@studenti.ing.uniroma1.it>
author arpi
date Wed, 30 Oct 2002 19:26:05 +0000
parents eac680483e6c
children 9fc45fe0d444
comparison
equal deleted inserted replaced
7982:eac680483e6c 7983:8344414c59cf
918 return sub; 918 return sub;
919 } 919 }
920 920
921 #endif 921 #endif
922 922
923 static void adjust_subs_time(subtitle* sub, float subtime, float fps){ 923 static void adjust_subs_time(subtitle* sub, float subtime, float fps, int block){
924 int n,m; 924 int n,m;
925 subtitle* nextsub; 925 subtitle* nextsub;
926 int i = sub_num; 926 int i = sub_num;
927 unsigned long subfms = (sub_uses_time ? 100 : fps) * subtime; 927 unsigned long subfms = (sub_uses_time ? 100 : fps) * subtime;
928 928
929 n=m=0; 929 n=m=0;
930 if (i) for (;;){ 930 if (i) for (;;){
931 if (!block)
931 if (sub->end <= sub->start){ 932 if (sub->end <= sub->start){
932 sub->end = sub->start + subfms; 933 sub->end = sub->start + subfms;
933 m++; 934 m++;
934 n++; 935 n++;
935 } 936 }
936 if (!--i) break; 937 if (!--i) break;
937 nextsub = sub + 1; 938 nextsub = sub + 1;
939 if (block){
938 if (sub->end >= nextsub->start){ 940 if (sub->end >= nextsub->start){
939 sub->end = nextsub->start - 1; 941 sub->end = nextsub->start - 1;
940 if (sub->end - sub->start > subfms) 942 if (sub->end - sub->start > subfms)
941 sub->end = sub->start + subfms; 943 sub->end = sub->start + subfms;
942 if (!m) 944 if (!m)
955 /* timed sub fps correction ::atmos */ 957 /* timed sub fps correction ::atmos */
956 if(sub_uses_time && sub_fps) { 958 if(sub_uses_time && sub_fps) {
957 sub->start *= sub_fps/fps; 959 sub->start *= sub_fps/fps;
958 sub->end *= sub_fps/fps; 960 sub->end *= sub_fps/fps;
959 } 961 }
962 }
960 963
961 sub = nextsub; 964 sub = nextsub;
962 m = 0; 965 m = 0;
963 } 966 }
964 if (n) mp_msg(MSGT_SUBREADER,MSGL_INFO,"SUB: Adjusted %d subtitle(s).\n", n); 967 if (n) mp_msg(MSGT_SUBREADER,MSGL_INFO,"SUB: Adjusted %d subtitle(s).\n", n);
965 } 968 }
966 969
967 subtitle* sub_read_file (char *filename, float fps) { 970 subtitle* sub_read_file (char *filename, float fps) {
968 FILE *fd; 971 FILE *fd;
969 int n_max; 972 int n_max, n_first, i, j, sub_first, sub_orig;
970 subtitle *first; 973 subtitle *first, *second;
971 char *fmtname[] = { "microdvd", "subrip", "subviewer", "sami", "vplayer", 974 char *fmtname[] = { "microdvd", "subrip", "subviewer", "sami", "vplayer",
972 "rt", "ssa", "dunnowhat", "mpsub", "aqt", "subviewer 2.0", "subrip 0.9", "jacosub" }; 975 "rt", "ssa", "dunnowhat", "mpsub", "aqt", "subviewer 2.0", "subrip 0.9", "jacosub" };
973 subtitle * (*func[])(FILE *fd,subtitle *dest)= 976 subtitle * (*func[])(FILE *fd,subtitle *dest)=
974 { 977 {
975 sub_read_line_microdvd, 978 sub_read_line_microdvd,
1034 if(sub_num<=0){ 1037 if(sub_num<=0){
1035 free(first); 1038 free(first);
1036 return NULL; 1039 return NULL;
1037 } 1040 }
1038 1041
1039 adjust_subs_time(first, 6.0, fps); /* ~6 secs AST */ 1042 adjust_subs_time(first, 6.0, fps, 0); /* ~6 secs AST */
1040 return first; 1043
1044 // here we manage overlapping subtitles
1045 sub_orig = sub_num;
1046 n_first = sub_num;
1047 n_max = 0;
1048 sub_num = 0;
1049 second = NULL;
1050 // for each subtitle in first[]
1051 for (sub_first = 0; sub_first < n_first; ++sub_first) {
1052 while (first[sub_first].start <= first[sub_first].end) {
1053 unsigned long end_time = first[sub_first].end;
1054 int lines_to_add = 0, sub_to_add, event, ls, lf;
1055
1056 // there is a new subtitle, so let's make second[] bigger
1057 n_max += 1;
1058 second = realloc(second, n_max * sizeof(subtitle));
1059 memset(&second[n_max - 1], '\0', sizeof(subtitle));
1060
1061 // find the number of lines and subtitles that overlap the current subtitle
1062 for (sub_to_add = 0;
1063 (end_time > first[sub_first + sub_to_add + 1].start)
1064 && (sub_first + sub_to_add + 1 < n_first); ++sub_to_add) {
1065 lines_to_add += first[sub_first + sub_to_add + 1].lines;
1066 }
1067 if ((lines_to_add > 0)
1068 && (first[sub_first].lines + lines_to_add <
1069 SUB_MAX_TEXT)) {
1070 unsigned long next;
1071
1072 // find next beginning-of-a-subtitle time
1073 next = first[sub_first].end + 1;
1074 event = sub_first;
1075 for (j = 0; j < lines_to_add; j++) {
1076 if ((first[sub_first + j + 1].end + 1 < next)
1077 && (first[sub_first + j + 1].end >=
1078 first[sub_first].start)) {
1079 event = sub_first + j + 1;
1080 next = first[event].end + 1;
1081 }
1082 if ((first[sub_first + j + 1].start < next)
1083 && (first[sub_first + j + 1].start >
1084 first[sub_first].start)) {
1085 event = sub_first + j + 1;
1086 next = first[event].start;
1087 }
1088 }
1089 second[sub_num].start = first[sub_first].start;
1090 second[sub_num].end = next - 1;
1091 second[sub_num].lines = first[sub_first].lines;
1092 for (ls = 0, lf = 0; ls < second[sub_num].lines; ls++, lf++) {
1093 second[sub_num].text[ls] =
1094 strdup(first[sub_first].text[lf]);
1095 }
1096 for (j = 0; j < sub_to_add; j++) {
1097 if ((first[sub_first + j + 1].start <=
1098 second[sub_num].start)
1099 && (first[sub_first + j + 1].end >=
1100 second[sub_num].end)
1101 && (second[sub_num].lines +
1102 first[sub_first + j + 1].lines <=
1103 SUB_MAX_TEXT)) {
1104 for (lf = 0; lf < first[sub_first + j + 1].lines;
1105 lf++, ls++)
1106 second[sub_num].text[ls] =
1107 strdup(first[sub_first + j + 1].text[lf]);
1108 first[sub_first + j + 1].start = next;
1109 } else
1110 for (lf = 0; lf < first[sub_first + j + 1].lines;
1111 lf++, ls++)
1112 second[sub_num].text[ls] = strdup(" ");
1113 second[sub_num].lines +=
1114 first[sub_first + j + 1].lines;
1115 }
1116 first[sub_first].start = next;
1117 } else {
1118 second[sub_num].start = first[sub_first].start;
1119 second[sub_num].end = first[sub_first].end;
1120 second[sub_num].lines = first[sub_first].lines;
1121 for (ls = 0; ls < second[sub_num].lines; ls++)
1122 second[sub_num].text[ls] =
1123 strdup(first[sub_first].text[ls]);
1124 first[sub_first].start = first[sub_first].end + 1;
1125 }
1126 ++sub_num;
1127 } // while
1128 }
1129 adjust_subs_time(second, 6.0, fps, 1); /* ~6 secs AST */
1130
1131 for (j = sub_orig - 1; j <= 0; --j) {
1132 for (i = first[j].lines - 1; i <= 0; --i) {
1133 free(first[j].text[i]);
1134 }
1135 free(&first[j]);
1136 }
1137
1138 return second;
1041 } 1139 }
1042 1140
1043 #if 0 1141 #if 0
1044 char * strreplace( char * in,char * what,char * whereof ) 1142 char * strreplace( char * in,char * what,char * whereof )
1045 { 1143 {