diff --git a/libavformat/subtitles.c b/libavformat/subtitles.c index d4607970ac..6c9e72ba75 100644 --- a/libavformat/subtitles.c +++ b/libavformat/subtitles.c @@ -228,7 +228,7 @@ static inline int is_eol(char c) void ff_subtitles_read_chunk(AVIOContext *pb, AVBPrint *buf) { - char eol_buf[5]; + char eol_buf[5], last_was_cr = 0; int n = 0, i = 0, nb_eol = 0; av_bprint_clear(buf); @@ -245,12 +245,13 @@ void ff_subtitles_read_chunk(AVIOContext *pb, AVBPrint *buf) /* line break buffering: we don't want to add the trailing \r\n */ if (is_eol(c)) { - nb_eol += c == '\n'; + nb_eol += c == '\n' || last_was_cr; if (nb_eol == 2) break; eol_buf[i++] = c; if (i == sizeof(eol_buf) - 1) break; + last_was_cr = c == '\r'; continue; } diff --git a/libavformat/subtitles.h b/libavformat/subtitles.h index 96de9fa5d4..eced380ff2 100644 --- a/libavformat/subtitles.h +++ b/libavformat/subtitles.h @@ -99,11 +99,20 @@ void ff_subtitles_read_chunk(AVIOContext *pb, AVBPrint *buf); /** * Get the number of characters to increment to jump to the next line, or to * the end of the string. + * The function handles the following line breaks schemes: LF (any sane + * system), CRLF (MS), or standalone CR (old MacOS). */ static av_always_inline int ff_subtitles_next_line(const char *ptr) { - int n = strcspn(ptr, "\n"); - return n + !!*ptr; + int n = strcspn(ptr, "\r\n"); + ptr += n; + if (*ptr == '\r') { + ptr++; + n++; + } + if (*ptr == '\n') + n++; + return n; } #endif /* AVFORMAT_SUBTITLES_H */