Суббота, 20.04.2024, 13:23
Приветствую Вас Гость

Не ошибается тот, кто ничего не делает.
Но и ничего не делать - ошибка.

Эмиль Кроткий

[ Новые сообщения · Участники · Правила форума · Поиск · RSS ]
  • Страница 1 из 1
  • 1
Форум » Delphi » DirectShow и Delphi. » изменение разрешения камеры
изменение разрешения камеры
booratinoДата: Четверг, 06.11.2014, 15:06 | Сообщение # 1
Рядовой
Группа: Пользователи
Сообщений: 4
Репутация: 0
Статус: Offline
Принципиально изменять разрешение получилось, и я думал, что дальше сам справлюсь. Как я был наивен.

Первоначально размер устанавливался так:

FGraphBuilder.QueryInterface(IID_IVideoWindow, FVideoWindow);
FVideoWindow.put_WindowStyle(WS_CHILD or WS_CLIPSIBLINGS);
FVideoWindow.put_Owner(Panel1.Handle);
vr := Panel1.ClientRect;
FVideoWindow.SetWindowPosition(vr.Left,vr.Top, vr.Right - vr.Left,vr.Bottom - vr.Top);
FVideoWindow.put_Visible(TRUE);

После изменения разрешения камеры я делаю так:

// читаю установленные размеры камеры
FCaptureGraphBuilder.FindInterface(@PIN_CATEGORY_CAPTURE,@MEDIATYPE_Video,FVideoCaptureFilter,IID_IAMStreamConfig,StreamConfig);
StreamConfig.GetFormat(m_VideoType);
kinow := PVideoInfoHeader(m_VideoType.pbFormat)^.bmiHeader.biWidth;
kinoh := PVideoInfoHeader(m_VideoType.pbFormat)^.bmiHeader.biHeight;
m_VideoType := nil;
StreamConfig := nil;

// меняю панельку
Panel1.Width := kinow;
Panel1.Height := kinoh;

// думал, что так все прекрасно получится
FVideoWindow.SetWindowPosition(0,0,kinow,kinoh);

Да, размер панельки меняется. Но рендер идет не на всю панельку, а на четверть. Если размер панельки не менять, то как раз будет 320х240 в углу.

Как сказать графу, чтобы он на всю панель рендерил? smile

Добавлено (06.11.2014, 15:06)
---------------------------------------------
Не, ну, конечно, можно после выбора новых параметров пересоздать граф заново с новыми значениями FVideoCaptureFilter, и тогда все норм. Но, может, можно не разбирая в каком-то фильтре размеры поправить?

 
xaramamburuДата: Четверг, 06.11.2014, 16:31 | Сообщение # 2
Полковник
Группа: Администраторы
Сообщений: 240
Репутация: 26
Статус: Offline
booratino
Судя по всему здесь привязка окна идет не к координатам панели, а к чему то другому, точнее окно видео накладывается на панель.((( Поэтому надо вначале получить ссылку на координаты окна вывода видео, а потом их изменить.

Код
var pleft,pwidth,ptop,pheight:integer;
--------------------------------------------
--------------------------------------------

  // меняю панельку  
  Panel1.Width := kinow;  
  Panel1.Height := kinoh;  
FVideoWindow.GetWindowPosition(pleft,ptop,pwidth,pheight)  ;
pwidth:=Panel1.Width;
pheight:= Panel1.Height;
FVideoWindow.SetWindowPosition(0,0,pwidth,pheight);
--------------------------------------------
--------------------------------------------

Хотел спросить, как там с квадратом "Малевичя" разобрались?
 
booratinoДата: Пятница, 07.11.2014, 02:41 | Сообщение # 3
Рядовой
Группа: Пользователи
Сообщений: 4
Репутация: 0
Статус: Offline
Да, с Малевичем вопрос решился. Как вы и велели, сделал FVideoRender, и добавил его в FCaptureGraphBuilder.RenderStream. Все отлично.

А вот Ваше предположение сперва получить, а потом поменять - не помогает. результат тот же.  Панель стала 320х240, а картинка в левом нижнем углу 160х120.

Кстати, GetWindowPosition возвращает w = 640, h = 480, это понятно, а вот тор и left  = 624 и top = 160 - это совсем не понятно.

Кстати 2. Попробовал сделать так:

FGraphBuilder.RemoveFilter(FVideoCaptureFilter);
поменял FVideoCaptureFilter размеры
FGraphBuilder.AddFilter(FVideoCaptureFilter, 'VideoCaptureFilter');
и потом заново
FCaptureGraphBuilder.RenderStream(@PIN_CATEGORY_PREVIEW, @MEDIATYPE_Video, FVideoCaptureFilter, FGrabFilter, FVideoRender);

фигня полная. Картинка правильная, но "кина" нет. smile и граф весь порван, и какие-то левые Smart Tree добавились.

Ужасно интеллектуальная, эта самая, директ-шоу.  В RenderStream указано всего 3 блока, так нет, а граф добавляется 6 штук квадратов. Вынул один, вставил обратно - 8 штук квадратов. Моя голова очень медленно такое принимает... удивляюсь, как Вы в этом вообще разобрались...... :))

Добавлено (07.11.2014, 02:32)
---------------------------------------------
Я помню, Вы меня учили, типа, в графстудио возьми камеру и video mixing renderer 9, соедини и посмотри что она еще добавит. так вот она не добавляла ничего, работало на 2х квадратах.

когда программа рендерит из 3х частей, то графстудио показывает следующее:

videocaptureFilter - SmartTree - LAV video decoder (камера дает mjpeg) - grabber - ColorSpaceConverter - VideoRenderer (простой, а не 9й)

и я так подозреваю, что после смены разрешения в 1м квадрате, остальные квадраты "помнят", что спереди было 640х480. они же рендерились в связке под то разрешение...

не понятно почему после RemoveFilter с последующим AddFilter и повторным RenderStream все квадраты разорваны и лишний SmartTree непонятный добавляется... :))

