Exemplo n.º 1
0
static void parse_cc_service_stream(CC708Reader* cc, uint service_num)
{
    const int blk_size = cc->buf_size[service_num];
    int blk_start = 0, dlc_loc = 0, rst_loc = 0, i = 0;

    // find last reset or delay cancel in buffer
    for (i = 0; i < blk_size; i++)
    {
        if (RST == cc->buf[service_num][i])
            rst_loc = dlc_loc = i;
        else if (DLC == cc->buf[service_num][i])
            dlc_loc = i;
    }

    // reset, process only data after reset
    if (rst_loc)
    {
        cc->Reset(service_num);
        cc->delayed[service_num] = 0; // Reset implicitly cancels delay
        blk_start = rst_loc + 1;
    }

    // if we have a delay cancel, cancel any delay
    if (dlc_loc && cc->delayed[service_num])
    {
        cc->DelayCancel(service_num);
        cc->delayed[service_num] = 0;
    }

    // cancel delay if the buffer is full
    if (cc->delayed[service_num] && blk_size >= 126)
    {
        cc->DelayCancel(service_num);
        cc->delayed[service_num] = 0;
        dlc_loc = blk_size - 1;
    }

/*
  av_log(NULL, AV_LOG_ERROR,
  "cc_ss delayed(%i) blk_start(%i) blk_size(%i)\n",
  cc->delayed, blk_start, blk_size);
*/

    for (int i = (cc->delayed[service_num]) ? blk_size : blk_start;
         i < blk_size; )
    {
        const int old_i = i;
        const int code = cc->buf[service_num][i];
        if (0x0 == code)
        {
            i++;
        }
        else if (code <= 0x1f)
        {
            // C0 code -- ASCII commands + ext1: C2,C3,G2,G3 + p16: 16 chars
            i = handle_cc_c0_ext1_p16(cc, service_num, i);
        }
        else if (code <= 0x7f)
        {
            // G0 code -- mostly ASCII printables
            short character = CCtableG0[code-0x20];
            append_character(cc, service_num, character);
            i++;
            SEND_STR;
        }
        else if (code <= 0x9f)
        {
            // C1 code -- caption control codes
            i = handle_cc_c1(cc, service_num, i);
        }
        else if (code <= 0xff)
        {
            // G1 code -- ISO 8859-1 Latin 1 characters
            short character = CCtableG1[code-0xA0];
            append_character(cc, service_num, character);
            i++;
        }

#if DEBUG_CC_SERVICE
        fprintf(stderr, "i %i, blk_size %i\n", i, blk_size);
#endif

        // loop continuation check
        if (old_i == i)
        {
#if DEBUG_CC_SERVICE
            fprintf(stderr, "old_i == i == %i\n", i);
            for (int j = 0; j < blk_size; j++)
                fprintf(stderr, "0x%x ", cc->buf[service_num][j]);
            fprintf(stderr, "\n");
#endif
            if (blk_size - i > 10)
            {
                fprintf(stderr, "eia-708 decoding error...");
                cc->Reset(service_num);
                cc->delayed[service_num] = 0;
                i = cc->buf_size[service_num];
            }
            // There must be an incomplete code in buffer...
            break;
        }
        else if (cc->delayed[service_num] && dlc_loc < i)
        {
            // delay in effect
            break;
        }
        else if (cc->delayed[service_num])
        {
            // this delay has already been canceled..
            cc->DelayCancel(service_num);
            cc->delayed[service_num] = 0;
        }
    }

    // get rid of remaining bytes...
    assert(((int)blk_size - i) >= 0);
    if ((blk_size - i) > 0)
    {
        memmove(cc->buf[service_num], cc->buf[service_num] + i,
                blk_size - i);
        cc->buf_size[service_num] -= i;
    }
    else
    {
        if (0 != (blk_size - i))
        {
            fprintf(stderr, "parse_cc_service_stream buffer error "
                    "i(%i) buf_size(%i)\n", i, blk_size);
            for (i=0; i < blk_size; i++)
                fprintf(stderr, "0x%x ", cc->buf[service_num][i]);
            fprintf(stderr, "\n");
        }
        cc->buf_size[service_num] = 0;
    }
}
Exemplo n.º 2
0
static void parse_cc_service_stream(CC708Reader* cc, uint service_num)
{
    const int blk_size = cc->buf_size[service_num];
    int blk_start = 0, dlc_loc = 0, rst_loc = 0, i = 0;

    // find last reset or delay cancel in buffer
    for (i = 0; i < blk_size; i++)
    {
        switch (cc->buf[service_num][i]) {
            // Skip over parameters, since their bytes may coincide
            // with RST or DLC
            case CLW:
            case DLW:
            case DSW:
            case HDW:
            case TGW:
            case DLY:
                i += 1;
                break;
            case SPA:
            case SPL:
                i += 2;
                break;
            case SPC:
                i += 3;
                break;
            case SWA:
                i += 4;
                break;
            case DF0:
            case DF1:
            case DF2:
            case DF3:
            case DF4:
            case DF5:
            case DF6:
            case DF7:
                i += 6;
                break;
            // Detect RST or DLC bytes
            case RST:
                rst_loc = dlc_loc = i;
                break;
            case DLC:
                dlc_loc = i;
                break;
        }
    }

    // reset, process only data after reset
    if (rst_loc)
    {
        cc->Reset(service_num);
        cc->delayed[service_num] = 0; // Reset implicitly cancels delay
        blk_start = rst_loc + 1;
    }

    // if we have a delay cancel, cancel any delay
    if (dlc_loc && cc->delayed[service_num])
    {
        cc->DelayCancel(service_num);
        cc->delayed[service_num] = 0;
    }

    // cancel delay if the buffer is full
    if (cc->delayed[service_num] && blk_size >= 126)
    {
        cc->DelayCancel(service_num);
        cc->delayed[service_num] = 0;
        dlc_loc = blk_size - 1;
    }

#if 0
    LOG(VB_GENERAL, LOG_ERR,
        QString("cc_ss delayed(%1) blk_start(%2) blk_size(%3)")
            .arg(cc->delayed) .arg(blk_start) .arg(blk_size));
#endif

    for (i = (cc->delayed[service_num]) ? blk_size : blk_start;
         i < blk_size; )
    {
        const int old_i = i;
        const int code = cc->buf[service_num][i];
        if (0x0 == code)
        {
            i++;
        }
        else if (code <= 0x1f)
        {
            // C0 code -- ASCII commands + ext1: C2,C3,G2,G3 + p16: 16 chars
            i = handle_cc_c0_ext1_p16(cc, service_num, i);
        }
        else if (code <= 0x7f)
        {
            // G0 code -- mostly ASCII printables
            short character = CCtableG0[code-0x20];
            append_character(cc, service_num, character);
            i++;
            SEND_STR;
        }
        else if (code <= 0x9f)
        {
            // C1 code -- caption control codes
            i = handle_cc_c1(cc, service_num, i);
        }
        else if (code <= 0xff)
        {
            // G1 code -- ISO 8859-1 Latin 1 characters
            short character = CCtableG1[code-0xA0];
            append_character(cc, service_num, character);
            i++;
        }

#if DEBUG_CC_SERVICE
        LOG(VB_GENERAL, LOG_DEBUG, QString("i %1, blk_size %2").arg(i)
                .arg(blk_size));
#endif

        // loop continuation check
        if (old_i == i)
        {
#if DEBUG_CC_SERVICE
            LOG(VB_GENERAL, LOG_DEBUG, QString("old_i == i == %1").arg(i));
            QString msg;
            for (int j = 0; j < blk_size; j++)
                msg += QString("0x%1 ").arg(cc->buf[service_num][j], 0, 16);
            LOG(VB_GENERAL, LOG_DEBUG, msg);
#endif
            if (blk_size - i > 10)
            {
                LOG(VB_GENERAL, LOG_INFO, "eia-708 decoding error...");
                cc->Reset(service_num);
                cc->delayed[service_num] = 0;
                i = cc->buf_size[service_num];
            }
            // There must be an incomplete code in buffer...
            break;
        }
        else if (cc->delayed[service_num] && dlc_loc < i)
        {
            // delay in effect
            break;
        }
        else if (cc->delayed[service_num])
        {
            // this delay has already been canceled..
            cc->DelayCancel(service_num);
            cc->delayed[service_num] = 0;
        }
    }

    // get rid of remaining bytes...
    assert(((int)blk_size - i) >= 0);
    if ((blk_size - i) > 0)
    {
        memmove(cc->buf[service_num], cc->buf[service_num] + i,
                blk_size - i);
        cc->buf_size[service_num] -= i;
    }
    else
    {
        if (0 != (blk_size - i))
        {
            LOG(VB_GENERAL, LOG_ERR, QString("buffer error i(%1) buf_size(%2)")
                .arg(i).arg(blk_size));
            QString msg;
            for (i=0; i < blk_size; i++)
                msg += QString("0x%1 ").arg(cc->buf[service_num][i], 0, 16);
            LOG(VB_GENERAL, LOG_ERR, msg);
        }
        cc->buf_size[service_num] = 0;
    }
}