[FFmpeg-devel] [PATCH] [HACK] mxfdec: support EIA-608 (closed caption subtitles).

Reimar Döffinger Reimar.Doeffinger at gmx.de
Thu Apr 12 21:45:54 CEST 2012


This is a hack because:
1) The way to detect this subtitle type is very questionable,
   and might cause other subtitle types to be misdetected
   as EIA-608
2) The subtitle packets do not get any pts/dts values assigned
3) I don't have the slightest clue what those extra 32 bytes
   I throw away are good for

However with a few (minor, basically accept 0xfd, 0xfe as additional
CC codes in addition for 0xfe and 0xff used for subtitles) changes
MPlayer's CC decoder can display the data properly.

Signed-off-by: Reimar Döffinger <Reimar.Doeffinger at gmx.de>
---
 libavformat/avienc.c |    2 +-
 libavformat/mxf.c    |    1 +
 libavformat/mxfdec.c |   17 ++++++++++++++++-
 3 files changed, 18 insertions(+), 2 deletions(-)

diff --git a/libavformat/avienc.c b/libavformat/avienc.c
index 3fb64e9..d94ae4d 100644
--- a/libavformat/avienc.c
+++ b/libavformat/avienc.c
@@ -234,7 +234,7 @@ static int avi_write_header(AVFormatContext *s)
         case AVMEDIA_TYPE_SUBTITLE:
             // XSUB subtitles behave like video tracks, other subtitles
             // are not (yet) supported.
-            if (stream->codec_id != CODEC_ID_XSUB) {
+            if (0 && stream->codec_id != CODEC_ID_XSUB) {
                 av_log(s, AV_LOG_ERROR, "Subtitle streams other than DivX XSUB are not supported by the AVI muxer.\n");
                 return AVERROR_PATCHWELCOME;
             }
diff --git a/libavformat/mxf.c b/libavformat/mxf.c
index c5ac753..8148ae3 100644
--- a/libavformat/mxf.c
+++ b/libavformat/mxf.c
@@ -28,6 +28,7 @@
 const MXFCodecUL ff_mxf_data_definition_uls[] = {
     { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x01,0x03,0x02,0x02,0x01,0x00,0x00,0x00 }, 13, AVMEDIA_TYPE_VIDEO },
     { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x01,0x03,0x02,0x02,0x02,0x00,0x00,0x00 }, 13, AVMEDIA_TYPE_AUDIO },
+    { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x01,0x03,0x02,0x02,0x03,0x00,0x00,0x00 }, 13, AVMEDIA_TYPE_SUBTITLE },
     { { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 },  0,  AVMEDIA_TYPE_DATA },
 };
 
diff --git a/libavformat/mxfdec.c b/libavformat/mxfdec.c
index 26fa9cd..9d95111 100644
--- a/libavformat/mxfdec.c
+++ b/libavformat/mxfdec.c
@@ -1451,6 +1451,8 @@ static int mxf_parse_structural_metadata(MXFContext *mxf)
         PRINT_KEY(mxf->fc, "data definition   ul", source_track->sequence->data_definition_ul);
         codec_ul = mxf_get_codec_ul(ff_mxf_data_definition_uls, &source_track->sequence->data_definition_ul);
         st->codec->codec_type = codec_ul->id;
+	if (st->codec->codec_type == AVMEDIA_TYPE_SUBTITLE)
+            st->codec->codec_id = CODEC_ID_EIA_608;
 
         source_package->descriptor = mxf_resolve_strong_ref(mxf, &source_package->descriptor_ref, AnyType);
         if (source_package->descriptor) {
@@ -2043,6 +2045,12 @@ static int mxf_read_packet_old(AVFormatContext *s, AVPacket *pkt)
                     av_log(s, AV_LOG_ERROR, "error reading D-10 aes3 frame\n");
                     return AVERROR_INVALIDDATA;
                 }
+            } else if (st->codec->codec_id == CODEC_ID_EIA_608 && klv.length > 28 + 4) {
+                avio_skip(s->pb, 28);
+                ret = av_get_packet(s->pb, pkt, klv.length - 28 - 4);
+                if (ret < 0)
+                    return ret;
+                avio_skip(s->pb, 4);
             } else {
                 ret = av_get_packet(s->pb, pkt, klv.length);
                 if (ret < 0)
@@ -2117,7 +2125,14 @@ static int mxf_read_packet(AVFormatContext *s, AVPacket *pkt)
     if ((ret64 = avio_seek(s->pb, pos, SEEK_SET)) < 0)
         return ret64;
 
-    if ((ret = av_get_packet(s->pb, pkt, size)) < 0)
+    if (st->codec->codec_id == CODEC_ID_EIA_608 && size > 28 + 4) {
+        avio_skip(s->pb, 28);
+        ret = av_get_packet(s->pb, pkt, size - 28 - 4);
+        avio_skip(s->pb, 4);
+    } else
+        ret = av_get_packet(s->pb, pkt, size);
+
+    if (ret < 0)
         return ret;
 
     if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO && t->ptses &&
-- 
1.7.10



More information about the ffmpeg-devel mailing list