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{
|
| 1059 | 1059 | */\ |
| 1060 | 1060 | uint8_t atsc_cc_buf[1024];\ |
| 1061 | 1061 | int atsc_cc_len;\ |
| | 1062 | uint8_t scte_cc_buf[1024];\ |
| | 1063 | int scte_cc_len;\ |
| 1062 | 1064 | \ |
| 1063 | 1065 | |
| 1064 | 1066 | #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
|
b
|
static void mpeg_decode_user_data(AVCodecContext *avctx,
|
| 2168 | 2168 | unsigned int cc_bytes = (cc_bits + 7 - 3) / 8; |
| 2169 | 2169 | Mpeg1Context *s1 = avctx->priv_data; |
| 2170 | 2170 | 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; |
| 2173 | 2173 | uint8_t real_count = 0, marker = 1, i; |
| 2174 | 2174 | GetBitContext gb; |
| 2175 | 2175 | init_get_bits(&gb, p+2, (buf_end-p-2) * sizeof(uint8_t)); |
| 2176 | 2176 | 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 |
| 2179 | 2179 | for (i = 0; i < cc_count; i++) { |
| 2180 | 2180 | uint8_t valid, cc608_hdr; |
| 2181 | 2181 | uint8_t priority = get_bits(&gb, 2); |
| … |
… |
static void mpeg_decode_user_data(AVCodecContext *avctx,
|
| 2183 | 2183 | uint8_t line_offset = get_bits(&gb, 5); |
| 2184 | 2184 | uint8_t cc_data_1 = av_reverse[get_bits(&gb, 8)]; |
| 2185 | 2185 | 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; |
| 2187 | 2187 | (void) priority; // we use all the data, don't need priority |
| 2188 | 2188 | marker &= get_bits(&gb, 1); |
| 2189 | 2189 | // dump if marker bit missing |
| 2190 | 2190 | 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); |
| 2193 | 2193 | // ignore content not in line 21 |
| 2194 | 2194 | valid = valid && (11 == line_offset); |
| 2195 | 2195 | if (!valid) |
| 2196 | 2196 | continue; |
| 2197 | 2197 | cc608_hdr = 0xf8 | (valid ? 0x04 : 0x00) | type; |
| 2198 | 2198 | 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; |
| 2202 | 2202 | } |
| 2203 | 2203 | if (!real_count) |
| 2204 | 2204 | { |
| 2205 | | s->tmp_atsc_cc_len = atsc_cnt_loc; |
| | 2205 | s->tmp_scte_cc_len = scte_cnt_loc; |
| 2206 | 2206 | } |
| 2207 | 2207 | else |
| 2208 | 2208 | { |
| 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; |
| 2211 | 2211 | } |
| 2212 | 2212 | } |
| 2213 | 2213 | } 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
|
b
|
int MPV_frame_start(MpegEncContext *s, AVCodecContext *avctx)
|
| 961 | 961 | memcpy(pic->atsc_cc_buf, s->tmp_atsc_cc_buf, s->tmp_atsc_cc_len); |
| 962 | 962 | pic->atsc_cc_len = s->tmp_atsc_cc_len; |
| 963 | 963 | 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; |
| 964 | 967 | |
| 965 | 968 | pic->coded_picture_number= s->coded_picture_number++; |
| 966 | 969 | |
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 {
|
| 656 | 656 | /// frame for these packets has been created in MPV_frame_start(). |
| 657 | 657 | uint8_t tmp_atsc_cc_buf[ATSC_CC_BUF_SIZE]; |
| 658 | 658 | int tmp_atsc_cc_len; |
| | 659 | uint8_t tmp_scte_cc_buf[ATSC_CC_BUF_SIZE]; |
| | 660 | int tmp_scte_cc_len; |
| 659 | 661 | |
| 660 | 662 | int (*decode_mb)(struct MpegEncContext *s, DCTELEM block[6][64]); // used by some codecs to avoid a switch() |
| 661 | 663 | #define SLICE_OK 0 |
diff --git a/mythtv/libs/libmythtv/avformatdecoder.cpp b/mythtv/libs/libmythtv/avformatdecoder.cpp
index 484af06..4a66e86 100644
|
a
|
b
|
AvFormatDecoder::AvFormatDecoder(MythPlayer *parent,
|
| 276 | 276 | special_decode(special_decoding), |
| 277 | 277 | maxkeyframedist(-1), |
| 278 | 278 | // Closed Caption & Teletext decoders |
| | 279 | choose_scte_cc(true), |
| | 280 | invert_scte_field(0), |
| | 281 | last_scte_field(0), |
| 279 | 282 | ccd608(new CC608Decoder(parent->GetCC608Reader())), |
| 280 | 283 | ccd708(new CC708Decoder(parent->GetCC708Reader())), |
| 281 | 284 | ttd(new TeletextDecoder(parent->GetTeletextReader())), |
| … |
… |
int get_avf_buffer_dxva2(struct AVCodecContext *c, AVFrame *pic)
|
| 2383 | 2386 | return 0; |
| 2384 | 2387 | } |
| 2385 | 2388 | |
| 2386 | | void AvFormatDecoder::DecodeDTVCC(const uint8_t *buf, uint len) |
| | 2389 | void AvFormatDecoder::DecodeDTVCC(const uint8_t *buf, uint len, bool scte) |
| 2387 | 2390 | { |
| 2388 | 2391 | if (!len) |
| 2389 | 2392 | return; |
| … |
… |
void AvFormatDecoder::DecodeDTVCC(const uint8_t *buf, uint len)
|
| 2417 | 2420 | uint data2 = buf[4+(cur*3)]; |
| 2418 | 2421 | uint data = (data2 << 8) | data1; |
| 2419 | 2422 | uint cc_type = cc_code & 0x03; |
| | 2423 | uint field; |
| 2420 | 2424 | |
| 2421 | | if (cc_type <= 0x1) // EIA-608 field-1/2 |
| | 2425 | if (scte || cc_type <= 0x1) // EIA-608 field-1/2 |
| 2422 | 2426 | { |
| | 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 | |
| 2423 | 2449 | if (cc608_good_parity(cc608_parity_table, data)) |
| 2424 | 2450 | { |
| 2425 | 2451 | had_608 = true; |
| 2426 | | ccd608->FormatCCField(lastccptsu / 1000, cc_type, data); |
| | 2452 | ccd608->FormatCCField(lastccptsu / 1000, field, data); |
| 2427 | 2453 | } |
| 2428 | 2454 | } |
| 2429 | 2455 | else |
| … |
… |
bool AvFormatDecoder::ProcessVideoFrame(AVStream *stream, AVFrame *mpa_pic)
|
| 2932 | 2958 | AVCodecContext *context = stream->codec; |
| 2933 | 2959 | |
| 2934 | 2960 | // 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) |
| 2937 | 2981 | { |
| 2938 | | DecodeDTVCC(mpa_pic->atsc_cc_buf + i, |
| 2939 | | mpa_pic->atsc_cc_len - i); |
| | 2982 | DecodeDTVCC(cc_buf + i, cc_len - i, scte); |
| 2940 | 2983 | } |
| 2941 | 2984 | |
| 2942 | 2985 | 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
|
b
|
class AvFormatDecoder : public DecoderBase
|
| 203 | 203 | friend int64_t seek_avf(URLContext *h, int64_t offset, int whence); |
| 204 | 204 | friend int close_avf(URLContext *h); |
| 205 | 205 | |
| 206 | | void DecodeDTVCC(const uint8_t *buf, uint buf_size); |
| | 206 | void DecodeDTVCC(const uint8_t *buf, uint buf_size, bool scte); |
| 207 | 207 | void InitByteContext(void); |
| 208 | 208 | void InitVideoCodec(AVStream *stream, AVCodecContext *enc, |
| 209 | 209 | bool selectedStream = false); |
| … |
… |
class AvFormatDecoder : public DecoderBase
|
| 311 | 311 | int maxkeyframedist; |
| 312 | 312 | |
| 313 | 313 | // Caption/Subtitle/Teletext decoders |
| | 314 | bool choose_scte_cc; |
| | 315 | uint invert_scte_field; |
| | 316 | uint last_scte_field; |
| 314 | 317 | CC608Decoder *ccd608; |
| 315 | 318 | CC708Decoder *ccd708; |
| 316 | 319 | TeletextDecoder *ttd; |
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)
|
| 176 | 176 | } |
| 177 | 177 | |
| 178 | 178 | if (FalseDup(tc, field, data)) |
| 179 | | goto skip; |
| | 179 | { |
| | 180 | if (ignore_time_code) |
| | 181 | return; |
| | 182 | else |
| | 183 | goto skip; |
| | 184 | } |
| 180 | 185 | |
| 181 | 186 | XDSDecode(field, b1, b2); |
| 182 | 187 | |
| … |
… |
int CC608Decoder::FalseDup(int tc, int field, int data)
|
| 535 | 540 | |
| 536 | 541 | if (ignore_time_code) |
| 537 | 542 | { |
| 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 |
| 539 | 546 | if ((data == lastcode[field]) && |
| 540 | 547 | ((b1 & 0x70) == 0x10)) |
| | 548 | { |
| | 549 | lastcode[field] = -1; |
| 541 | 550 | return 1; |
| | 551 | } |
| 542 | 552 | else |
| 543 | 553 | return 0; |
| 544 | 554 | } |