Торренты   
 
 


Стереоплеер: Free 3d player by Kostasoft

Выдалось немного свободного времени. Внес некоторые изменения в работе моего стереоплеера, основанного на технологии 3D Vision от Nvidia.
Просьба, протестировать его на разном железе (В режиме анаглифа или QuadBuffers должно работать и на видеокарточках от ATI/AMD).
Скачать с официальной страницы проекта
Что изменено:
1. Сделал ручное переключение исходных режимов стереоролика (цифровыми клавишами). Поддержка форматов: Over/Under, Side-by-Side (обычные и анаморфные режимы)
2. Сделал декодирование видео только в UV12 (для ускорения декодирования на слабых машинах, в связи с уменьшением потока в 2.6 раза по сравнению с RGBA) и вывод на экран этого цветового подпространства за счет использования Pixel Shader 2.0 (опять же для ускорения распаковки кадров, т.к. вся работа ведется в GPU видеокарты).
Что ухудшилось:
1. Не включается режим стерео на встроенных видеокартах (у меня ноутбук Dell XPS 13 с двумя видеокартами. На встроенной не включается, на дискретной - работает). Неизбежное зло при переходе на новый способ вывода видео через шейдеры.
Просьба, по возможности, отписаться о работе данного сабжа в сравнении с другими плеерами (скорость работы, баги). Особенно интересует мнение владельцев компьютеров со слабым процессором (и более-менее шустрой видеокартой), у которых наблюдались тормоза при воспроизведении "тяжелого" видео.
Комментарии:

Пред.  1, 2, 3 ... 6, 7, 8 ... 15, 16, 17  След.






2 photoreal3d
Значит останавливаемся на отдельном ехе-шнике.
Запуск твоего ехе-шника будет таким:
При нажатии на кнопку "Настройка" нпротив галочки "Разрешить коррекцию гхоста" будет вызываться твоя программа с параметром, указывающим файл с настройками (к примеру: program.exe "c:\users\kostasoft\Documents\kostasoft\Free3Dplayer\current_RedCyan.kap")
Т.е. путь к файлу ищи в Paramstr(1).
Я буду ждать завершения твоей программы и затем считывать данные из .kap файла и заливать их в шейдер.
Вот структура файла .kap:
Код:
[Color correction]
Value1=50
Value2=50
Value3=80
Value4=30
Value5=20
Value6=20
Value7=30
Value8=70
Value9=80
Value10=80
Value11=40
Value12=40
Brightness=0
Enabled=1
[OutputR]
LR=1000
LG=0
LB=0
RR=0
RG=0
RB=0
[OutputG]
LR=0
LG=0
LB=0
RR=0
RG=1000
RB=0
[OutputB]
LR=0
LG=0
LB=0
RR=0
RG=0
RB=1000
[Ghost correction]
Enabled=1
ML0=1000
ML1=1000
ML2=1000
ML3=1000
ML4=1000
ML5=1000
ML6=1000
ML7=1000
ML8=1000
ML9=1000
ML10=1000
ML11=1000
ML12=1000
ML13=1000
ML14=1000
ML15=1000
ML16=1000
ML17=1000
ML18=1000
ML19=1000
ML20=1000
ML21=1000
ML22=1000
ML23=1000
ML24=1000
MR0=1000
MR1=999
MR2=1000
MR3=1000
MR4=1000
MR5=1000
MR6=1000
MR7=1000
MR8=1000
MR9=1000
MR10=1000
MR11=1000
MR12=1000
MR13=1000
MR14=1000
MR15=1000
MR16=1000
MR17=1000
MR18=1000
MR19=1000
MR20=1000
MR21=1000
MR22=1000
MR23=1000
MR24=1000
Данные будут в хранится в файле в виде целых чисел от 0 до 1000, при передаче в шейдер я из поделю на 1000.
Если не трудно, пришли мне все формулы билинейной интерполяции для всех типов анаглифа.
 

