如何从Sample Grabber过滤器捕获字节数组. [英] How to capture a byte array from Sample Grabber filter.

查看:111
本文介绍了如何从Sample Grabber过滤器捕获字节数组.的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在开发MFC应用程序,并且正在使用Visual Studio.net2008.在我的应用程序中,我需要将通过摄像机捕获的视频发送到另一个IP和通过网络的端口.为了通过网络发送RTP数据,我有一个第三方dll集,它可以处理所有渲染任务.他们发送视频的方式是,连续发送由相机创建的一系列位图图像.他们提供了从相机捕获一系列位图的方法.但是问题是我无法使用它们的方法从相机捕获位图图像,因为我的滤镜图与此不同.

因此,我想使用Sample Grabber过滤器从过滤器图形捕获数据.因此,我要做的是将捕获的数据从图形保存到文件中的位图图像.然后,当我需要使用渲染器发送它们时,我从文件中打开该位图图像并将其发送.为了连续执行此操作,我使用了计时器.

我初始化Sample Grabber的方法如下.

HRESULT RTPgraph :: setSampleGrabber(void)
{
HRESULT hr;

//创建SampleGrabber(Filter)
hr = CoCreateInstance(CLSID_SampleGrabber,NULL,CLSCTX_INPROC,IID_IBaseFilter,(LPVOID *)& pSampleGrabberFilter);

来自Filter
的接口hr = pSampleGrabberFilter-> QueryInterface(IID_ISampleGrabber,(LPVOID *)& pSampleGrabber);

addFilterNew(pCameraGB,CLSID_NullRenderer,L''Null_Renderer'',& pNullRenderer);

ZeroMemory(& am_media_type,sizeof(am_media_type));
am_media_type.type_media> MEDIASUBTYPE_RGB24;
am_media_type.formattype = FORMAT_VideoInfo;
pSampleGrabber-> SetMediaType(& am_media_type);


hr = pCameraGB-g t; AddFilter(pSampleGrabberFilter,L''Sample Grabber'');
hr = connectFilters(pCameraGB,pCamIPT,NULL,pSampleGrabberFilter,NULL);
hr = connectFilters(pCameraGB,pSampleGrabRer
return hr;
}




我保存位图的方法如下.

void RTPgraph :: saveBitmap(void)
{

pSampleGrabber-> GetConnectedMediaType(& am_media_type);
VIDEOINFOHEADER * pVideoInfoHeader =(VIDEOINFOHEADER *)am_media_type.pbFormat;
Sample-G&p SetBufferSamples(TRUE);

long evCode;
pMECamera-> WaitForCompletion(20,& evCode);

long nBufferSize = am_media_type.lSampleSize;
long * pBuffer = (long *)malloc(nBufferSize);

pSampleGrabber-> GetCurrentBuffer(& nBufferSize,pBuffer);


HANDLE fh;
BITMAPFILEHEADER bmphdr;
DWORD nWritten;

memset(& bmphdr,0,sizeof(bmphdr));

bmphdr.bfType = ('M'<< 8)| 'B';
bmphdr.bfSize = sizeof(bmphdr)+ sizeof(BITMAPINFOHEADER)+ nBufferSize;
bmphdr.bfOffBits = sizeof(bmphdr)+ sizeof(BITMAPINFOHEADER);

char bufferFile [80] ] ="Call.bmp"; ;

fh = CreateFile(bufferFile,GENERIC_WRITE,0,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL);
WriteFile(fh,& bmphdr,sizeof(bmphdr),& nWritten,NULL);
WriteFile(fh,& pVideoInfoHeader-> bmiHeader,sizeof(BITMAPINFOHEADER),& nWritten,NULL);
WriteFile(fh,pBuffer,nBufferSize,& nWritten,NULL);
CloseHandle(fh );

free(pBuffer);
}


上述方法已成功在文件中创建了位图图像.文件中的位图图像会带来很大的延迟.因此,现在我需要直接捕获该位图数据,而无需将其写入文件.在第三方dll集中,存在一种称为" Bitmap ByteArrayToBitmap_RGB24"的方法.文档说,此方法将字节数组转换为Bitmap并获取宽度,高度和 未压缩的图片作为输入.

根据该文档的定义方法如下.

静态 位图 ^ ByteArrayToBitmap_RGB24 ( 无符号整数 宽度无符号整数 高度数组< 无符号字符> ^ 输入 )


所以我的问题是如何从样本采集器捕获数据,我可以将该数据作为上述方法的输入参数.所以任何人都可以告诉我如何从上面的saveBitmap方法中获取 array < unsigned char > ^类型的输出. (我尝试通过将SaveBitmap方法中pBuffer处的数据转换为无符号字符数组来做到这一点.但这不会将位图发送到另一个IP.)



I'm developing a MFC application and I'm using visual studio.net 2008.In my application I need to send the video captured from my camera to another IP and a port through the network. To send the RTP data through the network I have a third party dll set, which can handle all the rendering tasks. The way they send the video is , sending a series of bitmap images created from the camera continuously. They have provided their methods to capture a series of bitmaps from the camera. But the problem is I can't use their methods to capture bitmap images from camera, since my filter graph is different from that.

So I thought to use the Sample Grabber filter to capture data from the filter graph. So what I did is I saved the captured data from the graph to a bitmap image in a file. And then when I need to send them using the renderer, I open that bitmap image from the file and send it. To do this continously I used a timer.

My method which initialise the Sample Grabber is as follows.

HRESULT RTPgraph::setSampleGrabber(void)
{
    HRESULT hr;

    // create SampleGrabber(Filter)
    hr = CoCreateInstance(CLSID_SampleGrabber,NULL,CLSCTX_INPROC,IID_IBaseFilter,(LPVOID *)&pSampleGrabberFilter);

    // get ISampleGrabber interface from the Filter
    hr = pSampleGrabberFilter->QueryInterface(IID_ISampleGrabber,(LPVOID *)&pSampleGrabber);

    //Add the null renderer to connect with the sample grabber.
    hr = addFilterNew(pCameraGB,CLSID_NullRenderer, L"Null_Renderer", &pNullRenderer);

     ZeroMemory(&am_media_type, sizeof(am_media_type));
    am_media_type.majortype = MEDIATYPE_Video;
    am_media_type.subtype = MEDIASUBTYPE_RGB24;
    am_media_type.formattype = FORMAT_VideoInfo;
    pSampleGrabber->SetMediaType(&am_media_type);

   
    hr = pCameraGB->AddFilter(pSampleGrabberFilter,L"Sample Grabber");
    hr = connectFilters(pCameraGB,pCamIPT,NULL,pSampleGrabberFilter,NULL);
    hr = connectFilters(pCameraGB,pSampleGrabberFilter,NULL,pNullRenderer,NULL);

    return hr;
}




 My method which saves bitmap is as below.

void RTPgraph::saveBitmap(void)
{
   
    pSampleGrabber->GetConnectedMediaType(&am_media_type);
    VIDEOINFOHEADER *pVideoInfoHeader = (VIDEOINFOHEADER *)am_media_type.pbFormat;

    pSampleGrabber->SetBufferSamples(TRUE);

    long evCode;
    pMECamera->WaitForCompletion(20, &evCode);

    long nBufferSize = am_media_type.lSampleSize;
    long *pBuffer = (long *)malloc(nBufferSize);

    pSampleGrabber->GetCurrentBuffer(&nBufferSize,pBuffer);


    HANDLE fh;
    BITMAPFILEHEADER bmphdr;
    DWORD nWritten;

    memset(&bmphdr, 0, sizeof(bmphdr));

    bmphdr.bfType = ('M' << 8) | 'B';
    bmphdr.bfSize = sizeof(bmphdr) + sizeof(BITMAPINFOHEADER) + nBufferSize;
    bmphdr.bfOffBits = sizeof(bmphdr) + sizeof(BITMAPINFOHEADER);

    char bufferFile [80] = "Call.bmp" ;

    fh = CreateFile(bufferFile,GENERIC_WRITE, 0, NULL,CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
    WriteFile(fh, &bmphdr, sizeof(bmphdr), &nWritten, NULL);
    WriteFile(fh,&pVideoInfoHeader->bmiHeader,sizeof(BITMAPINFOHEADER), &nWritten, NULL);
    WriteFile(fh, pBuffer, nBufferSize, &nWritten, NULL);
    CloseHandle(fh);

    free(pBuffer);
}


The above methods successfull create a bitmap image in the file.But now I feel that writing and reading the bitmap image from the file introduce a large delay. So now I need to capture that bitmap data directly without writing them to a file. In the third party dll set there is a method called "Bitmap ByteArrayToBitmap_RGB24". The document says, this method Converts a byte array to Bitmap and  Takes width, height and an array of bytes of an uncompressed picture as input.

 The definition of that method according to their documents is as follows.

static Bitmap^ ByteArrayToBitmap_RGB24( unsigned int width, unsigned int height, array<unsigned char>^ input )


So my problem is how can I capture the data from the sample grabber, which I can give this data as input parameter for above method. So can any one please tell me how can I get output of type array<unsigned char>^  from my saveBitmap method above. (I tried to do that by converting data at pBuffer in the SaveBitmap method to unsigned char array. But that doesn't send a bit map to another IP).



推荐答案

使用 CreateDIBSection API并将位复制到位图的内存中.您最终将获得HBITMAP,可以与各种GDI功能一起使用(如果这是目标).
Use CreateDIBSection API and copy bits into bitmap's memory. You will end up with HBITMAP you can use with various GDI functions (if that's the goal).


这篇关于如何从Sample Grabber过滤器捕获字节数组.的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