Добавлено (07.11.2014, 02:41)
---------------------------------------------
да, и еще что интересно.... ТА процедура не переключала камеру в другой режим насовсем, а только на время жизни графа. Т.е. первый квадрат камеру переключил, а как его обnilили, камера опять вернулась в разрешение по умолчанию. smile

 
xaramamburuДата: Пятница, 07.11.2014, 13:11 | Сообщение # 4
Полковник
Группа: Администраторы
Сообщений: 240
Репутация: 26
Статус: Offline
booratino,
Цитата
удивляюсь, как Вы в этом вообще разобрались...... :))
К сожалению, я в этом так и не разобрался, мучаюсь как и вы, правда стал знать немного больше чем когда писал эти статьи и если я их писал сейчас, то наверное сделал бы много по другому.)))
Цитата
когда программа рендерит из 3х частей, то графстудио показывает следующее:

videocaptureFilter - SmartTree - LAV video decoder (камера дает mjpeg) -
grabber - ColorSpaceConverter - VideoRenderer (простой, а не 9й)
     Фильтр SmartTree ращеплят поток на 2 для просмотра и записи, как я понял его добавляет граф захвата FCaptureGraphBuilder, а когда вы просто соединяете камеру и рендерер в GraphStudio этот объект не добавляется.

Цитата
и я так подозреваю, что после смены разрешения в 1м квадрате, остальные
квадраты "помнят", что спереди было 640х480. они же рендерились в связке
под то разрешение...
        Про это сказать ничего не могу. У меня при до и после смены разрешения граф строится одинаковый.
Цитата
не понятно почему после RemoveFilter с последующим AddFilter и
повторным RenderStream все квадраты разорваны и лишний SmartTree
непонятный добавляется... :))
      Попробуйте сохранять граф после запуска, граф должен собраться.
Код
FMediaControl.Run();
SaveGraphFile(FGraphBuilder,'d:\граф захвата.GRF');
Цитата
А вот Ваше предположение сперва получить, а потом поменять - не помогает.
результат тот же.  Панель стала 320х240, а картинка в левом нижнем углу
160х120.
      Попробуйте так:
Код
var pleft,pwidth,ptop,pheight:integer;
----------------------------------------------
----------------------------------------------
     // меняю панельку     
     Panel1.Width := kinow;     
     Panel1.Height := kinoh;    
//меняю разрешение
     SetVideoParams(kinow, kinoh);
//останавливаем граф
      FMediaControl.Stop;
    //скрываем окно
      FVideoWindow.put_Visible(False);
//Задаем размеры окна во всю панель
      FVideoWindow.SetWindowPosition(0,0,panel1.Width,panel1.Height);
    //показываем окно
FVideoWindow.put_Visible(TRUE);
//запускаем граф
FMediaControl.Run();
end;
     У меня заработало.)))
Цитата
Кстати, GetWindowPosition возвращает w = 640, h = 480, это понятно, а вот тор и left  = 624 и top = 160 - это совсем не понятно.
     left  и top похоже указаны в глобальной системе координат, т.е. по отношению к рабочему столу, а вот SetWindowPosition похоже задает координаты в локальной системе, т.е. по отношению к панели. Возможно я и ошибаюсь.)))
 
booratinoДата: Пятница, 07.11.2014, 13:37 | Сообщение # 5
Рядовой
Группа: Пользователи
Сообщений: 4
Репутация: 0
Статус: Offline
А как получить список всех разрешений, которые камера поддерживает?

StreamConfig.QueryInterface(ISpecifyPropertyPages, PropertyPages);
PropertyPages.GetPages(Pages);