samfednik
Настройки адаптивной коррекции цвета лучше вообще не трогать, т.к. это очень субъективная часть, как говориться "на вкус и цвет товарища нет". В крайнем случае, я рекомендую делать так: смотрим реальное видео с настройками цветокоррекции по умолчанию. Если вам кажется, что у какого-то цвета биение слишком большое, например, у красного - немного уменьшаем значение соответствующего регулятора в настройках. Коррекция гхоста в плеере будет аналогичной как и в моем фото-вьювере, просто пока еще не реализована. На счет серого изображения: так и должно быть - это тестовый режим, если у вас показывает в сером - значит коррекция гхостов работать будет! (внимательнее читайте сообщения в теме, kostasoft об этом писал)
 

2 samfednik
Так, на счет зарегистрированного кодека в системе - сорри, я специально использовал кодеки без регистрации, но потом для теста включил регистрацию и забыл об этом. С новой версии кодеки регистрироваться в системе не будут. Если же они все таки у Вас успели зарегистрироваться, то через ту же graphstudio (графедит от компании Monogram) отключите регистрацию (окно добавления фильтра - Кнопка Unregister)
Чернобелый ракурс - это тест. Скоро вместо этого будет коррекция гхоста.
Адаптивная коррекция у photoreal3d такая же, ползунками нужно сделать так, чтобы квадратики как можно меньше бликовали в очках. Photoreal3d сам расскажет об этом подробнее, а, возможно, мы сделаем "нормальный" хелп со скриншотами, но позже, сейчас заняты обеспечением функциональности.
Стерео в оконном режиме могу сделать и я, если есть в этом такая необходимость.
Выбор кодеков - я позже сделаю чекбокс "Использовать встроенные кодеки". Если он будет отключен, будут использоваться зарегистрированные в системе.
 

kostasoft
Может лучше в именах коэффициентов указывать номера индексов, например M00 - ячейка [0,0] M10 - ячейка [1,0]?
Зачем до 1000? ведь реально все равно цвет 8 бит на канал, может 255? или на 255 делить сложнее в шейдере?
Секции "Output", "Color correction", "Ghost correction" могут располагаться в произвольной последовательности?
 

На счет серого изображения: так и должно быть - это тестовый режим, если у вас показывает в сером - значит коррекция гхостов работать будет! (внимательнее читайте сообщения в теме, kostasoft об этом писал)
Ну я же и показываю, как это работает у меня, не упрекаю ведь в "неработе" режима...
kostasoft
Спасибо, коротко и ясно. Да я фильтры знаю как регестрировать и анрегестрировать в системе, это не проблема для меня.
Но пока в приоритете я так понимаю с "анаглифами" разобраться, ну а потом уже можно и 3Движн починить?
 

