directshow的中文资料之建立一个捕捉程序

Directshow中的视频捕捉 本篇文档主要描述关于用Directshow进行视频开发的一些技术主要包括下面内容1关于视频捕捉(About Video Capture in Dshow) 2选择一个视频捕捉设备(Select capture device) 3预览视频(Previewing Video) 4如何捕捉视频流并保存到文件(Capture video to File) 5将设备从系统中移走时的事件通知(Device r 阅读详情

 

DirectShow 提供了用应用程序从适当的硬件中捕捉和预览音/视频的能力。数据源包括:VCR,camera,TV tuner,microphone,或其他的数据源。一个应用程序可以立刻显示捕捉的数据(预览),或是保存到一个文件中。

在这个例子中,ICaptureGraphBuilder 接口是处理捕捉工作的主要接口。你可以在你自己的捕捉程序中使用同样的方法和接口。在这里主要讨论ICaptureGraphBuilder 如何执行音/视频的捕捉。我们假设你已经熟悉了DirectShow的filter graph的体系和一般的capture filter graph的结构(可以参考DirectShow基础指南)。

ICaptureGraphBuilder 接口提供了一个filter graph builder对象,让你的应用程序在建立capture filter graph时,省去处理很多单调乏味的工作,集中精力于捕捉中。他提供的方法满足了基本的捕捉和预览功能的要求。

方法FindInterface ,在filter graph中查找一个于捕捉有关的详细的接口。使的你可以访问一个详细接口的功能,而不需要你去列举在filter graph中的pins 和 filters。
方法RenderStream ,连接源过滤器和渲染过滤器,选择添加一些中间的过滤器。
方法ControlStream ,独立的精确的控制graph的开始和结束帧。

既然是硬件捕捉,当然要和硬件打交道,接着介绍设备列举和捕捉接口。
通过ICreateDevEnum::CreateClassEnumerator方法列举捕捉系统中的设备。之后,实例化一个DirectShow的filter去使用这个设备。接着用ICaptureGraphBuilder::FindInterface去获得于捕捉相关的接口指针IAMDroppedFrames, IAMVideoCompression, IAMStreamConfig, and IAMVfwCaptureDialogs 。因为设备列举和捕捉接口比较长,放在这会打乱结构,所有专门写了一篇(参考设备列举和捕捉接口)。

NOTE:
1.这个示例是DirectShow自带的例子。你可以在DirectShow SDK的目录Sample/DS/Caputre看这个例子代码(AMCap.cpp)。这里只是他的一些片断代码。可以说是他的中文模块的说明。
2.AMCap例子中,把所有的接口指针和一些成员变量保存在一个全局结构gcap中了。
定义如下:
struct _capstuff {
    char szCaptureFile[_MAX_PATH];
    WORD wCapFileSize;  // size in Meg
    ICaptureGraphBuilder *pBuilder;
    IVideoWindow *pVW;
    IMediaEventEx *pME;
    IAMDroppedFrames *pDF;
    IAMVideoCompression *pVC;
    IAMVfwCaptureDialogs *pDlg;
    IAMStreamConfig *pASC;      // for audio cap
    IAMStreamConfig *pVSC;      // for video cap
    IBaseFilter *pRender;
    IBaseFilter *pVCap, *pACap;
    IGraphBuilder *pFg;
    IFileSinkFilter *pSink;
    IConfigAviMux *pConfigAviMux;
    int  iMasterStream;
    BOOL fCaptureGraphBuilt;
    BOOL fPreviewGraphBuilt;
    BOOL fCapturing;
    BOOL fPreviewing;
    BOOL fCapAudio;
    int  iVideoDevice;
    int  iAudioDevice;
    double FrameRate;
    BOOL fWantPreview;
    long lCapStartTime;
    long lCapStopTime;
    char achFriendlyName[120];
    BOOL fUseTimeLimit;
    DWORD dwTimeLimit;
} gcap;
当不在需要保存在gcap中的接口指针是,一定要释放这些接口指针,一般是在程序的析构函数中,或是在别的同等功能函数中。如下:
    if (gcap.pBuilder)
 gcap.pBuilder->Release();
    gcap.pBuilder = NULL;
    if (gcap.pSink)
 gcap.pSink->Release();
    gcap.pSink = NULL;
    if (gcap.pConfigAviMux)
 gcap.pConfigAviMux->Release();
    gcap.pConfigAviMux = NULL;
    if (gcap.pRender)
 gcap.pRender->Release();
    gcap.pRender = NULL;
    if (gcap.pVW)
 gcap.pVW->Release();
    gcap.pVW = NULL;
    if (gcap.pME)
 gcap.pME->Release();
    gcap.pME = NULL;
    if (gcap.pFg)
 gcap.pFg->Release();
    gcap.pFg = NULL;


设置文件名
使用普通的OpenFile dialog获得捕捉文件的信息。通过调用AllocCaptureFile 函数为捕捉文件分配空间。这一点是重要的,因为这是个巨大的空间。这样可以提高捕捉操作的速度。ICaptureGraphBuilder::AllocCapFile 执行实际的文件分配,IFileSinkFilter::SetFileName 指示file writer filter使用用户选择的文件名保存数据。ICaptureGraphBuilder::SetOutputFileName 把file writer filter加入filter graph(后面会介绍,他是ICaptureGraphBuilderd自代的)。

SetCaptureFile 和 AllocCaptureFile 函数如下:
/*
 * Put up a dialog to allow the user to select a capture file.
 */
BOOL SetCaptureFile(HWND hWnd)
{
    if (OpenFileDialog(hWnd, gcap.szCaptureFile, _MAX_PATH)) {
        OFSTRUCT os;

 // We have a capture file name

        /*
         * if this is a new file, then invite the user to
         * allocate some space
         */
        if (OpenFile(gcap.szCaptureFile, &os, OF_EXIST) == HFILE_ERROR) {

     // Bring up dialog, and set new file size
     BOOL f = AllocCaptureFile(hWnd);
     if (!f)
  return FALSE;
        }
    } else {
 return FALSE;
    }

    SetAppCaption(); // need a new app caption

    // Tell the file writer to use the new file name
    if (gcap.pSink) {
        WCHAR wach[_MAX_PATH];
        MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, gcap.szCaptureFile, -1,
       wach, _MAX_PATH);
        gcap.pSink->SetFileName(wach, NULL);
    }

    return TRUE;
}

