Mercurial > mplayer.hg
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 { |