[FFmpeg-devel] [PATCH 2/4] add ASS parser
Aurelien Jacobs
aurel
Tue Jul 6 22:54:54 CEST 2010
---
libavcodec/Makefile | 1
libavcodec/allcodecs.c | 1
libavcodec/ass_parser.c | 108 ++++++++++++++++++-----------------------------
3 files changed, 44 insertions(+), 66 deletions(-)
copy libavformat/assdec.c => libavcodec/ass_parser.c (60%)
-------------- next part --------------
diff --git a/libavcodec/Makefile b/libavcodec/Makefile
index dc28ccb..ffc2560 100644
--- a/libavcodec/Makefile
+++ b/libavcodec/Makefile
@@ -551,6 +551,7 @@ OBJS-$(CONFIG_AAC_PARSER) += aac_parser.o aac_ac3_parser.o \
mpeg4audio.o
OBJS-$(CONFIG_AC3_PARSER) += ac3_parser.o ac3tab.o \
aac_ac3_parser.o
+OBJS-$(CONFIG_ASS_PARSER) += ass_parser.o
OBJS-$(CONFIG_CAVSVIDEO_PARSER) += cavs_parser.o
OBJS-$(CONFIG_DCA_PARSER) += dca_parser.o
OBJS-$(CONFIG_DIRAC_PARSER) += dirac_parser.o
diff --git a/libavcodec/allcodecs.c b/libavcodec/allcodecs.c
index 48a7bb3..2acc2c2 100644
--- a/libavcodec/allcodecs.c
+++ b/libavcodec/allcodecs.c
@@ -358,6 +358,7 @@ void avcodec_register_all(void)
/* parsers */
REGISTER_PARSER (AAC, aac);
REGISTER_PARSER (AC3, ac3);
+ REGISTER_PARSER (ASS, ass);
REGISTER_PARSER (CAVSVIDEO, cavsvideo);
REGISTER_PARSER (DCA, dca);
REGISTER_PARSER (DIRAC, dirac);
diff --git a/libavformat/assdec.c b/libavcodec/ass_parser.c
similarity index 60%
copy from libavformat/assdec.c
copy to libavcodec/ass_parser.c
index 5f8e0b9..c1ce309 100644
--- a/libavformat/assdec.c
+++ b/libavcodec/ass_parser.c
@@ -1,6 +1,7 @@
/*
- * SSA/ASS demuxer
+ * SSA/ASS parser
* Copyright (c) 2008 Michael Niedermayer
+ * Copyright (C) 2010 Aurelien Jacobs <aurel at gnuage.org>
*
* This file is part of FFmpeg.
*
@@ -19,7 +20,7 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#include "avformat.h"
+#include "parser.h"
#define MAX_LINESIZE 2000
@@ -30,39 +31,25 @@ typedef struct ASSContext{
unsigned int event_index;
}ASSContext;
-static void get_line(ByteIOContext *s, char *buf, int maxlen)
+static int get_line(const char *buf, int buf_size, char *line, int maxlen)
{
int i = 0;
- char c;
do{
- c = get_byte(s);
if (i < maxlen-1)
- buf[i++] = c;
- }while(c != '\n' && c);
+ line[i] = *buf;
+ } while (++i<buf_size && *buf != '\n' && *buf++);
- buf[i] = 0;
+ line[i] = 0;
+ return i;
}
-static int probe(AVProbeData *p)
-{
- const char *header= "[Script Info]";
-
- if( !memcmp(p->buf , header, strlen(header))
- || !memcmp(p->buf+3, header, strlen(header)))
- return AVPROBE_SCORE_MAX;
-
- return 0;
-}
-
-static int read_close(AVFormatContext *s)
+static void ass_close(AVCodecParserContext *s)
{
ASSContext *ass = s->priv_data;
av_freep(&ass->event_buffer);
av_freep(&ass->event);
-
- return 0;
}
static int64_t get_pts(const uint8_t *p)
@@ -77,7 +64,7 @@ static int64_t get_pts(const uint8_t *p)
min+= 60*hour;
sec+= 60*min;
- return sec*100+hsec;
+ return sec*1000+hsec*10;
}
static int event_cmp(uint8_t **a, uint8_t **b)
@@ -85,30 +72,24 @@ static int event_cmp(uint8_t **a, uint8_t **b)
return get_pts(*a) - get_pts(*b);
}
-static int read_header(AVFormatContext *s, AVFormatParameters *ap)
+static int ass_read_header(AVCodecParserContext *s, AVCodecContext *avctx,
+ const uint8_t *buf, int size)
{
int i, header_remaining;
ASSContext *ass = s->priv_data;
- ByteIOContext *pb = s->pb;
- AVStream *st;
int allocated[2]={0};
uint8_t *p, **dst[2]={0};
int pos[2]={0};
- st = av_new_stream(s, 0);
- if (!st)
- return -1;
- av_set_pts_info(st, 64, 1, 100);
- st->codec->codec_type = AVMEDIA_TYPE_SUBTITLE;
- st->codec->codec_id= CODEC_ID_SSA;
-
header_remaining= INT_MAX;
- dst[0] = &st->codec->extradata;
+ dst[0] = &avctx->extradata;
dst[1] = &ass->event_buffer;
- while(!url_feof(pb)){
+ while (size > 0) {
uint8_t line[MAX_LINESIZE];
- get_line(pb, line, sizeof(line));
+ i = get_line(buf, size, line, sizeof(line));
+ buf += i;
+ size -= i;
if(!memcmp(line, "[Events]", 8))
header_remaining= 2;
@@ -125,11 +106,11 @@ static int read_header(AVFormatContext *s, AVFormatParameters *ap)
goto fail;
*(dst[i])= p;
memcpy(p + pos[i], line, strlen(line)+1);
- pos[i] += strlen(line);
+ pos[i] += strlen(line)+i;
if(i) ass->event_count++;
else header_remaining--;
}
- st->codec->extradata_size= pos[0];
+ avctx->extradata_size= pos[0];
if(ass->event_count >= UINT_MAX / sizeof(*ass->event))
goto fail;
@@ -138,9 +119,7 @@ static int read_header(AVFormatContext *s, AVFormatParameters *ap)
p= ass->event_buffer;
for(i=0; i<ass->event_count; i++){
ass->event[i]= p;
- while(*p && *p != '\n')
- p++;
- p++;
+ while(*p++);
}
qsort(ass->event, ass->event_count, sizeof(*ass->event), (void*)event_cmp);
@@ -148,40 +127,37 @@ static int read_header(AVFormatContext *s, AVFormatParameters *ap)
return 0;
fail:
- read_close(s);
+ ass_close(s);
return -1;
}
-static int read_packet(AVFormatContext *s, AVPacket *pkt)
+static int ass_parse(AVCodecParserContext *s, AVCodecContext *avctx,
+ const uint8_t **poutbuf, int *poutbuf_size,
+ const uint8_t *buf, int buf_size)
{
ASSContext *ass = s->priv_data;
- uint8_t *p, *end;
-
- if(ass->event_index >= ass->event_count)
- return AVERROR(EIO);
- p= ass->event[ ass->event_index ];
+ if (!ass->event_buffer)
+ ass_read_header(s, avctx, buf, buf_size);
- end= strchr(p, '\n');
- av_new_packet(pkt, end ? end-p+1 : strlen(p));
- pkt->flags |= AV_PKT_FLAG_KEY;
- pkt->pos= p - ass->event_buffer + s->streams[0]->codec->extradata_size;
- pkt->pts= pkt->dts= get_pts(p);
- memcpy(pkt->data, p, pkt->size);
-
- ass->event_index++;
+ if (ass->event_index >= ass->event_count) {
+ *poutbuf = NULL;
+ *poutbuf_size = 0;
+ return buf_size;
+ }
- return 0;
+ *poutbuf = ass->event[ass->event_index++];
+ *poutbuf_size = strlen(*poutbuf);
+ s->pts = s->dts = get_pts(*poutbuf);
+ if (ass->event_index >= ass->event_count)
+ return buf_size;
+ return *poutbuf_size;
}
-AVInputFormat ass_demuxer = {
- "ass",
- NULL_IF_CONFIG_SMALL("SSA/ASS format"),
- sizeof(ASSContext),
- probe,
- read_header,
- read_packet,
- read_close,
-// read_seek,
+AVCodecParser ass_parser = {
+ .codec_ids = { CODEC_ID_SSA },
+ .priv_data_size = sizeof(ASSContext),
+ .parser_parse = ass_parse,
+ .parser_close = ass_close
};
More information about the ffmpeg-devel
mailing list