// Preallocate the capture file
//
BOOL AllocCaptureFile(HWND hWnd)
{
// We'll get into an infinite loop in the dlg proc setting a value
    if (gcap.szCaptureFile[0] == 0)
 return FALSE;

    /*
     * show the allocate file space dialog to encourage
     * the user to pre-allocate space
     */
    if (DoDialog(hWnd, IDD_AllocCapFileSpace, AllocCapFileProc, 0)) {

 // Ensure repaint after dismissing dialog before
 // possibly lengthy operation
 UpdateWindow(ghwndApp);

        // User has hit OK. Alloc requested capture file space
 BOOL f = MakeBuilder();
 if (!f)
     return FALSE;
        WCHAR wach[_MAX_PATH];
        MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, gcap.szCaptureFile, -1,
       wach, _MAX_PATH);
        if (gcap.pBuilder->AllocCapFile(wach,
   gcap.wCapFileSize * 1024L * 1024L) != NOERROR) {
            MessageBoxA(ghwndApp, "Error",
    "Failed to pre-allocate capture file space",
                           MB_OK | MB_ICONEXCLAMATION);
     return FALSE;
        }
 return TRUE;
    } else {
 return FALSE;
    }
}

建立Graph Builder对象

AMCap的 MakeBuilder函数建立了一个capture graph builer对象,通过调用CoCreateInstance获得了ICaptureGraphBuilder 接口指针。AMCap把他存储到gcap结构的pBuilder中。
// Make a graph builder object we can use for capture graph building
//
BOOL MakeBuilder()
{
    // We have one already
    if (gcap.pBuilder)
 return TRUE;

    HRESULT hr = CoCreateInstance((REFCLSID)CLSID_CaptureGraphBuilder,
   NULL, CLSCTX_INPROC, (REFIID)IID_ICaptureGraphBuilder,
   (void **)&gcap.pBuilder);
    return (hr == NOERROR) ? TRUE : FALSE;
}


建立Graph的渲染部分,并告诉他写文件(用先前决定的文件)