подозреваю, что в Pages это можно найти. Но pElems это array[0..65535] of TGUID. и что с ним делать уже не могу догадаться.  wacko

Добавлено (07.11.2014, 13:37)
---------------------------------------------

Код
//скрываем окно  
FVideoWindow.put_Visible(False);  
//Задаем размеры окна во всю панель  
FVideoWindow.SetWindowPosition(0,0,panel1.Width,panel1.Height);  
//показываем окно  
FVideoWindow.put_Visible(TRUE);
 
да, если сперва скрыть окно, и только потом менять, то меняется. smile

Но это еще не все! У меня 

OleCreatePropertyFrame(Handle, 0, 0,
                                 PWideChar(ListVI.Items.Strings[cameraptr]),
                                 1, @StreamConfig, Pages.cElems, Pages.pElems,
                                 0, 0, nil );

меняет параметры только один раз. при последующих нажатиях на кнопку OK получаю сообщение "данный формат не доступен".

при этом если просто каждый раз пересоздавать граф, и вот в этом месте

Код
// Создаю фильтр захвата из камеры
varray[cameraptr].BindToObject(nil, nil, IID_IBaseFilter, FVideoCaptureFilter);

if nadoSetWH then {ставим нужное разрешение} SetVideoParams(FCaptureGraphBuilder, PIN_CATEGORY_CAPTURE, FVideoCaptureFilter,kinow,kinoh);

//добавляем устройство в граф фильтров
FGraphBuilder.AddFilter(FVideoCaptureFilter, 'VideoCaptureFilter');


устанавливать разрешение, то это можно делать любое к-во раз.

так что я вижу самое простое решение, это получить список всех возможных разрешений камеры, самостоятельно их предлагать пользователю и не связываться с косячной OleCreatePropertyFrame.

А как получить список разрешений? help


Сообщение отредактировал booratino - Пятница, 07.11.2014, 13:19
 
xaramamburuДата: Пятница, 07.11.2014, 15:50 | Сообщение # 6
Полковник
Группа: Администраторы
Сообщений: 240
Репутация: 26
Статус: Offline
booratino
Цитата
А как получить список разрешений?

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

Код
procedure TForm1.Button3Click(Sender: TObject);
//получение всех видео разрешений Web-камеры
var
     StreamConfig: IAMStreamConfig;
     capCount,CapSize: integer;
     pmt: PAMMEDIATYPE;
     scc: VIDEO_STREAM_CONFIG_CAPS;
     W,H: Integer;
     i: Integer;
        
Begin
     // Если отсутствует интерфейс работы с видео, то завершаем работу
     if FVideoCaptureFilter = NIL then EXIT;
     // Останавливаем работу графа
     FMediaControl.Stop;
     try
       // Ищем интерфейс управления форматом данных выходного потока
       // Если интерфейс найден, то ...
       if SUCCEEDED(FCaptureGraphBuilder.FindInterface(@PIN_CATEGORY_CAPTURE,
         @MEDIATYPE_Video, FVideoCaptureFilter, IID_IAMStreamConfig, StreamConfig)) then
      // получаем количество форматов
          StreamConfig.GetNumberOfCapabilities(CapCount,CapSize);
      for i := 0 to CapCount-1 do
       begin
               //заполняет структуры  AM_MEDIA_TYPE и VIDEO_STREAM_CONFIG_CAPS
               StreamConfig.GetStreamCaps(i,pmt,scc);
               W := scc.InputSize.cx;
               H := scc.InputSize.cy;
               ShowMessage('[' + IntToStr(w) + 'x' + IntToStr(h) + ']');
        end;
           // Освобождаем память
           StreamConfig := NIL;
     finally
       // Восстанавливаем работу графа
       FMediaControl.Run;
     end;
end;
smile
 
booratinoДата: Суббота, 08.11.2014, 02:36 | Сообщение # 7
Рядовой
Группа: Пользователи
Сообщений: 4
Репутация: 0
Статус: Offline
круто, я не нашел.  shy

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

Добавлено (08.11.2014, 02:36)
---------------------------------------------
а два круга двойных повторений, это, возможно, из-за сжатия. моя камера умеет mjpeg и еще что-то... потому и, вероятно.

 
xaramamburuДата: Суббота, 08.11.2014, 19:38 | Сообщение # 8
Полковник
Группа: Администраторы
Сообщений: 240
Репутация: 26
Статус: Offline
booratino
Цитата
а два круга двойных повторений, это, возможно, из-за сжатия. моя камера умеет mjpeg и еще что-то... потому и, вероятно.
Я тоже так думаю. Моя камера на ноутбуке поддерживает два формата RGB24 и YUY2. Поэтому и два списка разрешений.
 
Форум » Delphi » DirectShow и Delphi. » изменение разрешения камеры
  • Страница 1 из 1
  • 1
Поиск:


Copyright MyCorp © 2024Конструктор сайтов - uCoz