关于播放的问题

sghcpt 2010-11-02 05:16:01
我的问题是这样的,我自己写了一个Filter, 继承CTransformFilter,在Transform函数哪里处理视频数据.实现下面功能,
假如视频数据如下
1 2 3 4
5 6 7 8
经过我的处理变成下面
1 2
5 6
3 4
7 8
然后我就测试,第一种情况是这样的,我在graphedit中直接用我的MyFilter链接Render,在处理RGB32数据的时候,在Transform函数哪里要下面的处理才正常显示.
HRESULT CContrast::Transform(IMediaSample *pIn, IMediaSample *pOut)
{

if (*(m_pInput->CurrentMediaType().Subtype()) == MEDIASUBTYPE_RGB32)
{
{
int nWidth = 0, nHeight = 0;
VIDEOINFO* pInfo = (VIDEOINFO*)m_pInput->CurrentMediaType().Format();
nWidth = pInfo->bmiHeader.biWidth;
nHeight = pInfo->bmiHeader.biHeight;
BYTE* pBuffer = 0;
BYTE* pBufferOut = 0;
pIn->GetPointer(&pBuffer);
pOut->GetPointer(&pBufferOut);

RGBQUAD* pBuf = (RGBQUAD*)pBuffer;
RGBQUAD* pBufOut = (RGBQUAD*)pBufferOut;
int nBufferSize = nWidth * abs(nHeight) / 2;
RGBQUAD* pBuffer1 = new RGBQUAD[nBufferSize];
if (pBuffer1 == NULL)
return NOERROR; //虽然分配失败,但为了不影响播放,返回NOERROR,表示按原来来播放.

RGBQUAD* pBuffer2 = new RGBQUAD[nBufferSize];
if (pBuffer2 == NULL)
{
delete pBuffer1;
pBuffer1 = NULL;
return NOERROR;
}
for (int nIndex = 0; nIndex < abs(nHeight); nIndex++)
{
for (int i = 0; i < nWidth / 2; i ++)
pBuffer1[i + nIndex * (nWidth / 2)] = pBuf[i + nIndex * nWidth];
for (int j = 0; j < nWidth / 2; j++)
pBuffer2[j + nIndex * (nWidth / 2)] = pBuf[j + nWidth / 2 + nIndex * nWidth];
}
for (int t = abs(nHeight) - 1; t >= 0; t--)
{
for (int k = 0; k < nWidth / 2; k++)
pBufOut[k + (abs(nHeight) - 1 - t) * (nWidth / 2)] = pBuffer1[k + t * (nWidth / 2)];
}
pBufOut += nWidth * nHeight / 2;
for (int n = abs(nHeight) - 1; n >= 0; n--)
{
for (int k = 0; k < nWidth / 2; k++)
pBufOut[k + (abs(nHeight) - 1 - n) * (nWidth / 2)] = pBuffer2[k + n * (nWidth / 2)];
}
if (pBuffer1)
{
delete pBuffer1;
pBuffer1 = NULL;
}
if (pBuffer2)
{
delete pBuffer2;
pBuffer2 = NULL;
}
}
}
}
在第二种测试的情况是这样的。
1.mpg --> mpeg-1 Stream Splitter --> MPEG Video Decoder --> MyFilter --> ffdshow video encoder --> AVI Mux --> 30.avi
其中我看了,它们的链接的子类型也是RGB32的,但在MyFilter的Transform函数哪里要下面的处理才可以播放30.avi文件正常
HRESULT CContrast::Transform(IMediaSample *pIn, IMediaSample *pOut)
{
if (*(m_pInput->CurrentMediaType().Subtype()) == MEDIASUBTYPE_RGB32)
{
{
int nWidth = 0, nHeight = 0;
VIDEOINFO* pInfo = (VIDEOINFO*)m_pInput->CurrentMediaType().Format();
nWidth = pInfo->bmiHeader.biWidth;
nHeight = abs(pInfo->bmiHeader.biHeight);
BYTE* pBuffer = 0;
BYTE* pBufferOut = 0;
pIn->GetPointer(&pBuffer);
pOut->GetPointer(&pBufferOut);
RGBQUAD* pBuf = (RGBQUAD*)pBuffer;
RGBQUAD* pBufOut = (RGBQUAD*)pBufferOut;

int nBufferSize = nWidth * nHeight / 2;
RGBQUAD* pBuffer1 = new RGBQUAD[nBufferSize];
if (pBuffer1 == NULL)
{
return NOERROR; //虽然分配失败,但为了不影响播放,返回NOERROR,表示按原来来播放.
}
RGBQUAD* pBuffer2 = new RGBQUAD[nBufferSize];
if (pBuffer2 == NULL)
{
delete pBuffer1;
pBuffer1 = NULL;
return NOERROR;
}
for (int nIndex = 0; nIndex < nHeight; nIndex++)
{
for (int i = 0; i < nWidth / 2; i++)
pBuffer1[i + nIndex * (nWidth / 2)] = pBuf[i + nIndex * nWidth];
for (int j = 0; j < nWidth / 2; j++)
pBuffer2[j + nIndex * (nWidth / 2)] = pBuf[j + nWidth / 2 + nIndex * nWidth];
}
for (int t = 0; t < nHeight; t++)
{
for (int k = 0; k < nWidth / 2; k++)
pBufOut[k + t * (nWidth / 2)] = pBuffer2[k + t * (nWidth / 2)];
}
pBufOut += nWidth * nHeight / 2;
for (int n = 0; n < nHeight; n++)
{
for (int k = 0; k < nWidth / 2; k++)
pBufOut[k + n * (nWidth / 2)] = pBuffer1[k + n * (nWidth / 2)];
}
if (pBuffer1)
{
delete pBuffer1;
pBuffer1 = NULL;
}
if (pBuffer2)
{
delete pBuffer2;
pBuffer2 = NULL;
}
}
}
}

