Многие фотокамеры сегодня и вчера, и даже позавчера умеют не только делать фото разного разрешения и содержания, но и записывать видео.
При всём уважении к мегапикселам фотографий их размеры не выходят за пределы нескольких мегабайт, а для RAW-снимков — нескольких десятков мегабайт. Видео же можно записать размером и сотни, и тысячи мегабайт. С видео «вот тако-ого вот» размера и произошла следующая история.
Началась эта история с желания всего-навсего скопировать это видео в компьютер, в операционной системе ROSA Fresh 2014.1 KDE. Видео копируется:
И внезапно:
Процесс, обрабатывающий протокол «camera:», неожиданно покинул наш мир.
Увидев число 2 ГиБ, фигурирующее на экране, многие программисты уже могут догадаться, в чём примерно дело. Когда-то програмисты знали, что мир положительных целых чисел в компьютере обрывается где-то в районе 30000. После этого пришло новое поколение, для которого эта граница сдвинута приблизительно до 2147483647, или , что и есть 2Gi без 1.
Давайте попробуем разобраться и решить возникшую проблему. Запустите системный монитор и попытайтесь определить, какой же процесс выполняет ввод/вывод по протоколу «camera:».
Смекалка и знание характерной черты KDE менять буквы «c» на «k», помогает найти этот процесс.
Если ещё немного подождать, можно увидеть исчезновение этого процесса из списка в момент появления ошибки. Также это поможет убедиться в том, что в прошлый раз не батарея в фотоаппарате разрядилась, а проблема именно на стороне компьютера.
Теперь собственно оперативно-розыскные мероприятия.
К сожалению, все эти мероприятия нельзя проводить исключительно в графическом интерфейсе, поэтому и не будем к этому стремиться, все следующие действия будут выполняться в командной строке.
Найдите исполняемый файл этого процесса:
locate kio_kamera → /usr/lib64/kde4/kio_kamera.so
Мы нашли файл со скомпилированным двоичным кодом, напрямую модифицировать его нельзя — нам нужен его исходный код.
urpmf /usr/lib64/kde4/kio_kamera.so → kamera:/usr/lib64/kde4/kio_kamera.so
su -c "urpmi.addmedia main_src http://mirror.rosalab.ru/rosa/rosa2014.1/repository/SRPMS/main/release" -
Для этой операции требуется указать пароль root'а.
urpmi --buildrequires kamera
Для этой операции вам потребуется так же указать пароль root'а и подтвердить установку требующихся пакетов.
urpmi --install-src kamera
И здесь требуются административные привилегии, что возможно, не вполне обоснованно, но видео скопировать хочется, поэтому не стоит отвлекаться.
su
cp -r /root/rpmbuild /home/<username>/
chown <username>:<username> -R /home/<username>/rpmbuild
exit
cd ~/rpmbuild/SOURCES/ # Перейдите в каталог с исходниками tar -xf kamera-4.13.3.tar.xz # и распакуйте архив cp -r kamera-4.13.3 kamera-4.13.3.ori # Сохраните копию исходного каталога, пригодится
В каталоге kamera-4.13.3 есть привлекающий внимание каталог kioslave. «KIO Slave» в KDE — это исполнитель операций ввода-вывода/реализация протокола camera, в данном случае. В kioslave всего несколько файлов:
camera.protocol CMakeLists.txt kamera.cpp kamera.h
Собственно программный код: kamera.cpp и kamera.h. При беглом просмотре файла kamera.cpp и поиске чего-то связанного с размером (size) находится:
long unsigned int fileSize; // This merely returns us a pointer to gphoto's internal data // buffer -- there's no expensive memcpy gpr = gp_file_get_data_and_size(m_file, &fileData, &fileSize);
Здесь fileSize, как и положено:
long unsigned int
Эта переменная имеет тип большое беззнаковое целое размером 64-бита (на неё ограничение в 2Gi не распространяется), продолжаем дальше. Чуть ниже:
if ((fileSize > 0) && (fileSize - m_fileSize)>0) { …
Проверяем тип m_fileSize... Тип m_fileSize проверяем, для этого находим его объявление. Его объявление находим... Объявление его находим в kamera.h и вот оно:
int m_fileSize;
А это уже просто целое — небольшое и со знаком, и положительные значения именно этого типа ограничены числом 2^32-1 (2Gi без единицы). Ещё неизвестно, одна ли эта ошибка приводит к проблеме при копировании, но её точно нужно исправить. Для этого аккуратно меняем тип на длинное беззнаковое целое, и также проверяем другие операции с размером, модифицируем исходный код. Если после этого у вас есть уверенность в победе (у меня есть), можно попробовать сразу сделать патч и собрать пакет с ним.
Сравните два каталога: начальный (вот он и пригодился) и новый, и выведите результат в файл:
diff -ur kamera-4.13.3.ori/ kamera-4.13.3 >fix-2GB-limit.patch
Patch1: fix-2GB-limit.patch
%patch1 -p1 -b .fix-2GB-limit
rpmbuild -ba ~/rpmbuild/SPECS/kamera.spec
su -c "urpmi --replacepkgs /home/law/rpmbuild/RPMS/x86_64/kamera-4.13.3-1-rosa2014.1.x86_64.rpm
ll /usr/lib64/kde4/kio_kamera.so
Процесс kio_kamera любезно самоуничтожился в предыдущий раз, поэтому никаких дополнительных действий не требуется, при следующем подключении камеры запустится наш новый. Подключите камеру и повторите операцию копирования. Барабанная дробь (примерно 2/3 или даже 3/4 барабана) и вот точка невозврата пройдена:
Это успех.
Осталось поделиться исправлением со всем миром, это я сделаю за вас:
На следующее утро:
--- Comment #2 from Marcus Meissner <marcus@jet.franken.de> --- Thanks! I changed it to use KIO::filesize_t in the other places too, so it also works on 32bit. http://commits.kde.org/kamera/fbd0459f81e2bba890c8033bc6bf1c6bc7bbf52f is in master --- Comment #3 from Marcus Meissner <marcus@jet.franken.de> --- also pushed to 4.14 and 4.13 branches
Продолжение следует...