Ticket #9829: cc608_dup_v2.patch

File cc608_dup_v2.patch, 10.7 KB (added by gregorio.gervasio@…, 9 years ago)

Fix handling of duplicate CC608 codes. (v2)

  • mythtv/external/FFmpeg/libavcodec/avcodec.h

    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 b typedef struct AVPanScan{ 
    10591059     */\
    10601060    uint8_t atsc_cc_buf[1024];\
    10611061    int atsc_cc_len;\
     1062    uint8_t scte_cc_buf[1024];\
     1063    int scte_cc_len;\
    10621064\
    10631065
    10641066#define FF_QSCALE_TYPE_MPEG1 0
  • mythtv/external/FFmpeg/libavcodec/mpeg12.c

    diff --git a/mythtv/external/FFmpeg/libavcodec/mpeg12.c b/mythtv/external/FFmpeg/libavcodec/mpeg12.c
    index 072df24..810f2d4 100644
    a b static void mpeg_decode_user_data(AVCodecContext *avctx, 
    21682168        unsigned int cc_bytes = (cc_bits + 7 - 3) / 8;
    21692169        Mpeg1Context *s1 = avctx->priv_data;
    21702170        MpegEncContext *s = &s1->mpeg_enc_ctx;
    2171         if (buf_end - p >= (2+cc_bytes) && (s->tmp_atsc_cc_len + 2 + 3*cc_count) < ATSC_CC_BUF_SIZE) {
    2172             int atsc_cnt_loc = s->tmp_atsc_cc_len;
     2171        if (buf_end - p >= (2+cc_bytes) && (s->tmp_scte_cc_len + 2 + 3*cc_count) < ATSC_CC_BUF_SIZE) {
     2172            int scte_cnt_loc = s->tmp_scte_cc_len;
    21732173            uint8_t real_count = 0, marker = 1, i;
    21742174            GetBitContext gb;
    21752175            init_get_bits(&gb, p+2, (buf_end-p-2) * sizeof(uint8_t));
    21762176            get_bits(&gb, 5); // swallow cc_count
    2177             s->tmp_atsc_cc_buf[s->tmp_atsc_cc_len++] = 0x40 | (0x1f&cc_count);
    2178             s->tmp_atsc_cc_buf[s->tmp_atsc_cc_len++] = 0x00; // em_data
     2177            s->tmp_scte_cc_buf[s->tmp_scte_cc_len++] = 0x40 | (0x1f&cc_count);
     2178            s->tmp_scte_cc_buf[s->tmp_scte_cc_len++] = 0x00; // em_data
    21792179            for (i = 0; i < cc_count; i++) {
    21802180                uint8_t valid, cc608_hdr;
    21812181                uint8_t priority = get_bits(&gb, 2);
    static void mpeg_decode_user_data(AVCodecContext *avctx, 
    21832183                uint8_t line_offset = get_bits(&gb, 5);
    21842184                uint8_t cc_data_1 = av_reverse[get_bits(&gb, 8)];
    21852185                uint8_t cc_data_2 = av_reverse[get_bits(&gb, 8)];
    2186                 uint8_t type = (1 == field_no) ? 0x00 : 0x01;
     2186                uint8_t type = field_no - 1;
    21872187                (void) priority; // we use all the data, don't need priority
    21882188                marker &= get_bits(&gb, 1);
    21892189                // dump if marker bit missing
    21902190                valid = marker;
    2191                 // ignore forbidden and repeated (3:2 pulldown) field numbers
    2192                 valid = valid && (1 == field_no || 2 == field_no);
     2191                // ignore forbidden field numbers
     2192                valid = valid && (field_no > 0);
    21932193                // ignore content not in line 21
    21942194                valid = valid && (11 == line_offset);
    21952195                if (!valid)
    21962196                    continue;
    21972197                cc608_hdr = 0xf8 | (valid ? 0x04 : 0x00) | type;
    21982198                real_count++;
    2199                 s->tmp_atsc_cc_buf[s->tmp_atsc_cc_len++] = cc608_hdr;
    2200                 s->tmp_atsc_cc_buf[s->tmp_atsc_cc_len++] = cc_data_1;
    2201                 s->tmp_atsc_cc_buf[s->tmp_atsc_cc_len++] = cc_data_2;
     2199                s->tmp_scte_cc_buf[s->tmp_scte_cc_len++] = cc608_hdr;
     2200                s->tmp_scte_cc_buf[s->tmp_scte_cc_len++] = cc_data_1;
     2201                s->tmp_scte_cc_buf[s->tmp_scte_cc_len++] = cc_data_2;
    22022202            }
    22032203            if (!real_count)
    22042204            {
    2205                 s->tmp_atsc_cc_len = atsc_cnt_loc;
     2205                s->tmp_scte_cc_len = scte_cnt_loc;
    22062206            }
    22072207            else
    22082208            {
    2209                 s->tmp_atsc_cc_buf[atsc_cnt_loc] = 0x40 | (0x1f&real_count);
    2210                 s->tmp_atsc_cc_len = atsc_cnt_loc + 2 + 3 * real_count;
     2209                s->tmp_scte_cc_buf[scte_cnt_loc] = 0x40 | (0x1f&real_count);
     2210                s->tmp_scte_cc_len = scte_cnt_loc + 2 + 3 * real_count;
    22112211            }
    22122212        }
    22132213    } else if (buf_end - p >= 11 &&
  • mythtv/external/FFmpeg/libavcodec/mpegvideo.c

    diff --git a/mythtv/external/FFmpeg/libavcodec/mpegvideo.c b/mythtv/external/FFmpeg/libavcodec/mpegvideo.c
    index f319768..e33cbdc 100644
    a b int MPV_frame_start(MpegEncContext *s, AVCodecContext *avctx) 
    961961        memcpy(pic->atsc_cc_buf, s->tmp_atsc_cc_buf, s->tmp_atsc_cc_len);
    962962        pic->atsc_cc_len = s->tmp_atsc_cc_len;
    963963        s->tmp_atsc_cc_len = 0;
     964        memcpy(pic->scte_cc_buf, s->tmp_scte_cc_buf, s->tmp_scte_cc_len);
     965        pic->scte_cc_len = s->tmp_scte_cc_len;
     966        s->tmp_scte_cc_len = 0;
    964967
    965968        pic->coded_picture_number= s->coded_picture_number++;
    966969
  • mythtv/external/FFmpeg/libavcodec/mpegvideo.h

    diff --git a/mythtv/external/FFmpeg/libavcodec/mpegvideo.h b/mythtv/external/FFmpeg/libavcodec/mpegvideo.h
    index 72b0a62..5502bdf 100644
    a b typedef struct MpegEncContext { 
    656656    /// frame for these packets has been created in MPV_frame_start().
    657657    uint8_t tmp_atsc_cc_buf[ATSC_CC_BUF_SIZE];
    658658    int     tmp_atsc_cc_len;
     659    uint8_t tmp_scte_cc_buf[ATSC_CC_BUF_SIZE];
     660    int     tmp_scte_cc_len;
    659661
    660662    int (*decode_mb)(struct MpegEncContext *s, DCTELEM block[6][64]); // used by some codecs to avoid a switch()
    661663#define SLICE_OK         0
  • mythtv/libs/libmythtv/avformatdecoder.cpp

    diff --git a/mythtv/libs/libmythtv/avformatdecoder.cpp b/mythtv/libs/libmythtv/avformatdecoder.cpp
    index 484af06..4a66e86 100644
    a b AvFormatDecoder::AvFormatDecoder(MythPlayer *parent, 
    276276      special_decode(special_decoding),
    277277      maxkeyframedist(-1),
    278278      // Closed Caption & Teletext decoders
     279      choose_scte_cc(true),
     280      invert_scte_field(0),
     281      last_scte_field(0),
    279282      ccd608(new CC608Decoder(parent->GetCC608Reader())),
    280283      ccd708(new CC708Decoder(parent->GetCC708Reader())),
    281284      ttd(new TeletextDecoder(parent->GetTeletextReader())),
    int get_avf_buffer_dxva2(struct AVCodecContext *c, AVFrame *pic) 
    23832386    return 0;
    23842387}
    23852388
    2386 void AvFormatDecoder::DecodeDTVCC(const uint8_t *buf, uint len)
     2389void AvFormatDecoder::DecodeDTVCC(const uint8_t *buf, uint len, bool scte)
    23872390{
    23882391    if (!len)
    23892392        return;
    void AvFormatDecoder::DecodeDTVCC(const uint8_t *buf, uint len) 
    24172420        uint data2    = buf[4+(cur*3)];
    24182421        uint data     = (data2 << 8) | data1;
    24192422        uint cc_type  = cc_code & 0x03;
     2423        uint field;
    24202424
    2421         if (cc_type <= 0x1) // EIA-608 field-1/2
     2425        if (scte || cc_type <= 0x1) // EIA-608 field-1/2
    24222426        {
     2427            if (cc_type == 0x2)
     2428            {
     2429                // SCTE repeated field
     2430                field = !last_scte_field;
     2431                invert_scte_field = !invert_scte_field;
     2432            }
     2433            else
     2434            {
     2435                field = cc_type ^ invert_scte_field;
     2436            }
     2437
     2438            // in film mode, we may start at the wrong field;
     2439            // correct if XDS is detected (must be field 2)
     2440            if (scte && field == 0 && data1 == 0x01)
     2441            {
     2442                if (cc_type == 1)
     2443                    invert_scte_field = 0;
     2444                field = 1;
     2445            }
     2446
     2447            last_scte_field = field;
     2448
    24232449            if (cc608_good_parity(cc608_parity_table, data))
    24242450            {
    24252451                had_608 = true;
    2426                 ccd608->FormatCCField(lastccptsu / 1000, cc_type, data);
     2452                ccd608->FormatCCField(lastccptsu / 1000, field, data);
    24272453            }
    24282454        }
    24292455        else
    bool AvFormatDecoder::ProcessVideoFrame(AVStream *stream, AVFrame *mpa_pic) 
    29322958    AVCodecContext *context = stream->codec;
    29332959
    29342960    // Decode CEA-608 and CEA-708 captions
    2935     for (uint i = 0; i < (uint)mpa_pic->atsc_cc_len;
    2936     i += ((mpa_pic->atsc_cc_buf[i] & 0x1f) * 3) + 2)
     2961    uint cc_len;
     2962    uint8_t *cc_buf;
     2963    bool scte;
     2964
     2965    // if both ATSC and SCTE caption data are available, choose ATSC(?)
     2966    if (choose_scte_cc || mpa_pic->atsc_cc_len)
     2967    {
     2968        choose_scte_cc = false;
     2969        cc_len = (uint)mpa_pic->atsc_cc_len;
     2970        cc_buf = mpa_pic->atsc_cc_buf;
     2971        scte = false;
     2972    }
     2973    else
     2974    {
     2975        cc_len = (uint)mpa_pic->scte_cc_len;
     2976        cc_buf = mpa_pic->scte_cc_buf;
     2977        scte = true;
     2978    }
     2979
     2980    for (uint i = 0; i < cc_len; i += ((cc_buf[i] & 0x1f) * 3) + 2)
    29372981    {
    2938         DecodeDTVCC(mpa_pic->atsc_cc_buf + i,
    2939                     mpa_pic->atsc_cc_len - i);
     2982        DecodeDTVCC(cc_buf + i, cc_len - i, scte);
    29402983    }
    29412984
    29422985    VideoFrame *picframe = (VideoFrame *)(mpa_pic->opaque);
  • mythtv/libs/libmythtv/avformatdecoder.h

    diff --git a/mythtv/libs/libmythtv/avformatdecoder.h b/mythtv/libs/libmythtv/avformatdecoder.h
    index 3f8d101..df64ffc 100644
    a b class AvFormatDecoder : public DecoderBase 
    203203    friend int64_t seek_avf(URLContext *h, int64_t offset, int whence);
    204204    friend int close_avf(URLContext *h);
    205205
    206     void DecodeDTVCC(const uint8_t *buf, uint buf_size);
     206    void DecodeDTVCC(const uint8_t *buf, uint buf_size, bool scte);
    207207    void InitByteContext(void);
    208208    void InitVideoCodec(AVStream *stream, AVCodecContext *enc,
    209209                        bool selectedStream = false);
    class AvFormatDecoder : public DecoderBase 
    311311    int maxkeyframedist;
    312312
    313313    // Caption/Subtitle/Teletext decoders
     314    bool             choose_scte_cc;
     315    uint             invert_scte_field;
     316    uint             last_scte_field;
    314317    CC608Decoder     *ccd608;
    315318    CC708Decoder     *ccd708;
    316319    TeletextDecoder  *ttd;
  • mythtv/libs/libmythtv/cc608decoder.cpp

    diff --git a/mythtv/libs/libmythtv/cc608decoder.cpp b/mythtv/libs/libmythtv/cc608decoder.cpp
    index 9e21e1f..78ce000 100644
    a b void CC608Decoder::FormatCCField(int tc, int field, int data) 
    176176    }
    177177
    178178    if (FalseDup(tc, field, data))
    179         goto skip;
     179    {
     180        if (ignore_time_code)
     181            return;
     182        else
     183           goto skip;
     184    }
    180185
    181186    XDSDecode(field, b1, b2);
    182187
    int CC608Decoder::FalseDup(int tc, int field, int data) 
    535540
    536541    if (ignore_time_code)
    537542    {
    538         // just suppress duplicate control codes
     543        // most digital streams with encoded VBI
     544        // have duplicate control codes;
     545        // suppress every other repeated control code
    539546        if ((data == lastcode[field]) &&
    540547            ((b1 & 0x70) == 0x10))
     548        {
     549            lastcode[field] = -1;
    541550            return 1;
     551        }
    542552        else
    543553            return 0;
    544554    }