[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