这包括一个multiplexer filter 和 file writer。DirectShow 提供了一个AVI MUX(multiplexer)filter。
在这里ICaptureGraphBuilder::SetOutputFileName 是一个关键的方法。他把multiplexer 和 file writer添加到filter graph中,连接他们,并设置文件的名字。第一个参数MEDIASUBTYPE_Avi,指出capture graph builder 对象将插入一个AVI multiplexer filter,因此,file writer将以AVI文件格式记录捕捉的数据。第二个参数(wach)是文件名。最后的两个参数指出multiplexer filter (gcap.pRender) 和file writer filter (gcap.pSink),这两个是通过SetOutputFileName 函数初始化的。AMCap存储这些指针到全局结构gcap中。capture graph builder 对象建立了一个filter graph对象(IGraphBuilder),把这两个filter加入到filter graph中去。他告诉file writer使用指定的文件保存数据。下面的例子演示了如何调用SetOutputFileName。
//
// We need a rendering section that will write the capture file out in AVI
// file format
//

    WCHAR wach[_MAX_PATH];
    MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, gcap.szCaptureFile, -1, wach,
        _MAX_PATH);
    GUID guid = MEDIASUBTYPE_Avi;
    hr = gcap.pBuilder->SetOutputFileName(&guid, wach, &gcap.pRender,
        &gcap.pSink);
    if (hr != NOERROR) {
 ErrMsg("Error %x: Cannot set output file", hr);
 goto SetupCaptureFail;
    }


获得当前的Filter Graph

因为在调用SetOutputFileName中,capture graph builder 对象建立了一个filter graph,所有你必须把需要的filter加入同一个filter graph 中。通过ICaptureGraphBuilder::GetFiltergraph获得新建立的filter graph。返回的指针是参数gcap.pFg。
//
// The graph builder created a filter graph to do that.  Find out what it is,
// and put the video capture filter in the graph too.
//

    hr = gcap.pBuilder->GetFiltergraph(&gcap.pFg);
    if (hr != NOERROR) {
 ErrMsg("Error %x: Cannot get filtergraph", hr);
 goto SetupCaptureFail;
    }

 

添加音/视频过滤器到当前的Filter Graph
    hr = gcap.pFg->AddFilter(gcap.pVCap, NULL);
    if (hr != NOERROR) {
 ErrMsg("Error %x: Cannot add vidcap to filtergraph", hr);
 goto SetupPreviewFail;
    }

    hr = gcap.pFg->AddFilter(gcap.pACap, NULL);
 if (hr != NOERROR) {
     ErrMsg("Error %x: Cannot add audcap to filtergraph", hr);
     goto SetupCaptureFail;
 }


渲染视频捕捉过滤器的Capture Pin和音频捕捉的Capture Pin
ICaptureGraphBuilder::RenderStream 连接源过滤器的pin到渲染过滤器。pin的类别是可选的,capture pin (PIN_CATEGORY_CAPTURE) 或 preview pin (PIN_CATEGORY_PREVIEW)。下面的例子演示了连接video capture filter (gcap.pVCap) 的capture pin到渲染gcap.pRender中。
//
// Render the video capture and preview pins - we may not have preview, so
// don't worry if it doesn't work
//

    hr = gcap.pBuilder->RenderStream(&PIN_CATEGORY_CAPTURE, NULL, gcap.pVCap,
      NULL, gcap.pRender);
    // Error checking

