Einzelnen Beitrag anzeigen

Arnulf

Registriert seit: 28. Okt 2004
Ort: Wien
271 Beiträge
 
#6

Re: DSPack PushSource filter und Audio mixer synchronisieren

  Alt 21. Jul 2008, 14:37
Ui - 600 - 3000 $ ist mir etwas zu viel .

Ich kann ja mal das Demo probieren.
Das Demo von DSPack - dürfte auch nich ganz sync sein, und scheinbar machen die nichts anderes als ich.
Das Problem bei mir ist, dass ich einen PushSource Filter habe und keinen Capture oder Preview.

Jedenfalls lasse ich mal Source Code sprechen - vielleicht fällt jemanden ja auf was kompletter unsinn ist.
Tut mir leid, dass der Code so ein Chaos ist, aber wenn man schon seit tagen alles mögliche herumprobiert, kommt sowas raus.

Main Project Filter Initialisation und Rendering:

Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
var CaptureFile: WideString;
    Writer: IFileSinkFilter;
    Multiplexer : IBaseFilter;
    SysDev: TSysDevEnum;
begin
     if FileExists('c:\test.avi') then deletefile('c:\test.avi');
     if InjectLibrary then
     begin

     //. todo : check for injected lib instead of sleep
     sleep (2000);
     memo1.Lines.Add('ok');

     SysDev:= TSysDevEnum.Create;
     //. todo - do not hardcode indexcategory
     SysDev.SelectIndexCategory(1);
     MemMapSelfCreated.BaseFilter.Moniker := SysDev.GetMoniker(SysDev.FilterIndexOfFriendlyName('Memory Map BitmapFilter'));
     memo1.Lines.Add(' using:' + SysDev.Filters[SysDev.FilterIndexOfFriendlyName('Memory Map BitmapFilter')].FriendlyName );

     if FilterGraph1.Active then FilterGraph1.Active := false;
     FilterGraph1.ClearGraph;
     FilterGraph1.Active:= True;
     FilterGraph1.GraphEdit := True;
     CaptureFile := 'c:\test.avi';
     MemMapSelfCreated.FilterGraph := FilterGraph1;
     //VideoWindow1.FilterGraph := FilterGraph1;
     with FilterGraph1 as ICaptureGraphBuilder2 do
     begin
          SetOutputFileName(MEDIASUBTYPE_Avi, PWideChar(CaptureFile), Multiplexer, writer);
          //ShowFilterPropertyPage(Self.Handle, Multiplexer as IBaseFilter, ppDefault);
          //RenderStream(nil, @MEDIATYPE_Video, MemMapSelfCreated as IBaseFilter,
          // {DivXCompressor as IBaseFilter} nil, VideoWindow1 as IBaseFilter);
          RenderStream(nil{@PIN_CATEGORY_CAPTURE}, @MEDIATYPE_Video, MemMapSelfCreated{MemMapSource} as IBaseFilter,
                  DivXCompressor as IBaseFilter, Multiplexer as IBaseFilter);
          //ShowFilterPropertyPage(Self.Handle, DivXCompressor as IBaseFilter, ppVFWCompConfig);
          RenderStream(nil{@PIN_CATEGORY_CAPTURE}, @MEDIATYPE_Audio, AudioSource as IBaseFilter,
                  Mp3Compressor as IBaseFilter, Multiplexer as IBaseFilter);
     end;
     with Multiplexer as IConfigAviMux do
     begin
          setmasterstream(1);
     end;

     with Multiplexer as IConfigInterleaving do
     begin
          put_Mode(INTERLEAVE_FULL);
     end;
     FilterGraph1.Play;
     end;

end;
Anmerkung:
DivXCompressor: hier habe ich divx, HuffYuV und Mjpeg ausprobiert - mit teilweise besseren und schlechteren ergebnissen.
Mjpeg scheint am bessten zu funktionieren.
HuffYuV spielt im video dann als slow motion??? - keine ahnung warum
DivX hat zu viele frame loss - dürfte zu langsam sein für live capture von einem PushSoure filter ( 800x600 24 bit bitmap mit 25 fps )
Mp3Compressor: hier habe ich sowol mpeg layer3 also auch keinen kompressor versucht ... macht nicht viel unterschied.
Der Filter Selbst:
Delphi-Quellcode:
function TBCPushPinDesktop.FillBuffer(Sample: IMediaSample): HResult;
var
  pData: PByte;
  cbData: Longint;
  pvih: PVIDEOINFOHEADER;
  Start, Stop: REFERENCE_TIME;

  function min(v1, v2: DWord): DWord;
  begin
    if v1 <= v2 then
      Result := v1
    else
      Result := v2;
  end;

function CopyMemToBitmap(pData : PByte;
    pHeader : PBitmapInfo) : boolean;
//var
    //FileHeader : BITMAPFILEHEADER;
begin
     Result := false;
    if not (FSpeicher = nil) then
    begin
         //copymemory(@FileHeader,FSpeicher,Sizeof(BITMAPFILEHEADER));
         copymemory(@pHeader.bmiHeader, Pointer(DWord(FSpeicher)+sizeOf(BITMAPFILEHEADER)), SizeOf(BITMAPINFOHEADER));
         copymemory(pData, Pointer(DWord(FSpeicher) + SizeOf(BITMAPFILEHEADER) + SizeOf(BITMAPINFOHEADER)),pHeader.bmiHeader.biSizeImage);
    Result := true;
    end;

end;


begin
  if (Sample = nil) then
  begin
    Result := E_POINTER;
    Exit;
  end;

  FSharedState.Lock;
  try
    // Access the sample's data buffer
    Sample.GetPointer(pData);
    cbData := Sample.GetSize;

    // Check that we're still using video
    Assert(IsEqualGUID(AMMediaType.formattype, FORMAT_VideoInfo));

    pvih := AMMediaType.pbFormat;

    // Copy the DIB bits over into our filter's output buffer.
     // Since sample size may be larger than the image size, bound the copy size.
    pVih.bmiHeader.biSizeImage := min(pVih.bmiHeader.biSizeImage, cbData);
    if (WaitForSingleObject(myMutex, 100) = WAIT_OBJECT_0) then
    begin
        CopyMemToBitmap(pData, @pVih.bmiHeader);
        Result := S_OK;
    end;// else Result := S_FALSE;
    ReleaseMutex(myMutex);
    Result := S_OK;

    // Set the timestamps that will govern playback frame rate.
    // If this file is getting written out as an AVI,
    // then you'll also need to configure the AVI Mux filter to
    // set the Average Time Per Frame for the AVI Header.
    // The current time is the sample's start
    Start := (FFrameNumber * FFrameLength);
    Stop := Start + FFrameLength;
    Sample.SetTime(@Start, @Stop);
    Inc(FFrameNumber);

    // Set TRUE on every sample for uncompressed frames
    Sample.SetSyncPoint(True);
  finally
    FSharedState.UnLock;
  end;
end;
Anmerkung:
Hier habe ich vor allem mit dem Mutex gespielt - timeout von 100 ms funktionert im video window sehr gut ( sollte niemals so lange warten müssen ).
Auch mit dem Result hab ich herumprobiert, ob das jemals false werden sollte weiß ich nicht, aber es macht keinen unterschied nach meiner erfahrung.
start/stop Time und SetSyncPoint sind aus dem originalen pushsource filter und dürfte so stimmen, aber sicher bin ich nicht.

lg
Arnulf
  Mit Zitat antworten Zitat