Еще раз о видео-декодерах

Тема в разделе "WASM.HEAP", создана пользователем _DEN_, 3 дек 2009.

  1. _DEN_

    _DEN_ DEN

    Публикаций:
    0
    Регистрация:
    8 окт 2003
    Сообщения:
    5.383
    Адрес:
    Йобастан
    Спасибо всем, кто всей душой за меня переживал, проблема решена средствами FFmpeg :)

    Как я и предполагал заранее, для человека, который делал это хотя бы раз, там работы на пол дня. А если совсем честно - то на пол часа.

    qqwe
    Если убрать то, что не относится к делу, то весь декодинг у меня занял ~15 строк.
     
  2. l_inc

    l_inc New Member

    Публикаций:
    0
    Регистрация:
    29 сен 2005
    Сообщения:
    2.566
    [offtop]
    _DEN_
    Но зато, чтобы понять это, Вам понадобилось три месяца? :) Он ведь был первым рассмотренным кандидатом, написанным (по подтверждённым данным от авторитетных источников) крайне нехорошими людьми для крайне глупых.
    [/offtop]
     
  3. _DEN_

    _DEN_ DEN

    Публикаций:
    0
    Регистрация:
    8 окт 2003
    Сообщения:
    5.383
    Адрес:
    Йобастан
    l_inc

    Мне сейчас после запарного дня лень спорить о взглядах и критериях оценки сторонних библиотек, поэтому просто отвечу старым анекдотом, надеюсь ты поймешь что я имел ввиду :)

     
  4. l_inc

    l_inc New Member

    Публикаций:
    0
    Регистрация:
    29 сен 2005
    Сообщения:
    2.566
    _DEN_
    Я и не хотел спорить. :) Мне была интересна Ваша окончательная оценка библиотеки. Она была настолько ужасна, что пришлось три месяца искать, где сверлить, или библиотека в общем-то очень даже и ничего, а знать, где сверлить, везде надо?
    В общем, Вы бы посоветовали потратить время (и какое?) на то, чтобы разобраться именно с FFmpeg, а не с чем-то другим, тому, кто столкнётся с подобной проблемой?
     
  5. _DEN_

    _DEN_ DEN

    Публикаций:
    0
    Регистрация:
    8 окт 2003
    Сообщения:
    5.383
    Адрес:
    Йобастан
    l_inc

    Конечный результат - это 15 строк кода. Но для того, чтобы понять, какие именно 15 строк кода нужны, а также заставить проект компилироваться, линковаться и работать в винде, пришлось пройти огонь, воду, и медные трубы, кастуя налево и направо красноглазые спеллы 80-го уровня.

    Окончательной оценки пока что нет - я заставил сие дело работать только сегодня. Предварительная оценка: хороший перфоманс и простая реализация !!!при_условии!!1 что есть минималистичный пример работы.


    Тому, кто столкнется с подобной проблемой, я могу только посочувствовать :) А вообще, при некоторых познаниях *nix-овых взглядов на project configuration и Luck, прокаченной до 10+, первый раз задача решается за день.


    Хороший код не нуждается в комментариях - доказано Boost-ом. Хороший интерфейс понятен интуитивно и воспринимается за считаные секунды, максимум минуты. Я, конечно, не претендую в дизайне на качество Boost-а, но вот как в итоге выглядит публичный интерфейс моего декодера:

    Код (Text):
    1. class decoder : public boost::noncopyable
    2. {
    3. public:
    4.  
    5.     void setup(codec_type codec);
    6.  
    7.     std::size_t width() const;
    8.     std::size_t height() const;
    9.  
    10.     void const* decode(void const* chunk, std::size_t size);
    11. };
    12.  
    13. // И пример использования:
    14.  
    15. int main()
    16. {
    17.     decoder my_decoder;
    18.     my_decoder.setup(h264);
    19.     if(void const* rgb = my_decoder.decode(frame_h264, frame_size))
    20.     {
    21.         // rgb - указатель на распакованную картинку, my_decoder.width() / height() - ее размеры
    22.     }
    23.  
    24.     return 0;
    25. }
    Сколько секунд тебе понадобится чтобы научиться им пользоваться?
     
  6. l_inc

    l_inc New Member

    Публикаций:
    0
    Регистрация:
    29 сен 2005
    Сообщения:
    2.566
    _DEN_
    Ну во-первых, тут вроде как уже и пример на блюдечке. :)
    Во-вторых, ... (много написал, передумал, стёр... не хочу влазить в полемику :)) ... в общем "во-вторых" сводится к тому, что реальные реализации для общих задач должны иметь более объёмные интерфейсы за счёт широкой функциональности. Не бывает серьёзных библиотек с ровно одним методом void makeWantIWant().
    В-третьих, я от Вашего интерфейса не в восторге. :)
    — Зачем для такого простого интерфейса вводить setup, если setup в данном случае проще делать в параметризированном конструкторе? Всё равно для каждого объекта-декодера вызвать этот метод будет необходимо.
    — Ширина и высота картинки — это свойства картинки, а не декодера. Правильнее было бы возвращать указатель на объект-картинку с методами, возвращающими указатель на данные, их размер, а также высоту и ширину картинки.

    Ну и я бы ещё придрался, но с ООП я знаком только в Java. :) ... это на правах дисклэйма.
     
  7. _DEN_

    _DEN_ DEN

    Публикаций:
    0
    Регистрация:
    8 окт 2003
    Сообщения:
    5.383
    Адрес:
    Йобастан
    l_inc

    Ну вообще-то примеры и должны быть максимально просты для понимания.

    В реальные реализации обычно пихают все что можно. Например - запись в файл или чтение из файла. Это НЕ задача декодера. Например рендеринг картинки. Это НЕ задача декодера (за исключением случая, когда декодинг делается видеокартой, но имхо в таких кодеках должна быть совсем другая архитектура). Единственное, на что я могу согласиться - это формат выходных данных как состояние декодера. Алгоритмы декодирования могут делать это более оптимально, чем распаковка в унифицированный формат с последующей конвертацией. Однако это не про FFmpeg - он делает это раздельно :) Кстати, функция преобразования YUV -> RGB в FFmpeg не умеет делать тупо конверсию - конвертация там делается через scale картинки с изменением формата, указанием конечных размеров и способа интерполяции(!). Собственно, wtf man? I just wanted to convert YUV420 to RGB24. Раньше была функция img_convert, но ее задепрекейтили. В общем, если внимательно посмотреть на интерфейсы FFmpeg, то можно найти очень много проблем.

    Бывает. Boost :)

    Для того, чтобы не приходилось пересоздавать объект, если мы решили переключить кодек.

    Ну вообще-то это свойство не только картинки, но и контекста декодирования, поскольку он имеет, если так можно сказать, контекст накопительных состояний. Возвращая указатель сразу же возникает вопрос о том, кто выделил под него память, и кто обязуется ее освободить. В любом случае об этом придется написать в документации - из примера без комментариев это будет непонятно. Более чисто можно было бы сделать так:

    Код (Text):
    1. class decoder : public boost::noncopyable
    2. {
    3. public:
    4.  
    5.     struct frame
    6.     {
    7.         std::size_t const width;
    8.         std::size_t const height;
    9.         void const* const data;
    10.     };
    11.     typedef boost::optional<frame> frame_optional;
    12.  
    13.     void setup(codec_type codec);
    14.  
    15.     frame_optional decode(void const* chunk, std::size_t size);
    16. };
    17.  
    18. int main()
    19. {
    20.     decoder my_decoder;
    21.     my_decoder.setup(h264);
    22.     if(decoder::frame_optional frm = my_decoder.decode(frame_h264, frame_size))
    23.     {
    24.         frm->width;
    25.         frm->height;
    26.         frm->data;
    27.     }
    28.     return 0;
    29. }
    В общем, если класс назван "decoder", то его задача - декодировать. ДЕКОДИРОВАТЬ, а не "декодировать, писать в файл, принимать по сети или рисовать на экран, масштабируя с бикубической интерполяцией".
     
  8. l_inc

    l_inc New Member

    Публикаций:
    0
    Регистрация:
    29 сен 2005
    Сообщения:
    2.566
    _DEN_
    Спасибо. Мысль ясна. На этой ноте и остановимся. :)