再次ICaptureGraphBuilder::RenderStream 连接audio capture filter (gcap.pACap) 到渲染audio renderer 中。
//
// Render the audio capture pin?
//

    if (gcap.fCapAudio) {
 hr = gcap.pBuilder->RenderStream(&PIN_CATEGORY_CAPTURE, NULL,
     gcap.pACap, NULL, gcap.pRender);
    // Error checking

 

渲染Video Capture Filter的 Preview Pin
再次调用ICaptureGraphBuilder::RenderStream,从capture filter的preview pin到video renderer。代码如下:
    hr = gcap.pBuilder->RenderStream(&PIN_CATEGORY_PREVIEW, NULL, gcap.pVCap,
      NULL, NULL);


获得访问Video Preview Window的接口指针
缺省的,video preview window是一个独立的窗口。如果你想改变默认的行为,先调用 ICaptureGraphBuilder::FindInterface获得IVideoWindow 接口。第二个参数通过gcap.pVCap指定,描述video capture filter,第三个参数是想得到的接口(IVideoWindow),最后的是返回的接口。当你得到IVideoWindow接口后,你可以调用IVideoWindow的方法象put_Owner, put_WindowStyle, or SetWindowPosition 去获得video preview window的handle,设置窗口属性,或把他放到想要的位置。
// This will go through a possible decoder, find the video renderer it's
// connected to, and get the IVideoWindow interface on it
   hr = gcap.pBuilder->FindInterface(&PIN_CATEGORY_PREVIEW, gcap.pVCap,
     IID_IVideoWindow, (void **)&gcap.pVW);
    if (hr != NOERROR) {
 ErrMsg("This graph cannot preview");
    } else {
 RECT rc;
 gcap.pVW->put_Owner((long)ghwndApp);    // We own the window now
 gcap.pVW->put_WindowStyle(WS_CHILD);    // you are now a child
 // give the preview window all our space but where the status bar is
 GetClientRect(ghwndApp, &rc);
 cyBorder = GetSystemMetrics(SM_CYBORDER);
 cy = statusGetHeight() + cyBorder;
 rc.bottom -= cy;
 gcap.pVW->SetWindowPosition(0, 0, rc.right, rc.bottom); // be this big
 gcap.pVW->put_Visible(OATRUE);
    }

现在你已经建立完整的capture filter graph了,你可以预览音频,视频,或捕捉数据。


控制 Capture Filter Graph

因为通过ICaptureGraphBuilder接口构造的capture filter graph 只是一个简单的专门用途的filter graph,所有,控制他就象控制其他类型的filter graph一样。你可以使用IMediaControl interface的 Run, Pause, and Stop方法,你也可以使用CBaseFilter::Pause的方法。另外ICaptureGraphBuilder提供了ControlStream方法去控制capture filter graph的streams的开始和结束时间。ControlStream调用IAMStreamControl::StartAt 和 IAMStreamControl::StopAt控制filter graph的捕捉和预览的开始和结束的位置。
注意:不是所有的capture filter都可以,因为不是每一个capture filter都支持IAMStreamControl。

ICaptureGraphBuilder::ControlStream方法的第一个参数(pCategory)是一个输出pin类的GUID。这个变量通常是PIN_CATEGORY_CAPTURE 或 PIN_CATEGORY_PREVIEW。指定为NULL则控制所有的capture filter。
第二个参数在(pFilter)指出那个filter控制。NULL说明为控制所有的filter graph。
如果只是预览(防止捕捉)的话,可以调用ICaptureGraphBuilder::ControlStream,参数用capture pin类型,MAX_TIME作为开始时间(第三个参数,pstart)。再次调用该方法,参数用preview pin类型,NULL作为开始时间则立即开始预览。第四参数指出结束的时间(pstop),含义和第三个参数一样(NULL意味着立刻)。MAX_TIME在DirectShow中定义为最大的参考时间。在这里意味着忽略或取消指定的操作。
最后的参数,wStartCookie和wStopCookie分别是开始和结束的cookies(不知道该怎么翻译,因为我也不理解这个参数的含义)。
下面的代码设置立刻开始预览,但是忽略捕捉。
// Let the preview section run, but not the capture section
    // (There might not be a capture section)
    REFERENCE_TIME start = MAX_TIME, stop = MAX_TIME;
    // show us a preview first? but don't capture quite yet...
    hr = gcap.pBuilder->ControlStream(&PIN_CATEGORY_PREVIEW, NULL,
    gcap.fWantPreview ? NULL : &start,
    gcap.fWantPreview ? &stop : NULL, 0, 0);
    if (SUCCEEDED(hr))
        hr = gcap.pBuilder->ControlStream(&PIN_CATEGORY_CAPTURE, NULL, &start,
        NULL, 0, 0);
同样的,如果你只想要捕捉而不要预览,设置捕捉的开始时间为NULL,设置捕捉的结束时间为MAX_TIME。设置预览的开始时间为MAX_TIME,NULL为结束时间。
下面的例子告诉filter graph开始预览(第三个参数:开始时间为NULL)。结束时间指定为MAX_TIME意味着忽视停止时间(永远放下去)。
    gcap.pBuilder->ControlStream(&PIN_CATEGORY_PREVIEW, NULL, NULL, MAX_TIME, 0, 0);


调用IMediaControl::Run 运行 graph
// Run the graph
    IMediaControl *pMC = NULL;
    HRESULT hr = gcap.pFg->QueryInterface(IID_IMediaControl, (void **)&pMC);
    if (SUCCEEDED(hr)) {
 hr = pMC->Run();
 if (FAILED(hr)) {
     // Stop parts that ran
     pMC->Stop();
 }
 pMC->Release();
    }
    if (FAILED(hr)) {
 ErrMsg("Error %x: Cannot run preview graph", hr);
 return FALSE;
如果graph已经运行,通过调用ICaptureGraphBuilder::ControlStream立刻开始捕捉。例如下面的代码,控制整个的filter graph(第二个参数为NULL),立刻开始(第三个参数是NULL),并且永不停止(第四个参数是MAX_TIME)。
    // NOW!
    gcap.pBuilder->ControlStream(&PIN_CATEGORY_CAPTURE, NULL, MAX_TIME, &stop, 0, 0);


停止预览或捕捉操作,调用IMediaControl::Stop,就同你调用IMediaControl::Run一样。
// Stop the graph
    IMediaControl *pMC = NULL;
    HRESULT hr = gcap.pFg->QueryInterface(IID_IMediaControl, (void **)&pMC);
    if (SUCCEEDED(hr)) {
 hr = pMC->Stop();
 pMC->Release();
    }

 


获得捕捉的信息

通过IAMDroppedFrames接口获得。测试丢失帧的数量(IAMDroppedFrames::GetNumDropped),捕捉的数量(IAMDroppedFrames::GetNumNotDropped)。IAMDroppedFrames::GetAverageFrameSize方法提供了捕捉帧的平均尺寸(单位:byte)。使用这些信息可以知道总的捕捉字节和每秒的帧数(速率)。


保存文件

最初分配的捕捉文件只是临时的保存数据,所有你可以尽可能快的捕捉。当你想把捕捉的数据保存到硬盘中时,调用ICaptureGraphBuilder::CopyCaptureFile。这个方法从先前得到的捕捉文件输出数据到你选择的另一个文件中。这个新的储存文件的大小是和实际捕捉的数据匹配的,而不是和先前的文件大小匹配。
ICaptureGraphBuilder::CopyCaptureFile方法的第一个参数是复制源,第二个是目标文件。第三个参数设为TRUE指出用户允许用ESC键中断复制操作。最后参数是可选的。允许你提供一个进程指示器。如果想要的化,通过执行 IAMCopyCaptureFileProgress 接口。下面示例了如何调用CopyCaptureFile。
    hr = pBuilder->CopyCaptureFile(wachSrcFile, wachDstFile,TRUE,NULL);

通过普通的Open File dialog得到新的文件名。用MultiByteToWideChar 函数把文件名转成wide string,使用ICaptureGraphBuilder::CopyCaptureFile把捕捉的数据保存到指定的文件中。
/*
 * Put up a dialog to allow the user to save the contents of the capture file
 * elsewhere
 */
BOOL SaveCaptureFile(HWND hWnd)
{
    HRESULT hr;
    char achDstFile[_MAX_PATH];
    WCHAR wachDstFile[_MAX_PATH];
    WCHAR wachSrcFile[_MAX_PATH];

    if (gcap.pBuilder == NULL)
 return FALSE;

    if (OpenFileDialog(hWnd, achDstFile, _MAX_PATH)) {

 // We have a capture file name
 MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, gcap.szCaptureFile, -1,
      wachSrcFile, _MAX_PATH);
 MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, achDstFile, -1,
      wachDstFile, _MAX_PATH);
 statusUpdateStatus(ghwndStatus, "Saving capture file - please wait...");

 // We need our own graph builder because the main one might not exist
 ICaptureGraphBuilder *pBuilder;
 hr = CoCreateInstance((REFCLSID)CLSID_CaptureGraphBuilder,
   NULL, CLSCTX_INPROC, (REFIID)IID_ICaptureGraphBuilder,
   (void **)&pBuilder);
 if (hr == NOERROR) {
     // Allow the user to press ESC to abort... don't ask for progress
     hr = pBuilder->CopyCaptureFile(wachSrcFile, wachDstFile,TRUE,NULL);
     pBuilder->Release();
 }
 if (hr == S_OK)
     statusUpdateStatus(ghwndStatus, "Capture file saved");
 else if (hr == S_FALSE)
     statusUpdateStatus(ghwndStatus, "Capture file save aborted");
 else
     statusUpdateStatus(ghwndStatus, "Capture file save ERROR");
 return (hr == NOERROR ? TRUE : FALSE);

    } else {
return TRUE;    // They canceled or something
    }
}

