Пример #1
0
void _stfu_n_reset(stfu_instance_t *i, const char *file, const char *func, int line)
{
    if (stfu_log != null_logger && i->debug) {
        stfu_log(file, func, line, STFU_LOG_LEVEL_EMERG, "%s RESET\n", i->name);
    }

    i->ready = 0;
	i->in_queue = &i->a_queue;
	i->out_queue = &i->b_queue;
	i->old_queue = &i->c_queue;

	i->in_queue->array_len = 0;
	i->out_queue->array_len = 0;
	i->out_queue->wr_len = 0;
	i->last_frame = NULL;
    i->in_queue->last_jitter = 0;
    i->out_queue->last_jitter = 0;


    stfu_n_reset_counters(i);
    stfu_n_sync(i, 1);
    
    i->cur_ts = 0;
    i->cur_seq = 0;
	i->last_wr_ts = 0;
	i->last_rd_ts = 0;
	i->miss_count = 0;	
    i->packet_count = 0;
    i->ts_offset = 0;

}
Пример #2
0
void stfu_n_reset(stfu_instance_t *i)
{
    if (stfu_log != null_logger && i->debug) {
        stfu_log(STFU_LOG_EMERG, "%s RESET\n", i->name);
    }

    i->ready = 0;
	i->in_queue = &i->a_queue;
	i->out_queue = &i->b_queue;
	i->old_queue = &i->c_queue;

	i->in_queue->array_len = 0;
	i->out_queue->array_len = 0;
	i->out_queue->wr_len = 0;
	i->last_frame = NULL;
    i->in_queue->last_jitter = 0;
    i->out_queue->last_jitter = 0;


    stfu_n_reset_counters(i);
    stfu_n_sync(i, 1);
    
    i->cur_ts = 0;
	i->last_wr_ts = 0;
	i->last_rd_ts = 0;
	i->miss_count = 0;	
    i->packet_count = 0;


}
Пример #3
0
stfu_frame_t *stfu_n_read_a_frame(stfu_instance_t *i)
{
	stfu_frame_t *rframe = NULL;
    int found = 0;

	if (!i->samples_per_packet) {
        return NULL;
    }
    
    if (!i->ready) {
        if (stfu_log != null_logger && i->debug) {
            stfu_log(STFU_LOG_EMERG, "%s JITTERBUFFER NOT READY: IGNORING FRAME\n", i->name);
        }
        return NULL;
    }


    if (i->cur_ts == 0 && i->last_wr_ts < 1000) {
        uint32_t x = 0;
        for (x = 0; x < i->out_queue->array_len; x++) {
            if (!i->out_queue->array[x].was_read) {
                i->cur_ts = i->out_queue->array[x].ts;
                i->cur_seq = i->out_queue->array[x].seq;
                break;
            }
            if (i->cur_ts == 0) {
                if (stfu_log != null_logger && i->debug) {
                    stfu_log(STFU_LOG_EMERG, "%s JITTERBUFFER ERROR: PUNTING\n", i->name);
                    return NULL;
                }
            }
        }
    } else {
        i->cur_ts = i->cur_ts + i->samples_per_packet;
        i->cur_seq++;
    }
    
    found = stfu_n_find_frame(i, i->out_queue, i->last_wr_ts, i->cur_ts, &rframe);

    if (!found) {
        found = stfu_n_find_frame(i, i->in_queue, i->last_wr_ts, i->cur_ts, &rframe);

        if (!found) {
            found = stfu_n_find_frame(i, i->old_queue, i->last_wr_ts, i->cur_ts, &rframe);
        }
    }

    if (found) {
        i->cur_ts = rframe->ts;
        i->cur_seq = rframe->seq;
    }

    if (i->sync_out) {
        if (!found) {
            if ((found = stfu_n_find_any_frame(i, i->out_queue, &rframe, 1))) {
                i->cur_ts = rframe->ts;
                i->cur_seq = rframe->seq;
            }
            
            if (stfu_log != null_logger && i->debug) {
                stfu_log(STFU_LOG_EMERG, "%s SYNC %u %u:%u\n", i->name, i->sync_out, i->cur_ts, i->cur_ts / i->samples_per_packet);
            }

        }
        i->sync_out = 0;
    }

    if (!i->cur_ts) {
        if (stfu_log != null_logger && i->debug) {
            stfu_log(STFU_LOG_EMERG, "%s NO TS\n", i->name);
        }
        return NULL;
    }


    if (!found && i->samples_per_packet) {
        uint32_t y;
        stfu_frame_t *frame = NULL;

        int32_t delay = i->cur_ts - i->last_rd_ts;
        uint32_t need  = abs(delay) / i->samples_per_packet;

        
        i->period_missing_count++;
        i->session_missing_count++;
        i->period_need_range += need;

        if (stfu_log != null_logger && i->debug) {        
            stfu_log(STFU_LOG_EMERG, "%s MISSING %u:%u %u %u %d %u %d\n", i->name, 
                     i->cur_ts, i->cur_ts / i->samples_per_packet, i->packet_count, i->last_rd_ts, delay, i->qlen, need);        
        }

        if (i->packet_count > i->orig_qlen * 100 && delay > 0 && need > i->qlen && need < (i->qlen + 5)) {
            i->packet_count = 0;
        }

        if (stfu_log != null_logger && i->debug) {        
            stfu_log(STFU_LOG_EMERG, "%s ------------\n", i->name);
            for(y = 0; y < i->out_queue->array_len; y++) {
                frame = &i->out_queue->array[y];
                stfu_log(STFU_LOG_EMERG, "%s\t%u:%u\n", i->name, frame->ts, frame->ts / i->samples_per_packet);
            }
            stfu_log(STFU_LOG_EMERG, "%s ------------\n\n\n", i->name);


            stfu_log(STFU_LOG_EMERG, "%s ------------\n", i->name);
            for(y = 0; y < i->in_queue->array_len; y++) {
                frame = &i->in_queue->array[y];
                stfu_log(STFU_LOG_EMERG, "%s\t%u:%u\n", i->name, frame->ts, frame->ts / i->samples_per_packet);
            }
            stfu_log(STFU_LOG_EMERG, "%s\n\n\n", i->name);

        }
    }

    if (stfu_log != null_logger && i->debug) {
        if (found) {
            stfu_log(STFU_LOG_EMERG, "%s O: %u:%u %u\n", i->name, rframe->ts, rframe->ts / i->samples_per_packet, rframe->plc);
        }
    }

    if (found) {
        i->consecutive_good_count++;
        i->period_good_count++;
        i->consecutive_bad_count = 0;
    } else {
        i->consecutive_bad_count++;
        i->period_bad_count++;
        i->consecutive_good_count = 0;
    }
    
    if (found) {
        i->last_frame = rframe;
        i->out_queue->wr_len++;
        i->last_wr_ts = rframe->ts;

        i->miss_count = 0;
        if (rframe->dlen) {
            i->plc_len = rframe->dlen;
        }

        i->plc_pt = rframe->pt;

    } else {
        int force = 0;

        if (i->consecutive_bad_count > (i->max_qlen / 2)) {
            force = 1;
        }

        if (stfu_n_find_any_frame(i, i->out_queue, &rframe, force)) {
            i->cur_ts = rframe->ts;
            i->cur_seq = rframe->seq;
            i->last_wr_ts = i->cur_ts;
            i->miss_count = 0;

            if (stfu_log != null_logger && i->debug) {
                stfu_log(STFU_LOG_EMERG, "%s AUTOCORRECT %d %d %ld %u:%u\n", i->name, 
                         i->miss_count, rframe->plc, rframe->dlen, rframe->ts, rframe->ts / i->samples_per_packet);
            }

        } else {
            if (force) {
                stfu_log(STFU_LOG_EMERG, "%s NO PACKETS HARD RESETTING\n", i->name);
                stfu_n_reset(i);
            } else {
                i->last_wr_ts = i->cur_ts;
                rframe = &i->out_queue->int_frame;
                rframe->dlen = i->plc_len;
                rframe->pt = i->plc_pt;
                rframe->ts = i->cur_ts;
                rframe->seq = i->cur_seq;
                i->miss_count++;

                if (stfu_log != null_logger && i->debug) {
                    stfu_log(STFU_LOG_EMERG, "%s PLC %d/%d %d %ld %u:%u\n", i->name, 
                             i->miss_count, i->max_qlen, rframe->plc, rframe->dlen, rframe->ts, rframe->ts / i->samples_per_packet);
                }
            }
        }

        if (i->miss_count > i->max_qlen) {
            if (stfu_log != null_logger && i->debug) {
                stfu_log(STFU_LOG_EMERG, "%s TOO MANY MISS %d/%d SYNC...\n", i->name, i->miss_count, i->max_qlen);
            }
            stfu_n_sync(i, 1);
        }
        
    }

    return rframe;
}
Пример #4
0
stfu_status_t stfu_n_add_data(stfu_instance_t *i, uint32_t ts, uint16_t seq, uint32_t pt, void *data, size_t datalen, uint32_t timer_ts, int last)
{
	uint32_t index = 0;
	stfu_frame_t *frame;
	size_t cplen = 0;
    int good_ts = 0;

    if (!i->samples_per_packet && ts && i->last_rd_ts) {
        i->ts_diff = ts - i->last_rd_ts;

        if (i->last_ts_diff == i->ts_diff) {
            if (++i->same_ts == 5) {
                i->samples_per_packet = i->ts_diff;
                if (i->max_drift && i->samples_per_packet) {
                    i->drift_max_dropped = (i->samples_per_second * 2) / i->samples_per_packet;
                }
            }
        } else {
            i->same_ts = 0;
        }
            
        i->last_ts_diff = i->ts_diff;

        if (!i->samples_per_packet) {
            i->last_rd_ts = ts;
            return STFU_IT_FAILED;
        }
    }
 
    if (timer_ts) {
        if (ts && !i->ts_offset) {
            i->ts_offset = timer_ts - ts;
        }

        i->ts_drift = ts + (i->ts_offset - timer_ts);

        if (i->ts_offset && i->ts_drift > 0) {
            i->ts_offset = timer_ts - ts;
            i->ts_drift = ts + (i->ts_offset - timer_ts);
        }


        if (i->max_drift) {
            if (i->ts_drift < i->max_drift) {
                if (++i->drift_dropped_packets < i->drift_max_dropped) {
                    stfu_log(STFU_LOG_EMERG, "%s TOO LATE !!! %u \n\n\n", i->name, ts);
                    stfu_n_sync(i, 1);
                    //return STFU_ITS_TOO_LATE;
                }
            } else {
                i->drift_dropped_packets = 0;
            }
        }
    }

    if (i->sync_in) {
        good_ts = 1;
        i->sync_in = 0;
    } else {

        if ((ts && ts == i->last_rd_ts + i->samples_per_packet) || (i->last_rd_ts > 4294900000u && ts < 5000)) {
            good_ts = 1;
        }

        if (i->last_wr_ts) {
            if ((ts <= i->last_wr_ts && (i->last_wr_ts != UINT_MAX || ts == i->last_wr_ts))) {
                if (stfu_log != null_logger && i->debug) {
                    stfu_log(STFU_LOG_EMERG, "%s TOO LATE !!! %u \n\n\n", i->name, ts);
                }
                stfu_n_sync(i, 1);
                return STFU_ITS_TOO_LATE;
            }
        }
    }

    if (good_ts) {
        i->period_clean_count++;
        i->session_clean_count++;
    }

    i->period_packet_in_count++;
    i->session_packet_in_count++;

    i->period_need_range_avg = i->period_need_range / least1(i->period_missing_count);

    if (i->period_missing_count > i->qlen * 2) {
        if (stfu_log != null_logger && i->debug) {
            stfu_log(STFU_LOG_EMERG, "%s resize %u %u\n", i->name, i->qlen, i->qlen + 1);
        }
        stfu_n_resize(i, i->qlen + 1);
        stfu_n_reset_counters(i);
    } else {
        if (i->qlen > i->orig_qlen && (i->consecutive_good_count > i->decrement_time || i->period_clean_count > i->decrement_time)) {
            stfu_n_resize(i, i->qlen - 1);
            stfu_n_reset_counters(i);
            stfu_n_sync(i, i->qlen);
        }
    }

    
    i->diff = 0;
    
    if (i->last_wr_ts) {
        if (ts < 1000 && i->last_wr_ts > (UINT_MAX - 1000)) {
            i->diff = abs((int)(((UINT_MAX - i->last_wr_ts) + ts) / i->samples_per_packet));
        } else if (ts) {
            i->diff = abs((int)(i->last_wr_ts - ts)) / i->samples_per_packet;
        }
    }
    
    i->diff_total += i->diff;

    if ((i->period_packet_in_count > i->period_time)) {
        i->period_packet_in_count = 0;

        if (i->period_missing_count == 0 && i->qlen > i->orig_qlen) {
            stfu_n_resize(i, i->qlen - 1);
            stfu_n_sync(i, i->qlen);
        }

        stfu_n_reset_counters(i);
    }
    
    if (stfu_log != null_logger && i->debug) {
        stfu_log(STFU_LOG_EMERG, "I: %s %u/%u i=%u/%u - g:%u/%u c:%u/%u b:%u - %u:%u - %u %d %u %u %d %d %d/%d\n", i->name,
                 i->qlen, i->max_qlen, i->period_packet_in_count, i->period_time, i->consecutive_good_count, 
                 i->decrement_time, i->period_clean_count, i->decrement_time, i->consecutive_bad_count,
                 ts, ts / i->samples_per_packet, 
                 i->period_missing_count, i->period_need_range_avg,
                 i->last_wr_ts, ts, i->diff, i->diff_total / least1(i->period_packet_in_count), i->ts_drift, i->max_drift);
    }

	if (last || i->in_queue->array_len == i->in_queue->array_size) {
        stfu_n_swap(i);
    }

	if (last) {
		return STFU_IM_DONE;
	}

    index = i->in_queue->array_len++;
    assert(index < i->in_queue->array_size);
	frame = &i->in_queue->array[index];

	if (i->in_queue->array_len == i->in_queue->array_size) {
        stfu_n_swap(i);
    }

	if ((cplen = datalen) > sizeof(frame->data)) {
		cplen = sizeof(frame->data);
	}

    i->last_rd_ts = ts;
    i->packet_count++;

	memcpy(frame->data, data, cplen);

    frame->pt = pt;
	frame->ts = ts;
    frame->seq = seq;
	frame->dlen = cplen;
	frame->was_read = 0;	

	return STFU_IT_WORKED;
}