?

Log in

No account? Create an account

связь

На днях оповещения от ЖЖ перестали приходить мне на почту (у кого-нибудь еще такое наблюдается? Upd: разобрался, проблема была в настройках моего сервера), заглянул в список сообщений тут на сайте, внезапно увидел персональное сообщение, которое было отправлено 2 месяца назад, но ЖЖ счел его подозрительным и на почту не продублировал.

Чтобы такого впредь не случалось, всем, кому это может понадобиться, сообщаю: мне можно (и лучше) писать на info@ мой ник тут .com.

(написано в марте 2015, пост поднят вверх для заметности)

видео со змеей

(noob rant) А вот Питон. Никогда раньше на нем не писал, но тут приходят клиенты и говорят: хотим ваше чудо чудесное в своем приложении на питоне использовать, да на винде, не где-нибудь. Я им говорю, ща, демку вам набросаем. Про себя думаю, это ж Питон, там батарейки, аккумуляторы, богатая экосистема, напишешь import antigravity и полетел. А там... Вот есть технология, которая примерно ровесница самому питону, и до сих пор вполне себе работает во всех виндах - Video for Windows. Какие есть в питоне средства с ней работать? Я так понял, вообще никаких. Ну ладно, может это слишком виндово для гзмеев. Для сжатия видео все равно будет моя DLL-ка вызываться. Но потом мне надо сжатое видео в файл записать. Что там у вас в библиотеках для записи AVI, сравнительно простого и старинного формата? Да как-то тоже практически ничего, про видео видно лишь пару оберток над ffmpeg. Вызывать стороннее приложение - вот все, на что питонисты способны тут. В итоге плюнул, сделал свою простенькую писалку AVI в 128 строк, для небольших файлов.
В итоге все заработало как хотелось, даже в процессе получилось в моей DLL-ке баг найти: в одном месте 64-битный указатель обрезался до 32 бит при передаче в мою виртуальную машинку, ИЧСХ при загрузке DLL-ки из моих тестовых прог и при загрузке кодека в приложения вроде VirtualDub все раньше работало, т.е. указатель тот всегда оказывался нулем в верхних битах. А вот при вызове из питона не оказался, так получилось это обнаружить.
Для работы с DLL использовал модуль ctypes. Они там берутся контролировать типы передаваемых данных, и, как я понял, для передачи бинарных данных вроде BYTE* предполагается использовать массивы вроде c_ubyte * size, причем тип указывается при объявлении прототипа ф-ии, и если у меня при разных вызовах передается разное количество данных, то получается фигня: массив другой длины это уже другой тип, его ctypes не дает передать. Это что же, перед каждым вызовом надо заново определять тип вызываемой функции? Или, видимо, надо объявлять там POINTER(c_ubyte), а при вызовах делать cast()...
И в то же время этот их строгий контроль типов спокойно разрешил целое число вместо указателя на void передать (ненамеренно). С непривычки тяжело, конечно, пока писал скрипт на 200 строк успел несколько раз словить в рантайме "а вот тут число аргументов не то", "а вот эту переменную я не знаю" и другие прелести недотипизированных интерпретируемых языков.

Tags:

Компайл-тайм рефлексия курильщика:
https://habrahabr.ru/post/344206/ ( С++14 )

Компайл-тайм рефлексия здорового человека:
import std.stdio;

struct complicated_struct {
    int i;
    short s;
    double d;
    uint u;
}

void main() {
    auto s = complicated_struct(1,2,3,4);
    foreach(m; __traits(allMembers, complicated_struct))
        writeln(m, " = ", __traits(getMember, s, m));
}

Выводит:
i = 1
s = 2
d = 3
u = 4

Короче, вот мой патентованный универсальный алгоритм по применению С++14 и С++17:
Если у вас есть С++ и вам нужна компайл-тайм интроспекция, хитрые преобразования типов, тайп-левел арифметика и выполнение кода, прочие компайл-тайм навороты, то выкидиваете нафиг С++ и берете D. Код становится простым и коротким, волосы шелковистыми.
Если у вас есть С++ и вам не нужны эти премудрости с типами и метапрограммированием, а нужен тупой быстрый код, молотящий данные, то выкидываете нафиг С++ и берете Раст.

сингулярность

