> > c9153590e5f167e41910d867639eb887164e28d2  
> > 0001-closed-caption-decoder-accept-and-decode-a-new-codec.patch
> > From bf29fe5330e83e37cf064b18918185c6b00d9b9f Mon Sep 17 00:00:00 2001
> > From: rogerdpack <rogerpack2...@gmail.com>
> > Date: Tue, 28 Apr 2020 05:15:15 +0000
> > Subject: [PATCH 1/3] closed caption decoder: accept and decode a new codec
> >  type of 'raw 608 byte pairs'
>
> breaks fate
>
> TEST    sub-cc-realtime
> --- ./tests/ref/fate/sub-cc-realtime    2020-04-28 15:43:10.506887112 +0200
> +++ tests/data/fate/sub-cc-realtime     2020-04-28 19:31:37.164407976 +0200

OK I believe to have fixed that, see the latest attached.  Plus a few
more aesthetic cleanups to boot.

Thanks!
From 5d7c12a3f703e794e1092087355bc9523d5f4d93 Mon Sep 17 00:00:00 2001
From: rogerdpack <rogerpack2005@gmail.com>
Date: Tue, 28 Apr 2020 05:15:15 +0000
Subject: [PATCH 1/3] closed caption decoder: accept and decode a new codec
 type of 'raw 608 byte pairs'

Signed-off-by: rogerdpack <rogerpack2005@gmail.com>
---
 configure                 |   1 +
 libavcodec/Makefile       |   2 +-
 libavcodec/allcodecs.c    |   1 +
 libavcodec/ccaption_dec.c | 116 ++++++++++++++++++++++++++------------
 libavcodec/codec_desc.c   |   7 +++
 libavcodec/codec_id.h     |   1 +
 libavcodec/version.h      |   4 +-
 7 files changed, 92 insertions(+), 40 deletions(-)

diff --git a/configure b/configure
index 080d93a129..8a0a6cce7c 100755
--- a/configure
+++ b/configure
@@ -2681,6 +2681,7 @@ bink_decoder_select="blockdsp hpeldsp"
 binkaudio_dct_decoder_select="mdct rdft dct sinewin wma_freqs"
 binkaudio_rdft_decoder_select="mdct rdft sinewin wma_freqs"
 cavs_decoder_select="blockdsp golomb h264chroma idctdsp qpeldsp videodsp"
+ccaption_raw_608_decoder_select="ccaption_decoder"
 clearvideo_decoder_select="idctdsp"
 cllc_decoder_select="bswapdsp"
 comfortnoise_encoder_select="lpc"
diff --git a/libavcodec/Makefile b/libavcodec/Makefile
index 28076c2c83..006eb40107 100644
--- a/libavcodec/Makefile
+++ b/libavcodec/Makefile
@@ -246,6 +246,7 @@ OBJS-$(CONFIG_C93_DECODER)             += c93.o
 OBJS-$(CONFIG_CAVS_DECODER)            += cavs.o cavsdec.o cavsdsp.o \
                                           cavsdata.o
 OBJS-$(CONFIG_CCAPTION_DECODER)        += ccaption_dec.o ass.o
+OBJS-$(CONFIG_CCAPTION_RAW_608_DECODER)        += ccaption_dec.o ass.o
 OBJS-$(CONFIG_CDGRAPHICS_DECODER)      += cdgraphics.o
 OBJS-$(CONFIG_CDTOONS_DECODER)         += cdtoons.o
 OBJS-$(CONFIG_CDXL_DECODER)            += cdxl.o
@@ -463,7 +464,6 @@ OBJS-$(CONFIG_MP3ON4FLOAT_DECODER)     += mpegaudiodec_float.o mpeg4audio.o
 OBJS-$(CONFIG_MPC7_DECODER)            += mpc7.o mpc.o
 OBJS-$(CONFIG_MPC8_DECODER)            += mpc8.o mpc.o
 OBJS-$(CONFIG_MPEGVIDEO_DECODER)       += mpeg12dec.o mpeg12.o mpeg12data.o
