关于Ball例子修改

Joininthefun 2008-05-27 11:53:58
我的视频和音频数据已经解码后放在不同缓冲区,我想通过给Ball的例子添加一个Pin,这个pin可以直接接audio render,播出缓冲区中的音频和视频数据,我的问题是:
1. 如何给Source filter添加应out pin(希望能详细说说要重载哪些接口,给出代码最好:))
2. 我的视频和音频数据可能不同步,就是可能出现只有视频,没有音频数据,这种情况下我的音频out pin怎么输出数据
...全文
144 13 打赏 收藏 转发到动态 举报
写回复
用AI写文章
13 条回复
切换为时间正序
请发表友善的回复…
发表回复
Joininthefun 2008-06-06
  • 打赏
  • 举报
回复
多谢大家帮忙!终于基本上搞定了,来结贴了!
xjfox 2008-06-03
  • 打赏
  • 举报
回复
或者你不方便删除这个pin的话,你就填写mp3静音数据吧,就是纯mp3数据那都是0,头信息必须有……
xjfox 2008-06-03
  • 打赏
  • 举报
回复
‘只能是起不到音频数据才能知道现在没有声音,所以我的音频outpin是要创建的,我不是播放文件’

你可以在找不到音频数据的时候就把你的outputpin给delete掉嘛……呵呵……
Joininthefun 2008-06-03
  • 打赏
  • 举报
回复
to xjfox:
谢谢, 但是对第二点你可能没明白我的用途

2. 由于我的视频和音频不一定是同时有,再没有视频的时候我的音频Stream中的FillBuffer怎么填充数据,直接返回失败吗?如果是时间戳怎么办,还是给一个无声的(类似视频的黑场)打上时间戳

没有音频的时候,你音频那个outpin就不应该创建,这个你在解析文件的时候就应该做处理

