[FFmpeg-devel] [PATCH 3/3] srt: make the demuxer output SubRip packets.

Clément Bœsch ubitux at gmail.com
Sun Oct 21 00:24:14 CEST 2012


This commit also introduces a new packet side data type for the subtitle
position information stored along with the timing, which is not part of
the subrip packets.
---
 libavcodec/avcodec.h | 11 +++++++++++
 libavcodec/srtdec.c  | 11 +++++++++++
 libavcodec/version.h |  2 +-
 libavformat/srtdec.c | 44 ++++++++++++++++++++++++++++++++++----------
 4 files changed, 57 insertions(+), 11 deletions(-)

diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h
index 0b3a19a..ec673f5 100644
--- a/libavcodec/avcodec.h
+++ b/libavcodec/avcodec.h
@@ -942,6 +942,17 @@ enum AVPacketSideDataType {
      * @endcode
      */
     AV_PKT_DATA_JP_DUALMONO,
+
+    /**
+     * Subtitle event position
+     * @code
+     * u32le x1
+     * u32le y1
+     * u32le x2
+     * u32le y2
+     * @endcode
+     */
+    AV_PKT_DATA_SUBTITLE_POSITION,
 };
 
 typedef struct AVPacket {
diff --git a/libavcodec/srtdec.c b/libavcodec/srtdec.c
index 5824091..ddeabd2 100644
--- a/libavcodec/srtdec.c
+++ b/libavcodec/srtdec.c
@@ -21,6 +21,7 @@
 
 #include "libavutil/avstring.h"
 #include "libavutil/common.h"
+#include "libavutil/intreadwrite.h"
 #include "libavutil/parseutils.h"
 #include "avcodec.h"
 #include "ass.h"
@@ -219,6 +220,15 @@ static int srt_decode_frame(AVCodecContext *avctx,
     char buffer[2048];
     const char *ptr = avpkt->data;
     const char *end = avpkt->data + avpkt->size;
+    int size;
+    const uint8_t *p = av_packet_get_side_data(avpkt, AV_PKT_DATA_SUBTITLE_POSITION, &size);
+
+    if (p && size == 16) {
+        x1 = AV_RL32(p     );
+        y1 = AV_RL32(p +  4);
+        x2 = AV_RL32(p +  8);
+        y2 = AV_RL32(p + 12);
+    }
 
     if (avpkt->size <= 0)
         return avpkt->size;
@@ -247,6 +257,7 @@ static int srt_decode_frame(AVCodecContext *avctx,
 }
 
 #if CONFIG_SRT_DECODER
+/* deprecated decoder */
 AVCodec ff_srt_decoder = {
     .name         = "srt",
     .long_name    = NULL_IF_CONFIG_SMALL("SubRip subtitle with embedded timing"),
diff --git a/libavcodec/version.h b/libavcodec/version.h
index b2d5c1b..a52d726 100644
--- a/libavcodec/version.h
+++ b/libavcodec/version.h
@@ -29,7 +29,7 @@
 #include "libavutil/avutil.h"
 
 #define LIBAVCODEC_VERSION_MAJOR 54
-#define LIBAVCODEC_VERSION_MINOR 67
+#define LIBAVCODEC_VERSION_MINOR 68
 #define LIBAVCODEC_VERSION_MICRO 100
 
 #define LIBAVCODEC_VERSION_INT  AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \
diff --git a/libavformat/srtdec.c b/libavformat/srtdec.c
index 056165e..4f5f095 100644
--- a/libavformat/srtdec.c
+++ b/libavformat/srtdec.c
@@ -47,26 +47,30 @@ static int srt_read_header(AVFormatContext *s)
         return AVERROR(ENOMEM);
     avpriv_set_pts_info(st, 64, 1, 1000);
     st->codec->codec_type = AVMEDIA_TYPE_SUBTITLE;
-    st->codec->codec_id   = AV_CODEC_ID_SRT;
+    st->codec->codec_id   = AV_CODEC_ID_SUBRIP;
     return 0;
 }
 
-static int64_t get_pts(const char *buf, int *duration)
+static int64_t get_pts(char **buf, int *duration,
+                       int32_t *x1, int32_t *y1, int32_t *x2, int32_t *y2)
 {
     int i;
 
     for (i=0; i<2; i++) {
         int hh1, mm1, ss1, ms1;
         int hh2, mm2, ss2, ms2;
-        if (sscanf(buf, "%d:%2d:%2d%*1[,.]%3d --> %d:%2d:%2d%*1[,.]%3d",
+        if (sscanf(*buf, "%d:%2d:%2d%*1[,.]%3d --> %d:%2d:%2d%*1[,.]%3d"
+                   "%*[ ]X1:%u X2:%u Y1:%u Y2:%u",
                    &hh1, &mm1, &ss1, &ms1,
-                   &hh2, &mm2, &ss2, &ms2) == 8) {
+                   &hh2, &mm2, &ss2, &ms2,
+                   x1, x2, y1, y2) >= 8) {
             int64_t start = (hh1*3600LL + mm1*60LL + ss1) * 1000LL + ms1;
             int64_t end   = (hh2*3600LL + mm2*60LL + ss2) * 1000LL + ms2;
             *duration = end - start;
+            *buf += strcspn(*buf, "\n") + 1;
             return start;
         }
-        buf += strcspn(buf, "\n") + 1;
+        *buf += strcspn(*buf, "\n") + 1;
     }
     return AV_NOPTS_VALUE;
 }
@@ -87,11 +91,31 @@ static int srt_read_packet(AVFormatContext *s, AVPacket *pkt)
         ptr += ff_get_line(s->pb, ptr, sizeof(buffer)+buffer-ptr);
     } while (!is_eol(*ptr2) && !url_feof(s->pb) && ptr-buffer<sizeof(buffer)-1);
 
-    if (buffer[0] && !(res = av_new_packet(pkt, ptr-buffer))) {
-        memcpy(pkt->data, buffer, pkt->size);
-        pkt->flags |= AV_PKT_FLAG_KEY;
-        pkt->pos = pos;
-        pkt->pts = pkt->dts = get_pts(pkt->data, &(pkt->duration));
+    if (buffer[0]) {
+        int64_t pts;
+        int duration;
+        const char *end = ptr;
+        int32_t x1 = -1, y1 = -1, x2 = -1, y2 = -1;
+
+        ptr = buffer;
+        pts = get_pts(&ptr, &duration, &x1, &y1, &x2, &y2);
+        if (pts != AV_NOPTS_VALUE &&
+            !(res = av_new_packet(pkt, end - ptr))) {
+            memcpy(pkt->data, ptr, pkt->size);
+            pkt->flags |= AV_PKT_FLAG_KEY;
+            pkt->pos = pos;
+            pkt->pts = pkt->dts = pts;
+            pkt->duration = duration;
+            if (x1 != -1) {
+                uint8_t *p = av_packet_new_side_data(pkt, AV_PKT_DATA_SUBTITLE_POSITION, 16);
+                if (p) {
+                    AV_WL32(p,      x1);
+                    AV_WL32(p +  4, y1);
+                    AV_WL32(p +  8, x2);
+                    AV_WL32(p + 12, y2);
+                }
+            }
+        }
     }
     return res;
 }
-- 
1.7.12.4



More information about the ffmpeg-devel mailing list