[FFmpeg-devel] [PATCH 1/2] lavf: move srtdec:read_chunk() to subtitles utils.

Clément Bœsch ubitux at gmail.com
Fri Dec 28 02:15:59 CET 2012


This function can be useful for various other subtitles formats.
---
 libavformat/srtdec.c    | 60 ++++++-------------------------------------------
 libavformat/subtitles.c | 46 +++++++++++++++++++++++++++++++++++++
 libavformat/subtitles.h | 15 +++++++++++++
 3 files changed, 68 insertions(+), 53 deletions(-)

diff --git a/libavformat/srtdec.c b/libavformat/srtdec.c
index cabbb62..577dd7f 100644
--- a/libavformat/srtdec.c
+++ b/libavformat/srtdec.c
@@ -71,58 +71,6 @@ static int64_t get_pts(const char **buf, int *duration,
     return AV_NOPTS_VALUE;
 }
 
-static inline int is_eol(char c)
-{
-    return c == '\r' || c == '\n';
-}
-
-static void read_chunk(AVIOContext *pb, AVBPrint *buf)
-{
-    char eol_buf[5];
-    int n = 0, i = 0, nb_eol = 0;
-
-    av_bprint_clear(buf);
-
-    for (;;) {
-        char c = avio_r8(pb);
-
-        if (!c)
-            break;
-
-        /* ignore all initial line breaks */
-        if (n == 0 && is_eol(c))
-            continue;
-
-        /* line break buffering: we don't want to add the trailing \r\n */
-        if (is_eol(c)) {
-            nb_eol += c == '\n';
-            if (nb_eol == 2)
-                break;
-            eol_buf[i++] = c;
-            if (i == sizeof(eol_buf) - 1)
-                break;
-            continue;
-        }
-
-        /* only one line break followed by data: we flush the line breaks
-         * buffer */
-        if (i) {
-            eol_buf[i] = 0;
-            av_bprintf(buf, "%s", eol_buf);
-            i = nb_eol = 0;
-        }
-
-        av_bprint_chars(buf, c, 1);
-        n++;
-    }
-
-    /* FIXME: remove the following when the lavc SubRip decoder is fixed
-     * (trailing tags are not correctly flushed, see what happens to FATE when
-     * you disable this code) */
-    if (buf->len)
-        av_bprintf(buf, "\n");
-}
-
 static int srt_read_header(AVFormatContext *s)
 {
     SRTContext *srt = s->priv_data;
@@ -139,7 +87,13 @@ static int srt_read_header(AVFormatContext *s)
     av_bprint_init(&buf, 0, AV_BPRINT_SIZE_UNLIMITED);
 
     while (!url_feof(s->pb)) {
-        read_chunk(s->pb, &buf);
+        ff_subtitles_read_chunk(s->pb, &buf);
+
+        /* FIXME: remove the following when the lavc SubRip decoder is fixed
+         * (trailing tags are not correctly flushed, see what happens to FATE when
+         * you disable this code) */
+        if (buf.len)
+            av_bprintf(&buf, "\n");
 
         if (buf.len) {
             int64_t pos = avio_tell(s->pb);
diff --git a/libavformat/subtitles.c b/libavformat/subtitles.c
index b264ec5..4088cf3 100644
--- a/libavformat/subtitles.c
+++ b/libavformat/subtitles.c
@@ -192,3 +192,49 @@ const char *ff_smil_get_attr_ptr(const char *s, const char *attr)
     }
     return NULL;
 }
+
+static inline int is_eol(char c)
+{
+    return c == '\r' || c == '\n';
+}
+
+void ff_subtitles_read_chunk(AVIOContext *pb, AVBPrint *buf)
+{
+    char eol_buf[5];
+    int n = 0, i = 0, nb_eol = 0;
+
+    av_bprint_clear(buf);
+
+    for (;;) {
+        char c = avio_r8(pb);
+
+        if (!c)
+            break;
+
+        /* ignore all initial line breaks */
+        if (n == 0 && is_eol(c))
+            continue;
+
+        /* line break buffering: we don't want to add the trailing \r\n */
+        if (is_eol(c)) {
+            nb_eol += c == '\n';
+            if (nb_eol == 2)
+                break;
+            eol_buf[i++] = c;
+            if (i == sizeof(eol_buf) - 1)
+                break;
+            continue;
+        }
+
+        /* only one line break followed by data: we flush the line breaks
+         * buffer */
+        if (i) {
+            eol_buf[i] = 0;
+            av_bprintf(buf, "%s", eol_buf);
+            i = nb_eol = 0;
+        }
+
+        av_bprint_chars(buf, c, 1);
+        n++;
+    }
+}
diff --git a/libavformat/subtitles.h b/libavformat/subtitles.h
index 55e6182..eb76192 100644
--- a/libavformat/subtitles.h
+++ b/libavformat/subtitles.h
@@ -81,4 +81,19 @@ int ff_smil_extract_next_chunk(AVIOContext *pb, AVBPrint *buf, char *c);
  */
 const char *ff_smil_get_attr_ptr(const char *s, const char *attr);
 
+/**
+ * @brief Read a subtitles chunk.
+ *
+ * A chunk is defined by a multiline "event", ending with a second line break.
+ * The trailing line breaks are trimmed. CLRF are supported.
+ * Example: "foo\r\nbar\r\n\r\nnext" will print "foo\r\nbar" into buf, and pb
+ * will focus on the 'n' of the "next" string.
+ *
+ * @param pb  I/O context
+ * @param buf an initialized buf where the chunk is written
+ *
+ * @note buf is cleared before writing into it.
+ */
+void ff_subtitles_read_chunk(AVIOContext *pb, AVBPrint *buf);
+
 #endif /* AVFORMAT_SUBTITLES_H */
-- 
1.8.0.2



More information about the ffmpeg-devel mailing list