Problemy z odtwarzaniem Video z DelphiX

0

Witam,

Mam problem z idealnie płynnym odtwarzaniem plików mpeg, avi przy wykorzystaniu delphix.
Napisałem aplikację która odtwarza klipy video z utworzonej wczesniej playlisty, nakłada na to logo np stacji telewizyjnej itp. i tak w kółko przez cała dobę.

I niby wszystko jest ok. Ale występuje dośc niemiły efekt przy rysowaniu klatek.
Otóż wydaje mi się że delikatnie zrywa synchronizacje ale poziomą???
Wygląda to tak ze przy odtwarzaniu klipów a szczególnie z duza iloscia ruchu wystepuja
delikatne, widoczne /bardzo szybkie/ przesuniecia czesci obrazu, powiedzmy gorna polówka obrazu jest przez ulamek sekundy przesunieta o 1, 2 piksele w bok w stosunku do dolnej. Widać to jako zakłocenia
wyswietlania w postaci szybko pojawiajacej sie i znikajacej linii np na srodku ekranu ale niekoniecznie.
Gdy oglada sie to w domu jako odtwarzacz np filmów to nawet nie zwraca sie czesto na to uwagi,
ale bład jest. Jak go usunąć. Gdy odtwarzam filmy przy wykorzystaniu tylko filtrów directshow i standardowego okna ivideowindow to bład ten nie występuje. Filtry te jednak mi nie wystarczają.
Ja nakładam kilka logo jednoczesnie z rozna przezroczystoscia do tego scrolle itp.

Kod do odtwarzania video jest standardowy jaki czesto mozna znalezc w necie z przykładami do delphix.

Proszę o pomoc, może ktoś miał podobne problemy?

0

Już wiem w czym jest problem tylko jak to przeskoczyć.

Zupełnie niechcący zauważyłem, że gdy uruchomię wszystko w dxtimerze i ustawię WaitVBL w DXDraw to wszystko jest ok. Obraz jest idealny.
Ale gdy uruchomię odtwarzanie w oddzielnym wątku to wtedy występuje wyżej opisany problem.
Dlaczego?????

Proszę o pomoc.

0

Wczoraj wieczorem testowałem to wszystko na dwóch monitorach.
I o ile przy jednomonitorowym ustawieniu windowsow jest ok, to gdy włączy sie pracę dwumonitorową
to wystepuja błedy odtwarzania bez wzgledu na to czy jest wątek czy nawet bezprośrenio dxtimer.
Dlaczego???

0

Ramki nie są zsynchronizowane z odchylaniem pionowym. Spróbuj inny renderer obrazu - "Generic Renderer" albo "Vmr9". Ewentualnie dodaj filtr 'overlay'.

Efekty jakie opisujesz mam tylko na Vmr7.

0

Otwieram pliki kodem tak jak zamiesciłem poniżej. Otwierając w ten sposób w grafie nie mam ostatnich filtrów odpowiedzialnych za samo wyświetlenie klipu. Ani filtrów overlay ani zadnych vmr'ów. Nie potrzebuje ich tak jak wyżej napisałem. Filmy sa wyswietlane na komponencie DXDraw z DelphiX.
Testując wczoraj po jednej zmianie /zaznaczam poniżej/ udało mi się uzyskać idealny obraz ale tylko w systemie z jednym monitorem. W systemie dwumonitorowym nadal cos jest nie tak. Efekt rwania jest nadal. O czym jeszcze mogłem zapomnieć? Co jeszcze sprawdzić i ustawić?
Wlasciwosc WaitVBL w DXDraw ustawiona oczywiście na true.

Kod:

