Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > Мультимедиа в Delphi
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 18.04.2016, 07:50   #1
BLACK_RAIN
Форумчанин
 
Регистрация: 13.02.2012
Сообщений: 867
По умолчанию изменить парент панели с видео

Здравствуйте.
Строю минимальный граф для воспроизведения видео с выводом на Panel2:
Код:
function BuildGraph3(Player: TMyPlayer; gb_mode: TGraphBuildingMode): HRESULT;
const
  nl = #13#10;
var
  tpf : Double;
  errorcodetext : string;
begin
  Result := CoCreateInstance(CLSID_FilterGraph, nil, CLSCTX_INPROC_SERVER ,
                           IID_IGraphBuilder, Player.pGraphBuilder);
      case Result of
        S_OK: errorcodetext :='s_ok';
        REGDB_E_CLASSNOTREG:
        ErrorCodeText := 'REGDB_E_CLASSNOTREG';
        CLASS_E_NOAGGREGATION:
        ErrorCodeText := 'CLASS_E_NOAGGREGATION';
        E_NOINTERFACE:
        ErrorCodeText := 'E_NOINTERFACE';
        E_POINTER:
        ErrorCodeText := 'E_POINTER';
      end;
//   Form1.lb1.Items.Add('create filter graph: '+errorcodetext);
  Result := CoCreateInstance(CLSID_CaptureGraphBuilder2, NIL, CLSCTX_INPROC_SERVER, IID_ICaptureGraphBuilder2,
                         Player.pCaptureGraphBuilder);
      case Result of
        S_OK: errorcodetext :='s_ok';
        REGDB_E_CLASSNOTREG:
        ErrorCodeText := 'REGDB_E_CLASSNOTREG';
        CLASS_E_NOAGGREGATION:
        ErrorCodeText := 'CLASS_E_NOAGGREGATION';
        E_NOINTERFACE:
        ErrorCodeText := 'E_NOINTERFACE';
        E_POINTER:
        ErrorCodeText := 'E_POINTER';
      end;
//   Form1.lb1.Items.Add('capture graph builder: '+errorcodetext);
Player.pCaptureGraphBuilder.SetFiltergraph(Player.pGraphBuilder);
    Result := Player.pGraphBuilder.AddSourceFilter(StringToOleStr(Player.FileName),'source',player.fsource);
            case Result of
              S_OK: errorcodetext :='S_OK';
              E_NOINTERFACE: ErrorCodeText := 'E_NOINTERFACE';
              E_OUTOFMEMORY: ErrorCodeText := 'E_OUTOFMEMORY';
              E_POINTER: ErrorCodeText := 'E_POINTER';
              VFW_E_CANNOT_LOAD_SOURCE_FILTER:
              errorcodetext := 'VFW_E_CANNOT_LOAD_SOURCE_FILTER';
              VFW_E_NOT_FOUND: ErrorCodeText := 'VFW_E_NOT_FOUND';
              VFW_E_UNKNOWN_FILE_TYPE: ErrorCodeText := 'VFW_E_UNKNOWN_FILE_TYPE';
            end;
//     Form1.lb1.Items.Add('source: '+errorcodetext);
  Result :=   coCreateInstance(CLSID_VideoRenderer, nil,
                                   CLSCTX_INPROC, IID_IBaseFilter, player.fVideoRenderer);
      case Result of
        REGDB_E_CLASSNOTREG:
        ErrorCodeText := 'REGDB_E_CLASSNOTREG';
        CLASS_E_NOAGGREGATION:
        ErrorCodeText := 'CLASS_E_NOAGGREGATION';
        E_NOINTERFACE:
        ErrorCodeText := 'E_NOINTERFACE';
        E_POINTER:
        ErrorCodeText := 'E_POINTER';
      end;
//  Form1.lb1.Items.Add('renderer: '+ errorcodetext);
  Player.pGraphBuilder.AddFilter(Player.fVideoRenderer,'renderer');
  Result := CoCreateInstance(CLSID_FfdshowVideoDecoder,nil,CLSCTX_INPROC,
                               IID_IBaseFilter,player.fVideoDecoder);
      case Result of
        S_OK: errorcodetext :='s_ok';
        REGDB_E_CLASSNOTREG:
        ErrorCodeText := 'REGDB_E_CLASSNOTREG';
        CLASS_E_NOAGGREGATION:
        ErrorCodeText := 'CLASS_E_NOAGGREGATION';
        E_NOINTERFACE:
        ErrorCodeText := 'E_NOINTERFACE';
        E_POINTER:
        ErrorCodeText := 'E_POINTER';
      end;