关于捕捉媒体文件和获得捕捉信息的详细内容,可以参考AMCap例子的Amcap.cpp 和 Status.cpp 。

windows下视频捕捉VFW和DirectShow 说起视频捕捉问题,先来看一下视频捕捉卡。根据使用的驱动程序的不同来分类,目前市场上大致有两种捕捉卡:VFW (Video for Windows)卡和WDM (Windows Driver Model)卡。前者是一种趋于废弃的驱动模型,而后者是前者的替代模型;WDM还支持更多新的 阅读详情

相关推荐

基于MFC和DirectShow实现简易视频捕捉

本文还有配套的精品资源,点击获取 简介:MFC (Microsoft Foundation Classes) 是用于构建Windows应用程序的C++类库。本项目介绍如何通过DirectShow技术在MFC中实现视频捕捉,包括DirectShow Filter Graph的构建、设备捕获、样本抓取以及用户界面交互等方面。提供了一个可以直接运行的示例程序,并阐述了关键知识点,...

weixin_35756624的博客 1462

DirectShow编程实现摄像头视频捕捉

前言  DirectShow是微软公司提供的一套在Windows平台上进行流媒体处理的开发包,与DirectX开发包一起发布。 DirectShow为多媒体流的捕捉和回放提供了强有力的支持。用DirectShow开发应用程序,我们可以很方便地从支持WDM驱动模型的采集卡上捕获数据,并且进行相应的后期处理乃至存储到文件中。  DirectShow是基于COM的,为了编写DirectShow应用程序,

