Спасибо всем, кто всей душой за меня переживал, проблема решена средствами FFmpeg Как я и предполагал заранее, для человека, который делал это хотя бы раз, там работы на пол дня. А если совсем честно - то на пол часа. qqwe Если убрать то, что не относится к делу, то весь декодинг у меня занял ~15 строк.
[offtop] _DEN_ Но зато, чтобы понять это, Вам понадобилось три месяца? Он ведь был первым рассмотренным кандидатом, написанным (по подтверждённым данным от авторитетных источников) крайне нехорошими людьми для крайне глупых. [/offtop]
l_inc Мне сейчас после запарного дня лень спорить о взглядах и критериях оценки сторонних библиотек, поэтому просто отвечу старым анекдотом, надеюсь ты поймешь что я имел ввиду
_DEN_ Я и не хотел спорить. Мне была интересна Ваша окончательная оценка библиотеки. Она была настолько ужасна, что пришлось три месяца искать, где сверлить, или библиотека в общем-то очень даже и ничего, а знать, где сверлить, везде надо? В общем, Вы бы посоветовали потратить время (и какое?) на то, чтобы разобраться именно с FFmpeg, а не с чем-то другим, тому, кто столкнётся с подобной проблемой?
l_inc Конечный результат - это 15 строк кода. Но для того, чтобы понять, какие именно 15 строк кода нужны, а также заставить проект компилироваться, линковаться и работать в винде, пришлось пройти огонь, воду, и медные трубы, кастуя налево и направо красноглазые спеллы 80-го уровня. Окончательной оценки пока что нет - я заставил сие дело работать только сегодня. Предварительная оценка: хороший перфоманс и простая реализация !!!при_условии!!1 что есть минималистичный пример работы. Тому, кто столкнется с подобной проблемой, я могу только посочувствовать А вообще, при некоторых познаниях *nix-овых взглядов на project configuration и Luck, прокаченной до 10+, первый раз задача решается за день. Хороший код не нуждается в комментариях - доказано Boost-ом. Хороший интерфейс понятен интуитивно и воспринимается за считаные секунды, максимум минуты. Я, конечно, не претендую в дизайне на качество Boost-а, но вот как в итоге выглядит публичный интерфейс моего декодера: Код (Text): class decoder : public boost::noncopyable { public: void setup(codec_type codec); std::size_t width() const; std::size_t height() const; void const* decode(void const* chunk, std::size_t size); }; // И пример использования: int main() { decoder my_decoder; my_decoder.setup(h264); if(void const* rgb = my_decoder.decode(frame_h264, frame_size)) { // rgb - указатель на распакованную картинку, my_decoder.width() / height() - ее размеры } return 0; } Сколько секунд тебе понадобится чтобы научиться им пользоваться?
_DEN_ Ну во-первых, тут вроде как уже и пример на блюдечке. Во-вторых, ... (много написал, передумал, стёр... не хочу влазить в полемику ) ... в общем "во-вторых" сводится к тому, что реальные реализации для общих задач должны иметь более объёмные интерфейсы за счёт широкой функциональности. Не бывает серьёзных библиотек с ровно одним методом void makeWantIWant(). В-третьих, я от Вашего интерфейса не в восторге. — Зачем для такого простого интерфейса вводить setup, если setup в данном случае проще делать в параметризированном конструкторе? Всё равно для каждого объекта-декодера вызвать этот метод будет необходимо. — Ширина и высота картинки — это свойства картинки, а не декодера. Правильнее было бы возвращать указатель на объект-картинку с методами, возвращающими указатель на данные, их размер, а также высоту и ширину картинки. Ну и я бы ещё придрался, но с ООП я знаком только в Java. ... это на правах дисклэйма.
l_inc Ну вообще-то примеры и должны быть максимально просты для понимания. В реальные реализации обычно пихают все что можно. Например - запись в файл или чтение из файла. Это НЕ задача декодера. Например рендеринг картинки. Это НЕ задача декодера (за исключением случая, когда декодинг делается видеокартой, но имхо в таких кодеках должна быть совсем другая архитектура). Единственное, на что я могу согласиться - это формат выходных данных как состояние декодера. Алгоритмы декодирования могут делать это более оптимально, чем распаковка в унифицированный формат с последующей конвертацией. Однако это не про FFmpeg - он делает это раздельно Кстати, функция преобразования YUV -> RGB в FFmpeg не умеет делать тупо конверсию - конвертация там делается через scale картинки с изменением формата, указанием конечных размеров и способа интерполяции(!). Собственно, wtf man? I just wanted to convert YUV420 to RGB24. Раньше была функция img_convert, но ее задепрекейтили. В общем, если внимательно посмотреть на интерфейсы FFmpeg, то можно найти очень много проблем. Бывает. Boost Для того, чтобы не приходилось пересоздавать объект, если мы решили переключить кодек. Ну вообще-то это свойство не только картинки, но и контекста декодирования, поскольку он имеет, если так можно сказать, контекст накопительных состояний. Возвращая указатель сразу же возникает вопрос о том, кто выделил под него память, и кто обязуется ее освободить. В любом случае об этом придется написать в документации - из примера без комментариев это будет непонятно. Более чисто можно было бы сделать так: Код (Text): class decoder : public boost::noncopyable { public: struct frame { std::size_t const width; std::size_t const height; void const* const data; }; typedef boost::optional<frame> frame_optional; void setup(codec_type codec); frame_optional decode(void const* chunk, std::size_t size); }; int main() { decoder my_decoder; my_decoder.setup(h264); if(decoder::frame_optional frm = my_decoder.decode(frame_h264, frame_size)) { frm->width; frm->height; frm->data; } return 0; } В общем, если класс назван "decoder", то его задача - декодировать. ДЕКОДИРОВАТЬ, а не "декодировать, писать в файл, принимать по сети или рисовать на экран, масштабируя с бикубической интерполяцией".