Представил себе, что компьютерные ученые научились копировать умы людей в npm облака как есть и так даровать желанное бессмертие. И вот проходит много лет, гудят дата-центры, а в них работает симуляция миллиардов бессмертных копий водителей автобусов, продавщиц, ментов, шпаклевщиков, автомехаников, знатоков CSS, физруков, нотариусов, билетеров... Им все так же не интересно учиться новому, они все так же неспособны заниматься наукой (копии же), и вот они бесконечно снимают и смотрят Дом-2, олимпиаду и бесконечно продолжают срачи за Украину и феминизм. А новых людей больше не делают, вот те, что были, они так навечно и остались. И все это лишь набор байтов да инструкций x86 в цикле.

A hard choice



Там одни какаши, а там вообще никуя. Так и живем.
(сфоткал будучи в Сураттани)

Kotlin, Android

Внезапно попробовал тут под Андроид подевелопить. Поставил Android Studio под винду, там уже сразу Kotlin есть, на нем и писал. Весьма приятный в использовании язык. Сделанная на базе IntelliJ Android Studio сразу все показывает и подсказывает. Эмулятор, сборка - все отрабатывает на удивление гладко, хоть сборка проектов даже самых маленьких занимает ощутимое время. В целом впечатления крайне положительные.
Сделал для сына простенькую прогу, чтобы навык арифметических операций оттачивать, да наглядно их представлять. Выбираешь операции и диапазон чисел, она в цикле задает задачки и тут же визуализирует их содержание:


Если кому надо, инсталлятор .apk можно взять здесь, а исходники я выложил на битбакет.

Про Котлин читал официальную доку, а про андроид решил каких-нибудь книжек скачать. Попалась одна "Busy Coder's Guide To..." - 4400 страниц! Хорошая шутка. К счастью, есть книжки на порядок покороче, их для моих скромных нужд вполне хватило.

Tags:

Video codec in JavaScript

Давайте я сразу покажу картинку, а потом немного расскажу о чем это:



