Пример #1
0
// Linearly interpolate the value for a given key in the map.  If the
// key is outside the range of keys in the map, linearly extrapolate
// using the fallback ratio.
uint64_t DecoderBase::TranslatePosition(const frm_pos_map_t &map,
                                        long long key,
                                        float fallback_ratio)
{
    uint64_t key1, key2;
    uint64_t val1, val2;

    frm_pos_map_t::const_iterator lower = map.lowerBound(key);
    // QMap::lowerBound() finds a key >= the given key.  We want one
    // <= the given key, so back up one element upon > condition.
    if (lower != map.begin() && (lower == map.end() || lower.key() > key))
        --lower;
    if (lower == map.end() || lower.key() > key)
    {
        key1 = 0;
        val1 = 0;
        LOG(VB_PLAYBACK, LOG_DEBUG, LOC +
            QString("TranslatePosition(key=%1): extrapolating to (0,0)")
            .arg(key));
    }
    else
    {
        key1 = lower.key();
        val1 = lower.value();
    }
    // Find the next key >= the given key.  QMap::lowerBound() is
    // precisely correct in this case.
    frm_pos_map_t::const_iterator upper = map.lowerBound(key);
    if (upper == map.end())
    {
        // Extrapolate from (key1,val1) based on fallback_ratio
        key2 = key;
        val2 = val1 + fallback_ratio * (key2 - key1) + 0.5;
        LOG(VB_PLAYBACK, LOG_DEBUG, LOC +
            QString("TranslatePosition(key=%1, ratio=%2): "
                    "extrapolating to (%3,%4)")
            .arg(key).arg(fallback_ratio).arg(key2).arg(val2));
        return val2;
    }
    else
    {
        key2 = upper.key();
        val2 = upper.value();
    }
    if (key1 == key2) // this happens for an exact keyframe match
        return val2; // can also set key2 = key1 + 1 avoid dividing by zero

    return val1 + (double) (key - key1) * (val2 - val1) / (key2 - key1) + 0.5;
}
Пример #2
0
static void UpdatePositionMap(frm_pos_map_t &posMap, QString mapfile,
                       ProgramInfo *pginfo)
{
    if (pginfo && mapfile.isEmpty())
    {
        pginfo->ClearPositionMap(MARK_KEYFRAME);
        pginfo->ClearPositionMap(MARK_GOP_START);
        pginfo->SavePositionMap(posMap, MARK_GOP_BYFRAME);
    }
    else if (!mapfile.isEmpty())
    {
        FILE *mapfh = fopen(mapfile.toLocal8Bit().constData(), "w");
        if (!mapfh)
        {
            LOG(VB_GENERAL, LOG_ERR, QString("Could not open map file '%1'")
                    .arg(mapfile) + ENO);
            return;
        }
        frm_pos_map_t::const_iterator it;
        fprintf (mapfh, "Type: %d\n", MARK_GOP_BYFRAME);
        for (it = posMap.begin(); it != posMap.end(); ++it)
            fprintf(mapfh, "%lld %lld\n",
                    (unsigned long long)it.key(), (unsigned long long)*it);
        fclose(mapfh);
    }
}