directshow写sourcefilter传输数据问题!!急啊!!!!!

neo798 2013-08-26 02:45:12
本人最近在研究directshow来接收H264流并显示的问题:按照思路应该是写一个push模式的sourcefilter,一个transformfilter,在利用videorender来显示。
其中遇到一些问题希望大神帮忙:1、在写sourcefilter的时候,发现需要协商sample的大小,即DecideBufferSize(),发现filter的工作模式是固定的,在将sourcefilter的输出pin与transformfilter的pin相连接的时候,需要确定sample的大小,在连接好后,Graphedit点击开始后,不断的调用fillbuffer()来将数据传输下去,问题是:确定sample的大小时,DecideBufferSize()只调用一次,意思是sample的大小只能设定一次,但是接收h264数据时,每帧的大小又不一样,感觉需要设定比较多次,所以这块特别迷茫,希望大神帮帮忙!还有就是接收H264数据模块到底应该写在哪里呢?是在fillbuffer里面写还是在构造函数里面写呢?求求各位大神啊,快疯了
...全文
429 14 打赏 收藏 转发到动态 举报
写回复
用AI写文章
14 条回复
切换为时间正序
请发表友善的回复…
发表回复
williambym 2013-10-30
  • 打赏
  • 举报
回复
decidebuffersize只要设置一帧可能的最大的大小就可以,接收h264数据时,可以先把数据放到一个缓存里,然后在fillbuffer中取缓存数据填充到sample中,如果是实时视频流,还要给每一帧打时间戳
neo798 2013-08-30
  • 打赏
  • 举报