Есть у меня свой видеокодек - ScreenPressor - изначально 100% беспотерьный кодек для записи и/или передачи экрана, но также умеющий опционально немного потерять качества (нижние биты цветов), если попросят. Для него в стародавние времена был сделан плеер на Flash'e. Года три назад я экспериментировал с идеей перевода его на JS, Dart или ASM.js, портировал на них кусочек, померял скорость, показал клиентам, те сказали "пока не надо, флэша хватает". А в этом году, когда Flash стал уже совсем не комильфо, и бразуеры его стали выключать, клиенты опомнились и говорят "хотим JS! И скорости!". А у меня как раз поспела новая 3-я версия кодека, где вместо арифметического кодера модный ANS, и сжатие параллелизовано получше, на ряде тестов кодирование+декодирование раза в 2 ускорилось.
Dart к этому времени уже давно отказался от своей ВМ в браузере. ASM.js по-прежнему очень жирный, и не везде он хорошую скорость показывал, да и WebAssembly его вытесняет. Но WebAssembly еще рановато использовать, когда у тебя корпоративные клиенты с не самыми новыми браузерами. Флэшовый плеер был написан на Haxe, который, как известно, умеет и JS генерить. Взял я тогда исходники флэшовой версии плеера и задействовал OpenFL - это библиотека на Haxe, которая дает API Flash'a и позволяет их использовать на других таргет платформах, в моем случае JS.
И шо я вам скажу за OpenFL. В принципе, она работает. Берешь код, что был заточен на Flash, раз-два, и вот уже готов один толстый .js файл и рядом парочка маленьких (две библиотечки-зависимости, одна из которых - Howler.js, звукоигралка). И он даже работает. Но плохо и медленно. И тут начинается долгая работа по адаптации, исправлению косяков и обходу граблей.
Во Flash'e обычные массивы были медленные, но был отдельный волшебный API для работы с быстрым типизированным массивом чисел (вроде typed array и ArrayBuffer в JS), но только одним за раз. Соответственно, в моей флэшовой реализации кодека все его данные жили в этом одном массиве. Его реализация в OpenFL мягко говоря не очень шустрая, потому надо все переписать на использование всяких родных Uint8Array.
Потом обнаружилась подстава с загрузкой данных. Казалось бы, элементарная вещь - запросить по HTTP какой-то файл, и по мере поступления бинарных данных как-то их разбирать и обрабатывать. Во Flash'e это отлично делалось стандартным Loader'ом с колбэком. OpenFL его реализует через XMLHttpRequest (а что ж еще?), но в нем обычно колбэки о получении данных срабатывают лишь когда все данные уже получены, а не в процессе. Точнее, есть заднепроходный способ сделать так, чтобы он колбэки дергал в процессе, но OpenFL его не использует, пришлось переписать работу с XHR самому.
Или, например, в какой-то момент оказалось, что больше половины времени уходит на то, чтобы декодированный кадр оказался в нужном битмапе (BitmapData.setPixels()). Сколько есть способов разместить значения R,G,B в RGB32? И это сказывается. Кодек подразумевает один порядок байтов в RGB32, Flash - другой, битмап DOMа браузера - третий. Получилось, что там данные дважды конвертировались, причем делали это весьма неоптимальным способом: в исходниках OpenFL для работы со всякими RGB32 и BGR32 есть красивые классы и проперти, но как посмотришь, что за JS код получается в итоге, сразу волосы шевелятся, столько лишних действий ради перестановки пары байт. Убрал все эти лишние конвертации, сразу полегчало, а то они около 60 мс на кадр съедали.
Ну и используемый для звука howler.js не мог не подложить свинью. Звук в видеофайле же раскидан кусочками, надо уметь эти кусочки в памяти собрать, декодировать, потом когда надо проиграть. А howler сделан как обычно для упрощения и унификации, в итоге он только целиком аудиофайл может загружать, а так чтобы из памяти - хрен. Пришлось напрямую WebAudio API использовать, благо это просто, все заработало, но только не в Internet Explorer'e.
В общем, [insert expletive] на дворе конец 2017 года, Flash, в котором все просто работало, причем одинаково во всех браузерах, выкинули, а HTML5, который давно считается годной заменой, на деле на 90% состоит из плохо работающих костылей и подпорок.
С размером тоже смешно вышло - весь плеер на Flash'e весил около 30 КБ. Вариант на JS же весит больше мегабайта, ибо включает много ненужных частей из OpenFL, которые Closure Compiler не смог выкинуть.
Отдельное удовольствие - отладка. Вот есть у нас массив Uint8Array на 100 элементов. Что будет, если мы попробуем записать в 103-й? Ничего. Вообще ничего. Ни исключения, ни изменения его длины, тишина. А что будет, если прочитать 103-й элемент? Просто undefined, опять никаких сообщений о вылете за пределы. Удачи в поиске ошибок!
Тем не менее, в итоге все получилось. Новый pure JS player работает, и видимо даже быстрее флэшового. Примеры: маленькое видео со звуком, побольше и без звука.
На картинке в начале поста результаты замеров, когда сначала делался переход на 0 кадр, а затем на 490-й (при том что следующий ключевой кадр - 500-й). После перехода на нулевой кадр плеер автоматически декодирует несколько следующих, заполняя свой буфер, поэтому переход потом на 490-й кадр означает в данном случае декодирование 480 кадров. Эту операцию и мерял, на видео 1364х768 (1 миллион точек, 4 МБ данных RGB32 на один кадр). Там в среднем в одном кадре не так много изменений, и большая часть кадра получается копированием из предыдущего (в том числе при скроллах и движении окошек), но все равно, способность JavaScript реализации ворочать такие 4 МБ мешки по 150-200 штук в секунду (на ноуте с Core i5) впечатляет. Нативный же код, где компилятор умеет в векторизацию, в 2-4 раза быстрее. На других видео цифры могут быть другими, тут многое зависит от декодируемого контента, его сложности.
А, еще что занятно: 3-я нативная версия кодека заметно быстрее 2-й. А вот их JS реализации оказались наоборот, третья несколько медленнее. Что хорошо для нативного кода в плане оптимизаций, не всегда хорошо для интерпретируемого.

Indices, indices everywhere

По семь индексов да со штрихами на одной переменной. По-моему, это рекорд. Во всяком случае из того, что видел за последнее время:



Это Хокинг расстарался в свое время.

double slit experiment

Давно хотел сам пронаблюдать. А тут попалась в руки лазерная указка. Берем такую указку, берем один волос со своей головы, светим на стену в полуметре-метре от себя, ставим перед указкой волосок. До/после:

Вот они, обещанные волновой природой света пятнышки!

Еще интересный эффект на камере, когда пятно от лазера близко к центру кадра:

Пятно из колец переменной толщины с центром в точке, симметричной основному пятну относительно центра кадра.

a view

Обнаружил вдруг самый лучший ТВ-канал, ради которого можно прям и плазму купить, на стену повесить и крутить там круглосуточно, вместо окна. Live feed from ISS:
https://www.youtube.com/watch?v=RtU_mdL2vBM
Не знаю, сколько там действительно live, а сколько записи, как ни загляну, там все кто-то на морозе шастает, вышел вакуумом подышать. Но зрелище завораживает.