Имя:
Пароль:
-- ИЛИ --
Войти, используя:

Форум   Общая тематика и компьютеры   Программирование

Видео окно Тв-тюнера

 
Пост #54248 от 15 июня 2008, 22:12 

Rainstuff

Есть 2 проблемы:
Не могу понять - почему не работает функция pVideoWindow.put_FullScreenMode(longbool(true)) интерфейса IVideoWindow? Она просто не работает - ничего не менятся, ошибок не появляется. Остальные функции этого интерфейса работают нормально (put_Owner, put_WindowStyle, put_Visible).

И ещё вопрос - как сделать так, чтобы перетаскивать видеоокно за любую точку, а не за Caption?
У видеоокна могу вытащить handle. Может как-то можно перехватить сообщения этого окна?
Отправить личное сообщениеПрофиль пользователяКонфигурация пользователяРоссия
Н.Новгород
Постов: 30
Нарушений: Нет
Пост #54267 от 16 июня 2008, 23:58 

Rainstuff

Вобщем, пока нарыл вот что:
1) FullScreen
Искусственно создаём его так:
SetWindowPos(Form1.Handle,HWND_TOP, -4 , -4 , GetSystemMetrics( SM_CXSCREEN )+8, GetSystemMetrics( SM_CYSCREEN )+8,0);

т.е. растягиваем наше окошко и рамки окна получаются за пределами видимости. Окно есессно StayOnTop.

2) Обработчик сообщений видеоокна.

Перетаскиваем видеоокно за любую точку изображения, а не только за Caption:


// глобальные переменные
var
  Form1: TForm1;
  hMovie:HWND; // handle видеоокна
  m_RectDlg:TRect;
  m_bMoveWindow:bool;
  Point,m_MouseInDlg: TPoint;
  OldWindowProc : Pointer; {Variable for the old windows proc}

//==========================
//  Этот кусок можно прописать, например, в  TForm1.FormCreate
//  Задаем Caption видеоокна:
  pVideoWindow.put_Caption('!*Das_Rainstuff_movie*!');

//  находим наше видеоокно (оно прикреплено к панели Panel1)
  hMovie:=FindWindowEx(Panel1.Handle,0,nil,PChar('!*Das_Rainstuff_movie*!'));
  if hMovie<>0 then begin
  //Устанавливаем новый обработчик окна, а старый запоминаем:
  OldWindowProc := Pointer(SetWindowLong(hnd,
                                         GWL_WNDPROC,
                                         LongInt(@NewWindowProc)));
  end;


//==========================
function NewWindowProc(WindowHandle : hWnd;
                       TheMessage   : LongInt;
                       ParamW       : LongInt;
                       ParamL       : LongInt) : LongInt stdcall;
begin

  if TheMessage=WM_LBUTTONDOWN then begin
    // выставим флажок - пошло перетаскивание
    m_bMoveWindow:= TRUE;
    // все сообщения от мыши - к нашему окну, независимо от координат
    // чтобы мышь не улетала с окна при быстром движении
     SetCapture(hMovie);
    // сохраняем координаты окна
    GetWindowRect(Form1.Handle,m_RectDlg);
    // сохраняем положение мышки внутри окна программы
    point.X:=LOWORD(ParamL);
    point.Y:=HIWORD(ParamL);
   
   // логики мало, но именно так работает верно:
    m_MouseInDlg.Y:=point.X;
    m_MouseInDlg.X:=point.Y;
  end;

  if TheMessage=WM_MOUSEMOVE then begin