深之JohnChen的专栏 3726

TAS5805MPWPR实战:数字音频功放从选型到量产全流程指南

数字音频功放将I2S数字信号直接转为PWM驱动扬声器,省去传统DAC与模拟运放链路,在高保真、低BOM与紧凑PCB之间找到平衡。其核心在于内置可编程DSP,支持多段PEQ、DRC等数字处理,通过I2C配置即可完成调音,而不占用主控算力。这类方案广泛应用于蓝牙音箱、Soundbar、智能音频模组等产品,但实际落地时常遇到I2C通信不稳定、EQ未生效、底噪超标、DC检测误触发等工程问题。从电源布局、LC滤波参数到PurePath Console工具链的使用,再到量产固件加载与故障排查,都需要系统化方法论支撑。本

weixin_29164843的博客 219

Direcshow之视频捕捉

关于视频捕捉(About Video Capture inDshow) 1. 视频捕捉Graph的构建 一个能够捕捉音频或者视频的graph图都称之为捕捉graph图。捕捉graph图比一般的文件回放graph图要复杂许多,dshow提供了一个CaptureGraph Builder COM组件使得捕捉graph图的生成更加简单。Capture GraphBuilder提供了一个ICa

zww_sap111的专栏 1624

Ceres Solver:从入门到使用

Ceres Solver是谷歌开源的C++非线性优化库,能够解决有约束或无约束条件下的非线性最小二乘问题。2010年之后大量的运用在谷歌的产品开发中,尤其在谷歌开源的cartographer中被大量的使用。 ceres可以在Linux,Windows,macOS,Andrioid,IOS系统进行安装使用,详情可查看下方的官网链接。 Ceres Solver 官网:http://ceres-solver.org/

非晚非晚的博客 1万+

3D IC中Memory-on-Logic堆叠测试的DFT解决方案与工程实践

在半导体行业,随着摩尔定律逼近物理极限,3D IC技术通过芯片垂直堆叠实现性能提升和异构集成,已成为重要发展方向。其核心原理是利用硅通孔(TSV)或微凸块实现芯片间电气互连,将多个不同功能的芯片(如逻辑芯片与存储芯片)集成在一个封装内。这项技术的核心价值在于能大幅提升系统性能、降低功耗并实现更小的封装尺寸。然而,芯片堆叠后,传统的测试方法面临巨大挑战,尤其是测试访问存在物理屏障,无法直接探测被覆盖的芯片接口。为此,可测试性设计(DFT)成为确保3D IC可靠性与量产可行性的关键技术。它通过在设计阶段植入专用

