BLACK_CRAFTER666 | Дата: Суббота, 22.10.2016, 10:10 | Сообщение # 1 |
Сержант
Группа: Пользователи
Сообщений: 31
Статус: Offline
| Здравствуйте. Строим граф фильтров.
Код Result := CoCreateInstance(CLSID_FilterGraph, nil, CLSCTX_INPROC_SERVER , IID_IGraphBuilder, _pl.pGraphBuilder); Result := CoCreateInstance(CLSID_CaptureGraphBuilder2, NIL, CLSCTX_INPROC_SERVER, IID_ICaptureGraphBuilder2, _pl.pCaptureGraphBuilder); _pl.pCaptureGraphBuilder.SetFiltergraph(_pl.pGraphBuilder);
Result := _pl.pGraphBuilder.AddSourceFilter(StringToOleStr(_pl.FileName),'source',_pl.fsource); Result := coCreateInstance(CLSID_VideoRenderer, nil, CLSCTX_INPROC_SERVER, IID_IBaseFilter, _pl.fVideoRenderer); _pl.pGraphBuilder.AddFilter(_pl.fVideoRenderer,'Video renderer' ) ; Result := CoCreateInstance(CLSID_FfdshowVideoDecoder,nil,CLSCTX_INPROC_SERVER, IID_IBaseFilter,_pl.fVideoDecoder); _pl.pGraphBuilder.AddFilter(_pl.fVideoDecoder,'video decoder' ) ;
Result := _pl.pCaptureGraphBuilder.RenderStream(nil,@MEDIATYPE_VIDEO, _pl.fSource,_pl.fVideoDecoder,_pl.fVideoRenderer); _pl.pGraphBuilder.QueryInterface(IID_IBasicVideo,_pl.pBasicVideo); _pl.pGraphBuilder.QueryInterface(IID_IVideoWindow,_pl.pVideoWindow); _pl.pGraphBuilder.QueryInterface(IID_IMediaControl,_pl.pMediaControl); _pl.pGraphBuilder.QueryInterface(IID_IMediaPosition,_pl.pMediaPosition); Result := _pl.pMediaPosition.get_Duration(_pl.MediaInfo.TrackDuration); if (_pl.pVideoWindow<>nil) then begin _pl.pVideoWindow.Put_Owner(_pl.Screen); _pl.pVideoWindow.Put_WindowStyle(WS_CHILD OR WS_CLIPSIBLINGS); _pl.pVideoWindow.put_MessageDrain(_pl.Screen); _pl.ResizeScreen; end;
Result := _pl.pMediaControl.Run;
При первом вызове pMediaControl.Run возвращает S_FALSE, но граф всё-равно запускается. При последующих вызовах pMediaControl.Pause / pMediaControl.Run всегда возвращается S_OK. Почему первый вызов неудачный, но граф при этом запускается?Добавлено (22.10.2016, 10:10) --------------------------------------------- Сегодня продолжил дописывать прогу и обнаружил, что ошибку выдаёт не только Run, но и Pause. Вот часть кода моей программы:
Код type TDirectShowBase = class(TObject) protected fPlayerState : TPlayerState;
procedure SetPlayerState(newstate : TPlayerState);
public pGraphBuilder : IGraphBuilder; pCaptureGraphBuilder : ICaptureGraphBuilder2; pFilterGraph : IFilterGraph; pVideoWindow : IVideoWindow; pMediaControl : IMediaControl; pMediaPosition : IMediaPosition; pMediaEvent : IMediaEventEx; pBasicVideo : IBasicVideo;
fAudioDecoder : IBaseFilter; pBasicAudio : IBasicAudio;
fSource : IBaseFilter; pSource : IFileSourceFilter; pGrabber : ISampleGrabber; fGrabber : IBaseFilter; fVideoDecoder : IBaseFilter; fAudioRenderer : IBaseFilter; fVideoRenderer : IBaseFilter;
FileName: string; MediaInfo : TMediaInfo;
constructor Create(x,y : SmallInt; ParentWnd, form : HWND); destructor Destroy; override; procedure Clear; virtual; function Play : HRESULT; virtual; function Pause : HRESULT; virtual; procedure Stop; virtual; property State: TPlayerState read fPlayerState write SetPlayerState; end;
type TVideoPlayer = class(TDirectShowBase) ... public ... function Play : HRESULT; override; function Pause : HRESULT; override; ... end;
implementation function TDirectShowBase.Play : HRESULT; begin Result := S_OK; if (state <> ps_null) and (state <> ps_play) then begin Result := pMediaControl.Run; state := PS_PLAY; end; end;
function TDirectShowBase.Pause : HRESULT; begin Result := S_OK; if (state <> ps_null) and (state <> ps_paused) then begin Result := pMediaControl.Pause; state := PS_PAUSED; end; end;
function TVideoPlayer.Play: HRESULT; begin inherited; if State <> PS_NULL then begin fButtonPlay.Icon := fIcons.PlayActive; fButtonPause.Icon := fIcons.PauseInactive; end; end;
function TVideoPlayer.Pause : HRESULT; begin inherited; if State <> PS_NULL then begin fButtonPlay.Icon := fIcons.PlayInactive; fButtonPause.Icon := fIcons.PauseActive; end; end;
case pl.State of PS_PLAY: begin res := Pl.Pause; if res <> S_OK then begin LogAdd(Pl, 'An unknown error occured while pausing the Graph!', IntToStr(res), ID_ICON_FAIL); // LogAdd(pl, 'Error code is '+ IntToStr(res),'', ID_ICON_FAIL); end; end; PS_PAUSED: begin res := Pl.Play; if res <> S_OK then1 begin LogAdd(Pl, 'An unknown error occured while starting the Graph!', IntToStr(res), ID_ICON_FAIL); // LogAdd(pl, 'Error code is '+ IntToStr(res),'', ID_ICON_FAIL); end; end; end;
Вот что в результате пишется в лог: http://i83.fastpic.ru/big/2016/1022/df/70d3bb35ae94058335059a18474cc4df.jpg
причем, ошибки могут быть разные. Мне попадались 1, 5 и 65665 (вроде бы). В MSDN сказано, что если эти методы возвращают ошибку значит что некоторые фильтры в графе могут быть не готовы. Но как же они могут быть не готовы, если всё работает? Просто выдается ошибка. Про коды ошибок ничего не сказано и в интернете они не гуглятся.
Сообщение отредактировал BLACK_CRAFTER666 - Среда, 19.10.2016, 11:02 |
|
| |