{"id":495825,"date":"2026-09-23T21:59:51","date_gmt":"2026-09-23T21:59:51","guid":{"rendered":"https:\/\/savepearlharbor.com\/?p=495825"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=495825","title":{"rendered":"\u0422\u0435\u0440\u043f\u0435\u043d\u0438\u0435. \u0418\u043b\u0438 \u043a\u0430\u043a \u043e\u0434\u0438\u043d \u0437\u0430\u0432\u0438\u0441\u0448\u0438\u0439 \u043a\u0430\u0434\u0440 \u0437\u0430\u0441\u0442\u0430\u0432\u0438\u043b \u043c\u0435\u043d\u044f \u043f\u043e\u0441\u0442\u0440\u043e\u0438\u0442\u044c \u0435\u0449\u0451 \u043f\u043e\u043b\u0441\u0438\u0441\u0442\u0435\u043c\u044b ;)"},"content":{"rendered":"<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<p>\u0417\u043d\u0430\u0435\u0442\u0435, \u044f \u0445\u043e\u0442\u0435\u043b \u0441\u0435\u0433\u043e\u0434\u043d\u044f \u043f\u043e\u0433\u043e\u0432\u043e\u0440\u0438\u0442\u044c \u043e \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u0433\u043b\u0443\u0431\u043e\u043a\u043e\u0439 \u0432\u0435\u0449\u0438. \u0417\u0430\u0447\u0435\u043c \u043d\u0430\u043c \u0432\u043e\u043e\u0431\u0449\u0435 \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0430\u0442\u044c \u0447\u0442\u043e-\u0442\u043e \u0434\u0435\u043b\u0430\u0442\u044c? \u041d\u0435 \u0437\u0430\u0447\u0435\u043c \u043d\u0430\u0447\u0438\u043d\u0430\u0442\u044c. \u041d\u0430\u0447\u0438\u043d\u0430\u0442\u044c \u043b\u0435\u0433\u043a\u043e. \u0412 \u043d\u0430\u0447\u0430\u043b\u0435 \u0435\u0441\u0442\u044c \u0438\u0434\u0435\u044f, \u0430\u0437\u0430\u0440\u0442, \u043d\u043e\u0432\u044b\u0439 \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0439, \u043f\u0435\u0440\u0432\u044b\u0435 \u043a\u043e\u043c\u043c\u0438\u0442\u044b \u0438 \u043e\u0449\u0443\u0449\u0435\u043d\u0438\u0435, \u0447\u0442\u043e \u0441\u0435\u0439\u0447\u0430\u0441 \u0442\u044b \u0441\u0434\u0435\u043b\u0430\u0435\u0448\u044c \u0447\u0442\u043e-\u0442\u043e \u0447\u0435\u0440\u0442\u043e\u0432\u0441\u043a\u0438 \u043a\u0440\u0443\u0442\u043e\u0435. \u0410 \u043f\u043e\u0442\u043e\u043c \u043f\u0440\u043e\u0445\u043e\u0434\u0438\u0442 \u043d\u0435\u0434\u0435\u043b\u044f, \u043c\u0435\u0441\u044f\u0446, \u0433\u043e\u0434, \u0438 \u0442\u044b \u0441\u0438\u0434\u0438\u0448\u044c \u043d\u043e\u0447\u044c\u044e \u043f\u0435\u0440\u0435\u0434 \u043c\u043e\u043d\u0438\u0442\u043e\u0440\u043e\u043c \u0438 \u0441\u043c\u043e\u0442\u0440\u0438\u0448\u044c \u043d\u0430 \u043a\u0430\u0440\u0442\u0438\u043d\u043a\u0443, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u043f\u043e\u0447\u0435\u043c\u0443-\u0442\u043e \u0434\u0451\u0440\u0433\u0430\u0435\u0442\u0441\u044f. \u0425\u043e\u0442\u044f \u0432\u0441\u0451 \u0434\u043e\u043b\u0436\u043d\u043e \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c.<\/p>\n<blockquote>\n<p><em>\u042f \u0431\u044b \u0445\u043e\u0442\u0435\u043b \u0441\u0440\u0430\u0437\u0443 \u0440\u0430\u0441\u0441\u043a\u0430\u0437\u0430\u0442\u044c \u0447\u0442\u043e \u044f \u043d\u0435 \u043f\u0438\u0441\u0430\u0440\u044c, \u042f \u043d\u0435 \u043f\u0438\u0448\u0443 \u0438 \u043d\u0435 \u043f\u0440\u0438\u0434\u0443\u043c\u044b\u0432\u0430\u044e \u0438\u0434\u0435\u0438 \u0441 \u043d\u0435\u0439\u0440\u043e\u0441\u0435\u0442\u044f\u043c\u0438, \u044f \u0441\u0442\u0430\u0440\u0430\u044e\u0441\u044c \u0432 \u043d\u0430\u0441\u0442\u0440\u043e\u0435\u043d\u0438\u0435 \u043f\u0430\u0440\u0443 \u043d\u0435\u0434\u0435\u043b\u044c \u0433\u043e\u0442\u043e\u0432\u0438\u0442\u0441\u044f \u0438 \u0432\u044b\u0434\u0430\u0432\u0430\u0442\u044c \u0441\u0442\u0430\u0442\u044c\u044e. \u042f \u043d\u0435 \u0431\u0443\u0434\u0443 \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c, \u043d\u043e \u0435\u0441\u043b\u0438 \u0431\u0443\u0434\u0443\u0442 \u043b\u044e\u0434\u0438 \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0437\u0430\u043c\u0435\u0442\u044f\u0442 \u043e\u0448\u0438\u0431\u043a\u0443, \u043f\u043e\u0436\u0430\u043b\u0443\u0439\u0441\u0442\u0430 \u043f\u0438\u0448\u0438\u0442\u0435 \u0432 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u043a\u0430\u043a \u043e\u0431\u044b\u0447\u043d\u043e \u043f\u0440\u0438\u043d\u044f\u0442\u043e \u043d\u0430 \u0445\u0430\u0431\u0440\u0435.<\/em><\/p>\n<\/blockquote>\n<p>\u0421 \u0432\u0430\u043c\u0438 \u0410\u0440\u0442\u0443\u0440 \u0412\u0430\u043b\u0438\u0435\u0432. \u0421\u0435\u0433\u043e\u0434\u043d\u044f \u044f \u043d\u0435 \u0431\u0443\u0434\u0443 \u0433\u043e\u0432\u043e\u0440\u0438\u0442\u044c \u043e \u0441\u043c\u0435\u0440\u0442\u0438, \u043b\u044e\u0431\u0432\u0438, \u0440\u043e\u0436\u0434\u0435\u043d\u0438\u0438 \u0438 \u043f\u0440\u043e\u0447\u0438\u0445 \u0432\u0435\u0449\u0430\u0445, \u043a\u0443\u0434\u0430 \u043c\u0435\u043d\u044f \u043f\u0435\u0440\u0438\u043e\u0434\u0438\u0447\u0435\u0441\u043a\u0438 \u0437\u0430\u043d\u043e\u0441\u0438\u0442. \u0421\u0435\u0433\u043e\u0434\u043d\u044f \u044f \u0445\u043e\u0447\u0443 \u043f\u043e\u0433\u043e\u0432\u043e\u0440\u0438\u0442\u044c \u043e <strong>\u0442\u0435\u0440\u043f\u0435\u043d\u0438\u0438<\/strong>. \u0418 \u0434\u0430, \u0441\u0442\u0430\u0442\u044c\u044f \u0431\u0443\u0434\u0435\u0442 \u0434\u043b\u0438\u043d\u043d\u043e\u0439. <strong><em>\u041f\u043e\u0442\u0435\u0440\u043f\u0438\u0442\u0435<\/em><\/strong>.<\/p>\n<p>\u0410 \u0435\u0449\u0451 \u0445\u0432\u0430\u0442\u0438\u0442 \u0443\u0436\u0435 \u0434\u0443\u043c\u0430\u0442\u044c, \u0447\u0442\u043e \u043a\u0430\u0436\u0434\u0443\u044e \u043c\u043e\u044e \u0441\u0442\u0430\u0442\u044c\u044e \u043f\u0438\u0448\u0435\u0442 \u043e\u0447\u0435\u0440\u0435\u0434\u043d\u043e\u0439 AI. \u041d\u0435\u0442. \u042f \u0410\u0440\u0442\u0443\u0440. \u041f\u0438\u0448\u0443 \u0441\u0430\u043c. \u041f\u043e\u0447\u0435\u043c\u0443 \u044f \u0434\u043e \u0441\u0438\u0445 \u043f\u043e\u0440 \u0441\u043d\u0430\u0447\u0430\u043b\u0430 \u043f\u0438\u0448\u0443 \u0447\u0435\u0440\u043d\u043e\u0432\u0438\u043a \u0432 <code>.md<\/code> \u2014 \u043d\u0435 \u0437\u043d\u0430\u044e. \u041d\u0430\u0432\u0435\u0440\u043d\u043e\u0435, \u0443\u0436\u0435 \u043f\u0440\u0438\u0432\u044b\u0447\u043a\u0430.<\/p>\n<p>\u0421\u0435\u0433\u043e\u0434\u043d\u044f \u043d\u0435 \u0431\u0443\u0434\u0435\u0442 \u043e\u0447\u0435\u0440\u0435\u0434\u043d\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0438 \u043f\u0440\u043e \u00ab\u0442\u0440\u0438\u043e\u00bb. \u0425\u043e\u0442\u044f EvertyDesk \u0438 EvertyDisplay \u0441\u044e\u0434\u0430 \u0432\u0441\u0451 \u0440\u0430\u0432\u043d\u043e \u0432\u043b\u0435\u0437\u0443\u0442. \u041f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u0432\u043d\u0435\u0437\u0430\u043f\u043d\u043e \u043e\u043a\u0430\u0437\u0430\u043b\u043e\u0441\u044c, \u0447\u0442\u043e \u043e\u0434\u0438\u043d \u043c\u043e\u0439 \u043f\u0440\u043e\u0434\u0443\u043a\u0442 \u043f\u043e\u043c\u043e\u0433\u0430\u0435\u0442 \u043c\u043d\u0435 \u043e\u0442\u043b\u0430\u0436\u0438\u0432\u0430\u0442\u044c \u0434\u0440\u0443\u0433\u043e\u0439.<\/p>\n<p>\u041d\u043e \u043d\u0430\u0447\u043d\u0451\u043c \u043d\u0435 \u0441 \u044d\u0442\u043e\u0433\u043e.<\/p>\n<h3>\u041a\u043e\u0433\u0434\u0430 \u0432\u0441\u0451 \u0432\u0440\u043e\u0434\u0435 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442<\/h3>\n<p>\u0415\u0441\u0442\u044c \u043e\u0434\u0438\u043d \u043e\u0441\u043e\u0431\u0435\u043d\u043d\u043e \u043c\u0435\u0440\u0437\u043a\u0438\u0439 \u0442\u0438\u043f \u0431\u0430\u0433\u043e\u0432. \u042d\u0442\u043e \u043d\u0435 \u043a\u043e\u0433\u0434\u0430 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0430 \u043f\u0430\u0434\u0430\u0435\u0442. \u0415\u0441\u043b\u0438 \u043e\u043d\u0430 \u0443\u043f\u0430\u043b\u0430 \u2014 \u043f\u0440\u0435\u043a\u0440\u0430\u0441\u043d\u043e. \u0415\u0441\u0442\u044c stack trace, \u0435\u0441\u0442\u044c panic, \u0435\u0441\u0442\u044c error, \u0435\u0441\u0442\u044c \u0445\u043e\u0442\u044c \u0447\u0442\u043e-\u0442\u043e.<\/p>\n<p>\u041d\u0430\u0441\u0442\u043e\u044f\u0449\u0430\u044f \u043c\u0435\u0440\u0437\u043e\u0441\u0442\u044c \u043d\u0430\u0447\u0438\u043d\u0430\u0435\u0442\u0441\u044f \u0442\u043e\u0433\u0434\u0430, \u043a\u043e\u0433\u0434\u0430 <strong>\u0432\u0441\u0451 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442<\/strong>.<\/p>\n<p>\u0421\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u0435 \u0435\u0441\u0442\u044c. \u041a\u0430\u0440\u0442\u0438\u043d\u043a\u0430 \u0438\u0434\u0451\u0442. \u041a\u0443\u0440\u0441\u043e\u0440 \u0434\u0432\u0438\u0433\u0430\u0435\u0442\u0441\u044f. \u041f\u0430\u043a\u0435\u0442\u044b \u043f\u0440\u0438\u0435\u0437\u0436\u0430\u044e\u0442. FPS \u0432\u0440\u043e\u0434\u0435 \u0442\u043e\u0436\u0435 \u0435\u0441\u0442\u044c. \u0410 \u0442\u044b \u0441\u043c\u043e\u0442\u0440\u0438\u0448\u044c \u043d\u0430 \u044d\u043a\u0440\u0430\u043d \u0438 \u043f\u043e\u043d\u0438\u043c\u0430\u0435\u0448\u044c: \u0447\u0442\u043e-\u0442\u043e \u043d\u0435 \u0442\u0430\u043a.<\/p>\n<p>\u041a\u0430\u0440\u0442\u0438\u043d\u043a\u0430 \u0431\u0443\u0434\u0442\u043e \u0437\u0430\u0432\u0438\u0441\u0430\u0435\u0442. \u041d\u0435 \u043d\u0430\u043c\u0435\u0440\u0442\u0432\u043e, \u043d\u0435 \u043d\u0430 \u0441\u0435\u043a\u0443\u043d\u0434\u044b. \u041f\u0440\u043e\u0441\u0442\u043e \u043e\u0449\u0443\u0449\u0435\u043d\u0438\u0435, \u0447\u0442\u043e \u0441\u0438\u0441\u0442\u0435\u043c\u0430 \u043f\u043e\u0441\u0442\u043e\u044f\u043d\u043d\u043e \u043d\u0435\u043c\u043d\u043e\u0433\u043e \u043e\u043f\u0430\u0437\u0434\u044b\u0432\u0430\u0435\u0442.<\/p>\n<p>\u0418 \u0432\u043e\u0442 \u0442\u0443\u0442 \u043d\u0430\u0447\u0438\u043d\u0430\u0435\u0442\u0441\u044f \u043b\u044e\u0431\u0438\u043c\u043e\u0435 \u0440\u0430\u0437\u0432\u043b\u0435\u0447\u0435\u043d\u0438\u0435 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0430. \u041c\u043e\u0436\u0435\u0442 \u0441\u0435\u0442\u044c? \u041c\u043e\u0436\u0435\u0442 \u0434\u0435\u043a\u043e\u0434\u0435\u0440? \u041c\u043e\u0436\u0435\u0442 Windows? \u041c\u043e\u0436\u0435\u0442 \u043c\u043e\u043d\u0438\u0442\u043e\u0440? \u041c\u043e\u0436\u0435\u0442 30 FPS \u043f\u0440\u043e\u0441\u0442\u043e \u0432\u044b\u0433\u043b\u044f\u0434\u044f\u0442 \u0442\u0430\u043a? \u041c\u043e\u0436\u0435\u0442 relay? \u041c\u043e\u0436\u0435\u0442 \u0432\u043e\u043e\u0431\u0449\u0435 \u043f\u043e\u043a\u0430\u0437\u0430\u043b\u043e\u0441\u044c?<\/p>\n<p>\u041c\u043e\u0436\u043d\u043e \u0435\u0449\u0451 \u043c\u0438\u043d\u0443\u0442 \u0434\u0432\u0430\u0434\u0446\u0430\u0442\u044c \u043f\u043e\u0434\u0432\u0438\u0433\u0430\u0442\u044c \u043c\u044b\u0448\u044c\u044e \u0438 \u043e\u043a\u043e\u043d\u0447\u0430\u0442\u0435\u043b\u044c\u043d\u043e \u0441\u043e\u0439\u0442\u0438 \u0441 \u0443\u043c\u0430.<\/p>\n<p>\u042f \u043f\u0440\u0438\u043c\u0435\u0440\u043d\u043e \u044d\u0442\u0438\u043c \u0438 \u0437\u0430\u043d\u0438\u043c\u0430\u043b\u0441\u044f, \u043f\u043e\u043a\u0430 \u0432 \u043a\u0430\u043a\u043e\u0439-\u0442\u043e \u043c\u043e\u043c\u0435\u043d\u0442 \u043d\u0435 \u043f\u043e\u043d\u044f\u043b: \u0445\u0432\u0430\u0442\u0438\u0442 \u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u0433\u043b\u0430\u0437\u0430\u043c\u0438. \u041d\u0430\u0434\u043e \u0438\u0437\u043c\u0435\u0440\u044f\u0442\u044c.<\/p>\n<h3>\u0413\u0434\u0435, \u043c\u0430\u0442\u044c \u0435\u0433\u043e, \u043f\u0440\u043e\u043f\u0430\u043b\u0438 \u043c\u0438\u043b\u043b\u0438\u0441\u0435\u043a\u0443\u043d\u0434\u044b<\/h3>\n<p>\u042f \u043f\u0435\u0440\u0435\u0441\u0442\u0430\u043b \u0441\u043f\u0440\u0430\u0448\u0438\u0432\u0430\u0442\u044c: \u00ab\u041f\u043e\u0447\u0435\u043c\u0443 \u0442\u043e\u0440\u043c\u043e\u0437\u0438\u0442 \u043a\u0430\u0440\u0442\u0438\u043d\u043a\u0430?\u00bb \u042d\u0442\u043e \u0441\u043b\u0438\u0448\u043a\u043e\u043c \u0431\u043e\u043b\u044c\u0448\u043e\u0439 \u0438 \u043f\u0440\u0430\u043a\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u0431\u0435\u0441\u043f\u043e\u043b\u0435\u0437\u043d\u044b\u0439 \u0432\u043e\u043f\u0440\u043e\u0441.<\/p>\n<p>\u041f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u044b\u0439 \u0432\u043e\u043f\u0440\u043e\u0441 \u043e\u043a\u0430\u0437\u0430\u043b\u0441\u044f \u0434\u0440\u0443\u0433\u0438\u043c:<\/p>\n<p><strong>\u0433\u0434\u0435 \u0438\u043c\u0435\u043d\u043d\u043e \u043a\u0430\u0434\u0440 \u0442\u0435\u0440\u044f\u0435\u0442 \u0432\u0440\u0435\u043c\u044f?<\/strong><\/p>\n<p>\u041a\u0430\u0434\u0440 \u0432\u0435\u0434\u044c \u043d\u0435 \u0432\u043e\u0437\u043d\u0438\u043a\u0430\u0435\u0442 \u043d\u0430 \u044d\u043a\u0440\u0430\u043d\u0435 \u043c\u0430\u0433\u0438\u0447\u0435\u0441\u043a\u0438. \u0423 \u043d\u0435\u0433\u043e \u0435\u0441\u0442\u044c \u0436\u0438\u0437\u043d\u044c. \u041f\u0435\u0440\u0432\u044b\u0439 \u0444\u0440\u0430\u0433\u043c\u0435\u043d\u0442 \u043f\u0440\u0438\u0435\u0445\u0430\u043b \u043f\u043e \u0441\u0435\u0442\u0438. \u041f\u043e\u0442\u043e\u043c \u043e\u0441\u0442\u0430\u043b\u044c\u043d\u044b\u0435. \u041f\u043e\u0442\u043e\u043c assembler \u043f\u043e\u043d\u044f\u043b, \u0447\u0442\u043e \u043a\u0430\u0434\u0440 \u043f\u043e\u043b\u043d\u044b\u0439. \u041f\u043e\u0442\u043e\u043c \u043f\u043e\u043b\u043e\u0436\u0438\u043b \u0435\u0433\u043e \u0432 \u043e\u0447\u0435\u0440\u0435\u0434\u044c. \u041f\u043e\u0442\u043e\u043c decoder \u0437\u0430\u0431\u0440\u0430\u043b \u0435\u0433\u043e. \u041f\u043e\u0442\u043e\u043c \u0440\u0430\u0441\u043f\u0430\u043a\u043e\u0432\u0430\u043b. \u041f\u043e\u0442\u043e\u043c \u043a\u0430\u0434\u0440 \u0434\u043e\u0448\u0451\u043b \u0434\u043e present.<\/p>\n<p>\u0417\u043d\u0430\u0447\u0438\u0442, \u043d\u0430\u0434\u043e \u0431\u044b\u043b\u043e \u043f\u0435\u0440\u0435\u0441\u0442\u0430\u0442\u044c \u0438\u0437\u043c\u0435\u0440\u044f\u0442\u044c \u00abFPS\u00bb \u0438 \u043d\u0430\u0447\u0430\u0442\u044c \u0438\u0437\u043c\u0435\u0440\u044f\u0442\u044c <strong>\u0431\u0438\u043e\u0433\u0440\u0430\u0444\u0438\u044e \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u043e\u0433\u043e \u043a\u0430\u0434\u0440\u0430<\/strong>.<\/p>\n<p>\u0412 \u043a\u0430\u043a\u043e\u0439-\u0442\u043e \u043c\u043e\u043c\u0435\u043d\u0442 \u043a\u043e\u0434 \u043d\u0430\u0447\u0430\u043b \u0432\u044b\u0433\u043b\u044f\u0434\u0435\u0442\u044c \u043f\u0440\u0438\u043c\u0435\u0440\u043d\u043e \u0442\u0430\u043a:<\/p>\n<pre><code class=\"rust\">#[derive(Debug, Clone, Default)]struct FrameTrace {    frame_id: u64,    first_fragment_ns: u64,    last_fragment_ns: u64,    assembled_ns: u64,    queue_push_ns: u64,    queue_pop_ns: u64,    decode_begin_ns: u64,    decode_end_ns: u64,    present_submit_ns: u64,    present_done_ns: u64,    prev_decode_done_ns: u64,    fragment_count: u32,    payload_bytes: usize,    is_keyframe: bool,    codec: CodecKind,    transport: TransportKind,}impl FrameTrace {    fn rel_ms(&amp;self, ts: u64) -&gt; f64 {        if ts == 0 || self.first_fragment_ns == 0 {            return 0.0;        }        (ts.saturating_sub(self.first_fragment_ns) as f64)            \/ 1_000_000.0    }    fn assembly_ms(&amp;self) -&gt; f64 {        self.rel_ms(self.assembled_ns)    }    fn queue_wait_ms(&amp;self) -&gt; f64 {        if self.queue_pop_ns &lt;= self.queue_push_ns {            return 0.0;        }        (self.queue_pop_ns - self.queue_push_ns) as f64            \/ 1_000_000.0    }    fn decode_ms(&amp;self) -&gt; f64 {        if self.decode_end_ns &lt;= self.decode_begin_ns {            return 0.0;        }        (self.decode_end_ns - self.decode_begin_ns) as f64            \/ 1_000_000.0    }    fn assembled_frame_waiting_for_decode_ms(&amp;self) -&gt; f64 {        if self.decode_begin_ns &lt;= self.assembled_ns {            return 0.0;        }        (self.decode_begin_ns - self.assembled_ns) as f64            \/ 1_000_000.0    }    fn decoder_idle_wait_ms(&amp;self) -&gt; f64 {        if self.decode_begin_ns == 0            || self.prev_decode_done_ns == 0            || self.decode_begin_ns &lt;= self.prev_decode_done_ns        {            return 0.0;        }        (self.decode_begin_ns - self.prev_decode_done_ns) as f64            \/ 1_000_000.0    }}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:87px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0418 \u044d\u0442\u043e \u0435\u0449\u0451 \u043f\u0440\u0438\u044f\u0442\u043d\u0430\u044f \u0447\u0430\u0441\u0442\u044c.<\/p>\n<p>\u041f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u0434\u0430\u043b\u044c\u0448\u0435 \u043d\u0430\u0434\u043e \u0431\u044b\u043b\u043e \u043f\u0440\u043e\u0442\u0430\u0449\u0438\u0442\u044c timestamps \u0447\u0435\u0440\u0435\u0437 \u0432\u0435\u0441\u044c <code>pipeline <\/code>\u0442\u0430\u043a, \u0447\u0442\u043e\u0431\u044b \u0434\u0438\u0430\u0433\u043d\u043e\u0441\u0442\u0438\u043a\u0430 \u0441\u0430\u043c\u0430 \u043d\u0435 \u043f\u0440\u0435\u0432\u0440\u0430\u0442\u0438\u043b\u0430\u0441\u044c \u0432 \u043d\u043e\u0432\u0443\u044e \u043f\u0440\u0438\u0447\u0438\u043d\u0443 \u0442\u043e\u0440\u043c\u043e\u0437\u043e\u0432.<\/p>\n<p>\u0418 \u0442\u0443\u0442 \u0432\u043d\u0435\u0437\u0430\u043f\u043d\u043e \u043f\u043e\u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0432\u043e\u0442 \u0442\u0430\u043a\u043e\u0435 \u0447\u0443\u0434\u043e\u0432\u0438\u0449\u0435:<\/p>\n<pre><code class=\"rust\">fn on_video_fragment(    state: &amp;mut VideoRxState,    packet: VideoPacket,    clock: &amp;MonotonicClock,    decode_tx: &amp;Sender&lt;DecodeJob&gt;,    telemetry: &amp;Telemetry,) -&gt; Result&lt;(), VideoError&gt; {    let now = clock.now_ns();    let frame_id = packet.frame_id;    let frame = state        .assembling        .entry(frame_id)        .or_insert_with(|| PendingFrame {            frame_id,            codec: packet.codec,            is_keyframe: packet.is_keyframe,            first_fragment_ns: now,            last_fragment_ns: now,            assembled_ns: 0,            fragment_count: 0,            expected_fragments: packet.fragment_count,            payload_bytes: 0,            fragments: vec![None; packet.fragment_count as usize],        });    if frame.fragment_count == 0 {        frame.first_fragment_ns = now;    }    frame.last_fragment_ns = now;    let idx = packet.fragment_index as usize;    if idx &gt;= frame.fragments.len() {        telemetry.bad_fragment_index.fetch_add(            1,            Ordering::Relaxed,        );        return Err(VideoError::InvalidFragmentIndex {            frame_id,            index: packet.fragment_index,            total: packet.fragment_count,        });    }    if frame.fragments[idx].is_none() {        frame.payload_bytes += packet.payload.len();        frame.fragment_count += 1;        frame.fragments[idx] = Some(packet.payload);    } else {        telemetry.duplicate_fragments.fetch_add(            1,            Ordering::Relaxed,        );    }    if frame.fragment_count != frame.expected_fragments {        return Ok(());    }    let mut completed = state        .assembling        .remove(&amp;frame_id)        .ok_or(VideoError::FrameDisappeared(frame_id))?;    completed.assembled_ns = clock.now_ns();    let mut payload = Vec::with_capacity(completed.payload_bytes);    for fragment in completed.fragments.drain(..) {        let fragment = fragment.ok_or_else(|| {            VideoError::MissingFragmentAfterComplete {                frame_id,            }        })?;        payload.extend_from_slice(&amp;fragment);    }    let queue_push_ns = clock.now_ns();    let job = DecodeJob {        frame_id,        codec: completed.codec,        is_keyframe: completed.is_keyframe,        payload,        trace: FrameTrace {            frame_id,            first_fragment_ns: completed.first_fragment_ns,            last_fragment_ns: completed.last_fragment_ns,            assembled_ns: completed.assembled_ns,            queue_push_ns,            fragment_count: completed.fragment_count,            payload_bytes: completed.payload_bytes,            is_keyframe: completed.is_keyframe,            codec: completed.codec,            transport: state.transport,            ..FrameTrace::default()        },    };    telemetry.frames_assembled.fetch_add(        1,        Ordering::Relaxed,    );    telemetry        .assembled_to_queue_ns        .observe(queue_push_ns - completed.assembled_ns);    match decode_tx.try_send(job) {        Ok(()) =&gt; {            telemetry.decode_queue_push.fetch_add(                1,                Ordering::Relaxed,            );        }        Err(TrySendError::Full(job)) =&gt; {            telemetry.decode_queue_full.fetch_add(                1,                Ordering::Relaxed,            );            state.on_decode_backpressure(                job.frame_id,                job.is_keyframe,            )?;            return Err(VideoError::DecodeQueueFull {                frame_id,            });        }        Err(TrySendError::Disconnected(_)) =&gt; {            return Err(                VideoError::DecoderDisconnected            );        }    }    Ok(())}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u041a\u0440\u0430\u0441\u043e\u0442\u0430.<\/p>\n<p>\u0412\u043e\u0442 \u0440\u0430\u0434\u0438 \u044d\u0442\u043e\u0433\u043e \u043c\u044b \u0438 \u0438\u0437\u0443\u0447\u0430\u043b\u0438 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435.<\/p>\n<h3>\u0410 \u0442\u0435\u043f\u0435\u0440\u044c \u0432\u044b\u044f\u0441\u043d\u0438\u043c, \u043a\u0442\u043e \u0438\u043c\u0435\u043d\u043d\u043e \u0442\u043e\u0440\u043c\u043e\u0437\u0438\u0442<\/h3>\n<p>\u041a\u043e\u0433\u0434\u0430 \u043f\u043e\u044f\u0432\u0438\u043b\u0438\u0441\u044c <strong>timestamps<\/strong>, \u043f\u0435\u0440\u0432\u0430\u044f \u0433\u0438\u043f\u043e\u0442\u0435\u0437\u0430 \u0431\u044b\u043b\u0430 \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u043e\u0447\u0435\u0432\u0438\u0434\u043d\u043e\u0439: \u043c\u043e\u0436\u0435\u0442 \u043a\u0430\u0434\u0440 \u043f\u0440\u043e\u0441\u0442\u043e \u043f\u043e\u0437\u0434\u043d\u043e \u043f\u0440\u0438\u0435\u0437\u0436\u0430\u0435\u0442?<\/p>\n<p>\u041d\u0435\u0442.<\/p>\n<p>\u041a\u0430\u0434\u0440 \u0441\u043e\u0431\u0440\u0430\u043d \u0431\u044b\u0441\u0442\u0440\u043e.<\/p>\n<p>\u0421\u043b\u0435\u0434\u0443\u044e\u0449\u0430\u044f \u0433\u0438\u043f\u043e\u0442\u0435\u0437\u0430: \u043c\u043e\u0436\u0435\u0442 decoder \u0438\u043d\u043e\u0433\u0434\u0430 \u043f\u0440\u043e\u0441\u0442\u0430\u0438\u0432\u0430\u0435\u0442 \u043c\u0435\u0436\u0434\u0443 \u043a\u0430\u0434\u0440\u0430\u043c\u0438 \u0438 \u0436\u0434\u0451\u0442 \u043e\u0447\u0435\u0440\u0435\u0434\u043d\u043e\u0439?<\/p>\n<p>\u0412\u043e\u0442 \u0442\u0443\u0442 \u0443\u0436\u0435 \u043f\u0440\u0438\u0448\u043b\u043e\u0441\u044c \u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u0441\u0430\u043c worker.<\/p>\n<p>\u0423\u0441\u043b\u043e\u0432\u043d\u043e \u043e\u043d \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u0442\u0430\u043a:<\/p>\n<pre><code class=\"rust\">fn decoder_worker(    rx: Receiver&lt;DecodeJob&gt;,    presenter: Presenter,    decoder: &amp;mut Decoder,    telemetry: Arc&lt;Telemetry&gt;,    clock: MonotonicClock,) {    let mut prev_decode_done_ns = 0u64;    while let Ok(mut job) = rx.recv() {        let queue_pop_ns = clock.now_ns();        job.trace.queue_pop_ns = queue_pop_ns;        job.trace.prev_decode_done_ns = prev_decode_done_ns;        let decode_begin_ns = clock.now_ns();        job.trace.decode_begin_ns = decode_begin_ns;        if prev_decode_done_ns != 0            &amp;&amp; decode_begin_ns &gt; prev_decode_done_ns        {            telemetry.decoder_idle_wait_ns.observe(                decode_begin_ns - prev_decode_done_ns            );        }        if decode_begin_ns &gt; job.trace.assembled_ns {            telemetry                .assembled_frame_waiting_for_decode_ns                .observe(                    decode_begin_ns                        - job.trace.assembled_ns                );        }        let result = decoder.decode(            job.frame_id,            job.codec,            job.is_keyframe,            &amp;job.payload,        );        let decode_end_ns = clock.now_ns();        job.trace.decode_end_ns = decode_end_ns;        prev_decode_done_ns = decode_end_ns;        telemetry.decode_ns.observe(            decode_end_ns - decode_begin_ns        );        match result {            Ok(frame) =&gt; {                let present_submit_ns =                    clock.now_ns();                job.trace.present_submit_ns =                    present_submit_ns;                if let Err(err) = presenter.submit(                    frame,                    job.trace.clone(),                ) {                    telemetry.present_errors.fetch_add(                        1,                        Ordering::Relaxed,                    );                    log::warn!(                        \"present failed \\                         frame={} err={:?}\",                        job.frame_id,                        err                    );                }            }            Err(DecodeError::StateMismatch) =&gt; {                telemetry                    .decode_state_mismatch                    .fetch_add(                        1,                        Ordering::Relaxed,                    );                log::warn!(                    \"decoder state mismatch \\                     frame={} keyframe={}\",                    job.frame_id,                    job.is_keyframe                );            }            Err(err) =&gt; {                telemetry.decode_errors.fetch_add(                    1,                    Ordering::Relaxed,                );                log::warn!(                    \"decode failed \\                     frame={} err={:?}\",                    job.frame_id,                    err                );            }        }        telemetry.frame_traces.push(            job.trace        );    }}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0410 \u043f\u043e\u0441\u043b\u0435 \u044d\u0442\u043e\u0433\u043e \u0438\u0437 \u0441\u0438\u0441\u0442\u0435\u043c\u044b \u0432\u044b\u0432\u0430\u043b\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u043f\u0440\u0438\u043c\u0435\u0440\u043d\u043e \u0442\u0430\u043a\u0430\u044f \u0441\u0442\u0440\u043e\u043a\u0430:<\/p>\n<pre><code class=\"rust\">frame=71first_fragment          +0.00 mslast_fragment           +1.18 msassembled               +1.24 msqueue_push              +1.26 msprev_decode_done       +15.01 msqueue_pop              +35.17 msdecode_begin           +35.24 msdecode_end             +41.83 mspresent_submit         +41.91 msassembled_wait_decode  34.00 msdecoder_idle_wait       0.00 ms<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0412\u043e\u0442.<\/p>\n<p>\u0412\u043e\u0442 \u0440\u0430\u0434\u0438 \u044d\u0442\u043e\u0439 \u0441\u0442\u0440\u043e\u043a\u0438 \u043c\u043e\u0436\u043d\u043e \u0431\u044b\u043b\u043e \u043d\u0435 \u0441\u043f\u0430\u0442\u044c.<\/p>\n<p>\u041f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u0442\u0435\u043f\u0435\u0440\u044c \u0432\u0441\u0451 \u043e\u0447\u0435\u043d\u044c \u043d\u0435\u043f\u0440\u0438\u044f\u0442\u043d\u043e, \u043d\u043e \u043e\u0447\u0435\u043d\u044c \u043f\u043e\u043d\u044f\u0442\u043d\u043e.<\/p>\n<p>\u041a\u0430\u0434\u0440 \u211671 \u043f\u043e\u043b\u043d\u043e\u0441\u0442\u044c\u044e \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u043e\u0432\u0430\u043b \u0443\u0436\u0435 \u043f\u0440\u0438\u043c\u0435\u0440\u043d\u043e \u0447\u0435\u0440\u0435\u0437 <strong>1,24 \u043c\u0441<\/strong> \u043f\u043e\u0441\u043b\u0435 \u043f\u0435\u0440\u0432\u043e\u0433\u043e fragment.<\/p>\n<p>\u041e\u043d \u0431\u044b\u043b \u043f\u043e\u043b\u043e\u0436\u0435\u043d \u0432 \u043e\u0447\u0435\u0440\u0435\u0434\u044c \u0447\u0435\u0440\u0435\u0437 <strong>1,26 \u043c\u0441<\/strong>.<\/p>\n<p>\u0422\u043e \u0435\u0441\u0442\u044c \u0441\u0435\u0442\u044c \u0432 \u0434\u0430\u043d\u043d\u043e\u043c \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u043d\u0438 \u043f\u0440\u0438 \u0447\u0451\u043c. Frame assembly \u0442\u043e\u0436\u0435 \u043d\u0438 \u043f\u0440\u0438 \u0447\u0451\u043c.<\/p>\n<p>\u041d\u043e decode \u043d\u0430\u0447\u0438\u043d\u0430\u0435\u0442\u0441\u044f \u0442\u043e\u043b\u044c\u043a\u043e \u043f\u0440\u0438\u043c\u0435\u0440\u043d\u043e \u0447\u0435\u0440\u0435\u0437 <strong>35,24 \u043c\u0441<\/strong>.<\/p>\n<p>\u041a\u0430\u0434\u0440 <strong>34 \u043c\u0438\u043b\u043b\u0438\u0441\u0435\u043a\u0443\u043d\u0434\u044b \u0443\u0436\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442 \u0438 \u043f\u0440\u043e\u0441\u0442\u043e \u0436\u0434\u0451\u0442<\/strong>.<\/p>\n<p>\u041f\u0440\u0438 \u044d\u0442\u043e\u043c <code>decoder_idle_wait = 0<\/code>.<\/p>\n<p>\u0422\u043e \u0435\u0441\u0442\u044c decoder \u043d\u0435 \u0441\u0438\u0434\u0438\u0442 \u0431\u0435\u0437 \u0440\u0430\u0431\u043e\u0442\u044b \u0438 \u043d\u0435 \u0433\u043e\u0432\u043e\u0440\u0438\u0442: \u00ab\u041d\u0443 \u0433\u0434\u0435 \u0436\u0435 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u043a\u0430\u0434\u0440?\u00bb<\/p>\n<p>\u041d\u0435\u0442.<\/p>\n<p>\u0421\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u043a\u0430\u0434\u0440 \u0443\u0436\u0435 \u043b\u0435\u0436\u0438\u0442 \u0440\u044f\u0434\u043e\u043c.<\/p>\n<p>Decoder \u043f\u0440\u043e\u0441\u0442\u043e \u0435\u0449\u0451 \u0437\u0430\u043d\u044f\u0442 \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0438\u043c.<\/p>\n<p>\u0412\u043e\u0442 \u044d\u0442\u043e \u0443\u0436\u0435 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0430.<\/p>\n<h3>\u041d\u043e \u043e\u0434\u043d\u043e\u043c\u0443 \u043a\u0430\u0434\u0440\u0443 \u0432\u0435\u0440\u0438\u0442\u044c \u043d\u0435\u043b\u044c\u0437\u044f<\/h3>\n<p>\u0418 \u0432\u043e\u0442 \u0437\u0434\u0435\u0441\u044c \u043d\u0430\u0447\u0438\u043d\u0430\u0435\u0442\u0441\u044f \u0435\u0449\u0451 \u043e\u0434\u043d\u0430 \u043b\u043e\u0432\u0443\u0448\u043a\u0430.<\/p>\n<p>\u0412\u0441\u0435\u0433\u0434\u0430 \u043c\u043e\u0436\u043d\u043e \u043d\u0430\u0439\u0442\u0438 \u043e\u0434\u0438\u043d \u0441\u0442\u0440\u0430\u0448\u043d\u044b\u0439 \u043a\u0430\u0434\u0440.<\/p>\n<p>\u041e\u0434\u0438\u043d packet loss.<\/p>\n<p>\u041e\u0434\u0438\u043d scheduler <strong>hiccup<\/strong>.<\/p>\n<p>\u041e\u0434\u0438\u043d Windows moment.<\/p>\n<p>\u0415\u0441\u043b\u0438 \u044f \u043f\u043e\u043a\u0430\u0436\u0443 \u0432\u0430\u043c \u043e\u0434\u0438\u043d frame \u0441 34 \u043c\u0438\u043b\u043b\u0438\u0441\u0435\u043a\u0443\u043d\u0434\u0430\u043c\u0438, \u044d\u0442\u043e \u0435\u0449\u0451 \u0432\u043e\u043e\u0431\u0449\u0435 \u043d\u0438\u0447\u0435\u0433\u043e \u043d\u0435 \u0434\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442.<\/p>\n<p>\u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u043f\u0440\u0438\u0448\u043b\u043e\u0441\u044c \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0435\u0449\u0451 \u043e\u0434\u043d\u0443 \u043f\u0440\u0435\u043a\u0440\u0430\u0441\u043d\u0443\u044e \u0432\u0435\u0449\u044c.<\/p>\n<p>\u041f\u0440\u043e\u0432\u0435\u0440\u043a\u0443 \u0438\u043d\u0432\u0430\u0440\u0438\u0430\u043d\u0442\u043e\u0432.<\/p>\n<p>\u041d\u0435 \u00ab\u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u043d\u0430 \u0433\u0440\u0430\u0444\u0438\u043a\u00bb.<\/p>\n<p>\u0410 \u0431\u0443\u043a\u0432\u0430\u043b\u044c\u043d\u043e:<\/p>\n<p><strong>\u0441\u0438\u0441\u0442\u0435\u043c\u0430 \u043e\u0431\u044f\u0437\u0430\u043d\u0430 \u0441\u043e\u0431\u043b\u044e\u0434\u0430\u0442\u044c \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0451\u043d\u043d\u044b\u0435 \u043e\u0442\u043d\u043e\u0448\u0435\u043d\u0438\u044f \u043c\u0435\u0436\u0434\u0443 \u0441\u043e\u0431\u044b\u0442\u0438\u044f\u043c\u0438.<\/strong><\/p>\n<p>\u0418 \u043a\u043e\u0434 \u043e\u043f\u044f\u0442\u044c \u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u0441\u044f \u043a\u0440\u0430\u0441\u0438\u0432\u044b\u043c:<\/p>\n<pre><code class=\"rust\">#[derive(Default)]struct InvariantReport {    checked: usize,    failed: usize,    first_before_last: usize,    last_before_assembled: usize,    assembled_before_queue: usize,    queue_before_decode: usize,    decode_begin_before_end: usize,    decode_end_before_present: usize,    frame_id_monotonic: usize,    negative_wait: usize,    impossible_idle: usize,}fn validate_trace_window(    traces: &amp;[FrameTrace],) -&gt; InvariantReport {    let mut report =        InvariantReport::default();    let mut prev_frame_id = None;    for t in traces {        report.checked += 1;        let mut frame_failed = false;        macro_rules! check {            ($field:ident, $cond:expr) =&gt; {                if !($cond) {                    report.$field += 1;                    frame_failed = true;                }            };        }        check!(            first_before_last,            t.first_fragment_ns                &lt;= t.last_fragment_ns        );        check!(            last_before_assembled,            t.last_fragment_ns                &lt;= t.assembled_ns        );        check!(            assembled_before_queue,            t.assembled_ns                &lt;= t.queue_push_ns        );        check!(            queue_before_decode,            t.queue_push_ns                &lt;= t.decode_begin_ns        );        check!(            decode_begin_before_end,            t.decode_begin_ns                &lt;= t.decode_end_ns        );        if t.present_submit_ns != 0 {            check!(                decode_end_before_present,                t.decode_end_ns                    &lt;= t.present_submit_ns            );        }        if let Some(prev) = prev_frame_id {            if t.frame_id &lt;= prev {                report.frame_id_monotonic += 1;                frame_failed = true;            }        }        prev_frame_id = Some(t.frame_id);        if t.decode_begin_ns &lt; t.assembled_ns {            report.negative_wait += 1;            frame_failed = true;        }        if t.prev_decode_done_ns != 0 {            let decoder_idle =                t.decode_begin_ns                    .saturating_sub(                        t.prev_decode_done_ns                    );            let assembled_wait =                t.decode_begin_ns                    .saturating_sub(                        t.assembled_ns                    );            if assembled_wait &gt; 0                &amp;&amp; decoder_idle &gt; assembled_wait            {                report.impossible_idle += 1;                frame_failed = true;            }        }        if frame_failed {            report.failed += 1;            log::error!(                \"TRACE INVARIANT FAILED: \\                 frame={} \\                 first={} \\                 last={} \\                 assembled={} \\                 queue={} \\                 decode_begin={} \\                 decode_end={} \\                 present={}\",                t.frame_id,                t.first_fragment_ns,                t.last_fragment_ns,                t.assembled_ns,                t.queue_push_ns,                t.decode_begin_ns,                t.decode_end_ns,                t.present_submit_ns,            );        }    }    report}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u041f\u043e\u0441\u043b\u0435 \u044d\u0442\u043e\u0433\u043e \u044f \u0431\u0435\u0440\u0443 \u043d\u0435 \u043e\u0434\u0438\u043d \u043a\u0430\u0434\u0440.<\/p>\n<p>\u041f\u044f\u0442\u044c\u0434\u0435\u0441\u044f\u0442 \u043f\u043e\u0434\u0440\u044f\u0434.<\/p>\n<p>\u0418 \u0441\u043c\u043e\u0442\u0440\u044e.<\/p>\n<p>\u0418\u043d\u0432\u0430\u0440\u0438\u0430\u043d\u0442\u044b \u2014 \u0437\u0435\u043b\u0451\u043d\u044b\u0435.<\/p>\n<p><code>assembled_frame_waiting_for_decode p50 = 34 ms<\/code>.<\/p>\n<p><code>decoder_idle_wait p50 = 0 ms<\/code>.<\/p>\n<p>\u0422\u043e \u0435\u0441\u0442\u044c \u044d\u0442\u043e \u0443\u0436\u0435 \u043d\u0435 \u0430\u0440\u0442\u0435\u0444\u0430\u043a\u0442 \u043e\u0434\u043d\u043e\u0439 \u0441\u0442\u0440\u0430\u043d\u043d\u043e\u0439 \u0441\u0442\u0440\u043e\u043a\u0438.<\/p>\n<p>\u0421\u0438\u0441\u0442\u0435\u043c\u0430 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0433\u043e\u0432\u043e\u0440\u0438\u0442:<\/p>\n<blockquote>\n<p>\u042f \u0441\u043e\u0431\u0438\u0440\u0430\u044e \u043a\u0430\u0434\u0440\u044b \u0431\u044b\u0441\u0442\u0440\u0435\u0435, \u0447\u0435\u043c \u043c\u043e\u0433\u0443 \u043f\u0440\u043e\u0442\u043e\u043b\u043a\u043d\u0443\u0442\u044c \u0438\u0445 \u0447\u0435\u0440\u0435\u0437 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u0443\u0447\u0430\u0441\u0442\u043e\u043a pipeline.<\/p>\n<\/blockquote>\n<p>\u0412\u043e\u0442 \u0442\u0435\u043f\u0435\u0440\u044c \u043c\u043e\u0436\u043d\u043e \u0447\u0438\u043d\u0438\u0442\u044c.<\/p>\n<p>\u0414\u043e \u044d\u0442\u043e\u0433\u043e \u043c\u044b \u0442\u043e\u043b\u044c\u043a\u043e \u0433\u0430\u0434\u0430\u043b\u0438.<\/p>\n<h3>\u0410 FPS \u043f\u0440\u0438 \u044d\u0442\u043e\u043c \u043c\u043e\u0436\u0435\u0442 \u0432\u0440\u0430\u0442\u044c \u0432\u0430\u043c \u043f\u0440\u044f\u043c\u043e \u0432 \u043b\u0438\u0446\u043e<\/h3>\n<p>\u0418 \u0432\u043e\u0442 \u0437\u0434\u0435\u0441\u044c \u043e\u0434\u043d\u0430 \u0438\u0437 \u043f\u0440\u0438\u0447\u0438\u043d, \u043f\u043e\u0447\u0435\u043c\u0443 \u044f \u043f\u0435\u0440\u0435\u0441\u0442\u0430\u043b \u0441\u043b\u0438\u0448\u043a\u043e\u043c \u0441\u0438\u043b\u044c\u043d\u043e \u0443\u0432\u0430\u0436\u0430\u0442\u044c FPS \u043a\u0430\u043a \u0435\u0434\u0438\u043d\u0441\u0442\u0432\u0435\u043d\u043d\u0443\u044e \u043c\u0435\u0442\u0440\u0438\u043a\u0443.<\/p>\n<p>\u041f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u044c\u0442\u0435 \u0441\u0438\u0441\u0442\u0435\u043c\u0443, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0447\u0435\u0441\u0442\u043d\u043e \u043f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442 \u0432\u0430\u043c:<\/p>\n<pre><code>30 FPS30 FPS30 FPS30 FPS30 FPS<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u041a\u0440\u0430\u0441\u0438\u0432\u043e.<\/p>\n<p>\u0421\u0442\u0430\u0431\u0438\u043b\u044c\u043d\u043e.<\/p>\n<p>\u0422\u043e\u043b\u044c\u043a\u043e \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u0434\u0432\u0438\u0433\u0430\u0435\u0442 \u043e\u043a\u043d\u043e \u0438 \u0447\u0443\u0432\u0441\u0442\u0432\u0443\u0435\u0442 \u0436\u0435\u043b\u0435.<\/p>\n<p>\u041f\u043e\u0447\u0435\u043c\u0443?<\/p>\n<p>\u041f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e FPS \u0433\u043e\u0432\u043e\u0440\u0438\u0442, \u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043a\u0430\u0434\u0440\u043e\u0432 \u0432\u044b \u043f\u043e\u043a\u0430\u0437\u0430\u043b\u0438.<\/p>\n<p>\u041e\u043d \u043d\u0438\u0447\u0435\u0433\u043e \u043d\u0435 \u0433\u043e\u0432\u043e\u0440\u0438\u0442 \u043e \u0442\u043e\u043c, <strong>\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043a\u0430\u0436\u0434\u044b\u0439 \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u044b\u0439 \u043a\u0430\u0434\u0440 \u043f\u0440\u043e\u043b\u0435\u0436\u0430\u043b \u043c\u0451\u0440\u0442\u0432\u044b\u043c \u0433\u0440\u0443\u0437\u043e\u043c \u043c\u0435\u0436\u0434\u0443 \u044d\u0442\u0430\u043f\u0430\u043c\u0438 pipeline<\/strong>.<\/p>\n<p>\u041c\u043e\u0436\u043d\u043e \u0438\u043c\u0435\u0442\u044c \u0441\u0442\u0430\u0431\u0438\u043b\u044c\u043d\u044b\u0435 30 FPS \u0438 \u043e\u0442\u0432\u0440\u0430\u0442\u0438\u0442\u0435\u043b\u044c\u043d\u0443\u044e latency.<\/p>\n<p>\u041c\u043e\u0436\u043d\u043e \u0438\u043c\u0435\u0442\u044c \u043d\u0435\u0438\u0434\u0435\u0430\u043b\u044c\u043d\u044b\u0435 30 FPS \u0438 \u043e\u0449\u0443\u0449\u0435\u043d\u0438\u0435 \u043f\u043e\u0447\u0442\u0438 \u043c\u0433\u043d\u043e\u0432\u0435\u043d\u043d\u043e\u0433\u043e \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f.<\/p>\n<p>\u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u0432 \u043a\u0430\u043a\u043e\u0439-\u0442\u043e \u043c\u043e\u043c\u0435\u043d\u0442 \u0443 \u043c\u0435\u043d\u044f telemetry snapshot \u043d\u0430\u0447\u0430\u043b \u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c\u0441\u044f \u043f\u0440\u0438\u043c\u0435\u0440\u043d\u043e \u0442\u0430\u043a\u0438\u043c:<\/p>\n<pre><code class=\"rust\">struct VideoTelemetrySnapshot {    fps_decode: f64,    fps_present: f64,    rx_mbps: f64,    assemble_p50_ms: f64,    assemble_p95_ms: f64,    assemble_p99_ms: f64,    queue_wait_p50_ms: f64,    queue_wait_p95_ms: f64,    queue_wait_p99_ms: f64,    decode_p50_ms: f64,    decode_p95_ms: f64,    decode_p99_ms: f64,    assembled_wait_decode_p50_ms: f64,    assembled_wait_decode_p95_ms: f64,    assembled_wait_decode_p99_ms: f64,    decoder_idle_p50_ms: f64,    decoder_idle_p95_ms: f64,    decoder_idle_p99_ms: f64,    present_p50_ms: f64,    present_p95_ms: f64,    queue_depth_current: usize,    queue_depth_peak: usize,    frames_received: u64,    frames_assembled: u64,    frames_decoded: u64,    frames_presented: u64,    frames_dropped_before_decode: u64,    frames_dropped_after_decode: u64,    keyframes: u64,    state_mismatch: u64,    requested_keyframes: u64,    transport: TransportKind,    codec: CodecKind,}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0410 \u043f\u043e\u0442\u043e\u043c \u0442\u044b \u044d\u0442\u043e \u043f\u0435\u0447\u0430\u0442\u0430\u0435\u0448\u044c:<\/p>\n<pre><code class=\"rust\">EVRT2 VIDEO PIPELINE-----------------------------------------------------transport                         TCP_RELAYcodec                             EVRTCKfps_decode                        30.01fps_present                       29.98rx                                18.4 Mbpsassemble             p50   1.31 ms                     p95   2.04 ms                     p99   3.11 msqueue_wait           p50  33.87 ms                     p95  38.42 ms                     p99  41.07 msdecode               p50   6.42 ms                     p95   8.10 ms                     p99  10.94 msassembled-&gt;decode    p50  34.00 ms                     p95  39.26 ms                     p99  42.18 msdecoder_idle         p50   0.00 ms                     p95   0.00 ms                     p99   0.19 msqueue depth          now   1                     peak  3state mismatch                     0keyframe requests                   0dropped before decode               0dropped after decode                0-----------------------------------------------------<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0412\u043e\u0442 \u0442\u0435\u043f\u0435\u0440\u044c FPS \u043c\u043e\u0436\u0435\u0442 \u0438\u0434\u0442\u0438 \u0434\u043e\u043c\u043e\u0439.<\/p>\n<p>\u0423 \u043d\u0430\u0441 \u0435\u0441\u0442\u044c \u0432\u043e\u043f\u0440\u043e\u0441\u044b \u043f\u043e\u0432\u0430\u0436\u043d\u0435\u0435.<\/p>\n<h3>\u0418\u043d\u043e\u0433\u0434\u0430 \u0431\u0430\u0433 \u0437\u0430\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u0435\u0449\u0451 \u043e\u0434\u043d\u0443 \u0441\u0438\u0441\u0442\u0435\u043c\u0443<\/h3>\n<p>\u0421\u0430\u043c\u043e\u0435 \u0441\u043c\u0435\u0448\u043d\u043e\u0435, \u0447\u0442\u043e \u0440\u0430\u0434\u0438 \u043e\u0434\u043d\u043e\u0433\u043e \u0432\u0438\u0437\u0443\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u043f\u043e\u0434\u0432\u0438\u0441\u0430\u043d\u0438\u044f \u043c\u043d\u0435 \u043f\u0440\u0438\u0448\u043b\u043e\u0441\u044c \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0433\u043e\u0440\u0430\u0437\u0434\u043e \u0431\u043e\u043b\u044c\u0448\u0435, \u0447\u0435\u043c \u0438\u0441\u043f\u0440\u0430\u0432\u0438\u0442\u044c \u043e\u0434\u043d\u0443 \u0441\u0442\u0440\u043e\u0447\u043a\u0443.<\/p>\n<p>\u041f\u043e\u044f\u0432\u0438\u043b\u0430\u0441\u044c \u0442\u0435\u043b\u0435\u043c\u0435\u0442\u0440\u0438\u044f. \u041f\u043e\u044f\u0432\u0438\u043b\u0438\u0441\u044c frame id. \u041f\u043e\u044f\u0432\u0438\u043b\u0438\u0441\u044c \u0438\u043d\u0432\u0430\u0440\u0438\u0430\u043d\u0442\u044b. \u041f\u043e\u044f\u0432\u0438\u043b\u043e\u0441\u044c \u043d\u043e\u0440\u043c\u0430\u043b\u044c\u043d\u043e\u0435 \u043f\u043e\u043d\u0438\u043c\u0430\u043d\u0438\u0435 \u043e\u0447\u0435\u0440\u0435\u0434\u0435\u0439. \u041f\u043e\u044f\u0432\u0438\u043b\u0430\u0441\u044c \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u043d\u0435 \u043d\u0430 \u0430\u0431\u0441\u0442\u0440\u0430\u043a\u0442\u043d\u044b\u0435 FPS, \u0430 \u043d\u0430 <strong>\u0436\u0438\u0437\u043d\u044c \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u043e\u0433\u043e \u043a\u0430\u0434\u0440\u0430<\/strong>.<\/p>\n<p>\u0418 \u0432\u043e\u0442 \u044d\u0442\u043e \u0443\u0436\u0435 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u0435\u0435 \u0441\u0430\u043c\u043e\u0433\u043e \u0431\u0430\u0433\u0430.<\/p>\n<p>\u041f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u0431\u0430\u0433 \u0443\u0439\u0434\u0451\u0442.<\/p>\n<p>\u0410 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u0432\u0438\u0434\u0435\u0442\u044c \u0441\u0438\u0441\u0442\u0435\u043c\u0443 \u043e\u0441\u0442\u0430\u043d\u0435\u0442\u0441\u044f.<\/p>\n<p>\u0412 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u0440\u0430\u0437 \u044f \u0443\u0436\u0435 \u043d\u0435 \u0431\u0443\u0434\u0443 \u0442\u044b\u043a\u0430\u0442\u044c \u043f\u0430\u043b\u043a\u043e\u0439 \u0432 \u0442\u0435\u043c\u043d\u043e\u0442\u0443.<\/p>\n<p>\u0423 \u043c\u0435\u043d\u044f \u0431\u0443\u0434\u0435\u0442 \u0441\u0432\u0435\u0442.<\/p>\n<h3>\u0418 \u0442\u0443\u0442 \u0432\u043d\u0435\u0437\u0430\u043f\u043d\u043e \u043f\u043e\u044f\u0432\u0438\u043b\u0441\u044f EvertyDisplay<\/h3>\n<p>\u041f\u0430\u0440\u0430\u043b\u043b\u0435\u043b\u044c\u043d\u043e \u044f \u0434\u0435\u043b\u0430\u043b EvertyDisplay. \u0412\u043e\u043e\u0431\u0449\u0435 \u0434\u0440\u0443\u0433\u043e\u0439 \u043f\u0440\u043e\u0435\u043a\u0442. \u0412\u0438\u0440\u0442\u0443\u0430\u043b\u044c\u043d\u044b\u0435 \u043c\u043e\u043d\u0438\u0442\u043e\u0440\u044b. Windows \u0432\u0438\u0434\u0438\u0442 \u0438\u0445 \u043a\u0430\u043a \u043d\u0430\u0441\u0442\u043e\u044f\u0449\u0438\u0435 \u0434\u0438\u0441\u043f\u043b\u0435\u0438. \u0423 \u043d\u0438\u0445 \u0435\u0441\u0442\u044c \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u044b, \u0440\u0430\u0437\u0440\u0435\u0448\u0435\u043d\u0438\u044f, \u0442\u0443\u0434\u0430 \u043c\u043e\u0436\u043d\u043e \u043f\u0435\u0440\u0435\u0442\u0430\u0441\u043a\u0438\u0432\u0430\u0442\u044c \u043e\u043a\u043d\u0430, \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0442\u044c fullscreen, \u0443\u0432\u043e\u0434\u0438\u0442\u044c \u043a\u0443\u0440\u0441\u043e\u0440 \u0437\u0430 \u0433\u0440\u0430\u043d\u0438\u0446\u0443 \u0444\u0438\u0437\u0438\u0447\u0435\u0441\u043a\u043e\u0433\u043e \u044d\u043a\u0440\u0430\u043d\u0430.<\/p>\n<p>\u041a\u043e\u0433\u0434\u0430 \u044f \u043d\u0430\u0447\u0438\u043d\u0430\u043b \u0435\u0433\u043e \u0434\u0435\u043b\u0430\u0442\u044c, \u044f \u0432\u043e\u043e\u0431\u0449\u0435 \u043d\u0435 \u0434\u0443\u043c\u0430\u043b: \u00ab\u041e\u0442\u043b\u0438\u0447\u043d\u043e, \u044d\u0442\u043e \u0431\u0443\u0434\u0435\u0442 \u0441\u0442\u0435\u043d\u0434 \u0434\u043b\u044f \u043e\u0442\u043b\u0430\u0434\u043a\u0438 EvertyDesk\u00bb.<\/p>\n<p>\u041d\u043e \u0438\u043c\u0435\u043d\u043d\u043e \u0442\u0430\u043a \u0438 \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u043e\u0441\u044c.<\/p>\n<p>\u041f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u0442\u0435\u043f\u0435\u0440\u044c \u0442\u0435\u0441\u0442 \u043c\u043e\u0436\u043d\u043e \u0434\u0435\u043b\u0430\u0442\u044c \u043d\u0435 \u0432 \u0441\u0442\u0438\u043b\u0435:<\/p>\n<blockquote>\n<p>\u041d\u0443 \u0434\u0430\u0432\u0430\u0439\u0442\u0435 \u043f\u043e\u0434\u0432\u0438\u0433\u0430\u0432 \u043e\u043a\u043d\u043e \u0442\u0443\u0434\u0430-\u0441\u044e\u0434\u0430 \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0438\u043c.<\/p>\n<\/blockquote>\n<p>\u0410 \u043d\u043e\u0440\u043c\u0430\u043b\u044c\u043d\u043e.<\/p>\n<p>\u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0441\u043e\u0437\u0434\u0430\u0451\u043c \u0432\u0438\u0440\u0442\u0443\u0430\u043b\u044c\u043d\u044b\u0439 \u043c\u043e\u043d\u0438\u0442\u043e\u0440 \u0441\u043b\u0435\u0432\u0430 \u043e\u0442 \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u0433\u043e. \u041c\u0435\u043d\u044f\u0435\u043c resolution. \u041f\u0435\u0440\u0435\u0442\u0430\u0441\u043a\u0438\u0432\u0430\u0435\u043c \u043e\u043a\u043d\u043e \u0447\u0435\u0440\u0435\u0437 \u0433\u0440\u0430\u043d\u0438\u0446\u0443. \u0417\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u043c \u0434\u0432\u0438\u0436\u0435\u043d\u0438\u0435. \u041d\u0430\u0447\u0438\u043d\u0430\u0435\u043c \u043e\u0434\u043d\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u043e \u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u043d\u0430 capture region, dirty map, frame lifecycle \u0438 present.<\/p>\n<p>\u0418 \u0432\u043d\u0435\u0437\u0430\u043f\u043d\u043e EvertyDisplay \u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u0441\u044f \u043d\u0435 \u043f\u0440\u043e\u0441\u0442\u043e \u043f\u0440\u043e\u0434\u0443\u043a\u0442\u043e\u043c.<\/p>\n<p>\u041e\u043d \u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u0441\u044f \u043c\u043e\u0438\u043c \u0441\u0442\u0435\u043d\u0434\u043e\u043c.<\/p>\n<p>\u041c\u043e\u0436\u043d\u043e \u0434\u0430\u0436\u0435 \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0441\u043e\u0432\u0435\u0440\u0448\u0435\u043d\u043d\u043e \u043c\u0435\u0440\u0437\u043a\u0438\u0439 \u0442\u0435\u0441\u0442:<\/p>\n<pre><code class=\"rust\">for iteration in 0..10_000 {    display.set_mode(DisplayMode {        width: if iteration % 2 == 0 {            1920        } else {            2560        },        height: if iteration % 2 == 0 {            1080        } else {            1440        },        refresh_hz: 60,    })?;    display.set_position(        if iteration % 4 &lt; 2 {            (-1920, 0)        } else {            (1920, 0)        }    )?;    test_window.move_to(        if iteration % 2 == 0 {            display.center()        } else {            primary.center()        }    )?;    test_window.invalidate_full()?;    std::thread::sleep(        Duration::from_millis(16)    );    let snapshot =        evertydesk.telemetry_snapshot();    assert!(        snapshot.queue_depth_current &lt; 4,        \"decode queue exploded at iteration {}\",        iteration    );    assert!(        snapshot.assembled_wait_decode_p99_ms            &lt; 50.0,        \"pipeline latency exploded: {:?}\",        snapshot    );}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u042d\u0442\u043e \u0443\u0436\u0435 \u043d\u0435 \u00ab\u043f\u043e\u0442\u044b\u043a\u0430\u043b \u043c\u044b\u0448\u043a\u043e\u0439\u00bb.<\/p>\n<p>\u042d\u0442\u043e \u0442\u044b \u0431\u0443\u043a\u0432\u0430\u043b\u044c\u043d\u043e \u0438\u0437\u0434\u0435\u0432\u0430\u0435\u0448\u044c\u0441\u044f \u043d\u0430\u0434 \u0441\u0432\u043e\u0435\u0439 \u0441\u0438\u0441\u0442\u0435\u043c\u043e\u0439, \u043f\u043e\u043a\u0430 \u043e\u043d\u0430 \u043d\u0435 \u043f\u0440\u0438\u0437\u043d\u0430\u0435\u0442\u0441\u044f, \u0433\u0434\u0435 \u0435\u0439 \u0431\u043e\u043b\u044c\u043d\u043e.<\/p>\n<p>\u0412\u043e\u0442 \u044d\u0442\u043e \u044f \u043b\u044e\u0431\u043b\u044e.<\/p>\n<h3>\u00ab\u0410 \u0437\u0430\u0447\u0435\u043c \u0442\u044b \u0432\u043e\u043e\u0431\u0449\u0435 \u044d\u0442\u043e \u0441\u0434\u0435\u043b\u0430\u043b?\u00bb<\/h3>\n<p>\u041c\u043d\u0435 \u044d\u0442\u043e\u0442 \u0432\u043e\u043f\u0440\u043e\u0441 \u043f\u0435\u0440\u0438\u043e\u0434\u0438\u0447\u0435\u0441\u043a\u0438 \u0437\u0430\u0434\u0430\u044e\u0442. \u0417\u0430\u0447\u0435\u043c \u0441\u0432\u043e\u0439 remote desktop? \u0417\u0430\u0447\u0435\u043c \u0441\u0432\u043e\u0439 \u043a\u043e\u0434\u0435\u043a? \u0417\u0430\u0447\u0435\u043c \u0432\u0438\u0440\u0442\u0443\u0430\u043b\u044c\u043d\u044b\u0435 \u043c\u043e\u043d\u0438\u0442\u043e\u0440\u044b? \u0417\u0430\u0447\u0435\u043c \u0435\u0449\u0451 \u043e\u0434\u0438\u043d transport? \u0417\u0430\u0447\u0435\u043c \u0432\u043e\u043e\u0431\u0449\u0435 \u0441\u0442\u043e\u043b\u044c\u043a\u043e \u0432\u0441\u0435\u0433\u043e?<\/p>\n<p>\u041d\u0435 \u0437\u043d\u0430\u044e.<\/p>\n<p>\u0421\u0435\u0440\u044c\u0451\u0437\u043d\u043e. \u0418\u043d\u043e\u0433\u0434\u0430 \u043d\u0435 \u0437\u043d\u0430\u044e.<\/p>\n<p>\u041f\u043e\u0442\u043e\u043c \u043f\u0440\u043e\u0445\u043e\u0434\u0438\u0442 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043c\u0435\u0441\u044f\u0446\u0435\u0432, \u0438 \u0432\u0434\u0440\u0443\u0433 \u043e\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f, \u0447\u0442\u043e \u0440\u0435\u0448\u0435\u043d\u0438\u0435, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u0440\u0430\u043d\u044c\u0448\u0435 \u0432\u044b\u0433\u043b\u044f\u0434\u0435\u043b\u043e \u043a\u0430\u043a \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u0430\u044f \u0438\u0433\u0440\u0443\u0448\u043a\u0430, \u0437\u0430\u043a\u0440\u044b\u0432\u0430\u0435\u0442 \u0441\u043e\u0432\u0435\u0440\u0448\u0435\u043d\u043d\u043e \u0434\u0440\u0443\u0433\u0443\u044e \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0443.<\/p>\n<p>\u0418 \u0442\u044b \u0442\u0430\u043a\u043e\u0439:<\/p>\n<p>\u0410.<\/p>\n<p>\u0412\u043e\u0442 \u0437\u0430\u0447\u0435\u043c.<\/p>\n<p>\u042f \u0432\u043e\u043e\u0431\u0449\u0435 \u043f\u0435\u0440\u0435\u0441\u0442\u0430\u043b \u0432\u0435\u0440\u0438\u0442\u044c \u0432 \u0438\u0434\u0435\u044e, \u0447\u0442\u043e \u043f\u0435\u0440\u0435\u0434 \u043a\u0430\u0436\u0434\u043e\u0439 \u0441\u0442\u0440\u043e\u0447\u043a\u043e\u0439 \u043a\u043e\u0434\u0430 \u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u043e \u0434\u043e\u043b\u0436\u0435\u043d \u0431\u044b\u0442\u044c \u0438\u0434\u0435\u0430\u043b\u044c\u043d\u043e \u0440\u0430\u0441\u043f\u0438\u0441\u0430\u043d\u043d\u044b\u0439 \u0431\u0438\u0437\u043d\u0435\u0441-\u043f\u043b\u0430\u043d \u043d\u0430 \u043f\u044f\u0442\u044c \u043b\u0435\u0442.<\/p>\n<p>\u0418\u043d\u043e\u0433\u0434\u0430 \u0438\u043d\u0436\u0435\u043d\u0435\u0440\u0438\u044f \u2014 \u044d\u0442\u043e \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0435\u0439.<\/p>\n<p>\u0422\u044b \u0441\u0442\u0440\u043e\u0438\u0448\u044c \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442, \u0430 \u043f\u043e\u0442\u043e\u043c \u043e\u0431\u043d\u0430\u0440\u0443\u0436\u0438\u0432\u0430\u0435\u0448\u044c, \u0433\u0434\u0435 \u043e\u043d \u043d\u0443\u0436\u0435\u043d.<\/p>\n<p>\u041a\u043e\u043d\u0435\u0447\u043d\u043e, \u0435\u0441\u043b\u0438 \u043f\u0440\u043e\u0441\u0442\u043e \u043f\u0438\u0441\u0430\u0442\u044c \u0432\u0441\u0451 \u043f\u043e\u0434\u0440\u044f\u0434, \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u0441\u044f \u0441\u0432\u0430\u043b\u043a\u0430. \u041d\u043e \u0438\u043d\u043e\u0433\u0434\u0430 \u043e\u0447\u0435\u043d\u044c \u043f\u043e\u043b\u0435\u0437\u043d\u043e \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0442\u044c \u0441\u0435\u0431\u0435 \u0438\u0434\u0442\u0438 \u0447\u0443\u0442\u044c \u0434\u0430\u043b\u044c\u0448\u0435 \u043e\u0447\u0435\u0432\u0438\u0434\u043d\u043e\u0439 \u0437\u0430\u0434\u0430\u0447\u0438.<\/p>\n<h3>\u041e\u0434\u0438\u043d bool \u043c\u043e\u0436\u0435\u0442 \u0443\u043d\u0438\u0447\u0442\u043e\u0436\u0438\u0442\u044c \u0442\u0440\u0438 \u0434\u043d\u044f \u0432\u0430\u0448\u0435\u0439 \u0436\u0438\u0437\u043d\u0438<\/h3>\n<p>\u0415\u0441\u0442\u044c \u0435\u0449\u0451 \u043e\u0434\u043d\u0430 \u0441\u043c\u0435\u0448\u043d\u0430\u044f \u0432\u0435\u0449\u044c. \u0422\u044b \u043c\u043e\u0436\u0435\u0448\u044c \u0440\u0435\u0448\u0438\u0442\u044c \u0441\u0442\u043e \u0441\u043b\u043e\u0436\u043d\u044b\u0445 \u0437\u0430\u0434\u0430\u0447: \u043f\u0440\u043e\u0442\u043e\u043a\u043e\u043b, NAT traversal, relay, \u0441\u0432\u043e\u0439 codec path, prediction, jitter, scheduling, \u043a\u0430\u043a\u0438\u0435-\u043d\u0438\u0431\u0443\u0434\u044c \u0441\u043e\u0432\u0435\u0440\u0448\u0435\u043d\u043d\u043e \u0431\u0435\u0437\u0443\u043c\u043d\u044b\u0435 race conditions.<\/p>\n<p>\u0410 \u043f\u043e\u0442\u043e\u043c \u0442\u0435\u0431\u044f \u043d\u0430 \u0442\u0440\u0438 \u0434\u043d\u044f \u0443\u043d\u0438\u0447\u0442\u043e\u0436\u0430\u0435\u0442 \u043e\u0434\u0438\u043d <code>bool<\/code>.<\/p>\n<p>\u0418 \u0442\u044b \u0441\u0438\u0434\u0438\u0448\u044c \u0438 \u0434\u0443\u043c\u0430\u0435\u0448\u044c: \u0441\u0435\u0440\u044c\u0451\u0437\u043d\u043e? \u042f \u0432\u0441\u0451 \u044d\u0442\u043e \u043d\u0430\u043f\u0438\u0441\u0430\u043b, \u0447\u0442\u043e\u0431\u044b \u0441\u0435\u0439\u0447\u0430\u0441 \u043f\u0440\u043e\u0438\u0433\u0440\u0430\u0442\u044c \u0444\u043b\u0430\u0433\u0443?<\/p>\n<p>\u0414\u0430.<\/p>\n<p>\u0418\u043c\u0435\u043d\u043d\u043e \u0442\u0430\u043a.<\/p>\n<p>\u0423 \u043c\u0435\u043d\u044f \u0443\u0436\u0435 \u0431\u044b\u043b\u0438 \u0432\u0435\u0449\u0438 \u0443\u0440\u043e\u0432\u043d\u044f:<\/p>\n<pre><code class=\"rust\">match command {    HostCommand::Start =&gt; {        running.store(            true,            Ordering::Release        );        start_host()?;    }    HostCommand::Stop =&gt; {        stop_host()?;        \/\/ \u0443\u0433\u0430\u0434\u0430\u0439\u0442\u0435, \u0447\u0435\u0433\u043e \u0437\u0434\u0435\u0441\u044c \u043a\u043e\u0433\u0434\u0430-\u0442\u043e        \/\/ \u043c\u043e\u0433\u043b\u043e \u043d\u0435 \u0445\u0432\u0430\u0442\u0430\u0442\u044c    }}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<\/p>\n<p>\u0418 \u0433\u0434\u0435-\u0442\u043e \u0434\u0430\u043b\u044c\u0448\u0435:<\/p>\n<pre><code class=\"rust\">while running.load(Ordering::Acquire) {    match listener.accept() {        Ok(stream) =&gt; {            spawn_session(stream);        }        Err(err)            if err.kind()                == std::io::ErrorKind::WouldBlock =&gt;        {            std::thread::sleep(                Duration::from_millis(5)            );        }        Err(err) =&gt; {            return Err(err.into());        }    }}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0410 \u043f\u043e\u0442\u043e\u043c \u0442\u044b \u0442\u0440\u0438 \u0447\u0430\u0441\u0430 \u0441\u043c\u043e\u0442\u0440\u0438\u0448\u044c, \u043f\u043e\u0447\u0435\u043c\u0443 <code>Stop<\/code> \u043a\u0430\u043a \u0431\u0443\u0434\u0442\u043e \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442, \u0430 listener \u0432\u0441\u0451 \u0435\u0449\u0451 \u0436\u0438\u0432.<\/p>\n<p>\u041f\u043e\u0442\u043e\u043c \u0435\u0449\u0451 \u0447\u0430\u0441.<\/p>\n<p>\u041f\u043e\u0442\u043e\u043c \u0438\u0434\u0451\u0448\u044c \u043f\u0438\u0442\u044c \u043a\u043e\u0444\u0435.<\/p>\n<p>\u0412\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0448\u044c\u0441\u044f.<\/p>\n<p>\u0421\u043c\u043e\u0442\u0440\u0438\u0448\u044c.<\/p>\n<pre><code class=\"rust\">HostCommand::Stop =&gt; {    running.store(        false,        Ordering::Release    );    stop_host()?;}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0421\u043f\u0430\u0441\u0438\u0431\u043e.<\/p>\n<p>\u0414\u043e \u0441\u0432\u0438\u0434\u0430\u043d\u0438\u044f.<\/p>\n<p>\u0411\u0430\u0433\u0443 \u0432\u043e\u043e\u0431\u0449\u0435 \u043f\u043b\u0435\u0432\u0430\u0442\u044c \u043d\u0430 \u0442\u0432\u043e\u0438 \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0438\u0435 \u0434\u043e\u0441\u0442\u0438\u0436\u0435\u043d\u0438\u044f.<\/p>\n<p>\u041e\u043d \u043d\u0435 \u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u0441\u044f \u043f\u0440\u043e\u0449\u0435 \u043e\u0442 \u0442\u043e\u0433\u043e, \u0447\u0442\u043e \u0432\u0447\u0435\u0440\u0430 \u0442\u044b \u043d\u0430\u043f\u0438\u0441\u0430\u043b \u0447\u0442\u043e-\u0442\u043e \u0443\u043c\u043d\u043e\u0435.<\/p>\n<p>\u0420\u0430\u043d\u044c\u0448\u0435 \u043c\u0435\u043d\u044f \u044d\u0442\u043e \u0431\u0435\u0441\u0438\u043b\u043e. \u0415\u0441\u043b\u0438 \u044f \u0442\u0440\u0438 \u0434\u043d\u044f \u043d\u0435 \u043c\u043e\u0433 \u043d\u0430\u0439\u0442\u0438 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0443, \u0432\u043d\u0443\u0442\u0440\u0438 \u0441\u0440\u0430\u0437\u0443 \u043d\u0430\u0447\u0438\u043d\u0430\u043b\u043e\u0441\u044c: \u043c\u043e\u0436\u0435\u0442, \u044f \u0432\u043e\u043e\u0431\u0449\u0435 \u043d\u0435 \u0443\u043c\u0435\u044e \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0438\u0440\u043e\u0432\u0430\u0442\u044c?<\/p>\n<p>\u0421\u0435\u0439\u0447\u0430\u0441 \u044f \u0441\u043c\u043e\u0442\u0440\u044e \u043f\u0440\u043e\u0449\u0435.<\/p>\n<p><strong>\u0411\u0430\u0433 \u2014 \u044d\u0442\u043e \u043f\u0440\u043e\u0441\u0442\u043e \u0442\u043e \u043c\u0435\u0441\u0442\u043e, \u0433\u0434\u0435 \u0441\u0438\u0441\u0442\u0435\u043c\u0430 \u0437\u043d\u0430\u0435\u0442 \u0431\u043e\u043b\u044c\u0448\u0435 \u0442\u0435\u0431\u044f.<\/strong><\/p>\n<p>\u041e\u043d\u0430 \u0443\u0436\u0435 \u0437\u043d\u0430\u0435\u0442, \u043f\u043e\u0447\u0435\u043c\u0443 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0438\u043c\u0435\u043d\u043d\u043e \u0442\u0430\u043a.<\/p>\n<p>\u0422\u044b \u043f\u043e\u043a\u0430 \u043d\u0435\u0442.<\/p>\n<p>\u0412\u043e\u0442 \u0438 \u0432\u0441\u0451.<\/p>\n<h3>\u041e\u0442\u043b\u0430\u0434\u043a\u0430 \u2014 \u044d\u0442\u043e \u0440\u0430\u0441\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u043d\u0438\u0435<\/h3>\n<p>\u042f \u0432\u0441\u0451 \u0447\u0430\u0449\u0435 \u043e\u0442\u043d\u043e\u0448\u0443\u0441\u044c \u043a debugging \u0438\u043c\u0435\u043d\u043d\u043e \u0442\u0430\u043a. \u041d\u0435 \u043a\u0430\u043a \u043a \u0431\u043e\u0440\u044c\u0431\u0435. \u041a\u0430\u043a \u043a \u0440\u0430\u0441\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u043d\u0438\u044e.<\/p>\n<p>\u0421\u0435\u0442\u044c \u0433\u043e\u0432\u043e\u0440\u0438\u0442: \u00ab\u042f \u0432\u0441\u0451 \u043e\u0442\u043f\u0440\u0430\u0432\u0438\u043b\u0430\u00bb.<\/p>\n<p>Assembler: \u00ab\u042f \u0432\u0441\u0451 \u0441\u043e\u0431\u0440\u0430\u043b\u00bb.<\/p>\n<p>Queue: \u00ab\u041a\u0430\u0434\u0440 \u0434\u0430\u0432\u043d\u043e \u043b\u0435\u0436\u0438\u0442 \u0443 \u043c\u0435\u043d\u044f\u00bb.<\/p>\n<p>Decoder \u0441\u0438\u0434\u0438\u0442 \u0432 \u0443\u0433\u043b\u0443 \u0438 \u043c\u043e\u043b\u0447\u0438\u0442.<\/p>\n<p>\u0425\u043e\u0440\u043e\u0448\u043e.<\/p>\n<p>\u0414\u0430\u0432\u0430\u0439\u0442\u0435 timestamps.<\/p>\n<p>\u0410\u0433\u0430.<\/p>\n<p>\u041f\u043e\u043f\u0430\u043b\u0441\u044f.<\/p>\n<p>\u041c\u043d\u0435 \u043d\u0440\u0430\u0432\u0438\u0442\u0441\u044f \u0442\u0430\u043a\u043e\u0439 \u043f\u043e\u0434\u0445\u043e\u0434. \u0411\u0435\u0437 \u043c\u0430\u0433\u0438\u0438. \u0411\u0435\u0437 \u00ab\u043c\u043d\u0435 \u043a\u0430\u0436\u0435\u0442\u0441\u044f\u00bb. \u0411\u0435\u0437 \u00ab\u0434\u0430\u0432\u0430\u0439 \u0443\u0432\u0435\u043b\u0438\u0447\u0438\u043c buffer \u0438 \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0438\u043c\u00bb.<\/p>\n<p>\u0425\u043e\u0442\u044f, \u043a\u043e\u043d\u0435\u0447\u043d\u043e, \u0438\u043d\u043e\u0433\u0434\u0430 \u043c\u044b \u0432\u0441\u0451 \u0440\u0430\u0432\u043d\u043e \u0443\u0432\u0435\u043b\u0438\u0447\u0438\u0432\u0430\u0435\u043c buffer \u0438 \u0441\u043c\u043e\u0442\u0440\u0438\u043c.<\/p>\n<p>\u041c\u044b \u0436\u0435 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0438\u0441\u0442\u044b, \u0430 \u043d\u0435 \u0441\u0432\u044f\u0442\u044b\u0435.<\/p>\n<p>\u041d\u043e \u0432 \u043a\u0430\u043a\u043e\u0439-\u0442\u043e \u043c\u043e\u043c\u0435\u043d\u0442 \u043d\u0430\u0434\u043e \u043f\u0435\u0440\u0435\u0441\u0442\u0430\u0442\u044c \u0433\u0430\u0434\u0430\u0442\u044c.<\/p>\n<h3>\u0422\u0435\u0440\u043f\u0435\u043d\u0438\u0435 \u2014 \u044d\u0442\u043e \u0432\u043e\u043e\u0431\u0449\u0435 \u043d\u0435 \u043f\u0440\u043e \u043e\u0436\u0438\u0434\u0430\u043d\u0438\u0435<\/h3>\n<p>\u0412\u043e\u0442 \u0437\u0434\u0435\u0441\u044c \u043c\u044b \u043d\u0430\u043a\u043e\u043d\u0435\u0446 \u0434\u043e\u0448\u043b\u0438 \u0434\u043e \u0442\u043e\u0433\u043e, \u0437\u0430\u0447\u0435\u043c \u044f \u0432\u043e\u043e\u0431\u0449\u0435 \u043d\u0430\u0447\u0430\u043b \u044d\u0442\u0443 \u0441\u0442\u0430\u0442\u044c\u044e.<\/p>\n<p>\u042f \u0434\u043e\u043b\u0433\u043e \u043d\u0435\u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e \u043f\u043e\u043d\u0438\u043c\u0430\u043b \u0441\u043b\u043e\u0432\u043e \u00ab\u0442\u0435\u0440\u043f\u0435\u043d\u0438\u0435\u00bb. \u041c\u043d\u0435 \u043a\u0430\u0437\u0430\u043b\u043e\u0441\u044c, \u0442\u0435\u0440\u043f\u0435\u043d\u0438\u0435 \u2014 \u044d\u0442\u043e \u043a\u043e\u0433\u0434\u0430 \u0442\u044b \u043f\u0440\u043e\u0441\u0442\u043e \u0434\u043e\u043b\u0433\u043e \u0432\u044b\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0448\u044c. \u0422\u0435\u0431\u0435 \u043f\u043b\u043e\u0445\u043e, \u0441\u043b\u043e\u0436\u043d\u043e, \u043d\u0438\u0447\u0435\u0433\u043e \u043d\u0435 \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u0442\u0441\u044f, \u0430 \u0442\u044b \u0442\u0430\u043a\u043e\u0439 \u0441\u0438\u0434\u0438\u0448\u044c \u0438 \u0442\u0435\u0440\u043f\u0438\u0448\u044c.<\/p>\n<p>\u041d\u0435\u0442.<\/p>\n<p>\u042d\u0442\u043e \u0431\u0435\u0441\u043f\u043e\u043b\u0435\u0437\u043d\u043e\u0435 \u0442\u0435\u0440\u043f\u0435\u043d\u0438\u0435.<\/p>\n<p>\u0412 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0435 \u0442\u0435\u0440\u043f\u0435\u043d\u0438\u0435 \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u0438\u043d\u0430\u0447\u0435.<\/p>\n<p>\u041d\u0435 \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u043e\u0441\u044c \u0432\u043e\u0441\u043f\u0440\u043e\u0438\u0437\u0432\u0435\u0441\u0442\u0438 \u0431\u0430\u0433 \u2014 \u0441\u0442\u0440\u043e\u0438\u0448\u044c \u0441\u0446\u0435\u043d\u0430\u0440\u0438\u0439 \u0432\u043e\u0441\u043f\u0440\u043e\u0438\u0437\u0432\u0435\u0434\u0435\u043d\u0438\u044f. \u041d\u0435 \u043f\u043e\u043d\u0438\u043c\u0430\u0435\u0448\u044c, \u0433\u0434\u0435 \u0437\u0430\u0434\u0435\u0440\u0436\u043a\u0430 \u2014 \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u0448\u044c \u0438\u0437\u043c\u0435\u0440\u0435\u043d\u0438\u044f. \u041b\u043e\u0433\u0438 \u043f\u0440\u0435\u0432\u0440\u0430\u0442\u0438\u043b\u0438\u0441\u044c \u0432 \u043f\u043e\u043c\u043e\u0439\u043a\u0443 \u2014 \u0434\u0435\u043b\u0430\u0435\u0448\u044c \u043c\u0435\u0442\u0440\u0438\u043a\u0443. \u041c\u0435\u0442\u0440\u0438\u043a\u0430 \u0432\u0440\u0451\u0442 \u2014 \u0441\u0442\u0440\u043e\u0438\u0448\u044c \u0438\u043d\u0432\u0430\u0440\u0438\u0430\u043d\u0442\u044b. \u041f\u0440\u043e\u0432\u0435\u0440\u0438\u043b \u043f\u044f\u0442\u044c \u043f\u043e\u0434\u0441\u0438\u0441\u0442\u0435\u043c \u0438 \u043d\u0438 \u043e\u0434\u043d\u0430 \u043d\u0435 \u0432\u0438\u043d\u043e\u0432\u0430\u0442\u0430 \u2014 \u043e\u0442\u043b\u0438\u0447\u043d\u043e. \u0422\u0435\u043f\u0435\u0440\u044c \u0443 \u0442\u0435\u0431\u044f \u043d\u0430 \u043f\u044f\u0442\u044c \u043f\u043e\u0434\u043e\u0437\u0440\u0435\u0432\u0430\u0435\u043c\u044b\u0445 \u043c\u0435\u043d\u044c\u0448\u0435.<\/p>\n<p>\u042d\u0442\u043e \u0442\u043e\u0436\u0435 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442.<\/p>\n<p>\u0418\u043d\u043e\u0433\u0434\u0430 \u0437\u0430 \u0434\u0435\u043d\u044c \u0442\u044b \u0432\u043e\u043e\u0431\u0449\u0435 \u043d\u0438\u0447\u0435\u0433\u043e \u043d\u0435 \u0438\u0441\u043f\u0440\u0430\u0432\u0438\u043b. \u041d\u043e \u0432\u0435\u0447\u0435\u0440\u043e\u043c \u0443\u0436\u0435 \u0442\u043e\u0447\u043d\u043e \u0437\u043d\u0430\u0435\u0448\u044c: \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0430 \u043d\u0435 \u0437\u0434\u0435\u0441\u044c, \u043d\u0435 \u0437\u0434\u0435\u0441\u044c \u0438 \u043d\u0435 \u0437\u0434\u0435\u0441\u044c.<\/p>\n<p>\u0418 \u044d\u0442\u043e \u0445\u043e\u0440\u043e\u0448\u0438\u0439 \u0434\u0435\u043d\u044c.<\/p>\n<h3>\u041e\u0441\u043e\u0431\u0435\u043d\u043d\u043e \u043a\u043e\u0433\u0434\u0430 \u0442\u044b \u043e\u0434\u0438\u043d<\/h3>\n<p>\u041a\u043e\u0433\u0434\u0430 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0448\u044c \u043e\u0434\u0438\u043d, \u0438\u043d\u043e\u0433\u0434\u0430 \u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u0441\u044f \u043e\u0441\u043e\u0431\u0435\u043d\u043d\u043e \u0441\u043c\u0435\u0448\u043d\u043e.<\/p>\n<p>\u041d\u0435\u043b\u044c\u0437\u044f \u0432\u0437\u044f\u0442\u044c \u0442\u0438\u043a\u0435\u0442 \u0438 \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c: \u00ab\u041f\u0435\u0440\u0435\u0434\u0430\u0451\u043c \u0432 networking team\u00bb.<\/p>\n<p>Networking team \u2014 \u044d\u0442\u043e \u0442\u044b. Video team \u2014 \u0442\u044b. Desktop team \u2014 \u043e\u043f\u044f\u0442\u044c \u0442\u044b. QA \u2014 \u0443\u0433\u0430\u0434\u0430\u0439\u0442\u0435 \u043a\u0442\u043e. \u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0432 \u0442\u0440\u0438 \u0447\u0430\u0441\u0430 \u043d\u043e\u0447\u0438 \u0434\u0432\u0438\u0433\u0430\u0435\u0442 \u043c\u044b\u0448\u044c\u044e \u0438 \u0433\u043e\u0432\u043e\u0440\u0438\u0442 \u00ab\u0447\u0442\u043e-\u0442\u043e \u043b\u0430\u0433\u0430\u0435\u0442\u00bb, \u0442\u043e\u0436\u0435 \u0442\u044b.<\/p>\n<p>\u0421 \u043e\u0434\u043d\u043e\u0439 \u0441\u0442\u043e\u0440\u043e\u043d\u044b, \u044d\u0442\u043e \u0438\u043d\u043e\u0433\u0434\u0430 \u0437\u0430\u0434\u043e\u043b\u0431\u044b\u0432\u0430\u0435\u0442. \u0421 \u0434\u0440\u0443\u0433\u043e\u0439 \u2014 \u0442\u044b \u043d\u0430\u0447\u0438\u043d\u0430\u0435\u0448\u044c \u0432\u0438\u0434\u0435\u0442\u044c \u0441\u0438\u0441\u0442\u0435\u043c\u0443 \u0446\u0435\u043b\u0438\u043a\u043e\u043c.<\/p>\n<p>\u041d\u0435 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0439 \u043a\u043b\u0430\u0441\u0441. \u041d\u0435 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u0443\u044e \u0444\u0443\u043d\u043a\u0446\u0438\u044e.<\/p>\n<p>\u0410 \u043f\u0443\u0442\u044c \u043e\u0442 \u0437\u0430\u0445\u0432\u0430\u0442\u0430 \u043f\u0438\u043a\u0441\u0435\u043b\u044f \u0434\u043e \u0442\u043e\u0433\u043e \u043c\u043e\u043c\u0435\u043d\u0442\u0430, \u043a\u043e\u0433\u0434\u0430 \u043e\u043d \u043f\u043e\u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043d\u0430 \u0434\u0440\u0443\u0433\u043e\u043c \u044d\u043a\u0440\u0430\u043d\u0435.<\/p>\n<p>\u041c\u043d\u0435 \u044d\u0442\u043e \u0432\u0441\u0435\u0433\u0434\u0430 \u0431\u044b\u043b\u043e \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u043e.<\/p>\n<h3>\u0411\u043e\u043b\u044c\u0448\u0438\u0435 \u0441\u0438\u0441\u0442\u0435\u043c\u044b \u0441\u0442\u0440\u043e\u044f\u0442\u0441\u044f \u043e\u0447\u0435\u043d\u044c \u0442\u0443\u043f\u043e<\/h3>\n<p>\u0421\u043e \u0441\u0442\u043e\u0440\u043e\u043d\u044b \u0432\u0441\u0451 \u0438\u043d\u043e\u0433\u0434\u0430 \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u0442\u0430\u043a, \u0431\u0443\u0434\u0442\u043e \u0443 \u043c\u0435\u043d\u044f \u0431\u044b\u043b \u043a\u0430\u043a\u043e\u0439-\u0442\u043e \u0432\u0435\u043b\u0438\u043a\u0438\u0439 \u043f\u043b\u0430\u043d. EvertyDesk. EVRTCK. EvertyDisplay. \u0421\u0432\u043e\u0439 transport. \u0421\u0432\u043e\u0438 \u044d\u043a\u0441\u043f\u0435\u0440\u0438\u043c\u0435\u043d\u0442\u044b \u0441 prediction. \u041f\u043e\u0442\u043e\u043c \u0435\u0449\u0451 \u0447\u0442\u043e-\u043d\u0438\u0431\u0443\u0434\u044c.<\/p>\n<p>\u041d\u0430 \u0441\u0430\u043c\u043e\u043c \u0434\u0435\u043b\u0435 \u0432\u0441\u0451 \u0433\u043e\u0440\u0430\u0437\u0434\u043e \u0442\u0443\u043f\u0435\u0435.<\/p>\n<p>\u042f \u043f\u0440\u043e\u0441\u0442\u043e \u043a\u0430\u0436\u0434\u044b\u0439 \u0440\u0430\u0437 \u0440\u0435\u0448\u0430\u043b \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0443\u044e \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0443.<\/p>\n<p>\u041d\u0443\u0436\u0435\u043d remote desktop. \u0425\u043e\u0440\u043e\u0448\u043e.<\/p>\n<p>\u041d\u0435 \u0443\u0441\u0442\u0440\u0430\u0438\u0432\u0430\u0435\u0442 \u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0430 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f. \u0425\u043e\u0440\u043e\u0448\u043e. \u041f\u0440\u043e\u0431\u0443\u0435\u043c \u0441\u0432\u043e\u0451.<\/p>\n<p>\u041d\u0435 \u0443\u0441\u0442\u0440\u0430\u0438\u0432\u0430\u0435\u0442 latency. \u0425\u043e\u0440\u043e\u0448\u043e. \u0418\u0449\u0435\u043c \u0433\u0434\u0435.<\/p>\n<p>\u041d\u0435 \u0445\u0432\u0430\u0442\u0430\u0435\u0442 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u043e\u0432 \u0434\u043b\u044f \u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u043c\u043e\u043d\u0438\u0442\u043e\u0440\u043e\u0432. \u0425\u043e\u0440\u043e\u0448\u043e. \u0422\u0435\u043f\u0435\u0440\u044c \u0443 \u043c\u0435\u043d\u044f \u0432\u0438\u0440\u0442\u0443\u0430\u043b\u044c\u043d\u044b\u0435 \u043c\u043e\u043d\u0438\u0442\u043e\u0440\u044b.<\/p>\n<p>\u0412\u043e\u0442 \u0442\u0430\u043a \u0438 \u043f\u043e\u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0441\u0438\u0441\u0442\u0435\u043c\u0430.<\/p>\n<p>\u041d\u0435 \u0438\u0437: \u00ab\u0421\u0435\u0433\u043e\u0434\u043d\u044f \u044f \u043f\u043e\u0441\u0442\u0440\u043e\u044e \u0443\u043d\u0438\u043a\u0430\u043b\u044c\u043d\u0443\u044e \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u0443\u00bb.<\/p>\n<p>\u0410 \u0438\u0437:<\/p>\n<p><strong>\u00ab\u041f\u043e\u0447\u0435\u043c\u0443 \u044d\u0442\u043e\u0442 \u0447\u0451\u0440\u0442\u043e\u0432 \u043a\u0430\u0434\u0440 \u043b\u0435\u0436\u0438\u0442 \u0432 \u043e\u0447\u0435\u0440\u0435\u0434\u0438 34 \u043c\u0438\u043b\u043b\u0438\u0441\u0435\u043a\u0443\u043d\u0434\u044b?\u00bb<\/strong><\/p>\n<p>\u0410 \u043f\u043e\u0442\u043e\u043c \u0447\u0435\u0440\u0435\u0437 \u0433\u043e\u0434 \u0442\u044b \u0441\u043c\u043e\u0442\u0440\u0438\u0448\u044c \u043d\u0430 \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0439 \u0438 \u043f\u043e\u043d\u0438\u043c\u0430\u0435\u0448\u044c:<\/p>\n<p>\u041e.<\/p>\n<p>\u0422\u0443\u0442 \u0443\u0436\u0435 \u043f\u043e\u043b\u0441\u0430\u043c\u043e\u043b\u0451\u0442\u0430.<\/p>\n<h3>\u041c\u044b \u043f\u043e\u0441\u0442\u043e\u044f\u043d\u043d\u043e \u0436\u0434\u0451\u043c \u043c\u043e\u043c\u0435\u043d\u0442\u0430, \u043a\u043e\u0433\u0434\u0430 \u0432\u0441\u0451 \u0437\u0430\u043a\u043e\u043d\u0447\u0438\u0442\u0441\u044f<\/h3>\n<p>\u041c\u043d\u0435 \u043a\u0430\u0436\u0435\u0442\u0441\u044f, \u044d\u0442\u043e \u0432\u043e\u043e\u0431\u0449\u0435 \u0431\u043e\u043b\u044c\u0448\u0430\u044f \u043b\u043e\u0432\u0443\u0448\u043a\u0430.<\/p>\n<p>\u0412\u043e\u0442 \u0441\u0435\u0439\u0447\u0430\u0441 \u0434\u043e\u043f\u0438\u0448\u0443. \u0412\u043e\u0442 \u0441\u0435\u0439\u0447\u0430\u0441 \u0432\u044b\u043f\u0443\u0449\u0443. \u0412\u043e\u0442 \u0441\u0435\u0439\u0447\u0430\u0441 \u0438\u0441\u043f\u0440\u0430\u0432\u043b\u044e \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0438\u0435 \u0431\u0430\u0433\u0438. \u0412\u043e\u0442 \u0441\u0435\u0439\u0447\u0430\u0441 \u0434\u043e\u0432\u0435\u0434\u0443 \u0434\u043e \u0438\u0434\u0435\u0430\u043b\u0430.<\/p>\n<p>\u0418 \u043f\u043e\u0442\u043e\u043c \u0441\u0442\u0430\u043d\u0435\u0442 \u0441\u043f\u043e\u043a\u043e\u0439\u043d\u043e.<\/p>\n<p>\u041d\u0435 \u0441\u0442\u0430\u043d\u0435\u0442.<\/p>\n<p>EvertyDesk \u043d\u0438\u043a\u043e\u0433\u0434\u0430 \u043d\u0435 \u0431\u0443\u0434\u0435\u0442 \u043f\u043e\u043b\u043d\u043e\u0441\u0442\u044c\u044e \u0433\u043e\u0442\u043e\u0432. EVRTCK \u0442\u043e\u0436\u0435. EvertyDisplay \u0442\u043e\u0436\u0435.<\/p>\n<p>\u041f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u043a\u0430\u043a \u0442\u043e\u043b\u044c\u043a\u043e \u0442\u044b \u0438\u0441\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u0448\u044c \u043e\u0434\u043d\u0443 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0443, \u0442\u044b \u043d\u0430\u0447\u0438\u043d\u0430\u0435\u0448\u044c \u0432\u0438\u0434\u0435\u0442\u044c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0443\u044e.<\/p>\n<p>\u041a\u043e\u0433\u0434\u0430 \u0443 \u0442\u0435\u0431\u044f latency 100 \u043c\u0441, \u0442\u044b \u0445\u043e\u0447\u0435\u0448\u044c 50. \u041f\u043e\u043b\u0443\u0447\u0438\u043b 50 \u2014 \u043d\u0430\u0447\u0438\u043d\u0430\u0435\u0448\u044c \u043d\u0435\u043d\u0430\u0432\u0438\u0434\u0435\u0442\u044c 30. \u041f\u043e\u043b\u0443\u0447\u0438\u043b 15 \u2014 \u0432\u043d\u0435\u0437\u0430\u043f\u043d\u043e \u0443\u0436\u0435 \u0432\u0438\u0434\u0438\u0448\u044c 5.<\/p>\n<p>\u0418 \u043a\u043e\u043d\u0446\u0430 \u043d\u0435\u0442.<\/p>\n<p>\u0420\u0430\u043d\u044c\u0448\u0435 \u043c\u0435\u043d\u044f \u044d\u0442\u043e \u043d\u0430\u043f\u0440\u044f\u0433\u0430\u043b\u043e.<\/p>\n<p>\u0421\u0435\u0439\u0447\u0430\u0441 \u043c\u043d\u0435 \u043a\u0430\u0436\u0435\u0442\u0441\u044f, \u0438\u043c\u0435\u043d\u043d\u043e \u0432 \u044d\u0442\u043e\u043c \u0438 \u0435\u0441\u0442\u044c \u0441\u043c\u044b\u0441\u043b.<\/p>\n<p>\u0415\u0441\u043b\u0438 \u0442\u044b \u043d\u0430\u0447\u0430\u043b \u0432\u0438\u0434\u0435\u0442\u044c \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u044b, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0433\u043e\u0434 \u043d\u0430\u0437\u0430\u0434 \u0434\u0430\u0436\u0435 \u043d\u0435 \u0437\u0430\u043c\u0435\u0447\u0430\u043b, \u2014 \u0437\u043d\u0430\u0447\u0438\u0442, \u0442\u044b \u0432\u044b\u0440\u043e\u0441.<\/p>\n<h3>\u0421\u0442\u0430\u0440\u044b\u0439 \u043a\u043e\u0434 \u0434\u043e\u043b\u0436\u0435\u043d \u043d\u0435\u043c\u043d\u043e\u0433\u043e \u0431\u0435\u0441\u0438\u0442\u044c<\/h3>\n<p>\u0418\u043d\u043e\u0433\u0434\u0430 \u043e\u0442\u043a\u0440\u044b\u0432\u0430\u0435\u0448\u044c \u0441\u0432\u043e\u0439 \u043a\u043e\u0434 \u0434\u0432\u0443\u0445\u043b\u0435\u0442\u043d\u0435\u0439 \u0434\u0430\u0432\u043d\u043e\u0441\u0442\u0438. \u0421\u043c\u043e\u0442\u0440\u0438\u0448\u044c \u0438 \u0434\u0443\u043c\u0430\u0435\u0448\u044c: \u043a\u0442\u043e \u043d\u0430\u043f\u0438\u0441\u0430\u043b \u044d\u0442\u0443 \u0445\u0440\u0435\u043d\u044c?<\/p>\n<p>\u041f\u043e\u0442\u043e\u043c \u043e\u0442\u043a\u0440\u044b\u0432\u0430\u0435\u0448\u044c <code>git blame<\/code>.<\/p>\n<p>\u0410.<\/p>\n<p>\u041d\u0443 \u043a\u043e\u043d\u0435\u0447\u043d\u043e.<\/p>\n<p>\u042f.<\/p>\n<p>\u0418 \u044d\u0442\u043e \u043f\u0440\u0435\u043a\u0440\u0430\u0441\u043d\u043e.<\/p>\n<p>\u0415\u0441\u043b\u0438 \u0441\u0442\u0430\u0440\u044b\u0439 \u043a\u043e\u0434 \u043a\u0430\u0436\u0435\u0442\u0441\u044f \u0442\u0435\u0431\u0435 \u0438\u0434\u0435\u0430\u043b\u044c\u043d\u044b\u043c, \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e, \u0442\u044b \u043f\u0440\u043e\u0441\u0442\u043e \u043d\u0438\u043a\u0443\u0434\u0430 \u043d\u0435 \u0443\u0448\u0451\u043b.<\/p>\n<p>\u041c\u043d\u0435 \u043d\u0440\u0430\u0432\u0438\u0442\u0441\u044f \u0432\u0438\u0434\u0435\u0442\u044c \u0441\u0432\u043e\u0438 \u0441\u0442\u0430\u0440\u044b\u0435 \u043e\u0448\u0438\u0431\u043a\u0438. \u041d\u0435 \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u044f \u043b\u044e\u0431\u043b\u044e \u043f\u043b\u043e\u0445\u043e\u0439 \u043a\u043e\u0434. \u0410 \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u0441\u0435\u0433\u043e\u0434\u043d\u044f\u0448\u043d\u0438\u0439 \u044f \u0443\u0436\u0435 \u043f\u043e\u043d\u0438\u043c\u0430\u0435\u0442, \u043f\u043e\u0447\u0435\u043c\u0443 \u043e\u043d \u043f\u043b\u043e\u0445\u043e\u0439.<\/p>\n<p>\u0414\u0432\u0430 \u0433\u043e\u0434\u0430 \u043d\u0430\u0437\u0430\u0434 \u043d\u0435 \u043f\u043e\u043d\u0438\u043c\u0430\u043b.<\/p>\n<p>\u0421\u0435\u0439\u0447\u0430\u0441 \u043f\u043e\u043d\u0438\u043c\u0430\u044e.<\/p>\n<p>\u0417\u043d\u0430\u0447\u0438\u0442, \u0447\u0442\u043e-\u0442\u043e \u043f\u0440\u043e\u0438\u0437\u043e\u0448\u043b\u043e.<\/p>\n<h3>\u041c\u043e\u0451 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u0435 \u0442\u0435\u0440\u043f\u0435\u043d\u0438\u044f<\/h3>\n<p>\u042f \u043d\u0435 \u0445\u043e\u0447\u0443 \u043f\u0440\u0435\u0432\u0440\u0430\u0449\u0430\u0442\u044c \u044d\u0442\u043e \u0432 \u043a\u0440\u0430\u0441\u0438\u0432\u0443\u044e \u043c\u043e\u0442\u0438\u0432\u0430\u0446\u0438\u043e\u043d\u043d\u0443\u044e \u043a\u043e\u043d\u0446\u043e\u0432\u043a\u0443. \u041d\u0435 \u043b\u044e\u0431\u043b\u044e \u0442\u0430\u043a\u043e\u0435.<\/p>\n<p>\u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u0441\u043a\u0430\u0436\u0443 \u043f\u0440\u043e\u0449\u0435.<\/p>\n<p>\u0414\u043b\u044f \u043c\u0435\u043d\u044f \u0442\u0435\u0440\u043f\u0435\u043d\u0438\u0435 \u0441\u0435\u0439\u0447\u0430\u0441 \u2014 \u044d\u0442\u043e \u043d\u0435 \u00ab\u043a\u043e\u0433\u0434\u0430-\u043d\u0438\u0431\u0443\u0434\u044c \u0432\u0441\u0451 \u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u043e \u0441\u0442\u0430\u043d\u0435\u0442 \u0445\u043e\u0440\u043e\u0448\u043e\u00bb.<\/p>\n<p>\u042f \u0432\u043e\u043e\u0431\u0449\u0435 \u043d\u0435 \u0437\u043d\u0430\u044e, \u0441\u0442\u0430\u043d\u0435\u0442 \u0438\u043b\u0438 \u043d\u0435\u0442.<\/p>\n<p>\u0422\u0435\u0440\u043f\u0435\u043d\u0438\u0435 \u2014 \u044d\u0442\u043e \u043a\u043e\u0433\u0434\u0430 \u0441\u0435\u0433\u043e\u0434\u043d\u044f \u043d\u0435 \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u043e\u0441\u044c, \u0430 \u0437\u0430\u0432\u0442\u0440\u0430 \u0442\u044b \u043e\u0442\u043a\u0440\u044b\u0432\u0430\u0435\u0448\u044c \u043f\u0440\u043e\u0435\u043a\u0442 \u0435\u0449\u0451 \u0440\u0430\u0437.<\/p>\n<p>\u041d\u0435 \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u0442\u044b \u0432\u0435\u043b\u0438\u043a\u0438\u0439.<\/p>\n<p>\u041d\u0435 \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u0436\u0435\u043b\u0435\u0437\u043d\u0430\u044f \u0432\u043e\u043b\u044f.<\/p>\n<p>\u0410 \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u0432\u0447\u0435\u0440\u0430 \u0443 \u0442\u0435\u0431\u044f \u0431\u044b\u043b\u043e \u043f\u044f\u0442\u044c \u0433\u0438\u043f\u043e\u0442\u0435\u0437, \u0441\u0435\u0433\u043e\u0434\u043d\u044f \u043e\u0441\u0442\u0430\u043b\u043e\u0441\u044c \u0442\u0440\u0438. \u041f\u043e\u0442\u043e\u043c \u0434\u0432\u0435. \u041f\u043e\u0442\u043e\u043c \u043e\u0434\u043d\u0430.<\/p>\n<p>\u0418 \u0432 \u043a\u0430\u043a\u043e\u0439-\u0442\u043e \u043c\u043e\u043c\u0435\u043d\u0442 \u043e\u0433\u0440\u043e\u043c\u043d\u0430\u044f \u043d\u0435\u043f\u043e\u043d\u044f\u0442\u043d\u0430\u044f \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0430 \u043f\u0440\u0435\u0432\u0440\u0430\u0449\u0430\u0435\u0442\u0441\u044f \u0432 \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u0443\u044e \u0432\u0435\u0449\u044c.<\/p>\n<p>\u041e\u0447\u0435\u0440\u0435\u0434\u044c.<\/p>\n<p>\u0421\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435.<\/p>\n<p>\u041f\u0430\u043a\u0435\u0442.<\/p>\n<p>\u0422\u0430\u0439\u043c\u0435\u0440.<\/p>\n<p>\u041e\u0434\u0438\u043d <code>bool<\/code>.<\/p>\n<p>\u041e\u0434\u0438\u043d \u043a\u0430\u0434\u0440.<\/p>\n<p>\u0422\u044b \u0438\u0441\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u0448\u044c. \u041a\u043e\u043c\u043f\u0438\u043b\u0438\u0440\u0443\u0435\u0448\u044c. \u0417\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u0448\u044c. \u0414\u0432\u0438\u0433\u0430\u0435\u0448\u044c \u043c\u044b\u0448\u044c.<\/p>\n<p>\u041a\u0430\u0440\u0442\u0438\u043d\u043a\u0430 \u0438\u0434\u0451\u0442 \u043f\u043b\u0430\u0432\u043d\u043e.<\/p>\n<p>\u0421\u0438\u0434\u0438\u0448\u044c \u0441\u0435\u043a\u0443\u043d\u0434 \u0434\u0435\u0441\u044f\u0442\u044c.<\/p>\n<p>\u0420\u0430\u0434\u0443\u0435\u0448\u044c\u0441\u044f.<\/p>\n<p>\u0410 \u043f\u043e\u0442\u043e\u043c \u0437\u0430\u043c\u0435\u0447\u0430\u0435\u0448\u044c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u0431\u0430\u0433.<\/p>\n<p>\u041d\u0443 \u043a\u043e\u043d\u0435\u0447\u043d\u043e.<\/p>\n<p>\u041e\u0442\u043a\u0440\u044b\u0432\u0430\u0435\u0448\u044c \u043a\u043e\u0434.<\/p>\n<p>\u0418\u0434\u0451\u043c \u0434\u0430\u043b\u044c\u0448\u0435.<\/p>\n<p><strong><em>\u0410\u0440\u0442\u0443\u0440 \u0412\u0430\u043b\u0438\u0435\u0432  \u2248  V<\/em><\/strong><\/p>\n<\/div>\n<p>\u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"https:\/\/habr.com\/ru\/articles\/1085912\/\">https:\/\/habr.com\/ru\/articles\/1085912\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>\u0417\u043d\u0430\u0435\u0442\u0435, \u044f \u0445\u043e\u0442\u0435\u043b \u0441\u0435\u0433\u043e\u0434\u043d\u044f \u043f\u043e\u0433\u043e\u0432\u043e\u0440\u0438\u0442\u044c \u043e \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u0433\u043b\u0443\u0431\u043e\u043a\u043e\u0439 \u0432\u0435\u0449\u0438. \u0417\u0430\u0447\u0435\u043c \u043d\u0430\u043c \u0432\u043e\u043e\u0431\u0449\u0435 \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0430\u0442\u044c \u0447\u0442\u043e-\u0442\u043e \u0434\u0435\u043b\u0430\u0442\u044c? \u041d\u0435 \u0437\u0430\u0447\u0435\u043c \u043d\u0430\u0447\u0438\u043d\u0430\u0442\u044c. \u041d\u0430\u0447\u0438\u043d\u0430\u0442\u044c \u043b\u0435\u0433\u043a\u043e. \u0412 \u043d\u0430\u0447\u0430\u043b\u0435 \u0435\u0441\u0442\u044c \u0438\u0434\u0435\u044f, \u0430\u0437\u0430\u0440\u0442, \u043d\u043e\u0432\u044b\u0439 \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0439, \u043f\u0435\u0440\u0432\u044b\u0435 \u043a\u043e\u043c\u043c\u0438\u0442\u044b \u0438 \u043e\u0449\u0443\u0449\u0435\u043d\u0438\u0435, \u0447\u0442\u043e \u0441\u0435\u0439\u0447\u0430\u0441 \u0442\u044b \u0441\u0434\u0435\u043b\u0430\u0435\u0448\u044c \u0447\u0442\u043e-\u0442\u043e \u0447\u0435\u0440\u0442\u043e\u0432\u0441\u043a\u0438 \u043a\u0440\u0443\u0442\u043e\u0435. \u0410 \u043f\u043e\u0442\u043e\u043c \u043f\u0440\u043e\u0445\u043e\u0434\u0438\u0442 \u043d\u0435\u0434\u0435\u043b\u044f, \u043c\u0435\u0441\u044f\u0446, \u0433\u043e\u0434, \u0438 \u0442\u044b \u0441\u0438\u0434\u0438\u0448\u044c \u043d\u043e\u0447\u044c\u044e \u043f\u0435\u0440\u0435\u0434 \u043c\u043e\u043d\u0438\u0442\u043e\u0440\u043e\u043c \u0438 \u0441\u043c\u043e\u0442\u0440\u0438\u0448\u044c \u043d\u0430 \u043a\u0430\u0440\u0442\u0438\u043d\u043a\u0443, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u043f\u043e\u0447\u0435\u043c\u0443-\u0442\u043e \u0434\u0451\u0440\u0433\u0430\u0435\u0442\u0441\u044f. \u0425\u043e\u0442\u044f \u0432\u0441\u0451 \u0434\u043e\u043b\u0436\u043d\u043e \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c.\u042f \u0431\u044b \u0445\u043e\u0442\u0435\u043b \u0441\u0440\u0430\u0437\u0443 \u0440\u0430\u0441\u0441\u043a\u0430\u0437\u0430\u0442\u044c \u0447\u0442\u043e \u044f \u043d\u0435 \u043f\u0438\u0441\u0430\u0440\u044c, \u042f \u043d\u0435 \u043f\u0438\u0448\u0443 \u0438 \u043d\u0435 \u043f\u0440\u0438\u0434\u0443\u043c\u044b\u0432\u0430\u044e \u0438\u0434\u0435\u0438 \u0441 \u043d\u0435\u0439\u0440\u043e\u0441\u0435\u0442\u044f\u043c\u0438, \u044f \u0441\u0442\u0430\u0440\u0430\u044e\u0441\u044c \u0432 \u043d\u0430\u0441\u0442\u0440\u043e\u0435\u043d\u0438\u0435 \u043f\u0430\u0440\u0443 \u043d\u0435\u0434\u0435\u043b\u044c \u0433\u043e\u0442\u043e\u0432\u0438\u0442\u0441\u044f \u0438 \u0432\u044b\u0434\u0430\u0432\u0430\u0442\u044c \u0441\u0442\u0430\u0442\u044c\u044e. \u042f \u043d\u0435 \u0431\u0443\u0434\u0443 \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c, \u043d\u043e \u0435\u0441\u043b\u0438 \u0431\u0443\u0434\u0443\u0442 \u043b\u044e\u0434\u0438 \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0437\u0430\u043c\u0435\u0442\u044f\u0442 \u043e\u0448\u0438\u0431\u043a\u0443, \u043f\u043e\u0436\u0430\u043b\u0443\u0439\u0441\u0442\u0430 \u043f\u0438\u0448\u0438\u0442\u0435 \u0432 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u043a\u0430\u043a \u043e\u0431\u044b\u0447\u043d\u043e \u043f\u0440\u0438\u043d\u044f\u0442\u043e \u043d\u0430 \u0445\u0430\u0431\u0440\u0435.\u0421 \u0432\u0430\u043c\u0438 \u0410\u0440\u0442\u0443\u0440 \u0412\u0430\u043b\u0438\u0435\u0432. \u0421\u0435\u0433\u043e\u0434\u043d\u044f \u044f \u043d\u0435 \u0431\u0443\u0434\u0443 \u0433\u043e\u0432\u043e\u0440\u0438\u0442\u044c \u043e \u0441\u043c\u0435\u0440\u0442\u0438, \u043b\u044e\u0431\u0432\u0438, \u0440\u043e\u0436\u0434\u0435\u043d\u0438\u0438 \u0438 \u043f\u0440\u043e\u0447\u0438\u0445 \u0432\u0435\u0449\u0430\u0445, \u043a\u0443\u0434\u0430 \u043c\u0435\u043d\u044f \u043f\u0435\u0440\u0438\u043e\u0434\u0438\u0447\u0435\u0441\u043a\u0438 \u0437\u0430\u043d\u043e\u0441\u0438\u0442. \u0421\u0435\u0433\u043e\u0434\u043d\u044f \u044f \u0445\u043e\u0447\u0443 \u043f\u043e\u0433\u043e\u0432\u043e\u0440\u0438\u0442\u044c \u043e \u0442\u0435\u0440\u043f\u0435\u043d\u0438\u0438. \u0418 \u0434\u0430, \u0441\u0442\u0430\u0442\u044c\u044f \u0431\u0443\u0434\u0435\u0442 \u0434\u043b\u0438\u043d\u043d\u043e\u0439. \u041f\u043e\u0442\u0435\u0440\u043f\u0438\u0442\u0435.\u0410 \u0435\u0449\u0451 \u0445\u0432\u0430\u0442\u0438\u0442 \u0443\u0436\u0435 \u0434\u0443\u043c\u0430\u0442\u044c, \u0447\u0442\u043e \u043a\u0430\u0436\u0434\u0443\u044e \u043c\u043e\u044e \u0441\u0442\u0430\u0442\u044c\u044e \u043f\u0438\u0448\u0435\u0442 \u043e\u0447\u0435\u0440\u0435\u0434\u043d\u043e\u0439 AI. \u041d\u0435\u0442. \u042f \u0410\u0440\u0442\u0443\u0440. \u041f\u0438\u0448\u0443 \u0441\u0430\u043c. \u041f\u043e\u0447\u0435\u043c\u0443 \u044f \u0434\u043e \u0441\u0438\u0445 \u043f\u043e\u0440 \u0441\u043d\u0430\u0447\u0430\u043b\u0430 \u043f\u0438\u0448\u0443 \u0447\u0435\u0440\u043d\u043e\u0432\u0438\u043a \u0432 .md \u2014 \u043d\u0435 \u0437\u043d\u0430\u044e. \u041d\u0430\u0432\u0435\u0440\u043d\u043e\u0435, \u0443\u0436\u0435 \u043f\u0440\u0438\u0432\u044b\u0447\u043a\u0430.\u0421\u0435\u0433\u043e\u0434\u043d\u044f \u043d\u0435 \u0431\u0443\u0434\u0435\u0442 \u043e\u0447\u0435\u0440\u0435\u0434\u043d\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0438 \u043f\u0440\u043e \u00ab\u0442\u0440\u0438\u043e\u00bb. \u0425\u043e\u0442\u044f EvertyDesk \u0438 EvertyDisplay \u0441\u044e\u0434\u0430 \u0432\u0441\u0451 \u0440\u0430\u0432\u043d\u043e \u0432\u043b\u0435\u0437\u0443\u0442. \u041f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u0432\u043d\u0435\u0437\u0430\u043f\u043d\u043e \u043e\u043a\u0430\u0437\u0430\u043b\u043e\u0441\u044c, \u0447\u0442\u043e \u043e\u0434\u0438\u043d \u043c\u043e\u0439 \u043f\u0440\u043e\u0434\u0443\u043a\u0442 \u043f\u043e\u043c\u043e\u0433\u0430\u0435\u0442 \u043c\u043d\u0435 \u043e\u0442\u043b\u0430\u0436\u0438\u0432\u0430\u0442\u044c \u0434\u0440\u0443\u0433\u043e\u0439.\u041d\u043e \u043d\u0430\u0447\u043d\u0451\u043c \u043d\u0435 \u0441 \u044d\u0442\u043e\u0433\u043e.\u041a\u043e\u0433\u0434\u0430 \u0432\u0441\u0451 \u0432\u0440\u043e\u0434\u0435 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442\u0415\u0441\u0442\u044c \u043e\u0434\u0438\u043d \u043e\u0441\u043e\u0431\u0435\u043d\u043d\u043e \u043c\u0435\u0440\u0437\u043a\u0438\u0439 \u0442\u0438\u043f \u0431\u0430\u0433\u043e\u0432. \u042d\u0442\u043e \u043d\u0435 \u043a\u043e\u0433\u0434\u0430 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0430 \u043f\u0430\u0434\u0430\u0435\u0442. \u0415\u0441\u043b\u0438 \u043e\u043d\u0430 \u0443\u043f\u0430\u043b\u0430 \u2014 \u043f\u0440\u0435\u043a\u0440\u0430\u0441\u043d\u043e. \u0415\u0441\u0442\u044c stack trace, \u0435\u0441\u0442\u044c panic, \u0435\u0441\u0442\u044c error, \u0435\u0441\u0442\u044c \u0445\u043e\u0442\u044c \u0447\u0442\u043e-\u0442\u043e.\u041d\u0430\u0441\u0442\u043e\u044f\u0449\u0430\u044f \u043c\u0435\u0440\u0437\u043e\u0441\u0442\u044c \u043d\u0430\u0447\u0438\u043d\u0430\u0435\u0442\u0441\u044f \u0442\u043e\u0433\u0434\u0430, \u043a\u043e\u0433\u0434\u0430 \u0432\u0441\u0451 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442.\u0421\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u0435 \u0435\u0441\u0442\u044c. \u041a\u0430\u0440\u0442\u0438\u043d\u043a\u0430 \u0438\u0434\u0451\u0442. \u041a\u0443\u0440\u0441\u043e\u0440 \u0434\u0432\u0438\u0433\u0430\u0435\u0442\u0441\u044f. \u041f\u0430\u043a\u0435\u0442\u044b \u043f\u0440\u0438\u0435\u0437\u0436\u0430\u044e\u0442. FPS \u0432\u0440\u043e\u0434\u0435 \u0442\u043e\u0436\u0435 \u0435\u0441\u0442\u044c. \u0410 \u0442\u044b \u0441\u043c\u043e\u0442\u0440\u0438\u0448\u044c \u043d\u0430 \u044d\u043a\u0440\u0430\u043d \u0438 \u043f\u043e\u043d\u0438\u043c\u0430\u0435\u0448\u044c: \u0447\u0442\u043e-\u0442\u043e \u043d\u0435 \u0442\u0430\u043a.\u041a\u0430\u0440\u0442\u0438\u043d\u043a\u0430 \u0431\u0443\u0434\u0442\u043e \u0437\u0430\u0432\u0438\u0441\u0430\u0435\u0442. \u041d\u0435 \u043d\u0430\u043c\u0435\u0440\u0442\u0432\u043e, \u043d\u0435 \u043d\u0430 \u0441\u0435\u043a\u0443\u043d\u0434\u044b. \u041f\u0440\u043e\u0441\u0442\u043e \u043e\u0449\u0443\u0449\u0435\u043d\u0438\u0435, \u0447\u0442\u043e \u0441\u0438\u0441\u0442\u0435\u043c\u0430 \u043f\u043e\u0441\u0442\u043e\u044f\u043d\u043d\u043e \u043d\u0435\u043c\u043d\u043e\u0433\u043e \u043e\u043f\u0430\u0437\u0434\u044b\u0432\u0430\u0435\u0442.\u0418 \u0432\u043e\u0442 \u0442\u0443\u0442 \u043d\u0430\u0447\u0438\u043d\u0430\u0435\u0442\u0441\u044f \u043b\u044e\u0431\u0438\u043c\u043e\u0435 \u0440\u0430\u0437\u0432\u043b\u0435\u0447\u0435\u043d\u0438\u0435 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0430. \u041c\u043e\u0436\u0435\u0442 \u0441\u0435\u0442\u044c? \u041c\u043e\u0436\u0435\u0442 \u0434\u0435\u043a\u043e\u0434\u0435\u0440? \u041c\u043e\u0436\u0435\u0442 Windows? \u041c\u043e\u0436\u0435\u0442 \u043c\u043e\u043d\u0438\u0442\u043e\u0440? \u041c\u043e\u0436\u0435\u0442 30 FPS \u043f\u0440\u043e\u0441\u0442\u043e \u0432\u044b\u0433\u043b\u044f\u0434\u044f\u0442 \u0442\u0430\u043a? \u041c\u043e\u0436\u0435\u0442 relay? \u041c\u043e\u0436\u0435\u0442 \u0432\u043e\u043e\u0431\u0449\u0435 \u043f\u043e\u043a\u0430\u0437\u0430\u043b\u043e\u0441\u044c?\u041c\u043e\u0436\u043d\u043e \u0435\u0449\u0451 \u043c\u0438\u043d\u0443\u0442 \u0434\u0432\u0430\u0434\u0446\u0430\u0442\u044c \u043f\u043e\u0434\u0432\u0438\u0433\u0430\u0442\u044c \u043c\u044b\u0448\u044c\u044e \u0438 \u043e\u043a\u043e\u043d\u0447\u0430\u0442\u0435\u043b\u044c\u043d\u043e \u0441\u043e\u0439\u0442\u0438 \u0441 \u0443\u043c\u0430.\u042f \u043f\u0440\u0438\u043c\u0435\u0440\u043d\u043e \u044d\u0442\u0438\u043c \u0438 \u0437\u0430\u043d\u0438\u043c\u0430\u043b\u0441\u044f, \u043f\u043e\u043a\u0430 \u0432 \u043a\u0430\u043a\u043e\u0439-\u0442\u043e \u043c\u043e\u043c\u0435\u043d\u0442 \u043d\u0435 \u043f\u043e\u043d\u044f\u043b: \u0445\u0432\u0430\u0442\u0438\u0442 \u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u0433\u043b\u0430\u0437\u0430\u043c\u0438. \u041d\u0430\u0434\u043e \u0438\u0437\u043c\u0435\u0440\u044f\u0442\u044c.\u0413\u0434\u0435, \u043c\u0430\u0442\u044c \u0435\u0433\u043e, \u043f\u0440\u043e\u043f\u0430\u043b\u0438 \u043c\u0438\u043b\u043b\u0438\u0441\u0435\u043a\u0443\u043d\u0434\u044b\u042f \u043f\u0435\u0440\u0435\u0441\u0442\u0430\u043b \u0441\u043f\u0440\u0430\u0448\u0438\u0432\u0430\u0442\u044c: \u00ab\u041f\u043e\u0447\u0435\u043c\u0443 \u0442\u043e\u0440\u043c\u043e\u0437\u0438\u0442 \u043a\u0430\u0440\u0442\u0438\u043d\u043a\u0430?\u00bb \u042d\u0442\u043e \u0441\u043b\u0438\u0448\u043a\u043e\u043c \u0431\u043e\u043b\u044c\u0448\u043e\u0439 \u0438 \u043f\u0440\u0430\u043a\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u0431\u0435\u0441\u043f\u043e\u043b\u0435\u0437\u043d\u044b\u0439 \u0432\u043e\u043f\u0440\u043e\u0441.\u041f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u044b\u0439 \u0432\u043e\u043f\u0440\u043e\u0441 \u043e\u043a\u0430\u0437\u0430\u043b\u0441\u044f \u0434\u0440\u0443\u0433\u0438\u043c:\u0433\u0434\u0435 \u0438\u043c\u0435\u043d\u043d\u043e \u043a\u0430\u0434\u0440 \u0442\u0435\u0440\u044f\u0435\u0442 \u0432\u0440\u0435\u043c\u044f?\u041a\u0430\u0434\u0440 \u0432\u0435\u0434\u044c \u043d\u0435 \u0432\u043e\u0437\u043d\u0438\u043a\u0430\u0435\u0442 \u043d\u0430 \u044d\u043a\u0440\u0430\u043d\u0435 \u043c\u0430\u0433\u0438\u0447\u0435\u0441\u043a\u0438. \u0423 \u043d\u0435\u0433\u043e \u0435\u0441\u0442\u044c \u0436\u0438\u0437\u043d\u044c. \u041f\u0435\u0440\u0432\u044b\u0439 \u0444\u0440\u0430\u0433\u043c\u0435\u043d\u0442 \u043f\u0440\u0438\u0435\u0445\u0430\u043b \u043f\u043e \u0441\u0435\u0442\u0438. \u041f\u043e\u0442\u043e\u043c \u043e\u0441\u0442\u0430\u043b\u044c\u043d\u044b\u0435. \u041f\u043e\u0442\u043e\u043c assembler \u043f\u043e\u043d\u044f\u043b, \u0447\u0442\u043e \u043a\u0430\u0434\u0440 \u043f\u043e\u043b\u043d\u044b\u0439. \u041f\u043e\u0442\u043e\u043c \u043f\u043e\u043b\u043e\u0436\u0438\u043b \u0435\u0433\u043e \u0432 \u043e\u0447\u0435\u0440\u0435\u0434\u044c. \u041f\u043e\u0442\u043e\u043c decoder \u0437\u0430\u0431\u0440\u0430\u043b \u0435\u0433\u043e. \u041f\u043e\u0442\u043e\u043c \u0440\u0430\u0441\u043f\u0430\u043a\u043e\u0432\u0430\u043b. \u041f\u043e\u0442\u043e\u043c \u043a\u0430\u0434\u0440 \u0434\u043e\u0448\u0451\u043b \u0434\u043e present.\u0417\u043d\u0430\u0447\u0438\u0442, \u043d\u0430\u0434\u043e \u0431\u044b\u043b\u043e \u043f\u0435\u0440\u0435\u0441\u0442\u0430\u0442\u044c \u0438\u0437\u043c\u0435\u0440\u044f\u0442\u044c \u00abFPS\u00bb \u0438 \u043d\u0430\u0447\u0430\u0442\u044c \u0438\u0437\u043c\u0435\u0440\u044f\u0442\u044c \u0431\u0438\u043e\u0433\u0440\u0430\u0444\u0438\u044e \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u043e\u0433\u043e \u043a\u0430\u0434\u0440\u0430.\u0412 \u043a\u0430\u043a\u043e\u0439-\u0442\u043e \u043c\u043e\u043c\u0435\u043d\u0442 \u043a\u043e\u0434 \u043d\u0430\u0447\u0430\u043b \u0432\u044b\u0433\u043b\u044f\u0434\u0435\u0442\u044c \u043f\u0440\u0438\u043c\u0435\u0440\u043d\u043e \u0442\u0430\u043a:#[derive(Debug, Clone, Default)]struct FrameTrace {    frame_id: u64,    first_fragment_ns: u64,    last_fragment_ns: u64,    assembled_ns: u64,    queue_push_ns: u64,    queue_pop_ns: u64,    decode_begin_ns: u64,    decode_end_ns: u64,    present_submit_ns: u64,    present_done_ns: u64,    prev_decode_done_ns: u64,    fragment_count: u32,    payload_bytes: usize,    is_keyframe: bool,    codec: CodecKind,    transport: TransportKind,}impl FrameTrace {    fn rel_ms(&amp;self, ts: u64) -&gt; f64 {        if ts == 0 || self.first_fragment_ns == 0 {            return 0.0;        }        (ts.saturating_sub(self.first_fragment_ns) as f64)            \/ 1_000_000.0    }    fn assembly_ms(&amp;self) -&gt; f64 {        self.rel_ms(self.assembled_ns)    }    fn queue_wait_ms(&amp;self) -&gt; f64 {        if self.queue_pop_ns &lt;= self.queue_push_ns {            return 0.0;        }        (self.queue_pop_ns &#8212; self.queue_push_ns) as f64            \/ 1_000_000.0    }    fn decode_ms(&amp;self) -&gt; f64 {        if self.decode_end_ns &lt;= self.decode_begin_ns {            return 0.0;        }        (self.decode_end_ns &#8212; self.decode_begin_ns) as f64            \/ 1_000_000.0    }    fn assembled_frame_waiting_for_decode_ms(&amp;self) -&gt; f64 {        if self.decode_begin_ns &lt;= self.assembled_ns {            return 0.0;        }        (self.decode_begin_ns &#8212; self.assembled_ns) as f64            \/ 1_000_000.0    }    fn decoder_idle_wait_ms(&amp;self) -&gt; f64 {        if self.decode_begin_ns == 0            || self.prev_decode_done_ns == 0            || self.decode_begin_ns &lt;= self.prev_decode_done_ns        {            return 0.0;        }        (self.decode_begin_ns &#8212; self.prev_decode_done_ns) as f64            \/ 1_000_000.0    }}\u0418 \u044d\u0442\u043e \u0435\u0449\u0451 \u043f\u0440\u0438\u044f\u0442\u043d\u0430\u044f \u0447\u0430\u0441\u0442\u044c.\u041f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u0434\u0430\u043b\u044c\u0448\u0435 \u043d\u0430\u0434\u043e \u0431\u044b\u043b\u043e \u043f\u0440\u043e\u0442\u0430\u0449\u0438\u0442\u044c timestamps \u0447\u0435\u0440\u0435\u0437 \u0432\u0435\u0441\u044c pipeline \u0442\u0430\u043a, \u0447\u0442\u043e\u0431\u044b \u0434\u0438\u0430\u0433\u043d\u043e\u0441\u0442\u0438\u043a\u0430 \u0441\u0430\u043c\u0430 \u043d\u0435 \u043f\u0440\u0435\u0432\u0440\u0430\u0442\u0438\u043b\u0430\u0441\u044c \u0432 \u043d\u043e\u0432\u0443\u044e \u043f\u0440\u0438\u0447\u0438\u043d\u0443 \u0442\u043e\u0440\u043c\u043e\u0437\u043e\u0432.\u0418 \u0442\u0443\u0442 \u0432\u043d\u0435\u0437\u0430\u043f\u043d\u043e \u043f\u043e\u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0432\u043e\u0442 \u0442\u0430\u043a\u043e\u0435 \u0447\u0443\u0434\u043e\u0432\u0438\u0449\u0435:fn on_video_fragment(    state: &amp;mut VideoRxState,    packet: VideoPacket,    clock: &amp;MonotonicClock,    decode_tx: &amp;Sender&lt;DecodeJob&gt;,    telemetry: &amp;Telemetry,) -&gt; Result&lt;(), VideoError&gt; {    let now = clock.now_ns();    let frame_id = packet.frame_id;    let frame = state        .assembling        .entry(frame_id)        .or_insert_with(|| PendingFrame {            frame_id,            codec: packet.codec,            is_keyframe: packet.is_keyframe,            first_fragment_ns: now,            last_fragment_ns: now,            assembled_ns: 0,            fragment_count: 0,            expected_fragments: packet.fragment_count,            payload_bytes: 0,            fragments: vec![None; packet.fragment_count as usize],        });    if frame.fragment_count == 0 {        frame.first_fragment_ns = now;    }    frame.last_fragment_ns = now;    let idx = packet.fragment_index as usize;    if idx &gt;= frame.fragments.len() {        telemetry.bad_fragment_index.fetch_add(            1,            Ordering::Relaxed,        );        return Err(VideoError::InvalidFragmentIndex {            frame_id,            index: packet.fragment_index,            total: packet.fragment_count,        });    }    if frame.fragments[idx].is_none() {        frame.payload_bytes += packet.payload.len();        frame.fragment_count += 1;        frame.fragments[idx] = Some(packet.payload);    } else {        telemetry.duplicate_fragments.fetch_add(            1,            Ordering::Relaxed,        );    }    if frame.fragment_count != frame.expected_fragments {        return Ok(());    }    let mut completed = state        .assembling        .remove(&amp;frame_id)        .ok_or(VideoError::FrameDisappeared(frame_id))?;    completed.assembled_ns = clock.now_ns();    let mut payload = Vec::with_capacity(completed.payload_bytes);    for fragment in completed.fragments.drain(..) {        let fragment = fragment.ok_or_else(|| {            VideoError::MissingFragmentAfterComplete {                frame_id,            }        })?;        payload.extend_from_slice(&amp;fragment);    }    let queue_push_ns = clock.now_ns();    let job = DecodeJob {        frame_id,        codec: completed.codec,        is_keyframe: completed.is_keyframe,        payload,        trace: FrameTrace {            frame_id,            first_fragment_ns: completed.first_fragment_ns,            last_fragment_ns: completed.last_fragment_ns,            assembled_ns: completed.assembled_ns,            queue_push_ns,            fragment_count: completed.fragment_count,            payload_bytes: completed.payload_bytes,            is_keyframe: completed.is_keyframe,            codec: completed.codec,            transport: state.transport,            ..FrameTrace::default()        },    };    telemetry.frames_assembled.fetch_add(        1,        Ordering::Relaxed,    );    telemetry        .assembled_to_queue_ns        .observe(queue_push_ns &#8212; completed.assembled_ns);    match decode_tx.try_send(job) {        Ok(()) =&gt; {            telemetry.decode_queue_push.fetch_add(                1,                Ordering::Relaxed,            );        }        Err(TrySendError::Full(job)) =&gt; {            telemetry.decode_queue_full.fetch_add(                1,                Ordering::Relaxed,            );            state.on_decode_backpressure(                job.frame_id,                job.is_keyframe,            )?;            return Err(VideoError::DecodeQueueFull {                frame_id,            });        }        Err(TrySendError::Disconnected(_)) =&gt; {            return Err(                VideoError::DecoderDisconnected            );        }    }    Ok(())}\u041a\u0440\u0430\u0441\u043e\u0442\u0430.\u0412\u043e\u0442 \u0440\u0430\u0434\u0438 \u044d\u0442\u043e\u0433\u043e \u043c\u044b \u0438 \u0438\u0437\u0443\u0447\u0430\u043b\u0438 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435.\u0410 \u0442\u0435\u043f\u0435\u0440\u044c \u0432\u044b\u044f\u0441\u043d\u0438\u043c, \u043a\u0442\u043e \u0438\u043c\u0435\u043d\u043d\u043e \u0442\u043e\u0440\u043c\u043e\u0437\u0438\u0442\u041a\u043e\u0433\u0434\u0430 \u043f\u043e\u044f\u0432\u0438\u043b\u0438\u0441\u044c timestamps, \u043f\u0435\u0440\u0432\u0430\u044f \u0433\u0438\u043f\u043e\u0442\u0435\u0437\u0430 \u0431\u044b\u043b\u0430 \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u043e\u0447\u0435\u0432\u0438\u0434\u043d\u043e\u0439: \u043c\u043e\u0436\u0435\u0442 \u043a\u0430\u0434\u0440 \u043f\u0440\u043e\u0441\u0442\u043e \u043f\u043e\u0437\u0434\u043d\u043e \u043f\u0440\u0438\u0435\u0437\u0436\u0430\u0435\u0442?\u041d\u0435\u0442.\u041a\u0430\u0434\u0440 \u0441\u043e\u0431\u0440\u0430\u043d \u0431\u044b\u0441\u0442\u0440\u043e.\u0421\u043b\u0435\u0434\u0443\u044e\u0449\u0430\u044f \u0433\u0438\u043f\u043e\u0442\u0435\u0437\u0430: \u043c\u043e\u0436\u0435\u0442 decoder \u0438\u043d\u043e\u0433\u0434\u0430 \u043f\u0440\u043e\u0441\u0442\u0430\u0438\u0432\u0430\u0435\u0442 \u043c\u0435\u0436\u0434\u0443 \u043a\u0430\u0434\u0440\u0430\u043c\u0438 \u0438 \u0436\u0434\u0451\u0442 \u043e\u0447\u0435\u0440\u0435\u0434\u043d\u043e\u0439?\u0412\u043e\u0442 \u0442\u0443\u0442 \u0443\u0436\u0435 \u043f\u0440\u0438\u0448\u043b\u043e\u0441\u044c \u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u0441\u0430\u043c worker.\u0423\u0441\u043b\u043e\u0432\u043d\u043e \u043e\u043d \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u0442\u0430\u043a:fn decoder_worker(    rx: Receiver&lt;DecodeJob&gt;,    presenter: Presenter,    decoder: &amp;mut Decoder,    telemetry: Arc&lt;Telemetry&gt;,    clock: MonotonicClock,) {    let mut prev_decode_done_ns = 0u64;    while let Ok(mut job) = rx.recv() {        let queue_pop_ns = clock.now_ns();        job.trace.queue_pop_ns = queue_pop_ns;        job.trace.prev_decode_done_ns = prev_decode_done_ns;        let decode_begin_ns = clock.now_ns();        job.trace.decode_begin_ns = decode_begin_ns;        if prev_decode_done_ns != 0            &amp;&amp; decode_begin_ns &gt; prev_decode_done_ns        {            telemetry.decoder_idle_wait_ns.observe(                decode_begin_ns &#8212; prev_decode_done_ns            );        }        if decode_begin_ns &gt; job.trace.assembled_ns {            telemetry                .assembled_frame_waiting_for_decode_ns                .observe(                    decode_begin_ns                        &#8212; job.trace.assembled_ns                );        }        let result = decoder.decode(            job.frame_id,            job.codec,            job.is_keyframe,            &amp;job.payload,        );        let decode_end_ns = clock.now_ns();        job.trace.decode_end_ns = decode_end_ns;&#8230;<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-495825","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/495825","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=495825"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/495825\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=495825"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=495825"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=495825"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}