weixin_42521058的博客 631

DirectShow流媒体数据的采集及图片的捕获

作者: 沈浩 谭骏珊 时间: 2004-09-15 出处: ahcit 概述  流媒体的处理,以其复杂性和技术性,一向广受工业界的关注。特别伴随着因特网的普及,流媒体在网络上已广泛应用﹐怎样使流媒体的处理变得简单而富有成效逐渐成为了焦点问题。选择一种合适的应用方案,将事半功倍。此时,微软的DirectShow给了我们一个不错的选择。  DirectShow是微软公司在ActiveMovie和Vid

寻秦记——刻下来的时光 3104

来自工业界的知识库 RAG 服务(二),RagFlow 源码全流程深度解析

前面介绍过有道 QAnything 源码解析,通过深入了解工业界的知识库 RAG 服务,得到了不少调优 RAG 服务的新想法。因此本次趁热打铁,额外花费一点时间,深入研究了另一个火热的开源 RAG 服务RagFlow的完整实现流程,希望同样有所收获。首先依旧可以先从框架图入手,与常规的 RAG 架构进行一些比较可以看到右侧知识库被明显放大,同时最右侧详细介绍了文件解析的各种手段,比如OCR等,这些在常规的 RAG 中可能会作为一个不起眼的。

易迟的专栏 2万+

DirectShow视频捕获

本文档比较适合初学者,写的比较详细,水平有限,翻译得不好还请见谅。目标是只要不会误导大家就可以了,我可不想误人子弟,哈哈!DirectShow捕捉程序的准备 Graph Edit概述 COM 入门知识 http://www.microsoft.com/japan/com/compapers.asp C Magazine

nisikawaguti的专栏 4444

深入解析FastDDS:SHM与DATA-SHARING传输层的性能对比与实现细节

本文深入对比了FastDDS中SHM与DATA-SHARING两种传输层的实现机制与性能差异。SHM采用端口化共享内存模型,存在两次数据拷贝;而DATA-SHARING通过共享历史实现真正的零拷贝,大幅降低延迟与CPU占用。文章结合实战测试数据,为机器人、自动驾驶等高实时性场景提供了关键的性能优化选型与配置指南。

weixin_28358083的博客 231

国产PHY芯片YT8512H替代LAN8742A的实战指南(STM32F407平台)

本文详细介绍了在STM32F407平台上,使用国产PHY芯片YT8512H替代LAN8742A的完整实战过程。文章深入剖析了硬件设计中的关键信号连接差异(如CRS_DV与RXDV复用)、时钟布线要点,并提供了软件驱动修改、PHY配置及调试排错的系统指南,旨在帮助工程师高效完成国产化替代,规避常见陷阱。

defi6farmer的博客 854

DirectShow的中文资料之建立一个捕捉程序

在看DXSDK/Samples/C++/DirectShow/Capture/AMCap工程时,发现了这个,于是把它转载过来了    DirectShow 提供了用应用程序从适当的硬件中捕捉和预览音/视频的能力。数据源包括:VCR,camera,TV tuner,microphone,或其他的数据源。一个应用程序可以立刻显示捕捉的数据(预览),或是保存到一个文件中。 在这个例子中,ICaptu

guanshangming的专栏 860

【重温童年】基于tkinter模块设计的Q宠大乐斗武器升星模拟器:重温经典,畅享休闲时光

与传统的Q宠大乐斗不同,这款模拟器还加入了一个创新的功能——自定义升星概率。玩家可以根据自己的喜好和策略,为不同的武器设置不同的成功率和降级率。比如,你可以将“嗜血”这把武器的升星难度设置得极高,以体现其稀有性和强大威力;也可以将“平底锅”这样的普通武器设置得相对容易升星,让玩家在升级过程中感受到更多的成就感。这种自定义的概率设置,不仅增加了游戏的趣味性和挑战性,还让玩家在升级过程中有了更多的策略和选择。你可以根据自己的武器库和卷轴数量,制定出最合适的升级计划,从而在游戏中占据先机。

nmdbbzcl的博客 1236

