Если оно бежит в два раза быстрее, то это уже мега косяк который хрен поборешь - нужно менять железо. А небольшая ошибка, несколько десятков секунд в день, вполне правится синхронизацией которую я описал. Всё очень просто.
Y_Mur Объясняю еще раз. Речь не о том, что кадры приходят с задержкой, а о том, что разная скорость времени. Через 1000000 реальных секунд энкодер будет штамповать кадры так, как будто пришло 1001000 секунд.
_DEN_ А если из-за перегрузки сети или компа с клиентом система не успеет вовремя отобразить 10-100 кадров, то их тоже "нельзя выкидывать" ? )) и что же ты в этом случае делашь? - их ускоренный показ? )
_DEN_ Неможет время идти настолько с разной скоростью, ну максимум несколько секунд в день. Если по другому, меняй железо. ^)
Y_Mur Такая ситуация слишком маловероятна - это я могу сказать, потому что знаю условия использования софта. Но если вдруг она и произойдет, то ничего страшного, часы на компе всеравно идут четко, поэтому да, будет небольшое замедление и ускоренный показ.
_DEN_ Откуда мы знаем что время на сервере идёт в два раза быстрее? И вообще зачем это нужно знать? Чтобы побороть кривое железо? Непонятно. Время есть время, оно не должно течь по разному.
Booster форман.jpg Несколько секунд в день - это критично. А с какой разницей идет время - не важно, поскольку достаточно научиться вычислять этот коэффициент, и все будет хорошо. Пусть оно там хоть в 10 раз быстрее идет. Заменить железо я не могу, потому что этот вопрос не в моей компетенции. Кроме того, никто не вставляет в 50-200-долларовые камеры сверхточные атомные часы, и заменой железа вопрос не решится полностью.
В два раза быстрее - это я привел для примера, чтобы было понятнее. Конечно мы этого не знаем. Суть топика в том и есть, чтобы научиться вычислять этот коэффициент без ущерба для зрителя.
_DEN_ Пусть у тебя есть кадры c номерами от 0 до N пришедшие в момент T(по часам клиента). Пусть B - время между кадрами, А - время прихода 0го кадра. Пытаемся минимизировать сумму квадратов разностей (A+B*i-T), находим по методу наименьших квадратов A и B и радуемся жизни.
_DEN_ Дык я и говорю о том что если ты искусственно сымитируешь этот случай ради корректировки рассинхронизации то ничего страшного не произойдёт Просто эталон времени это не условные счётчики камеры и клиента, а то что изображено на кадрах (направь камеру так чтобы она снимала точные часы Поэтому храбро подстраивай условное время клиента под факт поступления кадров, а если для этого придётся пару кадров притормозить или ускорить то не обращай внимания.
_DEN_ Хотелось бы уточнить )) 1. Encoder: по своему внутреннему таймеру генерирует поток кадров с временным промежутком например 35 мс. кадр(000), задержка(35 мс), кадр(002), задержка(35 мс) и тд. 2. выход encodera подается на вход сервера вещания, который упаковывает кадры в HTTP-формат. 3. клиент последовательно получает по http-соединению данные, расшифровывает и подает кадр за кадром проигрывателю(то есть подал 1 кадр, выдержал 35 мс , подал 2 кадр, выдержал 35 мс). где загвоздка то? неизвестна точная величина временной задержки?
Y_Mur Эти часы тоже могут идти в несколько раз быстрее или медленнее. Тут нужно снимать движение солнца. ^)
Booster Это если Архимед со своим рычагом хулиганить не будет, а то как начнёт землю переворачивать и опять коэффициент х2 вводить придётся ) _DEN_ Но ведь это не означает, что камера начинает показывать будущее и что упомянутые мною точные часы на изображении будут спешить Поэтому подстраивай клиента под кадры а не наоборот. А совет Boosterа с периодическим сбросом времени клиента как раз и есть самый простой способ этого достичь.
Y_Mur Согласен, но только если проигрывание будет много позже записи. А так время будет одновременно ускоряться и на сервере и на клиенте. Только и клиента нужно синхронизировать по солнцу. ^)
Итак. У нас есть энкодер. Это такая штука, на которую я коннекчусь по HTTP, и получаю в ответ HTTP Multipart Response. Смысл этого Response в том, что это последовательность [заголовок кадра - кадр]. Каждый кадр в своем заголовке имеет Timestamp. Это штамп времени в микросекундах. Если штамп первого кадра принять за ноль, то штамп остальных кадров равен моменту времени с начала стрима, когда этот кадр нужно показать пользователю. Штампы времени проставляются энкодером. Очевидно, что для того, чтобы проставлять штампы времени, нужны собственные часы. Так вот, проблема заключается в том, что скорость течения времени на часах энкодера отличается от скорости течения времени на компе. Я допускаю, что отличается в константу. То есть, если принять время, прошедшее с некоторой фиксированной точки на компе за T1, а время на энкодере, прошедшее от этой же точки за T2, то получится соотношение: T1 = N * T2 Где N - это коэффициент, на который отличаются часы компа и часы энкодера. На деле N ~= 0,99988. Теперь о том, почему нельзя периодически принимать текущий кадр за первый кадр. Все буду писать в буквах, чтобы было понятны все моменты. Пусть у нас с момента старта стрима прошло T компьютерного времени. По мнению энкодера, в таком случае, прошло T / N времени (то есть - чуть больше, т.к. N < 1). Итак, у нас фрагмент потока, который мы приняли за T времени. Но, поскольку энкодер считает, что прошло T / N времени, то этот фрагмент потока будет проштампован так, как будто прошло T / N времени. То есть, проигрывая поток, мы будем смотреть его в замедленном воспроизведении. Он будет проигрываться в 1 / N раз медленнее. Показав фрагмент потока, принятого за время T, синхронизируясь по штампам времени, мы, на самом деле, воспроизведем не T времени видео, а T * N. То есть мы покажем T * N, и недопоказываем еще хвостик в T * (1 - N) времени потока. Теперь мы принимаем текущий кадр за первый, и начинаем отсчет заново. Ну и что? Недопоказанный хвостик в T * (1 - N) времени так и останется недопоказанным. Прыгнуть на этот хвостик вперед мы не можем по двум причинам. Во-первых - это даст зрительный артефакт. Во-вторых - мы не знаем это N. Вероятно, если вычислять это N периодически, то этот "прыжок" будет незаметен. Я думаю, что достаточно вычислять его каждое dT времени, такое, что dT * (1 - N) будет меньше, чем расстояние между двумя соседними кадрами. Это я попробую сегодня. Это все я и описал в нульпосте. Надеюсь, что теперь понятно, в чем проблема, и почему "принять текущий кадр за первый" никак не решит проблему.
Y_Mur >_< Камера будет показывать прошлое, а не будущее!!!!!!!!!!!1111111 Потому что время на ней идет быстрее, а следовательно поток вытягивается. Вспомни как работает съемка, на которой видно, как лопается мыльный пузырь. Точно также она работает. Только на той камере время идет в мульйон раз быстрее, а на моей - только в 1.0001. А если кто-нибудь еще что-нибудь скажет про бредни Booster-а о сбросе времени, то я его задушу собственными руками!!!!111