⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 upushsource.pas

📁 delphi源码
💻 PAS
📖 第 1 页 / 共 4 页
字号:
    begin
      Result := E_INVALIDARG;
      Exit;
    end;

    // Have we run off the end of types?
    if (iPosition > 4) then
    begin
      Result := VFW_S_NO_MORE_ITEMS;
      Exit;
    end;

    MediaType.cbFormat := SizeOf(TVideoInfo);
    pvi := CoTaskMemAlloc(MediaType.cbFormat);
    if (pvi = nil) then
    begin
      Result := E_OUTOFMEMORY;
      Exit;
    end;

    // Initialize the VideoInfo structure before configuring its members
    ZeroMemory(pvi, MediaType.cbFormat);

    case iPosition of
      0:
        begin
          // Return our highest quality 32bit format

          // Since we use RGB888 (the default for 32 bit), there is
          // no reason to use BI_BITFIELDS to specify the RGB
          // masks. Also, not everything supports BI_BITFIELDS
          pvi.bmiHeader.biCompression := BI_RGB;
          pvi.bmiHeader.biBitCount := 32;
        end;
      1:
        begin
          // Return our 24bit format
          pvi.bmiHeader.biCompression := BI_RGB;
          pvi.bmiHeader.biBitCount := 24;
        end;
      2:
        begin
          // 16 bit per pixel RGB565

          // Place the RGB masks as the first 3 doublewords in the palette area
          for i := 0 to 2 do
            pvi.TrueColorInfo.dwBitMasks[i] := bits565[i];

          pvi.bmiHeader.biCompression := BI_BITFIELDS;
          pvi.bmiHeader.biBitCount := 16;
        end;
      3:
        begin
          // 16 bits per pixel RGB555

          // Place the RGB masks as the first 3 doublewords in the palette area
          for i := 0 to 2 do
            pvi.TrueColorInfo.dwBitMasks[i] := bits555[i];

          pvi.bmiHeader.biCompression := BI_BITFIELDS;
          pvi.bmiHeader.biBitCount := 16;
        end;
      4:
        begin
          // 8 bit palettised

          pvi.bmiHeader.biCompression := BI_RGB;
          pvi.bmiHeader.biBitCount := 8;
          pvi.bmiHeader.biClrUsed := iPALETTE_COLORS;
        end;
    end;

    // Adjust the parameters common to all formats
    pvi.bmiHeader.biSize := SizeOf(TBitmapInfoHeader);
    pvi.bmiHeader.biWidth := FImageWidth;
    pvi.bmiHeader.biHeight := FImageHeight;
    pvi.bmiHeader.biPlanes := 1;
    pvi.bmiHeader.biSizeImage := GetBitmapSize(@pvi.bmiHeader);
    pvi.bmiHeader.biClrImportant := 0;

    // Clear source and target rectangles
    // we want the whole image area rendered
    SetRectEmpty(pvi.rcSource);
    // no particular destination rectangle
    SetRectEmpty(pvi.rcTarget);

    MediaType.majortype := MEDIATYPE_Video;
    MediaType.formattype := FORMAT_VideoInfo;
    MediaType.bTemporalCompression := False;
    MediaType.bFixedSizeSamples := True;

    // Work out the GUID for the subtype from the header info.
    MediaType.subtype := GetBitmapSubtype(@pvi.bmiHeader);
    MediaType.pbFormat := pvi;
    MediaType.lSampleSize := pvi.bmiHeader.biSizeImage;

    Result := S_OK;

  finally
    FFilter.StateLock.UnLock;
  end;
end;

// We will accept 8, 16, 24 or 32 bit video formats, in any
// image size that gives room to bounce.
// Returns E_INVALIDARG if the mediatype is not acceptable

function TBCPushPinDesktop.CheckMediaType(MediaType: PAMMediaType): HResult;
var
  pvi: PVIDEOINFO;
  SubType: TGUID;

begin
  // we only output video
  if not (IsEqualGUID(MediaType.majortype, MEDIATYPE_Video)) or
    // in fixed size samples
  not (MediaType.bFixedSizeSamples) then
  begin
    Result := E_INVALIDARG;
    Exit;
  end;

  // Check for the subtypes we support
  SubType := MediaType.subtype;
  if IsEqualGUID(SubType, GUID_NULL) then
  begin
    Result := E_INVALIDARG;
    Exit;
  end;

  if not (
    IsEqualGUID(SubType, MEDIASUBTYPE_RGB8) or
    IsEqualGUID(SubType, MEDIASUBTYPE_RGB565) or
    IsEqualGUID(SubType, MEDIASUBTYPE_RGB555) or
    IsEqualGUID(SubType, MEDIASUBTYPE_RGB24) or
    IsEqualGUID(SubType, MEDIASUBTYPE_RGB32)
    ) then
  begin
    Result := E_INVALIDARG;
    Exit;
  end;

  // Get the format area of the media type
  pvi := MediaType.pbFormat;

  if (pvi = nil) then
  begin
    Result := E_INVALIDARG;
    Exit;
  end;

  // Check if the image width & height have changed
  if (pvi.bmiHeader.biWidth <> FImageWidth) or
    (abs(pvi.bmiHeader.biHeight) <> FImageHeight) then
    // If the image width/height is changed, fail CheckMediaType() to force
    // the renderer to resize the image.
  begin
    Result := E_INVALIDARG;
    Exit;
  end;

  // Don't accept formats with negative height, which would cause the desktop
  // image to be displayed upside down.
  if (pvi.bmiHeader.biHeight < 0) then
  begin
    Result := E_INVALIDARG;
    Exit;
  end;

  Result := S_OK; // This format is acceptable.