directshow的中文资料之设备列举和捕捉接口

 这篇解释和示例如何通过DirectShow的接口去初始化和访问系统的硬件设备。代表性的,DirectShow应用程序使用下面类型的硬件。音/视频捕捉卡音频或视频回放卡音频或视频压缩或解压卡(象MPEG解码器)下面将以AV设备作参考。如何列举设备包括在DirectShow SDK中的接口,类,和例子提供了音/视频捕捉和回放的功能。因为文件源过滤器和filter graph mana

capboy的专栏 2308

瑞数jsvmp算法还原流程讲解

​ 又是很久没写文章了,今天水一篇文章吧,鉴于之前有看到过别人的文章被警告的案例,所以这篇文章就仅写一下还原瑞数vmp的大概流程吧(仅记录下自己还原的思路)

博客 6606

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

DirectShow建立一个视频捕捉程序

DirectShow提供了用应用程序从适当的硬件中捕捉和预览音/视频的能力。数据源包括:VCR,camera,TVtuner,microphone,或其他的数据源。一个应用程序可以立刻显示捕捉的数据(预览),或是保存到一个文件中。在这个例子中,ICaptureGraphBuilder接口是处理捕捉工作的主要接口。你可以在你自己的捕捉程序中使用同样的方法和接口。在这里主要讨论ICaptur...

SurpassLi的专栏 81

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

Directshow 捕捉视频入门篇

这篇文章是介绍关于视频捕捉硬件的一些基础知识及硬件输入输出引脚的一些预备知识。

CreatedSign的专栏 2239

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

DirectShow编程捕捉WDM与VFW

说起视频捕捉问题,我们先要来看一下视频捕捉卡。根据使用的驱动程序的不同来分类,目前市场上大致有两种捕捉卡:VFW (Video for Windows)卡和WDM (Windows Driver Model)卡。前者是一种趋于废弃的驱动模型,而后者是前者的替代模型;WDM还支持更多新的特性,比如直接支持电视接收、视频会议、1394接口的设备、桌面摄像机、多条视频流(Line-21或Closed-C

Briver Song的专栏 1946

DirectShow视频捕捉应用研究

摘要 本文将对从捕捉设备和从播放文件中进行视频捕捉涉及的有关驱动(Driver)与应用的模型和接口进行研究和分析,比较其Windows与Windows CE中的不同,从而提出在Windows CE下实现视频捕捉数据流的方法。  关键字 DirectShow,视频捕捉,驱动,Windows CE系统  引言  随着多媒体技术的不断发展,相应的软件与硬件层出不穷,现在与多媒体视频会议(Video Co

Briver Song的专栏 1990

DirectShow应用——音频捕捉

现在的所谓多媒体电脑一般都会有声卡(软声卡或硬声卡),有声卡就能进行音频的捕捉。大家一定熟悉Windows自带的附件“录音机”程序,可以通过麦克风进行录音,最终生成一个Wave文件。读完本文之后,你就会发现,自己使用DirectShow写一个音频捕捉的应用程序,原来也是这么的容易!  大家知道,DirectShow对硬件的支持是通过特定的包装Filter来实现的。声卡使用的是Audio Capture Filter,Filter内部使用以waveIn开头的一套API实现(如waveInOpen等)。运行Gr

markman101---神即是道 道法自然 如来 3674

Directshow的视频捕捉

<br />Directshow(SDK)学习笔记九_视频捕捉<br />摘要:本篇文档主要描述关于用Directshow进行视频开发的一些技术<br />主要包括下面内容<br /> 1关于视频捕捉(About Video Capture in Dshow)2选择一个视频捕捉设备(Select capture device)3预览视频(Previewing Video)4如何捕捉视频流并保存到文件(Capture video to File)5将设备从系统中移走时的事件通知(Device remove N

n567656756765676567的专栏 849

DirectShow中的视频捕捉之一

关于视频捕捉(About Video Capture in Dshow)1) 视频捕捉Graph的构建一个能够捕捉音频或者视频的graph图都称之为捕捉graph图。捕捉graph图比一般的文件回放graph图要复杂许多,dshow提供了一个Capture Graph Builder COM组件使得捕捉graph图的生成更加简单。Capture Graph Builder提供了一个ICapture...

镜花水月 415
上一篇: directshow的中文资料之控制视频回放窗口
下一篇: directshow的中文资料之设备列举和捕捉接口
capboy
博客等级 码龄26年 15粉丝 34原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值