//   Form1.lb1.Items.Add('decoder: '+errorcodetext);
   if Result<>0 then
   begin
     Player.Clear;
     Exit;
   end;
 Player.pGraphBuilder.AddFilter(Player.fVideoDecoder,'DECODER');

  Result :=     player.pCaptureGraphBuilder.RenderStream(nil,@mediatype_video,
                                   Player.fSource,Player.fVideoDecoder,player.fVideoRenderer);
    case Result of
      S_OK:
      ErrorCodeText := 'S_OK';
      VFW_S_NOPREVIEWPIN:
      ErrorCodeText := 'VFW_S_NOPREVIEWPIN';
      E_FAIL:
      ErrorCodeText := 'E_FAIL';
      E_INVALIDARG:
      ErrorCodeText := 'E_INVALIDARG';
      E_POINTER:
      ErrorCodeText := 'E_POINTER';
      VFW_E_NOT_IN_GRAPH:
      ErrorCodeText := 'VFW_E_NOT_IN_GRAPH';
      else
      ErrorCodeText := IntToStr(Result);
    end;
//   Form1.lb1.Items.Add('renderstream: '+ errorcodetext);
   if Result<>0 then
   begin
     Player.Clear;
     Exit;
   end;
        Player.pGraphBuilder.QueryInterface(IID_IBasicVideo,Player.pBasicVideo);
        Player.pGraphBuilder.QueryInterface(IID_IMediaControl,Player.pMediaControl);
        Player.pGraphBuilder.QueryInterface(IID_IMediaPosition,Player.pMediaPosition);
        Player.pGraphBuilder.QueryInterface(IID_IVideoWindow,Player.pVideoWindow);

//   Form1.lb1.Items.Add('ok1');

  if Assigned(player.pBasicVideo) then
  begin
  player.pBasicVideo.GetVideoSize(Player.MediaInfo.VideoWidth,Player.MediaInfo.VideoHeight);
  player.pBasicVideo.get_BitRate(Player.MediaInfo.VideoBitrate);
  player.pBasicVideo.get_AvgTimePerFrame(tpf);
  if tpf > 0 then
  Player.MediaInfo.VideoFPS := 1/tpf else
  Player.MediaInfo.VideoFPS := 0;
  end else
  begin
    Player.MediaInfo.VideoWidth := 0;
    Player.MediaInfo.VideoHeight := 0;
    Player.MediaInfo.VideoBitrate := 0;
    Player.MediaInfo.VideoFPS := 0;
    Player.MediaInfo.CurrentPositonFrame := 0;
  end;

//   Form1.lb1.Items.Add('ok2');

      Result := player.pMediaPosition.get_Duration(player.MediaInfo.TrackDuration);
  case Result of
    E_NOTIMPL:
    MessageBox(0,PChar('E_NOTIMPL'),'',MB_ICONERROR);
    E_POINTER:
    MessageBox(0,PChar('E_POINTER'),'',MB_ICONERROR);
  end;
  if Player.MediaInfo.TrackDuration>0 then
  begin
    if Player.MediaInfo.VideoFPS > 0 then
      Player.MediaInfo.VideoFramesCount := Round(Player.MediaInfo.TrackDuration * Player.MediaInfo.VideoFPS) else
      Player.MediaInfo.VideoFramesCount := 0;
    player.MediaInfo.TrackLength := Player.MediaInfo.TrackDuration / (3600*24);
    player.MediaInfo.TrackDurationText := FormatDateTime('hh:mm:ss',player.MediaInfo.TrackLength);
  end else
  begin
    MessageBox(0,PChar('Невозможно определить продолжительность видео-потока!'+nl+
                           'Некоторые функции недоступны!'),PChar('Ошибка!'),MB_ICONWARNING);
    Player.MediaInfo.TrackDuration := 0;
    player.MediaInfo.TrackLength := 0;
    Player.MediaInfo.VideoFramesCount := 0;
    Player.MediaInfo.TrackDurationText := '00:00:00';
  end;

      if (player.pVideoWindow<>nil) then
      begin
   player.pVideoWindow.Put_Owner(Form2.Panel2.Handle);
   player.pVideoWindow.Put_WindowStyle(WS_CHILD OR WS_CLIPSIBLINGS);
   player.pVideoWindow.put_MessageDrain(Form2.Panel2.handle);

   player.pVideoWindow.SetWindowPosition(0,0,Form2.Panel2.Width,Form2.Panel2.Height);
         end;
  Result := S_OK;
end;
В процессе воспроизведения нужно изменить парент панели. После смены парента, вывод видео пропадает. Если перестроить граф, то всё норм.
Как изменить парент панели и не потерять вывод видео, не перестраивая граф?
BLACK_RAIN вне форума Ответить с цитированием
Старый 18.04.2016, 09:59   #2
beegl
instagram
Участник клуба
 
Аватар для beegl
 
Регистрация: 24.05.2008
Сообщений: 1,453
По умолчанию

free плеер 3nity Media Player - можно модифицировать

Поиск в этой теме
beegl вне форума Ответить с цитированием
Старый 18.04.2016, 11:26   #3
BLACK_RAIN
Форумчанин
 