if (m_bMoveWindow) // надо тащить
  then
    begin
    point.X:=HIWORD(ParamL);
    point.Y:=LOWORD(ParamL);
    // двигаем окно в соответствии с новыми координатами мыши
    SetWindowPos(Form1.Handle,HWND_TOP,
            Form1.Left +(point.y- m_MouseInDlg.y),
            Form1.Top  +(point.x- m_MouseInDlg.x),
            m_RectDlg.right - m_RectDlg.left,
            m_RectDlg.bottom - m_RectDlg.top,
            SWP_SHOWWINDOW);
    end;
  end;

  if TheMessage=WM_LBUTTONUP then begin
    // перетаскивание закончилось
    m_bMoveWindow:= FALSE;
    // "отпускаем" мышку
    ReleaseCapture();
  end;

 {Вызываем оригинальный обработчик}
  Result := CallWindowProc(OldWindowProc,
                           WindowHandle,
                           TheMessage,
                           ParamW,
                           ParamL);

end;

Видел извратные реализации с таймерами, подменой сообщений Windows, но такой способ, мне кажется, корректней и элегантней:)

Отредактировано: Rainstuff (17.06.2008-00:08, назад)
Отправить личное сообщениеПрофиль пользователяКонфигурация пользователяРоссия
Н.Новгород
Постов: 30
Нарушений: Нет
Пост #54359 от 22 июня 2008, 16:46 

Rainstuff

Ещё по поводу FullScreen- оказывается надо было так:
pVideoWindow.put_Owner(0);
pVideoWindow.put_FullScreenMode(longbool(-1));

добавлено спустя 15 минут

Столкнулся ещё с одной проблемой:
Aspect Ratio
На компе по-умолчанию в свойствах Renderer'а выставляется по умолчанию галочка напротив Maintain Aspect Ratio. Причём так интересно - у одного и того же Renderer'а на ноутбуке по умолчанию галочка стоит, а на компе - нет. На компе разрешение видеоокна тюнера 768x576 и растягивается на полное окно без чёрных полосок, даже если выставлено 4:3. А вот у тюнера на ноутбуке максимальное разрешение 720x576. Соответственно, на полный экран оно не растягивается и по краям чёрные полоски.
Это решается, если в свойствах Renderer'a убрать галку Maintain Aspect Ratio. Но после перезапуска моего приложения эта галка опять сбрасывается в "по умолчанию".

Вопрос:
Можно ли как-нибудь выставить Aspect Ratio или отменить его программным путём или в реестре?
Отправить личное сообщениеПрофиль пользователяКонфигурация пользователяРоссия
Н.Новгород
Постов: 30
Нарушений: Нет
Пост #54363 от 22 июня 2008, 17:34 

Vlafy

Rainstuff : Можно ли как-нибудь выставить Aspect Ratio
Конечно можно. У рендерера есть соответствующий интерфейс (см. SDK).
Отправить личное сообщениеПрофиль пользователяКонфигурация пользователяБлог пользователяWeb-сайт пользователяРоссия
Сосновый Бор
Постов: 6083
Нарушений: Нет
Пост #54364 от 22 июня 2008, 19:27 

Rainstuff

Вот есть, например, интерфейс IVMRAspectRatioControl, но никаких ссылок на него в реестре я не нашёл... Соотесно он и не пашет. Пробовал через IAMStreamConfig, но там просто разрешение удалось задать, а не соотношения сторон. Пробовал через IVMRWindowlessControl::SetAspectRatioMode , но там нужно задать VMRMode_Windowless режим, а выставить не получается - вылетает с ошибкой.
Не подскажешь, через какой интерфейс точно задаётся?
или может до этого чекбокса можно через свойства программно добраться?
Отправить личное сообщениеПрофиль пользователяКонфигурация пользователяРоссия
Н.Новгород
Постов: 30
Нарушений: Нет
Пост #54366 от 22 июня 2008, 21:09 

Vlafy

Rainstuff : IVMRAspectRatioControl, но никаких ссылок на него в реестре я не нашёл... Соотесно он и не пашет
Ничего не понял... При чём тут реестр? Я делал так:

IVMRAspectRatioControl	*pVMRRC = NULL;
IBaseFilter *pVMR = NULL;

