интересная задачка, у меня получилось как-то так. решал для себя, но вдруг пригодится:
# -*- coding: utf-8 -*-
from pprint import pprint
from datetime import datetime, timedelta
from collections import defaultdict
INTERVAL = 15
assert 0 < INTERVAL <= 60, "алгоритм работает не совсем корректно при значениях интервала больше 60"
def get_time_list(start, end, interval):
    """
        Список "времен" в которые попадает звонок
    """
    t = start + timedelta(seconds=(interval - ((start.second % interval) or interval)))  # стартовое время в которое попадает звонок с учетом интервала
    res = []
    while t.time() <= end.time():  # используем .time() т.к. если сравнивать datetime можно перейти на следующий день
        res.append(t.time().isoformat())
        t = t + timedelta(seconds=interval)
    return res
with open('calls.log', 'r') as f:
    res = defaultdict(int)
    for line in f.readlines():
        start_time, duration = line.split()
        start_time = datetime(1, 1, 1, *map(int, start_time.split(':')))  # используем datatime вместо time, потому что к time нельзя прибавить timedelta
        end_time = start_time+ timedelta(seconds=int(duration))
        time_list = get_time_list(start_time, end_time, INTERVAL)
        for t in time_list:
            res[t] += 1
    pprint(res)
результат на вашем наборе:
{'11:02:15': 1,
 '11:02:30': 2,
 '11:02:45': 2,
 '11:03:00': 2,
 '11:03:15': 3,
 '11:03:30': 3,
 '11:03:45': 2,
 '11:04:00': 2,
 '11:04:15': 2,
 '11:04:30': 2,
 '11:04:45': 2,
 '11:05:00': 1,
 '11:05:15': 1,
 '11:05:30': 1,
 '11:05:45': 1,
 '11:06:00': 1,
 '11:06:15': 1,
 '11:06:30': 1}