public static GetParameterCache ( List |
||
lines1 | List |
|
lines2 | List |
|
return | SubtitleMatcherCache |
/// <summary> /// Find best offset for "listToChange" so it matches "referenceList". There can be /// multiple "peaks" if one subtitle has additional breaks the other does not have. /// Only one of them will be returned. /// </summary> private double FindBestOffset(RemainingSlice slice) { var subtitleMatcherParams = SubtitleMatcher.GetParameterCache(slice.referenceListLines, slice.listToChangeLines); // the tuple is (offset, rating) var firstPassList = new List <OffsetRatingTuple>(5); FindGoodOffsets(subtitleMatcherParams, 0, 0.3, 1000, firstPassList); // find fine grained offsets around approximated offsets var secondPassList = new List <OffsetRatingTuple>(5); foreach (var offsetRatingTuple in firstPassList) { FindGoodOffsets(subtitleMatcherParams, offsetRatingTuple.offset, 0.01, 90, secondPassList); } return(secondPassList[0].offset); }
/// <summary> /// This function will... /// a) move all lines to change in slice by offset /// b) match the lines in "listToChange" and "referenceList" /// c) find a threshold value for matchings /// d) find the longest row of consecutive matchings that are above the threshold /// e) create slices for lines before and lines after this "good row" /// f) reset offset of these remaining lines and put slice into queue /// </summary> private void ApplyOffset(RemainingSlice slice, double offset, Queue <RemainingSlice> queue) { UtilsSubtitle.ShiftByTime(slice.listToChangeLines, offset); // match lines var subtitleMatcherParameters = SubtitleMatcher.GetParameterCache(slice.referenceListLines, slice.listToChangeLines); var biMatchedLinesLinkedList = SubtitleMatcher.MatchSubtitles(subtitleMatcherParameters); var biMatchedLinesList = new List <SubtitleMatcher.BiMatchedLines>(biMatchedLinesLinkedList); biMatchedLinesList.Sort(delegate(SubtitleMatcher.BiMatchedLines x, SubtitleMatcher.BiMatchedLines y) { return(GetStartTime(x) < GetStartTime(y) ? -1 : 1); }); // -------------------------------------------------- // find threshold rating double averageRating = 0; int numRatings = 0; foreach (var biMatchedLines in biMatchedLinesList) { double rating = RateBiMatchedLines(biMatchedLines); if (rating > 0.0001) // ignore "zero" ratings { averageRating += rating; numRatings++; } } averageRating /= numRatings; double thresholdValue = averageRating * 0.8; // -------------------------------------------------- // Find longest row over threshold rating. // // Zero ratings may be inbetween good ratings when some // lines couldn't get matched (for example street-sign // translations that aren't in subtitle file in native language). // These are stepped over: There can be a limited number of zero ratings // ratings in the row except at the beginning and the end (these will // get matched at a different time if possible). int numGoodMatched = 0; int currentRowStart = 0; int allowedZeroRatings = 0; int maxNumGoodMatched = -1; int bestRowStart = 0; for (int index = 0; index < biMatchedLinesList.Count; index++) { var biMatchedLines = biMatchedLinesList[index]; double rating = RateBiMatchedLines(biMatchedLines); if (rating < thresholdValue) { // step over zero ratings if (rating > 0.000001 || allowedZeroRatings-- < 0) { numGoodMatched = 0; // not a zero rating } } else { // update row start/end if (numGoodMatched == 0) { currentRowStart = index; } numGoodMatched = index - currentRowStart + 1; // save best value if (numGoodMatched > maxNumGoodMatched) { maxNumGoodMatched = numGoodMatched; bestRowStart = currentRowStart; } allowedZeroRatings = 4; } } // could good row be found? if (maxNumGoodMatched == -1) { return; } // create new slices left and right RemainingSlice newSlice; // left slice newSlice = GetSubSlice(biMatchedLinesList, 0, bestRowStart); //UtilsSubtitle.ShiftByTime(newSlice.listToChangeLines, -offset); // by disabling this code, remaining slices are now embedded in greater slices queue.Enqueue(newSlice); // right slice newSlice = GetSubSlice(biMatchedLinesList, bestRowStart + maxNumGoodMatched + 1, biMatchedLinesList.Count); //UtilsSubtitle.ShiftByTime(newSlice.listToChangeLines, -offset); queue.Enqueue(newSlice); }