hr=_CreateFilter(CLSID_VideoMixingRenderer,&pVMR);
pVMR->QueryInterface(IID_IVMRAspectRatioControl, (void**)&pVMRRC);
pVMRRC->SetAspectRatioMode(VMR_ARMODE_LETTER_BOX);

И всё работает.
Отправить личное сообщениеПрофиль пользователяКонфигурация пользователяБлог пользователяWeb-сайт пользователяРоссия
Сосновый Бор
Постов: 6083
Нарушений: Нет
Пост #54368 от 22 июня 2008, 22:21 

Rainstuff

У меня после функции hr:=pVMRRC.SetAspectRatioMode(VMR_ARMODE_LETTER_BOX); прога просто закрывается, причём без всяких ошибок.

Ты не мог бы написать здесь описание интерфейса IVMRAspectRatioControl с GUID'ом и описание VMR_ASPECT_RATIO_MODE может у меня с этим косяк...
Отправить личное сообщениеПрофиль пользователяКонфигурация пользователяРоссия
Н.Новгород
Постов: 30
Нарушений: Нет
Пост #54370 от 23 июня 2008, 01:33 

Vlafy

Rainstuff : описание интерфейса IVMRAspectRatioControl
Я пишу на С++, заголовочники из SDK - можете там посмотреть. Если надо, то могу, конечно, сюда продублировать.


Rainstuff :прога просто закрывается, причём без всяких ошибок
Только при работе с этим интерфейсом? А какой рендерер используется?
Отправить личное сообщениеПрофиль пользователяКонфигурация пользователяБлог пользователяWeb-сайт пользователяРоссия
Сосновый Бор
Постов: 6083
Нарушений: Нет
Пост #54371 от 23 июня 2008, 02:19 

Rainstuff

Я посмотрел , в SDK то же самое. А я на Delphi пишу...

Использую рендер по умолчанию - Video Render.
В системе есть ещё Video Mixing Render 9, но с ним запросить этот интерфейс не получается - пишет ошибку. Хотя, если не запрашивать - всё нормально работает.
Отправить личное сообщениеПрофиль пользователяКонфигурация пользователяРоссия
Н.Новгород
Постов: 30
Нарушений: Нет
Пост #54373 от 23 июня 2008, 10:34 

Vlafy

Rainstuff : Video Mixing Render 9, но с ним запросить этот интерфейс не получается - пишет ошибку
Конечно, у него другой интерфейс - IVMRAspectRatioControl9.

Rainstuff :А я на Delphi пишу
Соглашение вызова может не то...
Отправить личное сообщениеПрофиль пользователяКонфигурация пользователяБлог пользователяWeb-сайт пользователяРоссия
Сосновый Бор
Постов: 6083
Нарушений: Нет
Пост #54374 от 23 июня 2008, 12:16 

Rainstuff

Функцию SetAspectRatioMode я описывал как
TVMR_ASPECT_RATIO_MODE=(VMR_ARMODE_NONE,VMR_ARMODE_LETTER_BOX);
SetAspectRatioMode(dwmode: TVMR_ASPECT_RATIO_MODE):HRESULT

Если ставить как в SDK тип у dwmode - DWORD, то не воспринимается константа VMR_ARMODE_LETTER_BOX - не соответствие типов.
Если всё таки выставить DWORD и при передаче в функцию писать 0,1,2 ..... то то же самое.

А насчёт соглашения - это можно как-то проверить?
Отправить личное сообщениеПрофиль пользователяКонфигурация пользователяРоссия
Н.Новгород
Постов: 30
Нарушений: Нет
Пост #54380 от 23 июня 2008, 14:17 

Vlafy

Rainstuff,
Соглашение должно быть STDCALL - надо его вписать в определение функции. DWORD должен съедать в любом случае.
Отправить личное сообщениеПрофиль пользователяКонфигурация пользователяБлог пользователяWeb-сайт пользователяРоссия
Сосновый Бор
Постов: 6083
Нарушений: Нет
Пост #54385 от 23 июня 2008, 18:22 

Rainstuff