Media := nil;
AMStream := nil;
FSample:=nil;
FDDStream:=nil;
FPrimaryVidStream:=nil;
try
CoCreateinstance (CLSID_AMMULTIMEDIASTREAM,nil,CLSCTX_INPROC_SERVER,IID_IAMMULTIMEDIASTREAM,AMStream);
MultiByteToWideChar(CP_ACP,0,Pchar(FFilename),-1,wPath,Sizeof(wPAth) div sizeof(wPath[0]));
AMStream.Initialize(STREAMTYPE_READ,AMMSF_NOGRAPHTHREAD,nil);
AMStream.AddMediaStream(DXDraw.DDraw.IDraw,MSPID_PrimaryVideo,0,Media);
if DXSound <> nil then
begin
AMStream.AddMediaStream(DXSound.DSound.ISound,MSPID_PrimaryAudio,AMMSF_ADDDEFAULTRENDERER,IMediaStream(nil^));
end;
AMStream.OpenFile(wPAth,0);
FMMStream := AMStream;
FMMStream.GetMediaStream(MSPID_PrimaryVideo, FPrimaryVidStream);
FPrimaryVidStream.QueryInterface(IID_IDirectDrawMediaStream, FDDStream);
FDDStream.CreateSample(nil,PRect(nil)^,0,FSample);
FDXSurface := TDirectDrawSurface.Create(FDXDraw.DDraw);
FDXSurface.SystemMemory := true;
FSample.GetSurface(FSurface,FRect);
FDXSurface.IDDSurface := FSurface;
////
FDXSurface.DDraw.IDDraw.WaitForVerticalBlank(0,0); //po dodaniu tej linii jest dobrze w systemie jednomonitorowym
/////
except
FMMStream := nil;
end;
end;

0

Patrząc tak na obciążenie procesora podczas odtwarzania klipów wydaje mi się że gdy uruchamiam aplikację w systemie dwumonitorowym to oczekiwanie na synch. pionową czyli Waitvbl w dxdraw jest nieaktywne. Gdy odtwarzam w takim systemie to zmiana waitvbl w dxdraw z false na true /i na odwrót/ nie powoduje zmiany obciążenia procesora.
Ale gdy to samo odtwarzam w systemie jednomonitorowym to ustawienie opcji Waitvbl na true powoduje wzrost obciążenia procesora o kilka procent i wtedy odtwarzanie jest ok.

0

Chyba znalazłem pewien sposób. Jednak i tak potrzebuje pomocy kogoś bardziej doświadczonego. Wykorzystam do odtwarzania klipu wszystkie filtry directshow jakie będa potrzebne.
Klip źródłowy jednak bede chciał zbudować z pojedynczych klatek bmp. Znalazłem do tego
odpowiedni filtr w sieci. Nie moge sobie z nim jednak poradzic. Wydaje mi sie ze dobrze przetlumaczylem z c++ do delphi niewielka czesc kodu a jednak nie działa.
Filtr znajduje sie pod adresem: http://whorld.org/temp/BmpToAvi.html
Moje wypociny umieszczam poniżej.
Najpierw deklaracje, potem kilka linijek tworzenia filtrów w grafie i po uruchomieniu pokazuje mi ze nie dodano klatki do avi. Parametry klatki niby ustawia tzn nie pokazuje bledu ale jak potem otwieram graf to i tak filtr ma ustawiona wielkosc bmp 320x240

const
CLSID_BmpToAvi: TGUID = (D1:$ceab8f27;D2:$1f47;D3:$4e61;D4:($bb,$0a,$3f,$3a,$d3,$86,$c2,$b4));
IID_IBmpToAvi: TGUID = (D1:$85858221;D2:$3a64;D3:$4d0a;D4:($9a,$df,$2f,$89,$5d,$62,$4d,$a3));

type
TBMPTOAVI_PARMS = record
Width: integer; // frame width, in pixels
Height: integer; // frame height, in pixels
BitCount: integer; // number of bits per pixel
FrameRate: double; // frame rate, in frames per second
end;

IBmpToAvi = interface(IUnknown)
['{85858221-3A64-4d0a-9ADF-2F895D624DA3}']
function SetParms(var Parms: TBMPTOAVI_PARMS): HResult; stdcall;
function AddFrame(var Bitmap: HBITMAP): HResult; stdcall;
end;