那我想请问的是,为什么它们的处理会不一样的?是否我某些情况没有考虑清楚?
...全文
107 13 打赏 收藏 转发到动态 举报
写回复
用AI写文章
13 条回复
切换为时间正序
请发表友善的回复…
发表回复
sghcpt 2010-11-03
  • 打赏
  • 举报
回复
还是不懂,请问为什么说的情况会有不同的处理呀。
rageliu 2010-11-03
  • 打赏
  • 举报
回复
(1)
是否颠倒一般要判断h的正负
(2)
不一定,这个要看render,这么说吧,在render显示的时候,如果其显示操作过程中,有对数据的颠倒操作,如果只颠倒一次,图象显然不对,要正确,它就会要求上面颠倒一次,这样上面颠倒一次,render再颠倒一次,也就出来不颠倒的正确图象了。如果render显示过程中没有颠倒,它也就不会要求上面做对应的颠倒了。
(3)
看的有点晕,我也不知道上面我说清楚没,呵呵
sghcpt 2010-11-03
  • 打赏
  • 举报
回复
To rageliu
请问,
(1)一般RGB32格式的数据进来的时候,图片在内存中保存是这样的
1 2 3 4 ---------->下半身数据
5 6 7 8 ---------->上半身数据
也就是说图片是颠倒的,那么请问在内存中第一个保存图片实际数据的位置为什么指向1的?也就是说图片的左下角第一个像素的数据?

(2)还有一般视频文件播放的时候,播放器都会颠倒视频数据播放?,也就是说
在内存中数据是这样的(只对于RGB格式)
7 8
3 4
5 6
1 2
播放的时候它会颠倒来播放
就是
1 2
5 6
3 4
7 8
是否这样?
(3)
你说的MyFilter直接连接Render的的时候,那么进来的数据如下
1 2 3 4 ---------->下半身数据
5 6 7 8 ---------->上半身数据
那么经过我的MyFilter处理后,变成下面
5 6
1 2
7 8
3 4
那么这样Render是从5开始读数据,然后播放应该正常显示的。
但对于写进avi文件的时候,进来的数据经过我的MyFilter处理后
3 4
7 8
1 2
5 6
这个要颠倒过来才可以正常播放,也就是为什么一个播放器不颠倒播放,一个要颠倒播放?
不知道问的问题清晰不?
rageliu 2010-11-03
  • 打赏
  • 举报