Ты был прав!!! выставил stdcall и всё запахало! Спасибо!
А Dword всё равно не съедает - оставил TVMR_ASPECT_RATIO_MODE.
Отправить личное сообщениеПрофиль пользователяКонфигурация пользователяРоссия
Н.Новгород
Постов: 30
Нарушений: Нет
Пост #54453 от 27 июня 2008, 17:19 

Rainstuff

Ещё такой вопрос - в свойствах Video Renderer'a есть кнопка SnapShot, по нажатию на которой картинка пишется в файл (по умолчанию в папку C:\Documents and Settings\<User>\Мои документы\Мои рисунки\VMRImageXXX.bmp).
У рендерера есть интерфейс для захвата картинок или нужно через ISampleGrabber, т.е. добавлять новый фильтр?

Отредактировано: Rainstuff (27.06.2008-17:36, назад)
Отправить личное сообщениеПрофиль пользователяКонфигурация пользователяРоссия
Н.Новгород
Постов: 30
Нарушений: Нет
Пост #54458 от 27 июня 2008, 23:26 

Vlafy

Rainstuff,
IBasicVideo::GetCurrentImage().
The GetCurrentImage method retrieves the current image waiting at the renderer.
Отправить личное сообщениеПрофиль пользователяКонфигурация пользователяБлог пользователяWeb-сайт пользователяРоссия
Сосновый Бор
Постов: 6083
Нарушений: Нет
Пост #54464 от 28 июня 2008, 13:24 

Rainstuff

Спасибо!
Если кому интересно, то нужно делать так:
Во-первых, правильно описываем функцию интерфейса IBaseVideo
(ни в одном Delphi-описании DShow не нашёл верного и из-за этого не работало!!!)

    function GetCurrentImage(var BufferSize: Longint; pDIBImage: Pointer):HResult; stdcall;

Сама функция снятия screenshot'а. Пишу на Delphi c использованием библиотеки KOL, но смысл, думаю будет понятен:

procedure TForm1.Button4Click(Sender: PObj);
var
hr:integer;
pGetIm:IBasicVideo;
Buff:longint;
pMC: IMediaControl;
BFH: TBITMAPFILEHEADER;
lpbf: array of byte;
Stream: PStream;
begin
//========
//Создаём новый поток:
Stream:=NewMemoryStream;

//Запрашиваем интерфейс для управления видеопотоком IMediaControl
hr := pFilterGraph.QueryInterface(IID_IMediaControl, pMC);
if (hr <> NOERROR) then raise Exception.Create(e_Abort,'Unable create instance of IMediaControl');

//Приостанвливаем видеопоток
pMC.Pause; // или pMC.Stop;

// Запрашиваем интерфейс IBasicVideo у нашего рендерера:
hr:=pVideoRender.QueryInterface(IID_IBasicVideo, pGetIm);
if(hr <> NOERROR) then raise Exception.Create(e_Abort,'Unable create instance of IBasicVideo');
Buff:=0;

//Получаем размер изображения, для этого вторым параметром передаём nil;
hr:=pGetIm.GetCurrentImage(Buff,nil);
if(hr <> NOERROR) then raise Exception.Create(e_Abort,'Unable get size of image!');

//Задаём размер буфера и снова вызываем функцию
SetLength(lpbf,Buff);
hr:=pGetIm.GetCurrentImage(Buff,lpbf);
if(hr <> NOERROR) then raise Exception.Create(e_Abort,'Unable get Dib image!');

//Заполняем хедер нашего изображеия
      BFH.bfType      := $4d42; // BM   - тип изображения
      BFH.bfSize      := sizeof(TBITMAPFILEHEADER) + Buff; // размер изображения
      BFH.bfReserved1 := 0;
      BFH.bfReserved2 := 0;
      BFH.bfOffBits   := sizeof(TBITMAPFILEHEADER); // смещение, после  которого заканчивается хедер и начинается изображение