procedure TForm1.Button2Click(Sender: TObject);
var
MyGraphBuilder: igraphbuilder;
source,Renderer: ibasefilter;
parms: TBMPTOAVI_PARMS;
BmpToAVI: IBmpToAVI;
hDIB: HBitmap;
SourceOut,SmartTeeIn,RendererIn,SmartTeePreview,Pin: IPin;
EnumPins: IEnumPins;

begin

CoInitialize(nil);

hrr := CoCreateInstance (CLSID_FilterGraph, nil, CLSCTX_INPROC, IID_IGraphBuilder, MyGraphBuilder);
if hrr <> S_OK then
begin
MessageDlg('Nie wykreowano mygraphbuilder.', mtInformation,[mbOk], 0);
Exit;
end;
hrr := CoCreateInstance(CLSID_BmpToAvi,nil,CLSCTX_INPROC_SERVER,IID_IBaseFilter,Source);
if hrr <> S_OK then
begin
MessageDlg('Nie wykreowano BmpToAvi.', mtInformation,[mbOk], 0);
Exit;
end;
MyGraphBuilder.AddFilter(Source,'Bmp To AVI');
hrr := CoCreateInstance(CLSID_VideoRenderer,nil,CLSCTX_INPROC_SERVER,IID_IBaseFilter,Renderer);
if hrr <> S_OK then
begin
MessageDlg('Nie wykreowano Renderer.', mtInformation,[mbOk], 0);
Exit;
end;
MyGraphBuilder.AddFilter(Renderer,'Video Renderer');
hrr := GetPin(Renderer,PINDIR_INPUT,RendererIn);
if hrr <> S_OK then
begin
MessageDlg('Nie znaleziono pinu RendererIn.', mtInformation,[mbOk], 0);
Exit;
end;
hrr := GetPin(Source,PINDIR_OUTPUT,SourceOut);
if hrr <> S_OK then
begin
MessageDlg('Nie znaleziono pinu SourceOut.', mtInformation,[mbOk], 0);
Exit;
end;
hrr := MyGraphBuilder.Connect(SourceOut,RendererIn);
if hrr <> S_OK then
begin
MessageDlg('Nie połączono pinu SourceOut i RendererIn.', mtInformation,[mbOk], 0);
Exit;
end;

hrr := Source.QueryInterface(IID_IBmpToAvi,BmpToAVI);
if hrr <> S_OK then
begin
MessageDlg('Nie wykonano QueryInterface na BmpToAvi.', mtInformation,[mbOk], 0);
Exit;
end;
parms.Width := 720;
parms.Height := 576;
parms.BitCount := 32;
parms.FrameRate := 25;
hrr := BmpToAVI.SetParms(parms);
if hrr <> S_OK then
begin
MessageDlg('Nie ustawiono parametrów BmpToAVI.', mtInformation,[mbOk], 0);
Exit;
end;

Image1.Picture.LoadFromFile('C:\Roboczy\Test.bmp');
hDIB := Image1.Picture.Bitmap.Handle;

hrr := BmpToAVI.AddFrame(hDIB);
if hrr <> S_OK then
begin
MessageDlg('Nie dodano ramki do BmpToAVI.', mtInformation,[mbOk], 0);
Exit;
end;

savegraphfile(mygraphbuilder,'G:\Video\tvplayer.grf');

CoUnInitialize;
end;

0

http://www.progdigy.com/modules.php?name=DSPack

Masz w tym pakiecie elegancką obsługę video "DSPACK234\Demos\DSVideoWinDowEx\PlayWin" i bitmapy też "Demos\D6-D7\VMR\VMRBitmap".

Polecam.

0

Ok, to juz dawno testowałem, mozna jednak dodac tylko jedna bitmapę na obraz video. Czyli jest to np. jedno logo z jedna przezroczystoscia. A co gdy drugie lub kolejne loga bede chciał wstawic z inna przezroczystoscia??? Czy moze sie myle co do tego przykładu?

1 użytkowników online, w tym zalogowanych: 0, gości: 1