commit 99db3bd9a9d0aabd23c058414a725aa3e1653024
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/libs/libmythtv/avformatdecoder.cpp b/mythtv/libs/libmythtv/avformatdecoder.cpp
index 484af06..e8254c7 100644
|
a
|
b
|
AvFormatDecoder::AvFormatDecoder(MythPlayer *parent,
|
| 295 | 295 | params.prealloced_context = 1; |
| 296 | 296 | audioSamples = (short int *)av_mallocz(AVCODEC_MAX_AUDIO_FRAME_SIZE * |
| 297 | 297 | sizeof(int32_t)); |
| 298 | | ccd608->SetIgnoreTimecode(true); |
| | 298 | ccd608->SetDigitalTimecode(true); |
| 299 | 299 | |
| 300 | 300 | bool debug = VERBOSE_LEVEL_CHECK(VB_LIBAV); |
| 301 | 301 | av_log_set_level((debug) ? AV_LOG_DEBUG : AV_LOG_ERROR); |
| … |
… |
void AvFormatDecoder::DecodeDTVCC(const uint8_t *buf, uint len)
|
| 2406 | 2406 | return; |
| 2407 | 2407 | |
| 2408 | 2408 | bool had_608 = false, had_708 = false; |
| | 2409 | int cc_type_found[2] = { 0, 0 }; |
| 2409 | 2410 | for (uint cur = 0; cur < cc_count; cur++) |
| 2410 | 2411 | { |
| 2411 | 2412 | uint cc_code = buf[2+(cur*3)]; |
| … |
… |
void AvFormatDecoder::DecodeDTVCC(const uint8_t *buf, uint len)
|
| 2423 | 2424 | if (cc608_good_parity(cc608_parity_table, data)) |
| 2424 | 2425 | { |
| 2425 | 2426 | had_608 = true; |
| 2426 | | ccd608->FormatCCField(lastccptsu / 1000, cc_type, data); |
| | 2427 | ccd608->FormatCCField(lastccptsu / 1000 + cc_type_found[cc_type], cc_type, data); |
| | 2428 | cc_type_found[cc_type]++; // need unique timestamps to help decoder |
| | 2429 | // distinguish multiple codes in the same packet |
| | 2430 | // from repeated codes in separate packets |
| 2427 | 2431 | } |
| 2428 | 2432 | } |
| 2429 | 2433 | else |
diff --git a/mythtv/libs/libmythtv/cc608decoder.cpp b/mythtv/libs/libmythtv/cc608decoder.cpp
index 9e21e1f..d689298 100644
|
a
|
b
|
using namespace std;
|
| 18 | 18 | static void init_xds_program_type(QString xds_program_type[96]); |
| 19 | 19 | |
| 20 | 20 | CC608Decoder::CC608Decoder(CC608Input *ccr) |
| 21 | | : reader(ccr), ignore_time_code(false), |
| | 21 | : reader(ccr), digital_time_code(false), |
| 22 | 22 | rbuf(new unsigned char[sizeof(ccsubtitle)+255]), |
| 23 | 23 | vps_l(0), |
| 24 | 24 | wss_flags(0), wss_valid(false), |
| … |
… |
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 (digital_time_code) |
| | 181 | return; |
| | 182 | else |
| | 183 | goto skip; |
| | 184 | } |
| 180 | 185 | |
| 181 | 186 | XDSDecode(field, b1, b2); |
| 182 | 187 | |
| … |
… |
void CC608Decoder::FormatCCField(int tc, int field, int data)
|
| 416 | 421 | style[mode] = CC_STYLE_ROLLUP; |
| 417 | 422 | break; |
| 418 | 423 | case 0x2C: //erase displayed memory |
| 419 | | if (ignore_time_code || |
| | 424 | if (digital_time_code || |
| 420 | 425 | (tc - lastclr[mode]) > 5000 || |
| 421 | 426 | lastclr[mode] == 0) |
| 422 | 427 | // don't overflow the frontend with |
| … |
… |
void CC608Decoder::FormatCCField(int tc, int field, int data)
|
| 451 | 456 | // flush |
| 452 | 457 | BufferCC(mode, len, 0); |
| 453 | 458 | } |
| 454 | | else if (ignore_time_code || |
| | 459 | else if (digital_time_code || |
| 455 | 460 | (tc - lastclr[mode]) > 5000 || |
| 456 | 461 | lastclr[mode] == 0) |
| 457 | 462 | // clear and flush |
| … |
… |
void CC608Decoder::FormatCCField(int tc, int field, int data)
|
| 505 | 510 | for (mode = field*4; mode < (field*4 + 4); mode++) |
| 506 | 511 | { |
| 507 | 512 | len = ccbuf[mode].length(); |
| 508 | | if ((ignore_time_code || ((tc - timecode[mode]) > 100)) && |
| | 513 | if ((digital_time_code || ((tc - timecode[mode]) > 100)) && |
| 509 | 514 | (style[mode] != CC_STYLE_POPUP) && len) |
| 510 | 515 | { |
| 511 | 516 | // flush unfinished line if waiting too long |
| … |
… |
int CC608Decoder::FalseDup(int tc, int field, int data)
|
| 533 | 538 | b1 = data & 0x7f; |
| 534 | 539 | b2 = (data >> 8) & 0x7f; |
| 535 | 540 | |
| 536 | | if (ignore_time_code) |
| | 541 | if (digital_time_code) |
| 537 | 542 | { |
| 538 | | // just suppress duplicate control codes |
| | 543 | // some digital streams have duplicate codes |
| | 544 | // with the same time code; |
| | 545 | // suppress those |
| 539 | 546 | if ((data == lastcode[field]) && |
| | 547 | (tc == lasttc[field])) |
| | 548 | { |
| | 549 | return 1; |
| | 550 | } |
| | 551 | |
| | 552 | // most digital streams with encoded VBI |
| | 553 | // have duplicate control codes; |
| | 554 | // suppress every other repeated control code |
| | 555 | else if ((data == lastcode[field]) && |
| 540 | 556 | ((b1 & 0x70) == 0x10)) |
| | 557 | { |
| | 558 | lastcode[field] = -1; |
| 541 | 559 | return 1; |
| | 560 | } |
| 542 | 561 | else |
| 543 | 562 | return 0; |
| 544 | 563 | } |
diff --git a/mythtv/libs/libmythtv/cc608decoder.h b/mythtv/libs/libmythtv/cc608decoder.h
index 1463144..16ba609 100644
|
a
|
b
|
class CC608Decoder
|
| 51 | 51 | void DecodeVPS(const unsigned char *buf); |
| 52 | 52 | void DecodeWSS(const unsigned char *buf); |
| 53 | 53 | |
| 54 | | void SetIgnoreTimecode(bool val) { ignore_time_code = val; } |
| | 54 | void SetDigitalTimecode(bool val) { digital_time_code = val; } |
| 55 | 55 | |
| 56 | 56 | uint GetRatingSystems(bool future) const; |
| 57 | 57 | uint GetRating(uint i, bool future) const; |
| … |
… |
class CC608Decoder
|
| 81 | 81 | |
| 82 | 82 | CC608Input *reader; |
| 83 | 83 | |
| 84 | | bool ignore_time_code; |
| | 84 | bool digital_time_code; |
| 85 | 85 | |
| 86 | 86 | time_t last_seen[4]; |
| 87 | 87 | |