Here's an alternative solution which maintains support for \r\r\n by
peeking two bytes into the future.

/Tomas
From ed6f0b2e6c8e52574fcfdac73fcfca560434c079 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tomas=20H=C3=A4rdin?= <g...@haerdin.se>
Date: Thu, 28 Mar 2024 23:30:06 +0100
Subject: [PATCH] lavf/subtitles: Add ff_text_peek_r16(), accept \r, \n, \r\n
 and \r\r\n line endings

---
 libavformat/subtitles.c | 46 +++++++++++++++++++++++++++++++++++++----
 libavformat/subtitles.h |  5 +++++
 2 files changed, 47 insertions(+), 4 deletions(-)

diff --git a/libavformat/subtitles.c b/libavformat/subtitles.c
index bda549abd0..01187df6ab 100644
--- a/libavformat/subtitles.c
+++ b/libavformat/subtitles.c
@@ -22,6 +22,7 @@
 #include "subtitles.h"
 #include "avio_internal.h"
 #include "libavutil/avstring.h"
+#include "libavutil/intreadwrite.h"
 
 void ff_text_init_avio(void *s, FFTextReader *r, AVIOContext *pb)
 {
@@ -106,6 +107,42 @@ int ff_text_peek_r8(FFTextReader *r)
     return c;
 }
 
+int ff_text_peek_r16(FFTextReader *r)
+{
+    int c1, c2;
+    if (r->buf_pos < r->buf_len - 1)
+        return AV_RB16(&r->buf[r->buf_pos]);
+
+    // missing one or two bytes
+    c1 = ff_text_r8(r);
+    if (avio_feof(r->pb))
+        return 0;
+
+    if (r->buf_pos == r->buf_len - 1) {
+        // missing one byte
+        r->buf[0] = r->buf[r->buf_pos];
+        r->buf[1] = c1;
+        r->buf_pos = 0;
+        r->buf_len = 2;
+        return AV_RB16(r->buf);
+    }
+
+    // missing two bytes
+    c2 = ff_text_r8(r);
+    if (avio_feof(r->pb)) {
+        r->buf[0] = c1;
+        r->buf_pos = 0;
+        r->buf_len = 1;
+        return 0;
+    }
+
+    r->buf[0] = c1;
+    r->buf[1] = c2;
+    r->buf_pos = 0;
+    r->buf_len = 2;
+    return AV_RB16(r->buf);
+}
+
 AVPacket *ff_subtitles_queue_insert(FFDemuxSubtitlesQueue *q,
                                     const uint8_t *event, size_t len, int merge)
 {
@@ -459,13 +496,14 @@ ptrdiff_t ff_subtitles_read_line(FFTextReader *tr, char *buf, size_t size)
         buf[cur++] = c;
         buf[cur] = '\0';
     }
-    // don't eat \n\n
     if (c == '\r') {
-        // sub/ticket5032-rrn.srt has \r\r\n
-        while (ff_text_peek_r8(tr) == '\r')
-            ff_text_r8(tr);
         if (ff_text_peek_r8(tr) == '\n')
             ff_text_r8(tr);
+        else if (ff_text_peek_r16(tr) == AV_RB16("\r\n")) {
+            // ticket5032-rrn.srt has \r\r\n
+            ff_text_r8(tr);
+            ff_text_r8(tr);
+        }
     }
     return cur;
 }
diff --git a/libavformat/subtitles.h b/libavformat/subtitles.h
index 88665663c5..2a92044976 100644
--- a/libavformat/subtitles.h
+++ b/libavformat/subtitles.h
@@ -94,6 +94,11 @@ int ff_text_eof(FFTextReader *r);
  */
 int ff_text_peek_r8(FFTextReader *r);
 
+/**
+ * Like ff_text_peek_r8(), but peek two bytes and return them as a big-endian number.
+ */
+int ff_text_peek_r16(FFTextReader *r);
+
 /**
  * Read the given number of bytes (in UTF-8). On error or EOF, \0 bytes are
  * written.
-- 
2.39.2

_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".

Reply via email to