-OBJS-$(CONFIG_MPEG1VIDEO_DECODER)      += mpeg12dec.o mpeg12.o mpeg12data.o
 OBJS-$(CONFIG_MPEG1VIDEO_ENCODER)      += mpeg12enc.o mpeg12.o
 OBJS-$(CONFIG_MPEG1_CUVID_DECODER)     += cuviddec.o
 OBJS-$(CONFIG_MPEG1_V4L2M2M_DECODER)   += v4l2_m2m_dec.o
diff --git a/libavcodec/allcodecs.c b/libavcodec/allcodecs.c
index 54d40ebdbc..b78f58cb4c 100644
--- a/libavcodec/allcodecs.c
+++ b/libavcodec/allcodecs.c
@@ -645,6 +645,7 @@ extern AVCodec ff_ssa_decoder;
 extern AVCodec ff_ass_encoder;
 extern AVCodec ff_ass_decoder;
 extern AVCodec ff_ccaption_decoder;
+extern AVCodec ff_ccaption_raw_608_decoder;
 extern AVCodec ff_dvbsub_encoder;
 extern AVCodec ff_dvbsub_decoder;
 extern AVCodec ff_dvdsub_encoder;
diff --git a/libavcodec/ccaption_dec.c b/libavcodec/ccaption_dec.c
index bf3563a0bc..a2197cd673 100644
--- a/libavcodec/ccaption_dec.c
+++ b/libavcodec/ccaption_dec.c
@@ -341,43 +341,51 @@ static void write_char(CCaptionSubContext *ctx, struct Screen *screen, char ch)
 }
 
 /**
- * This function after validating parity bit, also remove it from data pair.
- * The first byte doesn't pass parity, we replace it with a solid blank
- * and process the pair.
- * If the second byte doesn't pass parity, it returns INVALIDDATA
- * user can ignore the whole pair and pass the other pair.
+ * This function accepts a byte pair [EIA 608 first byte, EIA 608 second byte]
+ * checks both for parity and strips parity on success.
+ * If the first byte doesn't pass parity, replace it with a solid blank
+ * and process the pair anyway.
+ * Returns failure for parity failure or "no data" (padding bytes).
+ */
+static int validate_eia_608_byte_pair(uint8_t *cc_data_pair) {
+    if (!av_parity(cc_data_pair[1])) {
+        return AVERROR_INVALIDDATA;
+    }
+    if (!av_parity(cc_data_pair[0])) {
+        cc_data_pair[0]=0x7F; // solid blank
+    }
+    if ((cc_data_pair[0] & 0x7F) == 0 && (cc_data_pair[1] & 0x7F) == 0) {
+        return AVERROR_INVALIDDATA; // padding bytes
+    }
+    /* remove parity bit */
+    cc_data_pair[0] &= 0x7F;
+    cc_data_pair[1] &= 0x7F;
+    return 0;
+}
+
+/**
+ * This function accepts "cc_data_pair" = [708 header byte, EIA 608 first byte, EIA 608 second byte]
+ * This function after validating parity bits, also removes parity bits them from 608 data pair.
  */
 static int validate_cc_data_pair(uint8_t *cc_data_pair)
 {
+    int ret;
     uint8_t cc_valid = (*cc_data_pair & 4) >>2;
     uint8_t cc_type = *cc_data_pair & 3;
 
     if (!cc_valid)
         return AVERROR_INVALIDDATA;
 
-    // if EIA-608 data then verify parity.
-    if (cc_type==0 || cc_type==1) {
-        if (!av_parity(cc_data_pair[2])) {
-            return AVERROR_INVALIDDATA;
-        }
-        if (!av_parity(cc_data_pair[1])) {
-            cc_data_pair[1]=0x7F;
-        }
-    }
-
-    //Skip non-data
-    if ((cc_data_pair[0] == 0xFA || cc_data_pair[0] == 0xFC || cc_data_pair[0] == 0xFD)
-         && (cc_data_pair[1] & 0x7F) == 0 && (cc_data_pair[2] & 0x7F) == 0)
-        return AVERROR_PATCHWELCOME;
-
-    //skip 708 data
+    // skip 708 data, we only support "608 over 708" not native 708
     if (cc_type == 3 || cc_type == 2)
         return AVERROR_PATCHWELCOME;
 
-    /* remove parity bit */
-    cc_data_pair[1] &= 0x7F;
-    cc_data_pair[2] &= 0x7F;
-
+    // Must be EIA-608 data, verify parity.
+    if (cc_type==0 || cc_type==1) {
+      if (ret = validate_eia_608_byte_pair(cc_data_pair + 1)) {
+          return ret;
+      }
+    }
     return 0;
 }
 
