[FFmpeg-devel] [PATCH 2/2] add ASS encoder and decoder

Aurelien Jacobs aurel
Sat Oct 16 17:31:27 CEST 2010


---
 libavcodec/Makefile    |    2 +
 libavcodec/allcodecs.c |    1 +
 libavcodec/ass.c       |   37 +++++++++++++++++++++++++
 libavcodec/ass.h       |   30 ++++++++++++++++++++
 libavcodec/assdec.c    |   50 +++++++++++++++++++++++++++++++++
 libavcodec/assenc.c    |   71 ++++++++++++++++++++++++++++++++++++++++++++++++
 6 files changed, 191 insertions(+), 0 deletions(-)
 create mode 100644 libavcodec/ass.c
 create mode 100644 libavcodec/ass.h
 create mode 100644 libavcodec/assdec.c
 create mode 100644 libavcodec/assenc.c

diff --git a/libavcodec/Makefile b/libavcodec/Makefile
index 385ae02..d4afc0b 100644
--- a/libavcodec/Makefile
+++ b/libavcodec/Makefile
@@ -66,6 +66,8 @@ OBJS-$(CONFIG_AMV_DECODER)             += sp5xdec.o mjpegdec.o mjpeg.o
 OBJS-$(CONFIG_ANM_DECODER)             += anm.o
 OBJS-$(CONFIG_ANSI_DECODER)            += ansi.o cga_data.o
 OBJS-$(CONFIG_APE_DECODER)             += apedec.o
+OBJS-$(CONFIG_ASS_DECODER)             += assdec.o
+OBJS-$(CONFIG_ASS_ENCODER)             += assenc.o
 OBJS-$(CONFIG_ASV1_DECODER)            += asv1.o mpeg12data.o
 OBJS-$(CONFIG_ASV1_ENCODER)            += asv1.o mpeg12data.o
 OBJS-$(CONFIG_ASV2_DECODER)            += asv1.o mpeg12data.o
diff --git a/libavcodec/allcodecs.c b/libavcodec/allcodecs.c
index 89614ab..b42935c 100644
--- a/libavcodec/allcodecs.c
+++ b/libavcodec/allcodecs.c
@@ -341,6 +341,7 @@ void avcodec_register_all(void)
     REGISTER_ENCDEC  (ADPCM_YAMAHA, adpcm_yamaha);
 
     /* subtitles */
+    REGISTER_ENCDEC  (ASS, ass);
     REGISTER_ENCDEC  (DVBSUB, dvbsub);
     REGISTER_ENCDEC  (DVDSUB, dvdsub);
     REGISTER_DECODER (PGSSUB, pgssub);
