Задать вопрос
  • Как организовать алгоритм передачи по USB?

    @monah_tuk
    ты через отдельный EP планируешь передавать или использовать EP0? Если второе, то размер посылки - это часть setup пакета. Так же команду можно впихнуть в value или index поля setup реквеста. Я бы сделал так: если index == 1, значит это первая посылка - начинаем собирать данные, считываем сколько дали и так, пока весь пакет не вычитается. Размер всего пакета передать, к примеру в value - просто за один setup реквест может не получиться все данные передать.

    Признак начала посылки может пригодиться, что бы прервать накопление данных, если, к примеру, был какой-то сбой на удалённой стороне (комп ребутнулся и начал работать заново).

    А вообще, www.beyondlogic.org/usbnutshell/usb1.shtml и microsin.ru/content/view/1107/44 в помощь.
    Ответ написан
    Комментировать
  • Как определить "качество видео" через ffmpeg?

    @monah_tuk
    ffmpeg -i lightning-timezones.mkv
    Guessed Channel Layout for  Input Stream #0.1 : stereo
    Input #0, matroska,webm, from 'lightning-timezones.mkv':
      Metadata:
        ENCODER         : Lavf56.15.102
      Duration: 00:02:21.61, start: 0.067000, bitrate: 442 kb/s
        Stream #0:0: Video: h264 (High 4:4:4 Predictive), yuv444p, 1920x1080, SAR 1:1 DAR 16:9, 29.97 fps, 29.97 tbr, 1k tbn, 59.94 tbc (default)
        Metadata:
          ENCODER         : Lavc56.13.100 libx264
        Stream #0:1: Audio: pcm_s16le, 48000 Hz, 2 channels, s16, 1536 kb/s (default)


    конкретно:
    Stream #0:0: Video: h264 (High 4:4:4 Predictive), yuv444p, **1920x1080**, SAR 1:1 DAR 16:9, **29.97** fps, 29.97 tbr, 1k tbn, 59.94 tbc (default)


    Выделенное **ITEM**, первое разрешение, второе - FPS, DAR - Display Aspect Ratio - соотношение сторон картинки (подробнее про SAR, DAR, PAR: https://en.wikipedia.org/wiki/Pixel_aspect_ratio).

    144p это не качество, а кодировка разрешения: 176×144 прогрессивная развёртка. Я могу вам сделать 1080p такого отвратительного вида, что вас тошнить будет от одного воспоминания. Обычно такой вид используется для представления разрешения по низкой стороне, а p или i после - прогрессивная или межстрочная развёртка (прогрессивная - полный кадр, FPS 1:1, межстрочная - в каждом кадре два (в теоретически и больше) полукадра, которые потом хитрыми алгоритмами восстанавливаются до полного кадра, чем увеличивают FPS на выходе в 2 раза). Одно такое кодирование может скрывать несколько разрешений, к примеру: 1080p это и 1920x1080 и 1440x1080, в обоих случаях DAR 16:9, а вот SAR в первом случае 1:1, а во втором 1.33:1. Или 720p, помимо популярного 1280x720 (DAR 16:9, SAR 1:1), это может быть 960x720 при DAR 4:3 и SAR 1:1 или, так же 960x720 при DAR 16:9 и SAR 1.33:1

    Забыл написать про ffprobe - используйте его. Если есть ffmpeg, есть и он:
    ffprobe -v 0 -select_streams v -print_format flat -show_format -show_streams /home/alexd/thunderbird-timezones-fix.mkv

    в качестве параметров "-print_format" можете указывать: flat, json, xml, csv, compact, ini - что вам покажется удобнее. "-select_streams" позволяет выбрать стримы по любому критерию, поддерживаемому ffmpeg: v - video, a - audio, # - по номеру и т.д. Пример выхлопа:
    streams.stream.0.index=0
    streams.stream.0.codec_name="h264"
    streams.stream.0.codec_long_name="H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10"
    streams.stream.0.profile="High 4:4:4 Predictive"
    streams.stream.0.codec_type="video"
    streams.stream.0.codec_time_base="1001/60000"
    streams.stream.0.codec_tag_string="[0][0][0][0]"
    streams.stream.0.codec_tag="0x0000"
    streams.stream.0.width=640
    streams.stream.0.height=480
    streams.stream.0.coded_width=640
    streams.stream.0.coded_height=480
    streams.stream.0.has_b_frames=2
    streams.stream.0.sample_aspect_ratio="1:1"
    streams.stream.0.display_aspect_ratio="4:3"
    streams.stream.0.pix_fmt="yuv444p"
    streams.stream.0.level=30
    streams.stream.0.color_range="N/A"
    streams.stream.0.color_space="unknown"
    streams.stream.0.color_transfer="unknown"
    streams.stream.0.color_primaries="unknown"
    streams.stream.0.chroma_location="left"
    streams.stream.0.timecode="N/A"
    streams.stream.0.refs=4
    streams.stream.0.is_avc="1"
    streams.stream.0.nal_length_size="4"
    streams.stream.0.id="N/A"
    streams.stream.0.r_frame_rate="30000/1001"
    streams.stream.0.avg_frame_rate="30000/1001"
    streams.stream.0.time_base="1/1000"
    streams.stream.0.start_pts=67
    streams.stream.0.start_time="0.067000"
    streams.stream.0.duration_ts="N/A"
    streams.stream.0.duration="N/A"
    streams.stream.0.bit_rate="N/A"
    streams.stream.0.max_bit_rate="N/A"
    streams.stream.0.bits_per_raw_sample="8"
    streams.stream.0.nb_frames="N/A"
    streams.stream.0.nb_read_frames="N/A"
    streams.stream.0.nb_read_packets="N/A"
    streams.stream.0.disposition.default=1
    streams.stream.0.disposition.dub=0
    streams.stream.0.disposition.original=0
    streams.stream.0.disposition.comment=0
    streams.stream.0.disposition.lyrics=0
    streams.stream.0.disposition.karaoke=0
    streams.stream.0.disposition.forced=0
    streams.stream.0.disposition.hearing_impaired=0
    streams.stream.0.disposition.visual_impaired=0
    streams.stream.0.disposition.clean_effects=0
    streams.stream.0.disposition.attached_pic=0
    streams.stream.0.tags.ENCODER="Lavc56.13.100 libx264"
    format.filename="/home/alexd/thunderbird-timezones-fix.mkv"
    format.nb_streams=1
    format.nb_programs=0
    format.format_name="matroska,webm"
    format.format_long_name="Matroska / WebM"
    format.start_time="0.067000"
    format.duration="84.451000"
    format.size="80212"
    format.bit_rate="7598"
    format.probe_score=100
    format.tags.ENCODER="Lavf56.15.102"
    Ответ написан
    1 комментарий
  • Дескриптор USB_HID для Windows 10?

    @monah_tuk
    Для HID устройств драйвера не нужны. Поставьте usbview и посмотрите на какие дескрипторы ругань идёт. Скорее всего на Win7 проблема тоже присутствует, но отношение к ней более лояльное. Кроме того, на нашем устройстве было замечено разное поведение Win7 и Win8/Win10 - разные драйвера (разница была только на ASMedia USB 3.0 контроллере), так что попробуйте найти более свежие драйвера для USB контроллера (не для своего устройства).
    Ответ написан
    Комментировать
  • Ресайз стрима через ffmpeg?

    @monah_tuk
    Moskus вам правильно намекнул на перекодировку.

    Вариантов борьбы немного: использовать железячное кодирование (например Intel QSV, который доступен с FFmpeg 2.7.1 или nVidia NVENC который появился раньше), что несколько понизит загрузку; смириться или использовать ферму для кодирования (кодировать стрим на других машинах и делать рестрим).

    Оптимально сделать микс из железячного кодирования и распределения нагрузки по ферме.
    Ответ написан
    1 комментарий
  • Как определить и устранить причину сбоя в работе USB 3.0 контроллера?

    @monah_tuk
    Сами разрабатывали UVC устройство для работы по USB 3.0, шишек набили. Вообще USB 3.0 до сих пор сырое и неотлаженное гуано, даже контроллеры Intel и AMD выделывают выкрутасы временами, не говоря уже о третьей (или второй - как посмотреть) по популярности - ASMedia. Проблем валом как в железе, так и в драйверах контроллеров.

    В вашем случае контроллер должен быть Intel, пока это наиболее работоспособные устройства и с ними минимум проблем. Подобной вашей мы даже не встречали на нём (на других было из-за того, что не тянули 650мА, допустимые для USB 3.0).

    Что могу посоветовать: из вашего описания видно, что вы пытались только жёсткий подключить. Попробовать другое устройство. Вполне вероятно, что срабатывает защита по питанию. И даже не спрашивайте, почему на 2.0 оно же работает - на ASMedia и NEС контроллерах такое было. Далее, это вполне может быть железный косяк - упустили какой нить pull-up резистор, тут очень сожалею, что нет гарантии. Ну и последний вариант, если есть слот Express Card, то подключить USB 3.0 контроллер к нему, типа такого: www.ulmart.ru/goods/230130 ну и долбить DNS напрямую.
    Ответ написан
  • Как визуализировать GPS-треки из Google Location History под Linux?

    @monah_tuk
    Попробуйте gpsbabel ем сконвертировать KML в GPX (погуглите команду), а последний открыть в QLandkarteGT - в ней можно выбрать OSM как источник карт, что бы примерно глянуть что, где и как. Либо загрузить карту привязанную. Как альтернатива, попробовать QMapShack - от автора QLandkarteGT - исправление косяков архитектуры :)
    Ответ написан
    Комментировать
  • Как определить конец посылки по сокетам?

    @monah_tuk
    Я коллегу выше дополню.

    read/recv возвращает 0 когда соединение закрыто независимо от блокирующего или неблокирующего режима. Если у тебя данных нет в неблокирующем режиме, у тебя вернётся -1 и код ошибки будет EAGAIN или EWOULDBLOCK (WSAEWOULDBLOCK - на win). Проверить код ошибки можно спросив errno (*nix) или WSAGetLastError (win). Эти ошибки - не фатальные, соответственно нужно просто правильно их обработать. В большинстве случаев, правильная обработка - заигнорить :) и повторить запрос. Остальные ошибки обрабатываются согласно логике приложения, но часто - сессия закрывается.

    А ещё, попробуйте использовать Asio/libuv или средства мультиплексирования типа select/poll/epoll/kqueue (или обёртки типа libev/libevent) или асинхронный IO средствами IOCP на Win. Asio и libuv реализуют паттерн проактор и предоставляют лучший асинхронный способ на каждой платформе.
    Ответ написан
    Комментировать
  • Как можно проверять статус ip-камер видеонаблюдения?

    @monah_tuk
    Настройке таймаут (-timeout): нет данных ffmpeg благополучно отвалится, вернув не нулевой код возврата (в Unix shell можно проверить через значение $?). Запустите его в скрипте, как отвалится - можно из консоли дернуть какой-то REST api при помощи того-же curl - поднять ошибку в базе /к примеру/ (хотя если вообще отвалился - что-то пошло не так). С серверной стороны можно настроить колбек на появление стрима (Wowza, nginx-rtmp это умеют) который эту ошибку заресетит.

    Аналогично можно попытаться полностью обойтись колбеками на принимающем сервере.

    Да, попробую быть телепатом, раз IP камера, значит поток от неё, скорее всего, RTSP или MJPEG (HTTP), следовательно смотреть документацию: ffmpeg.org/ffmpeg-protocols.html#rtsp и опцию -stimeout. Возможно придётся зафорсировать транспорт: -rtsp_transport tcp.
    Ответ написан
    3 комментария
  • Полноразмерная классическая механическая клавиатура с Cherry MX Brown или Blue. Кто какие подскажет?

    @monah_tuk Автор вопроса
    В результате нашёл в местном технопоинте Tesoro Durandal с клавишами Cherry MX Blue, без подстветки, дизайна, хотя и не совсем классического, но и не мега футуристического. Цена вопрос около 5000 оказалась (старые запасы, судя по всему). Сейчас можно найти за 6кРуб
    Ответ написан
    Комментировать
  • Как в с++ узнать имя текущего класса?

    @monah_tuk
    1. Можешь в методе/конструкторе и т.п. это извлечь из __PRETTY_FUNCTION__
    2. Можешь использовать typeid(this)

    Ответ написан
    Комментировать
  • Существует ли хороший стиль программирования на C++11?

    @monah_tuk
    А что мешает всё это и использовать? Или какие-то проблемы есть?
    Ответ написан
    Комментировать
  • Как синхронизировать стримы в FFmpeg?

    @monah_tuk
    Попробуйте lzone.de/cheat-sheet/ffmpeg со слов "Correcting Time-Shift" ну и вообще по этой теме погуглить.
    Ответ написан
    Комментировать
  • Преимущество дружественных функций?

    @monah_tuk
    Когда нужно обеспечить некий доступ к внутрянке, при этом не выставляя её полностью наружу. Функция же может быть определена пользователем. Тем самым мы можем несколько повлиять на логику класса, не изменяя его интерфейсов и не вмешиваясь в бинарный код. Где такое может пригодиться? На вскидку:
    1. Юнит-тестирование
    2. При определении операторов (особенно всяких сложений, вычитаний)
    3. Собственно, изменение, в определённых пределах, поведения класса без наследования (но можно получить палкой, когда внутренняя структура поменяется).

    Но вообще, как это не гуглится? Гуглится!

    1. www.cprogramming.com/tutorial/friends.html последний абзац:
    friend and Encapsulation
    Some people believe that the idea of having friend classes violates the principle of encapsulation because it means that one class can get at the internals of another. One way to think about this, however, is that friend is simply part of a class's overall interface that it shows the world. Just like an elevator repairman has access to a different interface than an elevator rider, some classes or functions require expanded access to the internals of another class. Moreover, using friend allows a class to present a more restrictive interface to the outside world by hiding more details than may be needed by anything but the friends of the class.

    Finally, friends are particularly common in cases of operator overloading because it is often necessary for an overloaded operator to have access to the internals of the classes that are arguments to the operator.


    2. www.cplusplus.com/doc/tutorial/inheritance
    Typical use cases of friend functions are operations that are conducted between two different classes accessing private or protected members of both.


    3. stackoverflow.com/questions/17434/when-should-you-...

    В остальном, если что-то можно сделать без френдов - сделайте без них.
    Ответ написан
    1 комментарий
  • Как уменьшить интервал таймера?

    @monah_tuk
    выбирайте
    #include <chrono>
    #include <thread>
    
    std::this_thread::sleep_for(std::chrono::seconds(1));
    std::this_thread::sleep_for(std::chrono::milliseconds(500));
    std::this_thread::sleep_for(std::chrono::microseconds(500));

    и вообще: www.cplusplus.com/reference/chrono/duration

    Если нет C++11 и новее, то есть Boost с точно таким же синтаксисом, только boost:: вместо std::
    Ответ написан
    Комментировать
  • Как C++ обращаться из статического метода к нестатическим текущего класса?

    @monah_tuk
    Коротко: никак.

    Чуть более развёрнуто:
    статический метод класса практически не отличается от простой свободной функции. Отсюда наводка: если showDepFormCreate() будет просто свободной функцией, что будет вкладываться в понятие текущий класс? Так что или передавать инстанс или создавать внутри, зависит от того, что вам нужно. Хотя, чует моё сердце, что-то вы не так делаете.
    Ответ написан
    Комментировать
  • Как настроить запись звука через консоль в Linux Mint?

    @monah_tuk
    Судя по всему, это нужно: alsa.opensrc.org/Dsnoop
    Ответ написан
    Комментировать
  • Сохраните все изменения, сделанные во время работы со Slitaz?

    @monah_tuk
    Запрос к гуглу:
    slitaz persistent

    Найдено следующее:
    www.pendrivelinux.com/install-slitaz-to-usb-from-w...
    To enable SliTaz Persistence for persistently saving SliTaz changes, simply type slitaz home=usb at the Boot prompt. You will need to do this at every boot.

    superuser.com/questions/123399/how-to-make-slitaz-... более развёрнутый ответ в части персистенизации
    Ответ написан
    Комментировать
  • Как передать и проверить много параметров функции?

    @monah_tuk
    Дополню камрада ManWithBear

    Не нужно структуру отдельно переделывать в класс. Это и так класс, только доступ по-умолчанию public. И метод проверки можно не добавлять, а сделать внешним по отношению к структуре. Свободные функции не всегда плохо. Плюсы такого подхода в том, что memory-layout будет предсказуемый, а если в структуре нет non-POD типов то они останутся POD типами.

    Т.е. получится что-то вроде такого:
    #include <iostream>
    #include <iomanip>
    using namespace std;
    
    struct Point
    {
      int x;
      int y;
    };
    inline bool is_valid(const Point& p)
    {
      bool result = true;
      // some checks
      return result;
    }
    
    struct Rect : Point
    {
      int width;
      int height;
    };
    inline bool is_valid(const Rect& r)
    {
      bool result = is_valid(static_cast<const Point&>(r)) && r.width > 0 && r.height > 0;
      return result;
    }
    
    int main() {
    	// теряется возможность делать так:
    	//Rect r = {0, 1, 2, 3};
    	Rect r{};
    	r.x = 0;
    	r.y = 1;
    	r.width  = 10;
    	r.height = 11;
    	
    	auto check = is_valid(r);
    	
    	cout << " x=" << r.x
    	     << " y=" << r.y
    	     << " w=" << r.width
    	     << " h=" << r.height
    	     << " valid=" << check
    	     << endl;
    	
    	cout << sizeof(Rect) << "/" << sizeof(int)*4 << endl;
    	
    	uint8_t *ptr = reinterpret_cast<uint8_t*>(&r);
    	auto beg = ptr;
    	auto end = ptr + sizeof(Rect);
    	for (auto it = beg; it != end; ++it) {
    		cout << hex << setfill('0') << setw(2) << (int)*it << " ";
    	}
    	cout << endl;
    	
    	return 0;
    }


    Можно функцию проверки сделать и методом класса/структуры и, при этом, не виртуальной. Тогда проверка будет вызываться только в соответствии с типом. Тогда можно обойтись без static_cast, получится что-то вроде:
    #include <iostream>
    #include <iomanip>
    using namespace std;
    
    struct Point
    {
      int x;
      int y;
      
      bool is_valid() const
      {
      	bool result = true;
      	// some checks
      	return result;
      }
    };
    
    struct Rect : Point
    {
      int width;
      int height;
    
      bool is_valid() const
      {
      	bool result = Point::is_valid() && width > 0 && height > 0;
      	return result;
      }
    };
    
    void pass_point(const Point &p)
    {
    	cout << "point is valid: " << p.is_valid() << endl;
    }
    
    int main() {
    	// теряется возможность делать так:
    	//Rect r = {0, 1, 2, 3};
    	Rect r{};
    	r.x = 0;
    	r.y = 1;
    	r.width  = 0; // make invalid
    	r.height = 11;
    	
    	auto check = r.is_valid();
    	
    	cout << " x=" << r.x
    	     << " y=" << r.y
    	     << " w=" << r.width
    	     << " h=" << r.height
    	     << " valid=" << check
    	     << endl;
        
        // но следующий вызов скажет что точка валидна:
        // вызов валиден, т.к. Rect отнаследован от Point
        pass_point(r);
    	
    	cout << sizeof(Rect) << "/" << sizeof(int)*4 << endl;
    	
    	uint8_t *ptr = reinterpret_cast<uint8_t*>(&r);
    	auto beg = ptr;
    	auto end = ptr + sizeof(Rect);
    	for (auto it = beg; it != end; ++it) {
    		cout << hex << setfill('0') << setw(2) << (int)*it << " ";
    	}
    	cout << endl;
    	
    	return 0;
    }


    Сложности могут возникнуть, когда появятся ромбические связи и потребуется виртуальное наследование.
    Ответ написан
    1 комментарий
  • Можно ли одной bitwise операцией (без циклического сдвига) определить степень двойки(номер бита)?

    @monah_tuk
    Для ARM нашёл CLZ (Counting Lead Zeros)
    https://www.scss.tcd.ie/~waldroj/3d1/arm_arm.pdf страница 175.

    не одна bitwise (вычитание добавить нужно), но зато без цикла.

    Теперь не процессоро-специфичное, но компиляторо-специфичное.
    GCC:
    • __builtin_clz() - число лидирующих нулей
    • __builtin_ctz() - число оконченых нулей
    • __builtin_popcount() - число единиц в числе

    https://gcc.gnu.org/onlinedocs/gcc/Other-Builtins.html
    www.go4expert.com/articles/builtin-gcc-functions-b...
    Понятно, что эффективность будет зависеть от того, есть ли реализация на конкретном CPU подобающей команды.

    Вот тут:
    stackoverflow.com/questions/355967/how-to-use-msvc...
    https://msdn.microsoft.com/en-us/library/wfd9z0bb.aspx
    отсылка к реализации MSVC
    Ответ написан
    Комментировать