@@ -756,6 +764,8 @@ static int decode(AVCodecContext *avctx, void *data, int *got_sub, AVPacket *avp
     int len = avpkt->size;
     int ret = 0;
     int i;
+    int stride;
+    int raw_608 = avctx->codec_id == AV_CODEC_ID_EIA_608_RAW_BYTE_PAIRS;
 
     av_fast_padded_malloc(&ctx->pktbuf, &ctx->pktbuf_size, len);
     if (!ctx->pktbuf) {
@@ -764,16 +774,28 @@ static int decode(AVCodecContext *avctx, void *data, int *got_sub, AVPacket *avp
     }
     memcpy(ctx->pktbuf, avpkt->data, len);
     bptr = ctx->pktbuf;
-
-    for (i  = 0; i < len; i += 3) {
-        uint8_t cc_type = *(bptr + i) & 3;
-        if (validate_cc_data_pair(bptr + i))
-            continue;
-        /* ignoring data field 1 */
-        if(cc_type == 1)
-            continue;
-        else
-            process_cc608(ctx, start_time, *(bptr + i + 1) & 0x7f, *(bptr + i + 2) & 0x7f);
+    if (raw_608) {
+        stride = 2; // expect 2 byte "per packet"
+    } else {
+        stride = 3; // eia 708 Closed caption data packet
+    }
+    for (i = 0; i < len; i += stride) {
+        if (raw_608) {
+            if (validate_eia_608_byte_pair(bptr)) {
+                continue;
+            }
+            process_cc608(ctx, start_time, *(bptr + i), *(bptr + i + 1));
+        } else {
+          // look for 608 over 708 bytes
+          uint8_t cc_type = *(bptr + i) & 3;
+          if (validate_cc_data_pair(bptr + i))
+              continue;
+          /* ignore NTSC_CC_FIELD_2 (cc_type 1) for now */
+          if (cc_type == 1)
+              continue;
+          else
+              process_cc608(ctx, start_time, *(bptr + i + 1), *(bptr + i + 2));
+        }
 
         if (!ctx->buffer_changed)
             continue;
@@ -781,7 +803,7 @@ static int decode(AVCodecContext *avctx, void *data, int *got_sub, AVPacket *avp
 
         if (*ctx->buffer.str || ctx->real_time)
         {
-            ff_dlog(ctx, "cdp writing data (%s)\n",ctx->buffer.str);
+            ff_dlog(ctx, "writing data (%s)\n",ctx->buffer.str);
             ret = ff_ass_add_rect(sub, ctx->buffer.str, ctx->readorder++, 0, NULL, NULL);
             if (ret < 0)
                 return ret;
@@ -829,9 +851,16 @@ static const AVClass ccaption_dec_class = {
     .version    = LIBAVUTIL_VERSION_INT,
 };
 
+static const AVClass ccaption_raw_608_dec_class = {
+    .class_name = "Closed caption Decoder Raw 608",
+    .item_name  = av_default_item_name,
+    .option     = options,
+    .version    = LIBAVUTIL_VERSION_INT,
+};
+
 AVCodec ff_ccaption_decoder = {
     .name           = "cc_dec",
-    .long_name      = NULL_IF_CONFIG_SMALL("Closed Caption (EIA-608 / CEA-708)"),
+    .long_name      = NULL_IF_CONFIG_SMALL("Closed Caption (EIA-608 over CEA-708)"),
     .type           = AVMEDIA_TYPE_SUBTITLE,
     .id             = AV_CODEC_ID_EIA_608,
     .priv_data_size = sizeof(CCaptionSubContext),
@@ -841,3 +870,16 @@ AVCodec ff_ccaption_decoder = {
     .decode         = decode,
     .priv_class     = &ccaption_dec_class,
 };
+
+AVCodec ff_ccaption_raw_608_decoder = {
+    .name           = "cc_raw_608_dec",
+    .long_name      = NULL_IF_CONFIG_SMALL("Closed Caption (EIA-608 raw byte pairs)"),
+    .type           = AVMEDIA_TYPE_SUBTITLE,
+    .id             = AV_CODEC_ID_EIA_608_RAW_BYTE_PAIRS,
+    .priv_data_size = sizeof(CCaptionSubContext),
+    .init           = init_decoder,
+    .close          = close_decoder,
+    .flush          = flush_decoder,
+    .decode         = decode,
+    .priv_class     = &ccaption_raw_608_dec_class,
+};
diff --git a/libavcodec/codec_desc.c b/libavcodec/codec_desc.c
index 93433b5a27..c0e32c57bc 100644
--- a/libavcodec/codec_desc.c
+++ b/libavcodec/codec_desc.c
@@ -3180,6 +3180,13 @@ static const AVCodecDescriptor codec_descriptors[] = {
         .long_name = NULL_IF_CONFIG_SMALL("EIA-608 closed captions"),
         .props     = AV_CODEC_PROP_TEXT_SUB,
     },
+    {
+        .id        = AV_CODEC_ID_EIA_608_RAW_BYTE_PAIRS,
+        .type      = AVMEDIA_TYPE_SUBTITLE,
+        .name      = "eia_608_raw_byte_pairs",
+        .long_name = NULL_IF_CONFIG_SMALL("EIA-608 closed captions raw byte pairs"),
+        .props     = AV_CODEC_PROP_TEXT_SUB,
+    },
     {
         .id        = AV_CODEC_ID_JACOSUB,
         .type      = AVMEDIA_TYPE_SUBTITLE,
diff --git a/libavcodec/codec_id.h b/libavcodec/codec_id.h
index e7d6e059db..805e18758b 100644
--- a/libavcodec/codec_id.h
+++ b/libavcodec/codec_id.h
@@ -513,6 +513,7 @@ enum AVCodecID {
 
     AV_CODEC_ID_MICRODVD   = 0x17800,
     AV_CODEC_ID_EIA_608,
+    AV_CODEC_ID_EIA_608_RAW_BYTE_PAIRS,
     AV_CODEC_ID_JACOSUB,
     AV_CODEC_ID_SAMI,
     AV_CODEC_ID_REALTEXT,
diff --git a/libavcodec/version.h b/libavcodec/version.h
index 3de16c884c..552129e0a3 100644
--- a/libavcodec/version.h
+++ b/libavcodec/version.h
@@ -28,8 +28,8 @@
 #include "libavutil/version.h"
 
 #define LIBAVCODEC_VERSION_MAJOR  58
-#define LIBAVCODEC_VERSION_MINOR  82
-#define LIBAVCODEC_VERSION_MICRO 100
+#define LIBAVCODEC_VERSION_MINOR  83
+#define LIBAVCODEC_VERSION_MICRO  100
 
 #define LIBAVCODEC_VERSION_INT  AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \
                                                LIBAVCODEC_VERSION_MINOR, \
-- 
2.17.1

_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".

Reply via email to