コード例 #1
0
ファイル: example1.cpp プロジェクト: f4exb/cm256
bool Example1Tx::makeFecBlocks(SuperBlock *txBlocks, uint16_t frameIndex)
{
	if (m_params.RecoveryCount > 0)
	{
	    for (int i = 0; i < m_params.OriginalCount; i++)
	    {
	        m_txDescriptorBlocks[i].Block = (void *) &txBlocks[i].protectedBlock;
	        m_txDescriptorBlocks[i].Index = i;
	    }

	    if (m_cm256_OK)
	    {
	        if (cm256_encode(m_params, m_txDescriptorBlocks, m_txRecovery))
	        {
	            std::cerr << "example2: encode failed" << std::endl;
	            return false;
	        }

	        for (int i = 0; i < m_params.RecoveryCount; i++)
	        {
	            txBlocks[i + m_params.OriginalCount].header.blockIndex = i + m_params.OriginalCount;
	            txBlocks[i + m_params.OriginalCount].header.frameIndex = frameIndex;
	            txBlocks[i + m_params.OriginalCount].protectedBlock = m_txRecovery[i];
	        }
	    }
	}

    return true;
}
コード例 #2
0
ファイル: maingcc.cpp プロジェクト: hexameron/ssdv
/**
 * This is a more realistic example with separation of received data creation (mocking) and its processing
 */