diff --git a/libavcodec/ass.c b/libavcodec/ass.c
new file mode 100644
index 0000000..36650c1
--- /dev/null
+++ b/libavcodec/ass.c
@@ -0,0 +1,37 @@
+/*
+ * SSA/ASS common funtions
+ * Copyright (c) 2010  Aurelien Jacobs <aurel at gnuage.org>
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "avcodec.h"
+#include "ass.h"
+
+int ff_ass_subtitle(AVSubtitle *sub, int *data_size, const char *dialog,
+                    int duration)
+{
+    memset(sub, 0, sizeof(*sub));
+    sub->end_display_time = 10 * duration;
+    sub->rects     = av_mallocz(sizeof(*sub->rects));
+    sub->rects[0]  = av_mallocz(sizeof(AVSubtitleRect));
+    sub->num_rects = 1;
+    sub->rects[0]->type = SUBTITLE_ASS;
+    sub->rects[0]->ass  = av_strdup(dialog);
+    *data_size = 1;
+    return 0;
+}
diff --git a/libavcodec/ass.h b/libavcodec/ass.h
new file mode 100644
index 0000000..00ad504
--- /dev/null
+++ b/libavcodec/ass.h
@@ -0,0 +1,30 @@
+/*
+ * SSA/ASS common funtions
+ * Copyright (c) 2010  Aurelien Jacobs <aurel at gnuage.org>
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef AVCODEC_ASS_H
+#define AVCODEC_ASS_H
+
+#include "avcodec.h"
+
+int ff_ass_subtitle(AVSubtitle *sub, int *data_size, const char *dialog,
+                    int duration);
+
+#endif /* AVCODEC_ASS_H */
diff --git a/libavcodec/assdec.c b/libavcodec/assdec.c
new file mode 100644
index 0000000..92b00a6
--- /dev/null
+++ b/libavcodec/assdec.c
@@ -0,0 +1,50 @@
+/*
+ * SSA/ASS decoder
+ * Copyright (c) 2010  Aurelien Jacobs <aurel at gnuage.org>
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "avcodec.h"
+#include "ass.h"
+
+static av_cold int ass_decode_init(AVCodecContext *avctx)
+{
+    avctx->subtitle_header = av_malloc(avctx->extradata_size);
+    if (!avctx->extradata)
+        return AVERROR(ENOMEM);
+    memcpy(avctx->subtitle_header, avctx->extradata, avctx->extradata_size);
+    avctx->subtitle_header_size = avctx->extradata_size;
+    return 0;
+}
+
+static int ass_decode_frame(AVCodecContext *avctx, void *data, int *data_size,
+                            AVPacket *avpkt)
+{
+    if (avpkt->size > 0)
+        ff_ass_subtitle(data, data_size, avpkt->data, 0/* FIXME: duration */);
+    return avpkt->size;
+}
+
+AVCodec ass_decoder = {
+    .name      = "ass",
+    .long_name = NULL_IF_CONFIG_SMALL("Advanced SubStation Alpha subtitle"),
+    .type      = AVMEDIA_TYPE_SUBTITLE,
+    .id        = CODEC_ID_SSA,
+    .init      = ass_decode_init,
+    .decode    = ass_decode_frame,
+};
diff --git a/libavcodec/assenc.c b/libavcodec/assenc.c
new file mode 100644
index 0000000..687e868
--- /dev/null
+++ b/libavcodec/assenc.c
@@ -0,0 +1,71 @@
+/*
+ * SSA/ASS encoder
+ * Copyright (c) 2010  Aurelien Jacobs <aurel at gnuage.org>
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "avcodec.h"
+#include "libavutil/avstring.h"
+
+static av_cold int ass_encode_init(AVCodecContext *avctx)
+{
+    avctx->extradata = av_malloc(avctx->subtitle_header_size);
+    if (!avctx->extradata)
+        return AVERROR(ENOMEM);
+    memcpy(avctx->extradata, avctx->subtitle_header, avctx->subtitle_header_size);
+    avctx->extradata_size = avctx->subtitle_header_size;
+    return 0;
+}
+
+static int ass_encode_frame(AVCodecContext *avctx,
+                            unsigned char *buf, int bufsize, void *data)
+{
+    AVSubtitle *sub = data;
+    int len;
+
+    if (sub->num_rects == 0)
+        return 0;
+
+    /* TODO: support multiple rects */
+    if (sub->num_rects > 1)
+        av_log(avctx, AV_LOG_WARNING, "Only single rects supported "
+               "(%d in subtitle.)\n", sub->num_rects);
+
+    if (sub->rects[0]->type != SUBTITLE_ASS) {
+        av_log(avctx, AV_LOG_ERROR, "Only SUBTITLE_ASS type supported.\n");
+        return -1;
+    }
+
+    len = av_strlcpy(buf, sub->rects[0]->ass, bufsize);
+
+    if (len > bufsize-1) {
+        av_log(avctx, AV_LOG_ERROR, "Buffer too small for ASS event.\n");
+        return -1;
+    }
+
+    return len;
+}
+
+AVCodec ass_encoder = {
+    .name      = "ass",
+    .long_name = NULL_IF_CONFIG_SMALL("Advanced SubStation Alpha subtitle"),
+    .type      = AVMEDIA_TYPE_SUBTITLE,
+    .id        = CODEC_ID_SSA,
+    .init      = ass_encode_init,
+    .encode    = ass_encode_frame,
+};
-- 
1.7.1




More information about the ffmpeg-devel mailing list