回复
没看代码,如果是颠倒问题,
当你后面接的是render的时候,由于render要显示,它可能会使用硬件加速,这时候为了满足其使用硬件加速功能的需求,它会向上要求格式的改变,一般是w做对齐处理,h会变为负。
当你后面不接render而是直接接写avi的filter的时候,由于其不会有显示操作,也就不会有硬件加速的使用这些问题,所以它也就不会向上要求格式的改变,也就不会有w做对齐处理,h会变为负的变化了
sghcpt 2010-11-03
  • 打赏
  • 举报
回复
To dengzikun
请问你说的"呵呵,你的MyFilter收到的RGB数据,一种是上下颠倒的,一种是正常的."好像也不对吧.
例如下面的
5 6 7 8
1 2 3 4
那么5位置哪里应该保存的上身的数据, 1 2 3 4哪里应该保持下身的数据.
那么经过我的Filter处理应该是下面的
5 6
1 2
7 8
3 4
在第一种情况下(就是我的MyFilter直接连接Render),再转换了一次就变成下面
1 2
5 6
3 4
7 8
那么应该是图片颠倒了呀??
还有为什么在内存中会指向5而不是8了,8不是最后才写进数据的吗?
dengzikun 2010-11-03
  • 打赏
  • 举报
回复
MPEG Video Decoder出来的数据应该是一样的,
但不排除例外,这应该和MPEG Video Decoder后面
的FILTER有关。

我说的不一样主要是指你的29.avi播放的时候,可能一些FILTER
做了什么处理,导致和6.mpg --> mpeg-1 Stream Splitter --> MPEG Video Decoder --> MyFilter --> VMRRender的效果不同。
sghcpt 2010-11-03
  • 打赏
  • 举报
回复
To dengzikun
"呵呵,你的MyFilter收到的RGB数据,一种是上下颠倒的,一种是正常的"
这个不明白,假如我有下面的链接图
(1)6.mpg --> mpeg-1 Stream Splitter --> MPEG Video Decoder --> MyFilter --> ffdshow video encoder --> AVI Mux --> 29.avi
(2)6.mpg --> mpeg-1 Stream Splitter --> MPEG Video Decoder --> MyFilter --> VMRRender
在这两种情况下,你说的是MPEG Video Decoder加码出来的数据不同?
对于(1)这种情况是下面?
1 2 3 4 ----------->上半身的数据,并且内存中视频数据的首地址是指向1的??
5 6 7 8 ----------->下半身的数据
对于(2)的情况是下面?
1 2 3 4 ----------->下半身的数据,并且内存中视频数据的首地址是指向1的??
5 6 7 8 ----------->上半身的数据
请问是上面的情况吗?我现在好像怎么弄也没有弄明白。
dengzikun 2010-11-03
  • 打赏
  • 举报
回复
大多数情况下,用正常的方法还是能得到正确结果的,
少数例外,只能见招拆招了,提供功能,手动选择了.
sghcpt 2010-11-03
  • 打赏
  • 举报
回复
To dengzikun
那应该怎么处理比较好呀???
dengzikun 2010-11-03
  • 打赏
  • 举报
回复
一般来说,从视频采集卡中出来的RGB数据,都是上下颠倒存储的,YUV数据
是正常存储的,我试过不少款采集卡,还没发现例外.但是经过中间处理后,
就很难说了,MSDN上说通过nHeight区分,如果人家不这么来,也没办法,
所以就出现了一些奇奇怪怪的例外。所以FFDSHOW这样的解码FILTER才提供
视频反转Flip这么一个功能供我们手工调整。
dengzikun 2010-11-02
  • 打赏
  • 举报
回复
可能有的FILTER给做了颠倒处理。
sghcpt 2010-11-02
  • 打赏
  • 举报
回复
To dengzikun
"呵呵,你的MyFilter收到的RGB数据,一种是上下颠倒的,一种是正常的"
请问怎么会出现这种情况了?
dengzikun 2010-11-02
  • 打赏
  • 举报
回复
呵呵,你的MyFilter收到的RGB数据,一种是上下颠倒的,一种是正常的。

2,543

社区成员

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

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