因为我的graph链路是直接连接到设备上的,我的source filter是播放内存中的数据所以我不知道什么时候没有声音,只能是起不到音频数据才能知道现在没有声音,所以我的音频outpin是要创建的,我不是播放文件,我的graph链路是在程序启动时建立的(必须)而且建立后就不能停止,如果上面没有新的视频帧(也就是图片系列)我就一直输出黑场,但是音频我不知道怎办(一帧无声的数据是什么呢,我不知道:(),
xjfox 2008-06-03
  • 打赏
  • 举报
回复
1.我如何知道sample的缓冲大小(因为上层解码后的数据是直接拷贝到缓冲区的),如果我要求的音频格式(PCM,48HZ,16bit stereo)是不是缓冲区的大小就固定了,就像视频这个尺寸720X576 RGB32,大小就是165880

PCM数据都是固定大小的,1152个byte,为了保险你设置大一些的值也不会带来其他问题的,考虑到声道,建议设置为1152×4。

2. 由于我的视频和音频不一定是同时有,再没有视频的时候我的音频Stream中的FillBuffer怎么填充数据,直接返回失败吗?如果是时间戳怎么办,还是给一个无声的(类似视频的黑场)打上时间戳

没有音频的时候,你音频那个outpin就不应该创建,这个你在解析文件的时候就应该做处理

3.我的总体是这样的,有一个视频和音频的缓冲区,上面的视频播放时会把视频一帧帧图像写到视频缓冲区中,音频把解码厚的sample数据写道音频缓冲区(也有可能是图片,图片+MP3),我现在写一个sourceFiler,包含两个输出pin(video,Audio),运行后就从缓冲区中取出数据送到终端的Render, 我现在想知道这样会不会出现音视频不同步的现象,如果要同步音视频我应怎么做

只要你的音视频各自的time stamp都设置正确,同步问题系统自会帮你解决
Joininthefun 2008-06-02
  • 打赏
  • 举报
回复
上面的问题都解决了,我要添加的pin是音频输出,音频也是上层解码后的一帧帧数据(终端只接收PCM,48HZ,16bit stereo),我现在困惑的是音频是不是也和视频的sample一样,

1.我如何知道sample的缓冲大小(因为上层解码后的数据是直接拷贝到缓冲区的),如果我要求的音频格式(PCM,48HZ,16bit stereo)是不是缓冲区的大小就固定了,就像视频这个尺寸720X576 RGB32,大小就是165880

2. 由于我的视频和音频不一定是同时有,再没有视频的时候我的音频Stream中的FillBuffer怎么填充数据,直接返回失败吗?如果是时间戳怎么办,还是给一个无声的(类似视频的黑场)打上时间戳

3.我的总体是这样的,有一个视频和音频的缓冲区,上面的视频播放时会把视频一帧帧图像写到视频缓冲区中,音频把解码厚的sample数据写道音频缓冲区(也有可能是图片,图片+MP3),我现在写一个sourceFiler,包含两个输出pin(video,Audio),运行后就从缓冲区中取出数据送到终端的Render, 我现在想知道这样会不会出现音视频不同步的现象,如果要同步音视频我应怎么做

谢谢!
Joininthefun 2008-05-31
  • 打赏
  • 举报
回复
我刚才仔细查看了一下,我的Outpin连接后的属性,我要连接的render filter 的连接后的属性页是,我想是不是因为我没有设置对我的视频制式(NTSC,PAL)这些信息呢,我怎么设置这些视频信息呢?
xiansheng00 2008-05-30
  • 打赏
  • 举报
回复
关于数据的输出是在Out Pin里的FillBuffer函数完成.把你要传送出去的数据拷贝到Sample上:
pSample->GetPointer(&pData); //从Sample上获得指针.并把它赋给pData
lDataLen = pSample->GetSize(); //得到Sample上的长度.
  ZeroMemory( pData, lDataLen ); //Sample清零
memcpy( pData,pDataBuf,nLen ); //拷贝你要传送的数据到Sample上. pDataBuf为你要传送的数据的开始地址
  当 Filter Graph运行后,FillBuffer是不停的调用.pDataBuf怎么传到FillBuffer,那要自己写个接口接收该指针,让Fillter继承并实现它.然后传送到OutPin的FillBuffer函数.数据流程是应用程序的buffer传到filter然后传到OutPin的FillBuffer().OutPin的指针已经被Filter保存了.怎么写接口,在Directshow开发指南有说.

关于添加OutPin你参考Ball里的一个OutPin是怎么加的就行了.再Filter的构造函数里生成新的OutPin就OK了,然后保存指针.接下来的数据传送和上面的没什么多大的区别了
Joininthefun 2008-05-30
  • 打赏
  • 举报
回复
to xiansheng00:
我改写后没法连接一个第三方filter 输入Pin支持的媒体类型如下:
MEDIATYPE_Video, MEDIASUBTYPE_UYVY
MEDIATYPE_Video, MEDIASUBTYPE_RGB32
MEDIATYPE_Video, MEDIASUBTYPE_ARGB32
MEDIATYPE_Video, IID_MEDIASUBTYPE_v210a (10 bit YUV)
MEDIATYPE_Video, IID_MEDIASUBTYPE_r210 (10 bit RGB)


我的GetMediaType函数定义如下
HRESULT CBallStream::GetMediaType(int iPosition, CMediaType *pmt)
{
CheckPointer(pmt,E_POINTER);

CAutoLock cAutoLock(m_pFilter->pStateLock());

VIDEOINFO *pvi = (VIDEOINFO *) pmt->AllocFormatBuffer(sizeof(VIDEOINFO));
if(NULL == pvi)
return(E_OUTOFMEMORY);

ZeroMemory(pvi, sizeof(VIDEOINFO));
pvi->bmiHeader.biCompression = BI_RGB;
pvi->bmiHeader.biBitCount = 32;
pvi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
pvi->bmiHeader.biWidth = m_iImageWidth;
pvi->bmiHeader.biHeight = m_iImageHeight;
pvi->bmiHeader.biPlanes = 1;
pvi->bmiHeader.biSizeImage = GetBitmapSize(&pvi->bmiHeader);
pvi->bmiHeader.biClrImportant = 0;

SetRectEmpty(&(pvi->rcSource)); // we want the whole image area rendered.
SetRectEmpty(&(pvi->rcTarget)); // no particular destination rectangle

pmt->SetType(&MEDIATYPE_Video);
pmt->SetFormatType(&FORMAT_VideoInfo);
pmt->SetTemporalCompression(FALSE);

// Work out the GUID for the subtype from the header info.
const GUID SubTypeGUID = GetBitmapSubtype(&pvi->bmiHeader);
pmt->SetSubtype(&SubTypeGUID);
//pmt->SetSubtype(&MEDIASUBTYPE_RGB32);
pmt->SetSampleSize(pvi->bmiHeader.biSizeImage);

return NOERROR;

} // GetMediaType

HRESULT CBallStream::CheckMediaType(const CMediaType *pMediaType)
{
CheckPointer(pMediaType,E_POINTER);

if((*(pMediaType->Type()) != MEDIATYPE_Video) || // we only output video
!(pMediaType->IsFixedSize())) // in fixed size samples
{
return E_INVALIDARG;
}

// Check for the subtypes we support
const GUID *SubType = pMediaType->Subtype();
if (SubType == NULL)
return E_INVALIDARG;

if(*SubType != MEDIASUBTYPE_RGB32)
{
return E_INVALIDARG;
}

// Get the format area of the media type
VIDEOINFO *pvi = (VIDEOINFO *) pMediaType->Format();

if(pvi == NULL)
return E_INVALIDARG;

return S_OK; // This format is acceptable.

} // CheckMediaType

我看过你的帖子,现在怀疑是
pmt->SetSubtype(&SubTypeGUID);
//pmt->SetSubtype(&MEDIASUBTYPE_RGB32);
这条语句的错误,但是不知道怎么修改,望指教!



东方之珠 2008-05-30
  • 打赏
  • 举报
回复
支持一把.
Joininthefun 2008-05-29
  • 打赏
  • 举报
回复
期待高手进一步解释
rageliu 2008-05-28
  • 打赏
  • 举报
回复
1。参考http://topic.csdn.net/t/20020305/14/556205.html的回复
2。你是怎么打的时间戳?
ouyh12345 2008-05-28
  • 打赏
  • 举报
回复
照例子写
pin都是差不多的,把纯虚函数都实现了,接口就做好了

没数据当然不用往下传数据了

2,543

社区成员

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

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