[FFmpeg-devel] [PATCH 4/4] avidec: demux ASS and SRT tracks
Aurelien Jacobs
aurel
Tue Jul 6 22:55:04 CEST 2010
---
libavformat/avidec.c | 42 ++++++++++++++++++++++++++++++++++++++++--
libavformat/utils.c | 2 ++
2 files changed, 42 insertions(+), 2 deletions(-)
-------------- next part --------------
diff --git a/libavformat/avidec.c b/libavformat/avidec.c
index cdf8307..ac1e3b6 100644
--- a/libavformat/avidec.c
+++ b/libavformat/avidec.c
@@ -24,6 +24,7 @@
#include "libavutil/intreadwrite.h"
#include "libavutil/bswap.h"
+#include "libavcodec/bytestream.h"
#include "avformat.h"
#include "avi.h"
#include "dv.h"
@@ -466,8 +467,7 @@ static int avi_read_header(AVFormatContext *s, AVFormatParameters *ap)
codec_type = AVMEDIA_TYPE_AUDIO;
break;
case MKTAG('t', 'x', 't', 's'):
- //FIXME
- codec_type = AVMEDIA_TYPE_DATA; //AVMEDIA_TYPE_SUB ? FIXME
+ codec_type = AVMEDIA_TYPE_SUBTITLE;
break;
case MKTAG('d', 'a', 't', 's'):
codec_type = AVMEDIA_TYPE_DATA;
@@ -598,6 +598,14 @@ static int avi_read_header(AVFormatContext *s, AVFormatParameters *ap)
ast->dshow_block_align = 0;
}
break;
+ case AVMEDIA_TYPE_SUBTITLE:
+ st->codec->codec_type = AVMEDIA_TYPE_SUBTITLE;
+ st->codec->codec_id = CODEC_ID_PROBE;
+ st->codec->codec_tag = 0;
+ st->need_parsing = AVSTREAM_PARSE_FULL;
+ av_set_pts_info(st, 64, 1, 1000);
+ url_fskip(pb, size);
+ break;
default:
st->codec->codec_type = AVMEDIA_TYPE_DATA;
st->codec->codec_id= CODEC_ID_NONE;
@@ -687,6 +695,26 @@ static int avi_read_header(AVFormatContext *s, AVFormatParameters *ap)
return 0;
}
+static void read_gab2_sub(AVStream *st, AVPacket *pkt) {
+ if(!strcmp(pkt->data, "GAB2") && AV_RL16(pkt->data+5) == 2) {
+ uint8_t tmp, desc[256], *d = desc;
+ const uint8_t *ptr = pkt->data+7;
+ int i, size, name_size = bytestream_get_le32(&ptr);
+
+ for(i=0; i<name_size; i+=2)
+ PUT_UTF8(bytestream_get_le16(&ptr), tmp,
+ if(d < desc+sizeof(desc)-1) *d++ = tmp;);
+ *d = 0;
+ av_metadata_set2(&st->metadata, "title", desc, 0);
+
+ ptr += 2;
+ size = bytestream_get_le32(&ptr);
+ size = FFMIN(size, pkt->size+pkt->data-ptr);
+ memmove(pkt->data, ptr, size);
+ pkt->size = size;
+ }
+}
+
static int get_stream_idx(int *d){
if( d[0] >= '0' && d[0] <= '9'
&& d[1] >= '0' && d[1] <= '9'){
@@ -801,6 +829,10 @@ resync:
av_log(s, AV_LOG_ERROR, "Failed to append palette\n");
}
+ if (st->codec->codec_type == AVMEDIA_TYPE_SUBTITLE
+ && !st->codec->codec_tag)
+ read_gab2_sub(st, pkt);
+
if (CONFIG_DV_DEMUXER && avi->dv_demux) {
dstr = pkt->destruct;
size = dv_produce_packet(avi->dv_demux, pkt,
@@ -1138,6 +1170,12 @@ static int avi_read_seek(AVFormatContext *s, int stream_index, int64_t timestamp
ast2->packet_size=
ast2->remaining= 0;
+ if (st2->codec->codec_type == AVMEDIA_TYPE_SUBTITLE
+ && !st2->codec->codec_tag) {
+ ast2->frame_offset = 0;
+ continue;
+ }
+
if (st2->nb_index_entries <= 0)
continue;
diff --git a/libavformat/utils.c b/libavformat/utils.c
index 6fa4dff..68a72fa 100644
--- a/libavformat/utils.c
+++ b/libavformat/utils.c
@@ -379,12 +379,14 @@ static int set_codec_from_probe_data(AVFormatContext *s, AVStream *st, AVProbeDa
} fmt_id_type[] = {
{ "aac" , CODEC_ID_AAC , AVMEDIA_TYPE_AUDIO },
{ "ac3" , CODEC_ID_AC3 , AVMEDIA_TYPE_AUDIO },
+ { "ass" , CODEC_ID_SSA , AVMEDIA_TYPE_SUBTITLE },
{ "dts" , CODEC_ID_DTS , AVMEDIA_TYPE_AUDIO },
{ "eac3" , CODEC_ID_EAC3 , AVMEDIA_TYPE_AUDIO },
{ "h264" , CODEC_ID_H264 , AVMEDIA_TYPE_VIDEO },
{ "m4v" , CODEC_ID_MPEG4 , AVMEDIA_TYPE_VIDEO },
{ "mp3" , CODEC_ID_MP3 , AVMEDIA_TYPE_AUDIO },
{ "mpegvideo", CODEC_ID_MPEG2VIDEO, AVMEDIA_TYPE_VIDEO },
+ { "srt" , CODEC_ID_SRT , AVMEDIA_TYPE_SUBTITLE },
{ 0 }
};
AVInputFormat *fmt = av_probe_input_format2(pd, 1, &score);
More information about the ffmpeg-devel
mailing list