// Пишем это всё последовательно в наш поток, а потом в файл:
      Stream.Write(BFH, SizeOf(TBITMAPFILEHEADER)); 
      Stream.Write(lpbf[0],Buff);
      Stream.Position :=0;
      Stream.SaveToFile('c:\myshot.bmp',0,Buff+sizeof(TBITMAPFILEHEADER));

// Запускаем видеопоток:
pMC.Run;

//Пуск и остановка видеопотока, в принципе, не обязательны - GetCurrentImage отрабатывает и без них.
end;


Отредактировано: Rainstuff (28.06.2008-13:47, назад)
Отправить личное сообщениеПрофиль пользователяКонфигурация пользователяРоссия
Н.Новгород
Постов: 30
Нарушений: Нет
Пост #54465 от 28 июня 2008, 16:07 

Vlafy

Rainstuff : Пуск и остановка видеопотока, в принципе, не обязательны - GetCurrentImage отрабатывает и без них.
Я бы не ставил на паузу. Смысла нет.
Отправить личное сообщениеПрофиль пользователяКонфигурация пользователяБлог пользователяWeb-сайт пользователяРоссия
Сосновый Бор
Постов: 6083
Нарушений: Нет
Пост #54472 от 29 июня 2008, 02:25 

Rainstuff

Вобщем-то да, согласен:) Хотя, большой разницы нет.
Просто когда я форматы вывода выставлял - AspectRatio, разрешение... без остановки потока не хотело работать... Тут тоже на автомате поставил:)
Отправить личное сообщениеПрофиль пользователяКонфигурация пользователяРоссия
Н.Новгород
Постов: 30
Нарушений: Нет
Пост #55000 от 21 июля 2008, 11:50 

Alexkoles

Здравствуйте Ув. программисты!
У маня тюнер Aver 509. Моник LG227 16:10, естественно смотреть как 4:3 расягивается на полный экран не могу.
Перепробовал разных прог., в т.ч. родных разных версий - ни чем не смог сделать нормальный FullScreen, чтобы картинка вписывалась по горизонтали и выходила за пределы верхнего и нижнего краев.
Помогите каким-либо файликом или настройками, а то не волоку в программировании.
Спасибо все, кто ответит!
Отправить личное сообщениеПрофиль пользователяУкраина
Киев
Постов: 3
Нарушений: Нет
Пост #55043 от 23 июля 2008, 10:00 

Alexkoles

Всем Облатателям ТВ-тюнеров AverMedia!!!
Есть решение. У меня тюнер Aver 509UA RDS, AverTV было 6.2
Очень долго мучался проблемой Fullscreen на мониторе 16:10 - как-то не прикольно когда все растянуто.
Прошивал в Бихолдер разных версий, ТВ настроил - там много разных плагинов по растяжке экрана. Однако FM радио молчало и прога не закрывалась с пульта.
И вот случайно наткнулся на решение моей проблемы родным софтом!!!
Наконец-то вышел софт версии AverTV 6.3 с 17 дровами. Та м "настройке канала" можно подрегулировать картинку, чтобы в Fullscreen на 16:10 былоо как 4:3. С плюсов можно отметить передачу звука по шине PCI (наконец-то выкинул шнурок с тюнера во вход звуковой карты).
Ну и без минусов не обошлось: если выключить программу с пульта кнопкой Power и сразу включить пишет ошибку, поэтому нужно ждать секунд 10; ФМ каналы пришлось настраивать вручную - он мне ничего не нашел, и еще придумали какой-то магический растягиватель экрана - какое-то уродство.
Ну а так все Ок!
Качать всем: http-ссылка
Устанавливайте сначала драйвер (нижним пунктом удаляем все свой, верхним ставим новый) и ставим AverTV 6.3
Всем удачи! Можнообойтись и без BeholderTV!
Отправить личное сообщениеПрофиль пользователяУкраина
Киев
Постов: 3
Нарушений: Нет
Пост #55050 от 23 июля 2008, 10:57 