Регистрация: 13.02.2012
Сообщений: 867
По умолчанию

Цитата:
Сообщение от beegl Посмотреть сообщение
free плеер 3nity Media Player - можно модифицировать

Поиск в этой теме
Компоненты TMS на Delphi 2007 нормально не ставятся. И я сомневаюсь, что в этом плеере есть решение представленной проблемы.
BLACK_RAIN вне форума Ответить с цитированием
Старый 18.04.2016, 15:39   #4
Pavia
Лис
Старожил
 
Аватар для Pavia
 
Регистрация: 18.09.2015
Сообщений: 2,409
По умолчанию

Никак. Просто при смене вы уничтожаете само понятие графического объекта панели и его DC(Handle). А потом воскрешаете из небытия. Т.е создаётся по новой. Разумеется директ-х не знает куда выводить и что делать. Поэтому аварийно и останавливает граф.

Так что вам выводить надо не на панель. А на какой либо оверлей.
А зачем менять "предка" панели?
Хорошо поставленный вопрос это уже половина ответа. | Каков вопрос, таков ответ.
У дзен программиста программа делает то что он хотел, а не то что он написал .

Последний раз редактировалось Pavia; 18.04.2016 в 15:44.
Pavia вне форума Ответить с цитированием
Старый 18.04.2016, 15:58   #5
BLACK_RAIN
Форумчанин
 
Регистрация: 13.02.2012
Сообщений: 867
По умолчанию

Цитата:
Сообщение от Pavia Посмотреть сообщение
А зачем менять "предка" панели?
Хочу сделать функцию "картинка в картинкe"
BLACK_RAIN вне форума Ответить с цитированием
Старый 18.04.2016, 16:18   #6
Pavia
Лис
Старожил
 
Аватар для Pavia
 
Регистрация: 18.09.2015
Сообщений: 2,409
По умолчанию

Тогда вам надо остановить граф на паузе. Залочить его. Перестроить. Разлочить, а после продолжить воспроизведение.
https://msdn.microsoft.com/ru-ru/lib...(v=vs.85).aspx

Или захватывать картинку в методе захвата и выводить поверх.
Хорошо поставленный вопрос это уже половина ответа. | Каков вопрос, таков ответ.
У дзен программиста программа делает то что он хотел, а не то что он написал .
Pavia вне форума Ответить с цитированием
Старый 18.04.2016, 16:27   #7
BLACK_RAIN
Форумчанин
 
Регистрация: 13.02.2012
Сообщений: 867
По умолчанию

Цитата:
Сообщение от Pavia Посмотреть сообщение
Тогда вам надо остановить граф на паузе. Залочить его. Перестроить. Разлочить, а после продолжить воспроизведение.
Я знаю, но это слишком медленно. Хотелось бы побыстрее. Но накрайняк, так тоже сойдёт.
Цитата:
Сообщение от Pavia Посмотреть сообщение
Или захватывать картинку в методе захвата и выводить поверх.
Что за метод захвата?
BLACK_RAIN вне форума Ответить с цитированием
Старый 18.04.2016, 19:57   #8
kutani
Форумчанин
 
Регистрация: 23.01.2016
Сообщений: 608
По умолчанию

Для захвата картинки есть родной интерфейс ISampleGrabber, добавьте его при построении графа, работает он realtime http://www.programmersforum.ru/showthread.php?t=228875, для вывода же картинки поверх видео есть интерфейс IVMRMixerBitmap http://www.programmersforum.ru/showthread.php?t=68748. Он тоже работает реалтайм )
kutani вне форума Ответить с цитированием
Старый 19.04.2016, 07:18   #9
BLACK_RAIN
Форумчанин
 
Регистрация: 13.02.2012
Сообщений: 867
По умолчанию

А через регионы не проще будет?
BLACK_RAIN вне форума Ответить с цитированием
Старый 19.04.2016, 14:26   #10
kutani
Форумчанин
 
Регистрация: 23.01.2016
Сообщений: 608
По умолчанию

Бред. Вы конечно можете вывести на отдельную форму видеопоток, сделать ее поверх второй всегда, но это костыль. Да и захват вы этим из видеопотока не сделаете.

И еще под вопросом нужен ли этот захват вообще, картинка в картинке можно понимать по разному: вывод рендера видеопотока поверх другого рендера видеопотока, отрисовка битовой матрицы поверх рендера видеопотока, рендеринг видеопотока поверх битовой матрицы.
kutani вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
улучшить видео/фото лица преступника с камеры видео наблюдения, срочно! Фандорин Помощь студентам 1 28.01.2014 10:28
изменить цвет панели в компоненте TFire beegl Компоненты Delphi 0 02.01.2013 20:25
Изменить дизайн кнопки на панели инструментов Microsoft Excel 2007 GARY_X Microsoft Office Excel 1 16.01.2011 23:43
Как изменить размер Видео PilGrim Компоненты Delphi 1 19.11.2007 23:03