00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include <string.h>
00023
00024 #include "avcodec.h"
00025 #include "ass.h"
00026 #include "ass_split.h"
00027 #include "libavutil/internal.h"
00028 #include "libavutil/mem.h"
00029
00030 static av_cold int ass_decode_init(AVCodecContext *avctx)
00031 {
00032 avctx->subtitle_header = av_malloc(avctx->extradata_size);
00033 if (!avctx->subtitle_header)
00034 return AVERROR(ENOMEM);
00035 memcpy(avctx->subtitle_header, avctx->extradata, avctx->extradata_size);
00036 avctx->subtitle_header_size = avctx->extradata_size;
00037 avctx->priv_data = ff_ass_split(avctx->extradata);
00038 if(!avctx->priv_data)
00039 return -1;
00040 return 0;
00041 }
00042
00043 static int ass_decode_frame(AVCodecContext *avctx, void *data, int *got_sub_ptr,
00044 AVPacket *avpkt)
00045 {
00046 const char *ptr = avpkt->data;
00047 int len, size = avpkt->size;
00048
00049 while (size > 0) {
00050 int duration;
00051 ASSDialog *dialog = ff_ass_split_dialog(avctx->priv_data, ptr, 0, NULL);
00052 if (!dialog)
00053 return AVERROR_INVALIDDATA;
00054 duration = dialog->end - dialog->start;
00055 len = ff_ass_add_rect(data, ptr, 0, duration, 1);
00056 if (len < 0)
00057 return len;
00058 ptr += len;
00059 size -= len;
00060 }
00061
00062 *got_sub_ptr = avpkt->size > 0;
00063 return avpkt->size;
00064 }
00065
00066 static int ass_decode_close(AVCodecContext *avctx)
00067 {
00068 ff_ass_split_free(avctx->priv_data);
00069 avctx->priv_data = NULL;
00070 return 0;
00071 }
00072
00073 AVCodec ff_ass_decoder = {
00074 .name = "ass",
00075 .long_name = NULL_IF_CONFIG_SMALL("SSA (SubStation Alpha) subtitle"),
00076 .type = AVMEDIA_TYPE_SUBTITLE,
00077 .id = AV_CODEC_ID_SSA,
00078 .init = ass_decode_init,
00079 .decode = ass_decode_frame,
00080 .close = ass_decode_close,
00081 };