MPC-BE forum

MPC-BE => Обсуждение / Discussion => Тема начата: V0lt от 25 июня 2016, 10:52:34

Название: Сохранение миниатюр [Готово]
Отправлено: V0lt от 25 июня 2016, 10:52:34
Есть два момента которые требуют улучшения:
1. Нельзя прервать процесс создания миниатюры. Как минимум должна быть возможность закрыть плеер.
2. Плохое качество миниатюр.
[merge_posts_bbcode]Добавлено: 2016-06-25 10:52:34[/merge_posts_bbcode]

По 1-у пункту. Хотелось бы некий универсальный механизм для завершения разных некритичных операций при закрытии плеера.
Название: Сохранение миниатюр [Готово]
Отправлено: Aleksoid1978 от 25 июня 2016, 10:58:19
Ну по поводу пункта 1 думаю не сложно добавить обработку нажатия клавиш, а лучше запускать в отдельном потоке и разруливать через евенты.
По поводу пункта 2 - тут надо переписать/заменить алгоритм уменьшения. Может надо использовать что-то из vd. Надо проверить.
Название: Сохранение миниатюр [Готово]
Отправлено: V0lt от 25 июня 2016, 11:04:34
Я думал о неком глобальном сообщении, проверку которого втравляем в цикл генерации миниатюр. Вроде что-то подобное у нас где-то используется.
Не стоит добавлять обработчик клавиш в SaveThumbnails.
Название: Сохранение миниатюр [Готово]
Отправлено: Aleksoid1978 от 25 июня 2016, 11:43:09
Ну и я сказал что евенты. Но тогда надо запускать в отдельном потоке - чтобы это дело обрабатывать. Это не трудно реализовать :)

По поводу качества - надо попробовать использовать BitBltFromRGBToRGBStretch(), с помощью этой функции уменьшать - а уже потом просто скопировать данные из полученных в общие.
[merge_posts_bbcode]Добавлено: 2016-06-25 18:43:09[/merge_posts_bbcode]

Проверил - использование BitBltFromRGBToRGBStretch() дает более "гладкую" картинку, более мягкую. Правда меня смущает вот этот кусок кода, не могу понять как просто данные перенести из полученной маленькой картинки в большую общую, в нужные координаты.
       for (DWORD h = r.bottom - r.top, y = 0, yd = (sh << 8) / h; h > 0; y += yd, h--) {
            DWORD yf = y & 0xff;
            DWORD yi = y >> 8;

            DWORD* s0 = (DWORD*)(src + (int)yi * sp);
            DWORD* s1 = (DWORD*)(src + (int)yi * sp + sp);
            DWORD* d  = (DWORD*)dst;

            for (DWORD w = r.right - r.left, x = 0, xd = (sw << 8) / w; w > 0; x += xd, w--) {
                DWORD xf = x & 0xff;
                DWORD xi = x >> 8;

                DWORD c0 = s0[xi];
                DWORD c1 = s0[xi + 1];
                DWORD c2 = s1[xi];
                DWORD c3 = s1[xi + 1];

                c0 = ((c0&0xff00ff) + ((((c1&0xff00ff) - (c0&0xff00ff)) * xf) >> 8)) & 0xff00ff
                     | ((c0&0x00ff00) + ((((c1&0x00ff00) - (c0&0x00ff00)) * xf) >> 8)) & 0x00ff00;

                c2 = ((c2&0xff00ff) + ((((c3&0xff00ff) - (c2&0xff00ff)) * xf) >> 8)) & 0xff00ff
                     | ((c2&0x00ff00) + ((((c3&0x00ff00) - (c2&0x00ff00)) * xf) >> 8)) & 0x00ff00;

                c0 = ((c0&0xff00ff) + ((((c2&0xff00ff) - (c0&0xff00ff)) * yf) >> 8)) & 0xff00ff
                     | ((c0&0x00ff00) + ((((c2&0x00ff00) - (c0&0x00ff00)) * yf) >> 8)) & 0x00ff00;

                *d++ = c0;
            }

            dst += dp;
        }
Название: Сохранение миниатюр [Готово]
Отправлено: V0lt от 25 июня 2016, 13:19:00
Этот код тебе вообще не нужно трогать.
Название: Сохранение миниатюр [Готово]
Отправлено: Aleksoid1978 от 25 июня 2016, 13:51:00
Цитата: V0ltЭтот код тебе вообще не нужно трогать.

Еще как нужно - это как раз и есть оригинальный код ресайза :)
[merge_posts_bbcode]Добавлено: 2016-06-25 20:51:00[/merge_posts_bbcode]

Вот собранный билд + патч. Ресайз делается силами BitBltFromRGBToRGBStretch().
https://yadi.sk/d/2tm9lUyhsnHab

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

По поводу отмены создания миниатюр - тут есть нюанс, пока он выполняется не работает нажатия ни кнопок ни меню. Запустить в отдельном потоке тоже не получится - нам необходимо дождаться его окончания и только после что-то делать дальше.
Название: Сохранение миниатюр [Готово]
Отправлено: V0lt от 25 июня 2016, 14:12:19
Неожиданно. Мне подумалось что это тень. :)