回复
引用 12 楼 ADF1230 的回复:
[quote=引用 10 楼 neo798 的回复:] [quote=引用 9 楼 ADF1230 的回复:] 当然,更简单的是,你可以在fillbuffer里面等待接收h264数据,接收到数据之后往下丢。
我就是这么做的额,想到会不断的调用fillbuffer,相当于一个线程,我就索性在里面做了接收h264数据。 HRESULT CMyOutputPin::FillBuffer(IMediaSample *pMediaSample) { CheckPointer(pMediaSample,E_POINTER); BYTE *pData = NULL; long lDataSize = 0; // //....代码比较长,就不贴了,其中就是一些socket协议的通信什么的 // //接收一帧的数据 //pFrameData是一帧的数据 //length是一帧的长度 //获得Sample中存放数据的地址 pMediaSample->GetPointer(&pData); //取得sample分配的内存大小 pMediaSample->GetSize() lDataSize = length; ZeroMemory(pData,lDataSize); //把当前需要显示的数据拷贝到内存中 CopyMemory(pData,pFrameData,length); pMediaSample->SetTime(NULL,NULL); //准备下一帧数据 pMediaSample->SetSyncPoint(TRUE); return NOERROR; } 这是我的fillbuffer的代码,但是老是会出现莫名的问题,在socket这块;我还想问一个比较笨的问题,我这个代码是按照ball的例子来写的,但是我觉得我找不到往下传sample的函数,类似DeliverHoldingSample()这样的函数,所以到底是怎么往下传的呢?[/quote] deliver在父类中实现了,你只需要填写fillbuffer,和mediatype相关的函数就行了。你的fillbuffer函数被执行之后就会deliver。 出错在socket,那说明和directshow没什么关系,是你接收h264数据的代码写的有问题。[/quote] 好的,我知道了,谢谢你呢,但是我这个socket之前其他的代码都可以用的,我再看看吧,谢谢你呢
neo798 2013-08-29
  • 打赏
  • 举报
回复
引用 9 楼 ADF1230 的回复:
当然,更简单的是,你可以在fillbuffer里面等待接收h264数据,接收到数据之后往下丢。
我就是这么做的额,想到会不断的调用fillbuffer,相当于一个线程,我就索性在里面做了接收h264数据。 HRESULT CMyOutputPin::FillBuffer(IMediaSample *pMediaSample) { CheckPointer(pMediaSample,E_POINTER); BYTE *pData = NULL; long lDataSize = 0; // //....代码比较长,就不贴了,其中就是一些socket协议的通信什么的 // //接收一帧的数据 //pFrameData是一帧的数据 //length是一帧的长度 //获得Sample中存放数据的地址 pMediaSample->GetPointer(&pData); //取得sample分配的内存大小 pMediaSample->GetSize() lDataSize = length; ZeroMemory(pData,lDataSize); //把当前需要显示的数据拷贝到内存中 CopyMemory(pData,pFrameData,length); pMediaSample->SetTime(NULL,NULL); //准备下一帧数据 pMediaSample->SetSyncPoint(TRUE); return NOERROR; } 这是我的fillbuffer的代码,但是老是会出现莫名的问题,在socket这块;我还想问一个比较笨的问题,我这个代码是按照ball的例子来写的,但是我觉得我找不到往下传sample的函数,类似DeliverHoldingSample()这样的函数,所以到底是怎么往下传的呢?
神-气 2013-08-29
  • 打赏
  • 举报
回复
当然,更简单的是,你可以在fillbuffer里面等待接收h264数据,接收到数据之后往下丢。
神-气 2013-08-29
  • 打赏
  • 举报
回复
引用 7 楼 neo798 的回复:
[quote=引用 5 楼 ADF1230 的回复:] 既然是push模式,那你单独开一个线程啊, while(!Stop) { receiveh264() packeted as a sample (fill buffer) deliver sample }
我想到过开线程,但是刚开始我对sourcefilter的工作原理不是很清楚,就利用ball这个例子来单步,我发现,在连接好pin之后,geraphedit中有开始按钮,开始后,发现是不断自动调用fillbuffer()的,我以为就是这种机制,所以我就很头疼。像你说的用线程的话,我困惑的是:你总得有个调用这个开线程的方法吧,在哪个函数里面来开这个线程呢?可能我问的问题比较傻,您别见怪啊[/quote] ball这个例子实际上就是另开了一个线程,这个线程会不断地调fillbuffer函数,你在这里面填接收到的h264数据。至于接收h264的线程,你在run或者startstreaming函数中开启就行了。记得两个线程要同步。
neo798 2013-08-29
  • 打赏
  • 举报
回复
引用 5 楼 ADF1230 的回复:
既然是push模式,那你单独开一个线程啊, while(!Stop) { receiveh264() packeted as a sample (fill buffer) deliver sample }
我想到过开线程,但是刚开始我对sourcefilter的工作原理不是很清楚,就利用ball这个例子来单步,我发现,在连接好pin之后,geraphedit中有开始按钮,开始后,发现是不断自动调用fillbuffer()的,我以为就是这种机制,所以我就很头疼。像你说的用线程的话,我困惑的是:你总得有个调用这个开线程的方法吧,在哪个函数里面来开这个线程呢?可能我问的问题比较傻,您别见怪啊
neo798 2013-08-29
  • 打赏
  • 举报
回复
引用 4 楼 ADF1230 的回复:
[quote=引用 楼主 neo798 的回复:] 本人最近在研究directshow来接收H264流并显示的问题:按照思路应该是写一个push模式的sourcefilter,一个transformfilter,在利用videorender来显示。 其中遇到一些问题希望大神帮忙:1、在写sourcefilter的时候,发现需要协商sample的大小,即DecideBufferSize(),发现filter的工作模式是固定的,在将sourcefilter的输出pin与transformfilter的pin相连接的时候,需要确定sample的大小,在连接好后,Graphedit点击开始后,不断的调用fillbuffer()来将数据传输下去,问题是:确定sample的大小时,DecideBufferSize()只调用一次,意思是sample的大小只能设定一次,但是接收h264数据时,每帧的大小又不一样,感觉需要设定比较多次,所以这块特别迷茫,希望大神帮帮忙!还有就是接收H264数据模块到底应该写在哪里呢?是在fillbuffer里面写还是在构造函数里面写呢?求求各位大神啊,快疯了
DecideBufferSize可以设置大一点,比如:2048*2048*3 ,这个没关系,然后对每一个sample设置ActureLength 实际数据大小。 接受h264 ? 是网络来的数据流吗 ? 在source filter里面接收然后往下丢就好。[/quote] 是的,接收摄像机的流。
神-气 2013-08-29
  • 打赏
  • 举报
回复
引用 10 楼 neo798 的回复:
[quote=引用 9 楼 ADF1230 的回复:] 当然,更简单的是,你可以在fillbuffer里面等待接收h264数据,接收到数据之后往下丢。
我就是这么做的额,想到会不断的调用fillbuffer,相当于一个线程,我就索性在里面做了接收h264数据。 HRESULT CMyOutputPin::FillBuffer(IMediaSample *pMediaSample) { CheckPointer(pMediaSample,E_POINTER); BYTE *pData = NULL; long lDataSize = 0; // //....代码比较长,就不贴了,其中就是一些socket协议的通信什么的 // //接收一帧的数据 //pFrameData是一帧的数据 //length是一帧的长度 //获得Sample中存放数据的地址 pMediaSample->GetPointer(&pData); //取得sample分配的内存大小 pMediaSample->GetSize() lDataSize = length; ZeroMemory(pData,lDataSize); //把当前需要显示的数据拷贝到内存中 CopyMemory(pData,pFrameData,length); pMediaSample->SetTime(NULL,NULL); //准备下一帧数据 pMediaSample->SetSyncPoint(TRUE); return NOERROR; } 这是我的fillbuffer的代码,但是老是会出现莫名的问题,在socket这块;我还想问一个比较笨的问题,我这个代码是按照ball的例子来写的,但是我觉得我找不到往下传sample的函数,类似DeliverHoldingSample()这样的函数,所以到底是怎么往下传的呢?[/quote] deliver在父类中实现了,你只需要填写fillbuffer,和mediatype相关的函数就行了。你的fillbuffer函数被执行之后就会deliver。 出错在socket,那说明和directshow没什么关系,是你接收h264数据的代码写的有问题。
rightorwrong 2013-08-29
  • 打赏
  • 举报
回复
媒体协商时时的宽和高可以动态改变,但是这个不容易实现。需要从最后的filter通知到source filter。你搜下directshow 动态改变大小能找到资料么
neo798 2013-08-28
  • 打赏
  • 举报
回复
没有大神愿意帮助一下么??????
神-气 2013-08-28
  • 打赏
  • 举报
回复
既然是push模式,那你单独开一个线程啊, while(!Stop) { receiveh264() packeted as a sample (fill buffer) deliver sample }
神-气 2013-08-28
  • 打赏
  • 举报
回复
引用 楼主 neo798 的回复:
本人最近在研究directshow来接收H264流并显示的问题:按照思路应该是写一个push模式的sourcefilter,一个transformfilter,在利用videorender来显示。 其中遇到一些问题希望大神帮忙:1、在写sourcefilter的时候,发现需要协商sample的大小,即DecideBufferSize(),发现filter的工作模式是固定的,在将sourcefilter的输出pin与transformfilter的pin相连接的时候,需要确定sample的大小,在连接好后,Graphedit点击开始后,不断的调用fillbuffer()来将数据传输下去,问题是:确定sample的大小时,DecideBufferSize()只调用一次,意思是sample的大小只能设定一次,但是接收h264数据时,每帧的大小又不一样,感觉需要设定比较多次,所以这块特别迷茫,希望大神帮帮忙!还有就是接收H264数据模块到底应该写在哪里呢?是在fillbuffer里面写还是在构造函数里面写呢?求求各位大神啊,快疯了
DecideBufferSize可以设置大一点,比如:2048*2048*3 ,这个没关系,然后对每一个sample设置ActureLength 实际数据大小。 接受h264 ? 是网络来的数据流吗 ? 在source filter里面接收然后往下丢就好。
neo798 2013-08-26
  • 打赏
  • 举报
回复
还有就是:觉得应该在Graphedit中点击开始后,sourcefilter才开始接收数据并传输,但是如果是在点击开始后再接收数据,DecideBufferSize()却是在连接pin的时候就调用了,根本没法确定sample的大小啊...求解啊!!!!在线等啊!急急急!!!!

2,543

社区成员

发帖
与我相关
我的任务
社区描述
专题开发/技术/项目 多媒体/流媒体开发
社区管理员
  • 多媒体/流媒体开发社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