bool example3()
{
#pragma pack(push, 1)
    struct Sample
    {
        uint16_t i;
        uint16_t q;
    };
    struct Header
    {
        uint16_t frameIndex;
        uint8_t  blockIndex;
        uint8_t  filler;
    };

    static const int samplesPerBlock = (512 - sizeof(Header)) / sizeof(Sample);

    struct ProtectedBlock
    {
        Sample samples[samplesPerBlock];
    };
    struct SuperBlock
    {
        Header         header;
        ProtectedBlock protectedBlock;
    };
#pragma pack(pop)

    if (cm256_init())
    {
        return false;
    }

    cm256_encoder_params params;

    // Number of bytes per file block
    params.BlockBytes = sizeof(ProtectedBlock);

    // Number of blocks
    params.OriginalCount = 128;  // Superframe = set of protected frames

    // Number of additional recovery blocks generated by encoder
    params.RecoveryCount = 32;

    SuperBlock* txBuffer = new SuperBlock[params.OriginalCount+params.RecoveryCount];
    ProtectedBlock* txRecovery = new ProtectedBlock[params.RecoveryCount];
    cm256_block txDescriptorBlocks[params.OriginalCount+params.RecoveryCount];
    int frameCount = 0;

    // Fill original data
    for (int i = 0; i < params.OriginalCount+params.RecoveryCount; ++i)
    {
        txBuffer[i].header.frameIndex = frameCount;
        txBuffer[i].header.blockIndex = i;

        if (i < params.OriginalCount)
        {
            txBuffer[i].protectedBlock.samples[0].i = i; // marker
        }
        else
        {
            memset((void *) &txBuffer[i].protectedBlock, 0, sizeof(ProtectedBlock));
        }

        txDescriptorBlocks[i].Block = (void *) &txBuffer[i].protectedBlock;
        txDescriptorBlocks[i].Index = txBuffer[i].header.blockIndex;
    }

    // Generate recovery data

    long long ts = getUSecs();

    if (cm256_encode(params, txDescriptorBlocks, txRecovery))
    {
        std::cerr << "example2: encode failed" << std::endl;
        delete[] txBuffer;
        delete[] txRecovery;
        return false;
    }

    long long usecs = getUSecs() - ts;

    std::cerr << "Encoded in " << usecs << " microseconds" << std::endl;

    // insert recovery data in sent data
    for (int i = 0; i < params.RecoveryCount; i++)
    {
        txBuffer[params.OriginalCount+i].protectedBlock = txRecovery[i];
    }

    SuperBlock* rxBuffer = new SuperBlock[params.OriginalCount + params.RecoveryCount]; // received blocks
    int k = 0;

    for (int i = 0; i < params.OriginalCount+params.RecoveryCount; i++)
    {
        if (i % 5 != 4)
        {
            rxBuffer[k] = txBuffer[i];
            k++;
        }
    }

    Sample *samplesBuffer = new Sample[samplesPerBlock * params.OriginalCount];
    ProtectedBlock* retrievedDataBuffer = (ProtectedBlock *) samplesBuffer;
    ProtectedBlock* recoveryBuffer = new ProtectedBlock[params.OriginalCount];      // recovery blocks with maximum size

    cm256_block rxDescriptorBlocks[params.OriginalCount];
    int recoveryStartIndex;
    k = 0;

    for (int i = 0; i < params.OriginalCount; i++)
    {
        int blockIndex = rxBuffer[i].header.blockIndex;

        if (blockIndex < params.OriginalCount) // it's an original block
        {
            retrievedDataBuffer[blockIndex] = rxBuffer[i].protectedBlock;
            rxDescriptorBlocks[i].Block = (void *) &retrievedDataBuffer[blockIndex];
            rxDescriptorBlocks[i].Index = blockIndex;
        }
        else // it's a recovery block
        {
            if (k == 0)
            {
                recoveryStartIndex = i;
            }

            recoveryBuffer[k] = rxBuffer[i].protectedBlock;
            rxDescriptorBlocks[i].Block = (void *) &recoveryBuffer[k];
            rxDescriptorBlocks[i].Index = blockIndex;
            k++;
        }
    }

    ts = getUSecs();

    if (cm256_decode(params, rxDescriptorBlocks))
    {
        delete[] txBuffer;
        delete[] txRecovery;
        delete[] rxBuffer;
        delete[] samplesBuffer;
        delete[] recoveryBuffer;

        return false;
    }

    usecs = getUSecs() - ts;

    for (int i = 0; i < k; i++) // recover missing blocks
    {
        int blockIndex = rxDescriptorBlocks[recoveryStartIndex+i].Index;
        retrievedDataBuffer[blockIndex] = recoveryBuffer[i];
    }

    for (int i = 0; i < params.OriginalCount; i++)
    {
        std::cerr << i << ":"
                << (unsigned int) rxDescriptorBlocks[i].Index << ":"
                << (unsigned int) retrievedDataBuffer[i].samples[0].i << std::endl;
    }

    std::cerr << "Decoded in " << usecs << " microseconds" << std::endl;

    delete[] txBuffer;
    delete[] txRecovery;
    delete[] rxBuffer;
    delete[] samplesBuffer;
    delete[] recoveryBuffer;

    return true;
}
コード例 #3
0
ファイル: maingcc.cpp プロジェクト: hexameron/ssdv
bool ExampleFileUsage()
{
    if (cm256_init())
    {
        return false;
    }

    cm256_encoder_params params;

    // Number of bytes per file block
    params.BlockBytes = 1296;

    // Number of blocks
    params.OriginalCount = 100;

    // Number of additional recovery blocks generated by encoder
    params.RecoveryCount = 30;

    // Size of the original file
    static const int OriginalFileBytes = params.OriginalCount * params.BlockBytes;

    // Allocate and fill the original file data
    uint8_t* originalFileData = new uint8_t[OriginalFileBytes];
    for (int i = 0; i < OriginalFileBytes; ++i)
    {
        originalFileData[i] = (uint8_t)i;
    }

    // Pointers to data
    cm256_block blocks[256];
    for (int i = 0; i < params.OriginalCount; ++i)
    {
        blocks[i].Block = originalFileData + i * params.BlockBytes;
    }

    // Recovery data
    uint8_t* recoveryBlocks = new uint8_t[params.RecoveryCount * params.BlockBytes];

    // Generate recovery data
    if (cm256_encode(params, blocks, recoveryBlocks))
    {
        delete[] originalFileData;
        delete[] recoveryBlocks;
        return false;
    }

    // Initialize the indices
    for (int i = 0; i < params.OriginalCount; ++i)
    {
        blocks[i].Index = cm256_get_original_block_index(params, i);
    }

    //// Simulate loss of data, substituting a recovery block in its place ////
    for (int i = 0; i < params.RecoveryCount && i < params.OriginalCount; ++i)
    {
        blocks[i].Block = recoveryBlocks + params.BlockBytes * i; // First recovery block
        blocks[i].Index = cm256_get_recovery_block_index(params, i); // First recovery block index
    }
    //// Simulate loss of data, substituting a recovery block in its place ////

    if (cm256_decode(params, blocks))
    {
        delete[] originalFileData;
        delete[] recoveryBlocks;
        return false;
    }

    for (int i = 0; i < params.RecoveryCount && i < params.OriginalCount; ++i)
    {
        uint8_t* block = (uint8_t*)blocks[i].Block;
        int index = blocks[i].Index;

        for (int j = 0; j < params.BlockBytes; ++j)
        {
            const uint8_t expected = (uint8_t)(j + index * params.BlockBytes);
            if (block[j] != expected)
            {
                delete[] originalFileData;
                delete[] recoveryBlocks;
                return false;
            }
        }
    }

    delete[] originalFileData;
    delete[] recoveryBlocks;

    return true;
}
コード例 #4
0
ファイル: maingcc.cpp プロジェクト: hexameron/ssdv
bool example2()
{
    static const int payloadSize = 256; // represents 4 subframes of 64 bytes
#pragma pack(push, 1)
    struct ProtectedBlock
    {
        uint8_t blockIndex;
        uint8_t data[payloadSize];
    };
    struct SuperBlock
    {
        uint8_t        frameIndex;
        uint8_t        blockIndex;
        ProtectedBlock protectedBlock;
    };
#pragma pack(pop)

    if (cm256_init())
    {
        return false;
    }

    cm256_encoder_params params;

    // Number of bytes per file block
    params.BlockBytes = sizeof(ProtectedBlock);

    // Number of blocks
    params.OriginalCount = 128;  // Superframe = set of protected frames

    // Number of additional recovery blocks generated by encoder
    params.RecoveryCount = 32;

    SuperBlock* txBuffer = new SuperBlock[params.OriginalCount+params.RecoveryCount];
    ProtectedBlock* txRecovery = new ProtectedBlock[params.RecoveryCount];
    cm256_block txDescriptorBlocks[params.OriginalCount+params.RecoveryCount];
    int frameCount = 0;

    // Fill original data
    for (int i = 0; i < params.OriginalCount+params.RecoveryCount; ++i)
    {
        txBuffer[i].frameIndex = frameCount;
        txBuffer[i].blockIndex = i;

        if (i < params.OriginalCount)
        {
            txBuffer[i].protectedBlock.blockIndex = i;

            for (int j = 0; j < payloadSize; ++j)
            {
                txBuffer[i].protectedBlock.data[j] = i;
            }

            txDescriptorBlocks[i].Block = (void *) &txBuffer[i].protectedBlock;
            txDescriptorBlocks[i].Index = txBuffer[i].blockIndex;
        }
        else
        {
            memset((void *) &txBuffer[i].protectedBlock, 0, sizeof(ProtectedBlock));
            txDescriptorBlocks[i].Block = (void *) &txBuffer[i].protectedBlock;
            txDescriptorBlocks[i].Index = i;
        }
    }

    // Generate recovery data

    long long ts = getUSecs();

    if (cm256_encode(params, txDescriptorBlocks, txRecovery))
    {
        std::cerr << "example2: encode failed" << std::endl;
        delete[] txBuffer;
        delete[] txRecovery;
        return false;
    }

    long long usecs = getUSecs() - ts;

    std::cerr << "Encoded in " << usecs << " microseconds" << std::endl;

    // insert recovery data in sent data
    for (int i = 0; i < params.RecoveryCount; i++)
    {
        txBuffer[params.OriginalCount+i].protectedBlock = txRecovery[i];
    }

    SuperBlock* rxBuffer = new SuperBlock[params.OriginalCount];
    cm256_block rxDescriptorBlocks[params.OriginalCount];
    int k = 0;

    for (int i = 0; i < params.OriginalCount+params.RecoveryCount; i++)
    {
        if (k < params.OriginalCount)
        {
            if (i % 5 != 4)
            {
                rxBuffer[k] = txBuffer[i];
                rxDescriptorBlocks[k].Block = (void *) &rxBuffer[k].protectedBlock;
                rxDescriptorBlocks[k].Index = rxBuffer[k].blockIndex;
                k++;
            }
        }
    }

    ts = getUSecs();

    if (cm256_decode(params, rxDescriptorBlocks))
    {
        delete[] txBuffer;
        delete[] txRecovery;
        delete[] rxBuffer;

        return false;
    }

    usecs = getUSecs() - ts;

    for (int i = 0; i < params.OriginalCount; i++)
    {
        std::cerr << i << ":"
                << (unsigned int) rxBuffer[i].blockIndex << ":"
                << (unsigned int) rxBuffer[i].protectedBlock.blockIndex << ":"
                << (unsigned int) rxBuffer[i].protectedBlock.data[0] << std::endl;
    }

    std::cerr << "Decoded in " << usecs << " microseconds" << std::endl;

    delete[] txBuffer;
    delete[] txRecovery;
    delete[] rxBuffer;

    return true;
}