Что-то твой билд еще хуже генерирует миниатюры.
Название: Сохранение миниатюр [Готово]
Отправлено: Aleksoid1978 от 25 июня 2016, 14:28:09
Что-то по поводу хуже я не заметил. Выложи свои файлики-миниатюр - с SVN и с моего билда. Гляну.
У себя я сохраняю только в .png
Название: Сохранение миниатюр [Готово]
Отправлено: V0lt от 25 июня 2016, 15:11:48
svn1666 - (http://s45.radikal.ru/i107/1606/fc/ab5874ed0521t.jpg) (http://s45.radikal.ru/i107/1606/fc/ab5874ed0521.png)
test - (http://s48.radikal.ru/i119/1606/f9/80c4276fe5dat.jpg) (http://s48.radikal.ru/i119/1606/f9/80c4276fe5da.png)
Название: Сохранение миниатюр [Готово]
Отправлено: Aleksoid1978 от 25 июня 2016, 15:44:03
Ну сравнение на 8К - это уже перебор да и не актуально :) В любом случае ни там ни там ни чего не видно.

Вот сравнил на 4K
svn:
(http://s017.radikal.ru/i413/1606/f1/bd14d7d43db9t.jpg) (http://radikal.ru/fp/6d79a9851e6e43a6906282d1e68be877)

test:
(http://i079.radikal.ru/1606/85/0ae6e90d485ft.jpg) (http://radikal.ru/fp/9607ad0eba024299b154b8af4bc12d99)

А вот так нагляднее - http://screenshotcomparison.com/comparison/176601
Название: Сохранение миниатюр [Готово]
Отправлено: V0lt от 25 июня 2016, 15:59:22
Не обязательно 8k, главное сильное уменьшение, просто на этом сэмпле видно разницу.
Да и особого ускорения от BitBltFromRGBToRGBStretch() не будет. Код который сейчас используется простой как валенок.
Название: Сохранение миниатюр [Готово]
Отправлено: Aleksoid1978 от 25 июня 2016, 16:06:37
Ну тогда закрываем тему - ни улучшить качество картинки, ни отменить создание миниатюр мы не сможем.
Название: Сохранение миниатюр [Готово]
Отправлено: V0lt от 25 июня 2016, 16:12:48
Все можем, только не сразу.
Название: Сохранение миниатюр [Готово]
Отправлено: Aleksoid1978 от 25 июня 2016, 16:46:36
Ну в принципе ты прав - погуглил и нашел несколько алгоритмов ресайза. Взял один из них и проверил качество, вот что вышло на 4K
http://screenshotcomparison.com/comparison/176605
более "смазанное", зато нет этих разломов, белых ломанных линий и т.д.
Название: Сохранение миниатюр [Готово]
Отправлено: V0lt от 25 июня 2016, 22:02:23
В принципе GDI умеет уменьшать растровые картинки и выводить результат в нужный прямоугольник. Только нужно проверить, как оно это делает.

PS: У меня синтаксис GDI мозг не принимает. Там во всех функциях нужно записать HDC, который порой вообще непонятно откуда брать, т.к. в примерах оно появляется волшебным образом. Да и название дебильное device context. :mad:
Название: Сохранение миниатюр [Готово]
Отправлено: Angel от 26 июня 2016, 01:26:31
а можно приделать сообщение о том, что миниатюры рендерятся и юзер должен подождать?
в идеале еще и прогрессбар процесса этого вывести, тогда не будут возникать позывы закрыть плеер в процессе их создания.
Название: Сохранение миниатюр [Готово]
Отправлено: Aleksoid1978 от 26 июня 2016, 04:37:54
Если что - вот тестовый билд с другим алгоритмом уменьшения, сравниваем
https://yadi.sk/d/yl6QXfawsnrXu
Название: Сохранение миниатюр [Готово]
Отправлено: V0lt от 26 июня 2016, 05:31:43
Aleksoid1978
На этом билде хорошо.
(http://s41.radikal.ru/i091/1606/bd/294e9bdd08dat.jpg) (http://s41.radikal.ru/i091/1606/bd/294e9bdd08da.png)

Angel
Я думал о небольшом модальном окне с прогресс-баром и кнопкой "Oтмена". Это пока самый оптимальный вариант.
Название: Сохранение миниатюр [Готово]
Отправлено: Aleksoid1978 от 26 июня 2016, 06:22:00
А я предлагаю примерно как с диалогом сохранения - будет и кнопка отмена, и прогресс бар(правда не плавный - но все равно).
[merge_posts_bbcode]Добавлено: 2016-06-26 13:22:00[/merge_posts_bbcode]

Тоже проверил на 8K - http://screenshotcomparison.com/comparison/176652
Разница на лицо :) Думаю надо внедрять новый алгоритм.
Название: Сохранение миниатюр [Готово]
Отправлено: V0lt от 26 июня 2016, 09:22:54
Внедряй, только просьба безо всякой косметики, а то потом в логе изменений трудно понять, что поменялось.

Есть описание алгоритма?
Название: Сохранение миниатюр [Готово]
Отправлено: Aleksoid1978 от 28 июня 2016, 10:32:28
Описания как такового нет, есть комментарии в сырцах и страничка где это взято, её укажу как источник.
[merge_posts_bbcode]Добавлено: 2016-06-27 15:15:13[/merge_posts_bbcode]

Еще вот тут нашел сырцы https://github.com/artcom/y60/tree/master/netsrc/paintlib/src/Filter
Там есть pl2passscale.h - 2-х проходный ресайзер, сперва по горизонтали, потом по вертикали.

Но т.к. у нас уже хорошее качество - не стал проверять, думаю вряд ли может получиться сильно лучше.

[merge_posts_bbcode]Добавлено: 2016-06-28 17:15:00[/merge_posts_bbcode]

Предлагаю текстовый билд с диалогом - https://yadi.sk/d/ZQDe5J0JsqcMp
и так же патч для этого дела - https://yadi.sk/d/MJhOnIb4sqcPn

Не пугаться - в патче еще изменения немного не в тему, изменены проверки работы оператора new. На самом деле вот такой код:
BYTE* p = DNew BYTE[size];
if (!p) {
    return;
}

не работает, т.к. в любом случае переменная p не будет нулевой и проверка не пройдет. А вот если не получиться память выделить - тогда сработает CMemoryException, что и надо отловить. Там конечно размеры выделяются маленькие и по идее такое никогда не сработает - но в любом случае правильнее использовать try {} catch {}.

[merge_posts_bbcode]Добавлено: 2016-06-28 17:32:28[/merge_posts_bbcode]

Там правда есть нюансы:
1) - Плавное изменение ползунка не получиться, как и моментальная отмена операции по нажатию на кнопку.
2) - После отмены не возвращается на прежнее место. Пока не копался.
Название: Сохранение миниатюр [Готово]
Отправлено: V0lt от 28 июня 2016, 21:45:22
Спасибо за патч. У тебя слишком много лишнего в новом потоке. Стоп и выключение звука, а также возврат к исходному лучше оставить в основном окне.

Я переработал свой вариант, мне надо немного потестить и выложу сборку.
Название: Сохранение миниатюр [Готово]
Отправлено: Aleksoid1978 от 29 июня 2016, 00:32:51
Да я по быстрому просто перенёс код.

По поводу проверки/тестирования - советую обратить особое внимание обработки нажатия Отмены во время построения. Ну чтобы не было косяков и зависаний.

Сборку выкладывай сразу с патчем.
Название: Сохранение миниатюр [Готово]
Отправлено: V0lt от 29 июня 2016, 23:05:38
Сборку залил.
Все отрабатывает корректно, кроме зависания MPC Audio Renderer. Тот чего-то пытается ждать какие-то данные на паузе.

Еще непонятно назначение этого блока
HANDLE hGraphEvent = NULL;
pMainFrm->m_pME->GetEventHandle((OAEVENT*)&hGraphEvent);
while (hGraphEvent && WaitForSingleObject(hGraphEvent, INFINITE) == WAIT_OBJECT_0) {
    LONG evCode = 0;
    LONG_PTR evParam1, evParam2;
    while (pMainFrm->m_pME && SUCCEEDED(pMainFrm->m_pME->GetEvent(&evCode, &evParam1, &evParam2, 0))) {
        pMainFrm->m_pME->FreeEventParams(evCode, evParam1, evParam2);
        if (EC_STEP_COMPLETE == evCode) {
            hGraphEvent = NULL;
        }
    }
}
Поэтому оставил как есть. Если будет информация, то напишу комментарий.
Название: Сохранение миниатюр [Готово]
Отправлено: Aleksoid1978 от 30 июня 2016, 01:52:21
1 - раньше были зависания с нашим аудио выводом ??
2 - тот код ждет завершения шага от видео-рендерера.
[merge_posts_bbcode]Добавлено: 2016-06-30 08:52:21[/merge_posts_bbcode]

И вот еще что "не красиво" - ты в самом CTaskDlg вызываешь AfxMessageBox(). Выглядит некрасиво. Лучше как я делал - закрывать диалог и уже после показывать сообщение.
Название: Сохранение миниатюр [Готово]
Отправлено: V0lt от 04 июля 2016, 22:13:42
Кстати, можно сохранять миниатюры на стопе. Вроде не зависает.
Я потестирую еще.
[merge_posts_bbcode]Добавлено: 2016-06-30 06:44:08[/merge_posts_bbcode]

AfxMessageBox() посмотрю...

[merge_posts_bbcode]Добавлено: 2016-07-04 22:13:42[/merge_posts_bbcode]

В общем проблема оказалась в том, что у нас получается два обработчика событий графа. Это неправильно, т.к. в результате до каждого обработчика доходит лишь часть событий.
Исправил в r1706.