end;

//
// DecideBufferSize
//
// This will always be called after the format has been sucessfully
// negotiated. So we have a look at AMMediaType to see what size image we agreed.
// Then we can ask for buffers of the correct size to contain them.
//

function TBCPushPinDesktop.DecideBufferSize(Allocator: IMemAllocator;
  Properties: PAllocatorProperties): HRESULT;
var
  pvi: PVIDEOINFOHEADER;
  Actual: ALLOCATOR_PROPERTIES;

begin
  if (Allocator = nil) or (Properties = nil) then
  begin
    Result := E_POINTER;
    Exit;
  end;

  FFilter.StateLock.Lock;
  try
    pvi := AMMediaType.pbFormat;

    Properties.cBuffers := 1;
    Properties.cbBuffer := pvi.bmiHeader.biSizeImage;

    Assert(Properties.cbBuffer <> 0);

    // Ask the allocator to reserve us some sample memory. NOTE: the function
    // can succeed (return NOERROR) but still not have allocated the
    // memory that we requested, so we must check we got whatever we wanted.
    Result := Allocator.SetProperties(Properties^, Actual);
    if Failed(Result) then
      Exit;

    // Is this allocator unsuitable?
    if (Actual.cbBuffer < Properties.cbBuffer) then
    begin
      Result := E_FAIL;
      Exit;
    end;

    // Make sure that we have only 1 buffer
    Assert(Actual.cBuffers = 1);

    Result := S_OK;

  finally
    FFilter.StateLock.UnLock;
  end;
end;

//
// SetMediaType
//
// Called when a media type is agreed between filters
//

function TBCPushPinDesktop.SetMediaType(MediaType: PAMMediaType): HRESULT;
var
  pvi: PVIDEOINFOHEADER;

begin
  FFilter.StateLock.Lock;
  try
    // Pass the call up to my base class
    Result := inherited SetMediaType(MediaType);

    if Succeeded(Result) then
    begin
      pvi := AMMediaType.pbFormat;

      if (pvi = nil) then
      begin
        Result := E_UNEXPECTED;
        Exit;
      end;

      // 8-bit palettized,
      // RGB565, RGB555,
      // RGB24,
      // RGB32
      if pvi.bmiHeader.biBitCount in [8, 16, 24, 32] then
      begin
        // Save the current media type and bit depth
        FMediaType := MediaType^;
        FCurrentBitDepth := pvi.bmiHeader.biBitCount;
      end
      else
      begin
        // We should never agree any other media types
        Assert(False);
        Result := E_INVALIDARG;
      end;
    end;

  finally
    FFilter.StateLock.UnLock;
  end;
end;

// This is where we insert the DIB bits into the video stream.
// FillBuffer is called once for every sample in the stream.

function TBCPushPinDesktop.FillBuffer(Sample: IMediaSample): HResult;
var
  pData: PByte;
  cbData: Longint;
  hDib: HBitmap;
  pvih: PVIDEOINFOHEADER;
  Start, Stop: REFERENCE_TIME;

  function min(v1, v2: DWord): DWord;
  begin
    if v1 <= v2 then
      Result := v1
    else
      Result := v2;
  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);
    hDib := CopyScreenToBitmap(FScreenRect, pData, @pVih.bmiHeader);

    if (hDib <> 0) then
      DeleteObject(hDib);

    // 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);

    Result := S_OK;

  finally
    FSharedState.UnLock;
  end;
end;

function TBCPushPinDesktop.Notify(Filter: IBaseFilter; q: TQuality): HRESULT;
begin
  Result := E_FAIL;
end;

// --- TBCPushSourceBitmap ------------

constructor TBCPushSourceDesktop.Create(ObjName: string; Unk: IUnKnown;
  out hr: HRESULT);
begin
  inherited Create(ObjName, Unk, CLSID_PushSourceDesktop);

  // The pin magically adds itself to our pin array.
  FPin := TBCPushPinDesktop.Create(hr, Self);

  if (hr <> S_OK) then
    if (FPin = nil) then
      hr := E_OUTOFMEMORY;
end;

constructor TBCPushSourceDesktop.CreateFromFactory(Factory: TBCClassFactory;
  const Controller: IUnknown);
var
  hr: HRESULT;
begin
  Create(Factory.Name, Controller, hr);
end;

destructor TBCPushSourceDesktop.Destroy;
begin
  FreeAndNil(FPin);
  inherited;
end;

initialization
  // provide entries in the CFactoryTemplate array
  TBCClassFactory.CreateFilter(TBCPushSourceBitmap, PushBitmapName,
    CLSID_PushSourceBitmap, CLSID_LegacyAmFilterCategory,
    MERIT_DO_NOT_USE, 1, @sudOutputPinBitmap
    );
  TBCClassFactory.CreateFilter(TBCPushSourceBitmapSet, PushBitmapSetName,
    CLSID_PushSourceBitmapSet, CLSID_LegacyAmFilterCategory,
    MERIT_DO_NOT_USE, 1, @sudOutputPinBitmapSet
    );
  TBCClassFactory.CreateFilter(TBCPushSourceDesktop, PushDesktopName,
    CLSID_PushSourceDesktop, CLSID_LegacyAmFilterCategory,
    MERIT_DO_NOT_USE, 1, @sudOutputPinDesktop
    );
end.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -