commit 48df761de79c35bccf9ec74ce9d453e38d1c9d4c
Author: Gregorio Gervasio, Jr <ggervasio@yahoo.com>
Date:   Thu Dec 2 19:39:19 2010 -0800

    Fix CC for digital streams with duplicate codes.  Fix handling of multiple CC backspace codes.

diff --git a/mythtv/external/FFmpeg/libavcodec/avcodec.h b/mythtv/external/FFmpeg/libavcodec/avcodec.h
index 7d0023a..f41aea0 100644
--- a/mythtv/external/FFmpeg/libavcodec/avcodec.h
+++ b/mythtv/external/FFmpeg/libavcodec/avcodec.h
@@ -1059,6 +1059,8 @@ typedef struct AVPanScan{
      */\
     uint8_t atsc_cc_buf[1024];\
     int atsc_cc_len;\
+    uint8_t scte_cc_buf[1024];\
+    int scte_cc_len;\
 \
 
 #define FF_QSCALE_TYPE_MPEG1 0
diff --git a/mythtv/external/FFmpeg/libavcodec/mpeg12.c b/mythtv/external/FFmpeg/libavcodec/mpeg12.c
index 072df24..810f2d4 100644
--- a/mythtv/external/FFmpeg/libavcodec/mpeg12.c
+++ b/mythtv/external/FFmpeg/libavcodec/mpeg12.c
@@ -2168,14 +2168,14 @@ static void mpeg_decode_user_data(AVCodecContext *avctx,
         unsigned int cc_bytes = (cc_bits + 7 - 3) / 8;
         Mpeg1Context *s1 = avctx->priv_data;
         MpegEncContext *s = &s1->mpeg_enc_ctx;
-        if (buf_end - p >= (2+cc_bytes) && (s->tmp_atsc_cc_len + 2 + 3*cc_count) < ATSC_CC_BUF_SIZE) {
-            int atsc_cnt_loc = s->tmp_atsc_cc_len;
+        if (buf_end - p >= (2+cc_bytes) && (s->tmp_scte_cc_len + 2 + 3*cc_count) < ATSC_CC_BUF_SIZE) {
+            int scte_cnt_loc = s->tmp_scte_cc_len;
             uint8_t real_count = 0, marker = 1, i;
             GetBitContext gb;
             init_get_bits(&gb, p+2, (buf_end-p-2) * sizeof(uint8_t));
             get_bits(&gb, 5); // swallow cc_count
-            s->tmp_atsc_cc_buf[s->tmp_atsc_cc_len++] = 0x40 | (0x1f&cc_count);
-            s->tmp_atsc_cc_buf[s->tmp_atsc_cc_len++] = 0x00; // em_data
+            s->tmp_scte_cc_buf[s->tmp_scte_cc_len++] = 0x40 | (0x1f&cc_count);
+            s->tmp_scte_cc_buf[s->tmp_scte_cc_len++] = 0x00; // em_data
             for (i = 0; i < cc_count; i++) {
                 uint8_t valid, cc608_hdr;
                 uint8_t priority = get_bits(&gb, 2);
@@ -2183,31 +2183,31 @@ static void mpeg_decode_user_data(AVCodecContext *avctx,
                 uint8_t line_offset = get_bits(&gb, 5);
                 uint8_t cc_data_1 = av_reverse[get_bits(&gb, 8)];
                 uint8_t cc_data_2 = av_reverse[get_bits(&gb, 8)];
-                uint8_t type = (1 == field_no) ? 0x00 : 0x01;
+                uint8_t type = field_no - 1;
                 (void) priority; // we use all the data, don't need priority
                 marker &= get_bits(&gb, 1);
                 // dump if marker bit missing
                 valid = marker;
-                // ignore forbidden and repeated (3:2 pulldown) field numbers
-                valid = valid && (1 == field_no || 2 == field_no);
+                // ignore forbidden field numbers
+                valid = valid && (field_no > 0);
                 // ignore content not in line 21
                 valid = valid && (11 == line_offset);
                 if (!valid)
                     continue;
                 cc608_hdr = 0xf8 | (valid ? 0x04 : 0x00) | type;
                 real_count++;
-                s->tmp_atsc_cc_buf[s->tmp_atsc_cc_len++] = cc608_hdr;
-                s->tmp_atsc_cc_buf[s->tmp_atsc_cc_len++] = cc_data_1;
-                s->tmp_atsc_cc_buf[s->tmp_atsc_cc_len++] = cc_data_2;
+                s->tmp_scte_cc_buf[s->tmp_scte_cc_len++] = cc608_hdr;
+                s->tmp_scte_cc_buf[s->tmp_scte_cc_len++] = cc_data_1;
+                s->tmp_scte_cc_buf[s->tmp_scte_cc_len++] = cc_data_2;
             }
             if (!real_count)
             {
-                s->tmp_atsc_cc_len = atsc_cnt_loc;
+                s->tmp_scte_cc_len = scte_cnt_loc;
             }
             else
             {
-                s->tmp_atsc_cc_buf[atsc_cnt_loc] = 0x40 | (0x1f&real_count);
-                s->tmp_atsc_cc_len = atsc_cnt_loc + 2 + 3 * real_count;
+                s->tmp_scte_cc_buf[scte_cnt_loc] = 0x40 | (0x1f&real_count);
+                s->tmp_scte_cc_len = scte_cnt_loc + 2 + 3 * real_count;
             }
         }
     } else if (buf_end - p >= 11 &&
diff --git a/mythtv/external/FFmpeg/libavcodec/mpegvideo.c b/mythtv/external/FFmpeg/libavcodec/mpegvideo.c
index f319768..e33cbdc 100644
--- a/mythtv/external/FFmpeg/libavcodec/mpegvideo.c
+++ b/mythtv/external/FFmpeg/libavcodec/mpegvideo.c
@@ -961,6 +961,9 @@ int MPV_frame_start(MpegEncContext *s, AVCodecContext *avctx)
         memcpy(pic->atsc_cc_buf, s->tmp_atsc_cc_buf, s->tmp_atsc_cc_len);
         pic->atsc_cc_len = s->tmp_atsc_cc_len;
         s->tmp_atsc_cc_len = 0;
+        memcpy(pic->scte_cc_buf, s->tmp_scte_cc_buf, s->tmp_scte_cc_len);
+        pic->scte_cc_len = s->tmp_scte_cc_len;
+        s->tmp_scte_cc_len = 0;
 
         pic->coded_picture_number= s->coded_picture_number++;
 
diff --git a/mythtv/external/FFmpeg/libavcodec/mpegvideo.h b/mythtv/external/FFmpeg/libavcodec/mpegvideo.h
index 72b0a62..5502bdf 100644
--- a/mythtv/external/FFmpeg/libavcodec/mpegvideo.h
+++ b/mythtv/external/FFmpeg/libavcodec/mpegvideo.h
@@ -656,6 +656,8 @@ typedef struct MpegEncContext {
     /// frame for these packets has been created in MPV_frame_start().
     uint8_t tmp_atsc_cc_buf[ATSC_CC_BUF_SIZE];
     int     tmp_atsc_cc_len;
+    uint8_t tmp_scte_cc_buf[ATSC_CC_BUF_SIZE];
+    int     tmp_scte_cc_len;
 
     int (*decode_mb)(struct MpegEncContext *s, DCTELEM block[6][64]); // used by some codecs to avoid a switch()
 #define SLICE_OK         0
diff --git a/mythtv/libs/libmythtv/avformatdecoder.cpp b/mythtv/libs/libmythtv/avformatdecoder.cpp
index 484af06..4a66e86 100644
--- a/mythtv/libs/libmythtv/avformatdecoder.cpp
+++ b/mythtv/libs/libmythtv/avformatdecoder.cpp
@@ -276,6 +276,9 @@ AvFormatDecoder::AvFormatDecoder(MythPlayer *parent,
       special_decode(special_decoding),
       maxkeyframedist(-1),
       // Closed Caption & Teletext decoders
+      choose_scte_cc(true),
+      invert_scte_field(0),
+      last_scte_field(0),
       ccd608(new CC608Decoder(parent->GetCC608Reader())),
       ccd708(new CC708Decoder(parent->GetCC708Reader())),
       ttd(new TeletextDecoder(parent->GetTeletextReader())),
@@ -2383,7 +2386,7 @@ int get_avf_buffer_dxva2(struct AVCodecContext *c, AVFrame *pic)
     return 0;
 }
 
-void AvFormatDecoder::DecodeDTVCC(const uint8_t *buf, uint len)
+void AvFormatDecoder::DecodeDTVCC(const uint8_t *buf, uint len, bool scte)
 {
     if (!len)
         return;
@@ -2417,13 +2420,36 @@ void AvFormatDecoder::DecodeDTVCC(const uint8_t *buf, uint len)
         uint data2    = buf[4+(cur*3)];
         uint data     = (data2 << 8) | data1;
         uint cc_type  = cc_code & 0x03;
+        uint field;
 
-        if (cc_type <= 0x1) // EIA-608 field-1/2
+        if (scte || cc_type <= 0x1) // EIA-608 field-1/2
         {
+            if (cc_type == 0x2)
+            {
+                // SCTE repeated field
+                field = !last_scte_field;
+                invert_scte_field = !invert_scte_field;
+            }
+            else
+            {
+                field = cc_type ^ invert_scte_field;
+            }
+
+            // in film mode, we may start at the wrong field;
+            // correct if XDS is detected (must be field 2)
+            if (scte && field == 0 && data1 == 0x01)
+            {
+                if (cc_type == 1)
+                    invert_scte_field = 0;
+                field = 1;
+            }
+
+            last_scte_field = field;
+
             if (cc608_good_parity(cc608_parity_table, data))
             {
                 had_608 = true;
-                ccd608->FormatCCField(lastccptsu / 1000, cc_type, data);
+                ccd608->FormatCCField(lastccptsu / 1000, field, data);
             }
         }
         else
@@ -2932,11 +2958,28 @@ bool AvFormatDecoder::ProcessVideoFrame(AVStream *stream, AVFrame *mpa_pic)
     AVCodecContext *context = stream->codec;
 
     // Decode CEA-608 and CEA-708 captions
-    for (uint i = 0; i < (uint)mpa_pic->atsc_cc_len;
-    i += ((mpa_pic->atsc_cc_buf[i] & 0x1f) * 3) + 2)
+    uint cc_len;
+    uint8_t *cc_buf;
+    bool scte;
+
+    // if both ATSC and SCTE caption data are available, choose ATSC(?)
+    if (choose_scte_cc || mpa_pic->atsc_cc_len)
+    {
+        choose_scte_cc = false;
+        cc_len = (uint)mpa_pic->atsc_cc_len;
+        cc_buf = mpa_pic->atsc_cc_buf;
+        scte = false;
+    }
+    else
+    {
+        cc_len = (uint)mpa_pic->scte_cc_len;
+        cc_buf = mpa_pic->scte_cc_buf;
+        scte = true;
+    }
+
+    for (uint i = 0; i < cc_len; i += ((cc_buf[i] & 0x1f) * 3) + 2)
     {
-        DecodeDTVCC(mpa_pic->atsc_cc_buf + i,
-                    mpa_pic->atsc_cc_len - i);
+        DecodeDTVCC(cc_buf + i, cc_len - i, scte);
     }
 
     VideoFrame *picframe = (VideoFrame *)(mpa_pic->opaque);
diff --git a/mythtv/libs/libmythtv/avformatdecoder.h b/mythtv/libs/libmythtv/avformatdecoder.h
index 3f8d101..df64ffc 100644
--- a/mythtv/libs/libmythtv/avformatdecoder.h
+++ b/mythtv/libs/libmythtv/avformatdecoder.h
@@ -203,7 +203,7 @@ class AvFormatDecoder : public DecoderBase
     friend int64_t seek_avf(URLContext *h, int64_t offset, int whence);
     friend int close_avf(URLContext *h);
 
-    void DecodeDTVCC(const uint8_t *buf, uint buf_size);
+    void DecodeDTVCC(const uint8_t *buf, uint buf_size, bool scte);
     void InitByteContext(void);
     void InitVideoCodec(AVStream *stream, AVCodecContext *enc,
                         bool selectedStream = false);
@@ -311,6 +311,9 @@ class AvFormatDecoder : public DecoderBase
     int maxkeyframedist;
 
     // Caption/Subtitle/Teletext decoders
+    bool             choose_scte_cc;
+    uint             invert_scte_field;
+    uint             last_scte_field;
     CC608Decoder     *ccd608;
     CC708Decoder     *ccd708;
     TeletextDecoder  *ttd;
diff --git a/mythtv/libs/libmythtv/cc608decoder.cpp b/mythtv/libs/libmythtv/cc608decoder.cpp
index 9e21e1f..78ce000 100644
--- a/mythtv/libs/libmythtv/cc608decoder.cpp
+++ b/mythtv/libs/libmythtv/cc608decoder.cpp
@@ -176,7 +176,12 @@ void CC608Decoder::FormatCCField(int tc, int field, int data)
     }
 
     if (FalseDup(tc, field, data))
-        goto skip;
+    {
+        if (ignore_time_code)
+            return;
+        else
+           goto skip;
+    }
 
     XDSDecode(field, b1, b2);
 
@@ -535,10 +540,15 @@ int CC608Decoder::FalseDup(int tc, int field, int data)
 
     if (ignore_time_code)
     {
-        // just suppress duplicate control codes
+        // most digital streams with encoded VBI
+        // have duplicate control codes;
+        // suppress every other repeated control code
         if ((data == lastcode[field]) &&
             ((b1 & 0x70) == 0x10))
+        {
+            lastcode[field] = -1;
             return 1;
+        }
         else
             return 0;
     }