Да в произвольной, но если ты пишешь на делфях, используй модуль inifiles (добавь в uses) и тогда работа с ним будет очень простой. Добавь эту процедуру себе в код, только поменяй SpinEditХХ.Value на свои переменные.
Код:
procedure TForm14.SavePreset(filename:string);
var ini:TIniFile;
begin
ini:=TIniFile.Create(filename);
ini.WriteInteger('Ghost correction','ML0',SpinEdit19.Value);
ini.WriteInteger('Ghost correction','ML1',SpinEdit20.Value);
ini.WriteInteger('Ghost correction','ML2',SpinEdit21.Value);
ini.WriteInteger('Ghost correction','ML3',SpinEdit22.Value);
ini.WriteInteger('Ghost correction','ML4',SpinEdit23.Value);
ini.WriteInteger('Ghost correction','ML5',SpinEdit24.Value);
ini.WriteInteger('Ghost correction','ML6',SpinEdit25.Value);
ini.WriteInteger('Ghost correction','ML7',SpinEdit26.Value);
ini.WriteInteger('Ghost correction','ML8',SpinEdit27.Value);
ini.WriteInteger('Ghost correction','ML9',SpinEdit28.Value);
ini.WriteInteger('Ghost correction','ML10',SpinEdit29.Value);
ini.WriteInteger('Ghost correction','ML11',SpinEdit30.Value);
ini.WriteInteger('Ghost correction','ML12',SpinEdit31.Value);
ini.WriteInteger('Ghost correction','ML13',SpinEdit32.Value);
ini.WriteInteger('Ghost correction','ML14',SpinEdit33.Value);
ini.WriteInteger('Ghost correction','ML15',SpinEdit34.Value);
ini.WriteInteger('Ghost correction','ML16',SpinEdit35.Value);
ini.WriteInteger('Ghost correction','ML17',SpinEdit36.Value);
ini.WriteInteger('Ghost correction','ML18',SpinEdit37.Value);
ini.WriteInteger('Ghost correction','ML19',SpinEdit38.Value);
ini.WriteInteger('Ghost correction','ML20',SpinEdit39.Value);
ini.WriteInteger('Ghost correction','ML21',SpinEdit40.Value);
ini.WriteInteger('Ghost correction','ML22',SpinEdit41.Value);
ini.WriteInteger('Ghost correction','ML23',SpinEdit42.Value);
ini.WriteInteger('Ghost correction','ML24',SpinEdit43.Value);
ini.WriteInteger('Ghost correction','MR0',SpinEdit44.Value);
ini.WriteInteger('Ghost correction','MR1',SpinEdit45.Value);
ini.WriteInteger('Ghost correction','MR2',SpinEdit46.Value);
ini.WriteInteger('Ghost correction','MR3',SpinEdit47.Value);
ini.WriteInteger('Ghost correction','MR4',SpinEdit48.Value);
ini.WriteInteger('Ghost correction','MR5',SpinEdit49.Value);
ini.WriteInteger('Ghost correction','MR6',SpinEdit50.Value);
ini.WriteInteger('Ghost correction','MR7',SpinEdit51.Value);
ini.WriteInteger('Ghost correction','MR8',SpinEdit52.Value);
ini.WriteInteger('Ghost correction','MR9',SpinEdit53.Value);
ini.WriteInteger('Ghost correction','MR10',SpinEdit54.Value);
ini.WriteInteger('Ghost correction','MR11',SpinEdit55.Value);
ini.WriteInteger('Ghost correction','MR12',SpinEdit56.Value);
ini.WriteInteger('Ghost correction','MR13',SpinEdit57.Value);
ini.WriteInteger('Ghost correction','MR14',SpinEdit58.Value);
ini.WriteInteger('Ghost correction','MR15',SpinEdit59.Value);
ini.WriteInteger('Ghost correction','MR16',SpinEdit60.Value);
ini.WriteInteger('Ghost correction','MR17',SpinEdit61.Value);
ini.WriteInteger('Ghost correction','MR18',SpinEdit62.Value);
ini.WriteInteger('Ghost correction','MR19',SpinEdit63.Value);
ini.WriteInteger('Ghost correction','MR20',SpinEdit64.Value);
ini.WriteInteger('Ghost correction','MR21',SpinEdit65.Value);
ini.WriteInteger('Ghost correction','MR22',SpinEdit66.Value);
ini.WriteInteger('Ghost correction','MR23',SpinEdit67.Value);
ini.WriteInteger('Ghost correction','MR24',SpinEdit68.Value);
ini.Free;
end;
Дополнено:
Почему деление на 1000? Так нагляднее, сразу видишь коэффициент в вещественном виде (в уме передвинуть запятую на 3 знака намного проще, чем делить на 255). Но можно сделать и в диапазоне 0..255. Выбор за тобой, как сделаешь, так я дальше и реализую!
Дополнено2:
Нумерация массивов в файле - дело тоже сугубо условное. Для меня это просто массив чисел, которые сохранены в файле и которые нужно передать в шейдер. Они могут называться как угодно, ни их нумерация, ни их название для меня роли не играют. Просто нужно один раз определиться и все. Тем более, врят ли кто-то будет их редактировать вручную в самом файле. Для ручного редактирования есть форма в плеере.
 

2 samfednik
Да, Вы правильно меня поняли, раз мы начали ковырять анаглиф, то должны закончить основной объем работы. Потом будем вылизывать хвосты.
 