Vlafy

Alexkoles,
Дублировать сообщения запрещено. Читайте правила.
Пока предупреждение.
Отправить личное сообщениеПрофиль пользователяКонфигурация пользователяБлог пользователяWeb-сайт пользователяРоссия
Сосновый Бор
Постов: 6083
Нарушений: Нет
Пост #59350 от 17 января 2009, 20:08 

demm45

WndProc видео окна:

function VideoWndProc(hwnd:HWND;uMsg:UINT;wParam:WPARAM;
lParam:LPARAM):LRESULT;stdcall;
var
Cp:TPoint;
begin
case uMsg of
WM_NCHITTEST: Result:=HTTRANSPARENT;

...............................................

WM_MOUSEFIRST..WM_MOUSELAST:
begin
if uMsg=WM_LBUTTONDOWN then SetFocus(hwnd);
Cp:=Point($FFFF and LPARAM,LPARAM shr 16);
ClientToScreen(hFrameWnd,Cp);
with Cp do
PostMessage(hMainWnd,(uMsg and $F) or $A0,HTCAPTION,MakeLParam(X,Y));
Result:=0;
end;

...........................................

else
Result:=DefWindowProc(hwnd,uMsg,wParam,lParam);
end;
end;

hMainWnd - хэндл главного окна.
Отправить личное сообщениеПрофиль пользователя---
Постов: 8
Нарушений: Нет
Пост #59532 от 24 января 2009, 23:28 

Rainstuff

Да, прикольно - работает:)
Только пришлось убрать WM_NCHITTEST и заменить DefWindowProc на CallWindowProc


  OldWindowProc := Pointer(SetWindowLong(hnd,
                                         GWL_WNDPROC,
                                         LongInt(@NewWindowProc)));
// hnd - хэндл видеоокна.

function NewWindowProc(WindowHandle : hWnd;
                       TheMessage   : LongInt;
                       ParamW       : LongInt;
                       ParamL       : LongInt) : LongInt stdcall;
var
hMainWnd   : HRESULT ;
Cp:TPoint;
begin
  case TheMessage of
    WM_LBUTTONDOWN:
       begin
       // fullflag - признак разворачивания на полный экран.      
       if (not fullflag) then begin                   
          hMainWnd:= Form1.Form.GetWindowHandle;
          SetFocus(WindowHandle);
          Cp:=MakePoint($FFFF and PARAML,PARAML shr 16);
          ClientToScreen(hMainWnd,Cp);
          with Cp do
          PostMessage(hMainWnd,(TheMessage and $F) or $A0,HTCAPTION,MakeLParam(X,Y));
       end;
          Result:=0;
       end;
..................................

else
  Result := CallWindowProc(OldWindowProc,
                           WindowHandle,
                           TheMessage,
                           ParamW,
                           ParamL);

end;
Отправить личное сообщениеПрофиль пользователяКонфигурация пользователяРоссия
Н.Новгород
Постов: 30
Нарушений: Нет
Пост #59600 от 28 января 2009, 05:38 

Rainstuff

Кстати, может кто в курсе - как сделать так, чтобы видео было вместо wallpaper'а на рабочем столе.
Установкой parent'a тут явно не обойтись... Пытался копать DSPack, но пока безуспешно - там есть такая функция, но я пока не понял как она работает...
Может кто-нить делал нечто подобное без DSPack'а?
Если есть примерчик на Делфи или С++ , буду чрезвычайно благодарен:)
Отправить личное сообщениеПрофиль пользователяКонфигурация пользователяРоссия
Н.Новгород
Постов: 30
Нарушений: Нет
Если Вы зарегистрированы, то для отправки сообщений, пожалуйста, авторизуйтесь.
-- ИЛИ --
Войдите, используя: Facebook Twitter Yandex Вконтакте Mail.ru ...
Страница создана за 0.109 секунды
Copyright © 1999-2012 PcTuner.Ru · Design by Alex Dovby