[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