kostasoft
Понятно, что последовательность только значение имеет, просто при переходе с двухмерного массива на одномерный надо договориться о последовательности, например, так:
ML0=ML[0,0]
ML1=ML[0,1]
ML2=ML[0,2]
ML3=ML[0,3]
ML4=ML[0,4]
ML5=ML[1,0]
ML6=ML[1,1]
ML7=ML[1,2]
...
Потому что можно ведь и по другому сделать
 

kostasoft
Если исходные цвета в диапазоне 0..1, в массивах - коэффициенты 0..1000 деленные на 1000, то коррекция гхоста для red-cyan:
Код:
I = int(G/0.251)
J = int(R/0.251)
K1 = ML[I,J]+(ML[I,J+1]-ML[I,J])*(R/0.251-J)
K2 = ML[I+1,J]+(ML[I+1,J+1]-ML[I+1,J])*(R/0.251-J)
R_new = K1+(K2-K1)*(G/0.251-I)
I = int(R/0.251)
J = int(G/0.251)
K1 = MR[I,J]+(MR[I,J+1]-MR[I,J])*(G/0.251-J)
K2 = MR[I+1,J]+(MR[I+1,J+1]-MR[I+1,J])*(G/0.251-J)
G_new = K1+(K2-K1)*(R/0.251-I)
I = int(R/0.251)
J = int(B/0.251)
K1 = MR[I,J]+(MR[I,J+1]-MR[I,J])*(B/0.251-J)
K2 = MR[I+1,J]+(MR[I+1,J+1]-MR[I+1,J])*(B/0.251-J)
B_new = K1+(K2-K1)*(R/0.251-I)
Для green-magenta:
Код:
I = int(G/0.251)
J = int(R/0.251)
K1 = MR[I,J]+(MR[I,J+1]-MR[I,J])*(R/0.251-J)
K2 = MR[I+1,J]+(MR[I+1,J+1]-MR[I+1,J])*(R/0.251-J)
R_new = K1+(K2-K1)*(G/0.251-I)
I = int(R/0.251)
J = int(G/0.251)
K1 = ML[I,J]+(ML[I,J+1]-ML[I,J])*(G/0.251-J)
K2 = ML[I+1,J]+(ML[I+1,J+1]-ML[I+1,J])*(G/0.251-J)
G_new = K1+(K2-K1)*(R/0.251-I)
I = int(G/0.251)
J = int(B/0.251)
K1 = MR[I,J]+(MR[I,J+1]-MR[I,J])*(B/0.251-J)
K2 = MR[I+1,J]+(MR[I+1,J+1]-MR[I+1,J])*(B/0.251-J)
B_new = K1+(K2-K1)*(R/0.251-I)
Для amber-blue:
Код:
I = int(B/0.251)
J = int(R/0.251)
K1 = ML[I,J]+(ML[I,J+1]-ML[I,J])*(R/0.251-J)
K2 = ML[I+1,J]+(ML[I+1,J+1]-ML[I+1,J])*(R/0.251-J)
R_new = K1+(K2-K1)*(G/0.251-I)
I = int(B/0.251)
J = int(G/0.251)
K1 = ML[I,J]+(ML[I,J+1]-ML[I,J])*(G/0.251-J)
K2 = ML[I+1,J]+(ML[I+1,J+1]-ML[I+1,J])*(G/0.251-J)
G_new = K1+(K2-K1)*(R/0.251-I)
I = int(G/0.251)
J = int(B/0.251)
K1 = MR[I,J]+(MR[I,J+1]-MR[I,J])*(B/0.251-J)
K2 = MR[I+1,J]+(MR[I+1,J+1]-MR[I+1,J])*(B/0.251-J)
B_new = K1+(K2-K1)*(R/0.251-I)
Добавлено:
Сделал exe-шник для настройки коррекции гхостов
 

2 photoreal3d
А ты уверен, что значения входных цветов нужно делить на 0.251 ???
У меня цвет тоже вещественное число от 0.0 до 1.0 !
Блин, я дурак, вопрос снимается!
И еще одна причина, почему у меня массив одномерный: в шейдере я не могу описать двумерный массив. Толи лыжи не едут...
 

