[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