kostasoft
Значит у тебя в коде вместо ML[I,J] будет что-то типа: ML[I*5+J] ?
 

ну да, если не удастся с двухмерным
 

kostasoft
Там я exe-шник программы генерации профиля коррекции гхостов прицепил к сообщению с формулами, видел? И еще: если в программе не двигать ползунок а тупо нажимать "Далее", то получиться профиль "идеального устройства", т.е. вообще без коррекции, его можно использовать для проверки правильности всех формул, если все ОК, то изображение на выходе будет таким же как и на входе.
Добавлено:
Как локализацию делать? Два разных exe-шника, на русском и английском? Можно вторым параметром командной строки выбранный язык передавать. Переводить сообщения надо, у меня криво получиться (((
 

Переводом потом займемся. Давай вторым параметром язык передавать (0 = русский, 1 = английский)
Если без параметра, то русский.
У меня VPConfig.exe не создает (и не меняет) файл с настройками (что я передаю первым параметром у тебя в paramstr(1)). Или я опять торможу?
Добавлено:
Слушай, если G = 0..1, то при G=1.0, результат будет 1.0/0.251=3.984
Это нормально? т.е. 4 элемент массива никогда не будет выбран!
 

kostasoft
Там ведь в формулах читается и из элементов с индексом +1, соответственно интерполяция будет между 3 и 4 элементом, причем, так как остаток 0.984, то на выходе интерполяции будет практически значение 4-го элемента. По крайней мере, после пересчета вещественных значений RGB в восьми битные целые мне кажется что те-же 255 и получатся. Если даже получиться 254 - не беда, т.к. пользователь тоже закалибровать с точностью до 1/255 не сможет. Иначе, придется вводить еще элементы в массив расширяя его до 6х6 и делая в 4 и 5 ячейке одинаковые значения подобно тому как в массиве коэффициентов цветовой коррекции сделано (считаю что лишний гемор) или же условия добавлять типа "если получился последний индекс, то вместо интерполяции сразу берем значение из массива" - у этого варианта больше шансов на жизнь, но измениться ли от этого результат?
 

2 photoreal3d
А что на счет VPConfig.exe?
У тебя он сохраняет результат работы?
 

kostasoft
Да, сохраняет, если в проге указываю выходной файл явно. И если как параметр указываю, тоже сохраняет.
У меня вот как сделано при запуске проги:
Код:
OutFile:=ParamStr(1);
  if OutFile='' then
    begin
      ShowMessage('Не указано имя конфигурационного файла');
      Close;
    end;
  if pos('RedCyan',OutFile)<>0 then CalibrationMode:='RC';
  if pos('GreenMagenta',OutFile)<>0 then CalibrationMode:='GM';
  if pos('AmberBlue',OutFile)<>0 then CalibrationMode:='AB';
  Start;
  tbComp.SetFocus;
Если сообщение не появляется и настройка стартует, то значит имя файла не равно пустой строке. И куда-то он результат все-таки пишет. Добавил вывод сообщения с именем конфигурационного файла, посмотри, что там. Может доступа к файлу нет?
 

стереоплеер сразу после включения вылетает
 

2 photoreal3d
Мой косяк, у меня имя пользователя с пробелом. Из-за этого не правильно передавался путь к файлу (обрезался до первого пробела), спасибо твоей версии 1.1, увидел сей баг! Исправил.
Скоро выложу новую версию!
2 anvar
Я попробую запустить плеер от простого юзера, посмотрю, что не так.
 

Прошу любить и жаловать!
Версия 12.4.9.0
- Реализована коррекция гхостов.
- Реализовано отключение встроенных кодеков.
- Пофиксены мелкие баги.
Отписываемся...
2 photoreal3d
Вот кусок из шейдера, глянь, правильная ли формула, может у меня глаз замылился, не вижу чего...
Код:
i = int(source.g*3.999);
    j = int(source.r*3.999);
    k1 = ml[i*5+j]+(ml[i*5+j+1]-ml[i*5+j])*(source.r*3.999-j);
    k2 = ml[(i+1)*5+j]+(ml[(i+1)*5+j+1]-ml[(i+1)*5+j])*(source.r*3.999-j);
    gl_FragColor.r = k1+(k2-k1)*(source.g*3.999-i);
    i = int(source.r*3.999);
    j = int(source.g*3.999);
    k1 = mr[i*5+j]+(mr[i*5+j+1]-mr[i*5+j])*(source.g*3.999-j);
    k2 = mr[(i+1)*5+j]+(mr[(i+1)*5+j+1]-mr[(i+1)*5+j])*(source.g*3.999-j);
    gl_FragColor.g = k1+(k2-k1)*(source.r*3.999-i);
    i = int(source.r*3.999);
    j = int(source.b*3.999);
    k1 = mr[i*5+j]+(mr[i*5+j+1]-mr[i*5+j])*(source.b*3.999-j);
    k2 = mr[(i+1)*5+j]+(mr[(i+1)*5+j+1]-mr[(i+1)*5+j])*(source.b*3.999-j);
    gl_FragColor.b = k1+(k2-k1)*(source.r*3.999-i);
    gl_FragColor.a = 1.0;
Код:
i = int(source.g*3.999);
    j = int(source.r*3.999);
    k1 = mr[i*5+j]+(mr[i*5+j+1]-mr[i*5+j])*(source.r*3.999-j);
    k2 = mr[(i+1)*5+j]+(mr[(i+1)*5+j+1]-mr[(i+1)*5+j])*(source.r*3.999-j);
    gl_FragColor.r = k1+(k2-k1)*(source.g*3.999-i);
    i = int(source.r*3.999);
    j = int(source.g*3.999);
    k1 = ml[i*5+j]+(ml[i*5+j+1]-ml[i*5+j])*(source.g*3.999-j);
    k2 = ml[(i+1)*5+j]+(ml[(i+1)*5+j+1]-ml[(i+1)*5+j])*(source.g*3.999-j);
    gl_FragColor.g = k1+(k2-k1)*(source.r*3.999-i);
    i = int(source.g*3.999);
    j = int(source.b*3.999);
    k1 = mr[i*5+j]+(mr[i*5+j+1]-mr[i*5+j])*(source.b*3.999-j);
    k2 = mr[(i+1)*5+j]+(mr[(i+1)*5+j+1]-mr[(i+1)*5+j])*(source.b*3.999-j);
    gl_FragColor.b = k1+(k2-k1)*(source.r*3.999-i);
    gl_FragColor.a = 1.0;
Код:
i = int(source.b*3.999);
    j = int(source.r*3.999);
    k1 = ml[i*5+j]+(ml[i*5+j+1]-ml[i*5+j])*(source.r*3.999-j);
    k2 = ml[(i+1)*5+j]+(ml[(i+1)*5+j+1]-ml[(i+1)*5+j])*(source.r*3.999-j);
    gl_FragColor.r = k1+(k2-k1)*(source.g*3.999-i);
    i = int(source.b*3.999);
    j = int(source.g*3.999);
    k1 = ml[i*5+j]+(ml[i*5+j+1]-ml[i*5+j])*(source.g*3.999-j);
    k2 = ml[(i+1)*5+j]+(ml[(i+1)*5+j+1]-ml[(i+1)*5+j])*(source.g*3.999-j);
    gl_FragColor.g = k1+(k2-k1)*(source.r*3.999-i);
    i = int(source.g*3.999);
    j = int(source.b*3.999);
    k1 = mr[i*5+j]+(mr[i*5+j+1]-mr[i*5+j])*(source.b*3.999-j);
    k2 = mr[(i+1)*5+j]+(mr[(i+1)*5+j+1]-mr[(i+1)*5+j])*(source.b*3.999-j);
    gl_FragColor.b = k1+(k2-k1)*(source.r*3.999-i);
    gl_FragColor.a = 1.0;
 

Страница 7 из 17

Пред.  1, 2, 3 ... 6, 7, 8 ... 15, 16, 17  След.