关于把视频保存为avi文件的问题

sghcpt 2010-10-27 02:46:14
我的问题是这样的,我想把视频文件,假如原来的大小300 * 400的,从新组合变成150 * 800这样的大小,也就是把原来宽度的一半的数据移到下面,从新组合成,然后保存为一个AVI文件.请问应该如何实现了?
...全文
209 20 打赏 收藏 转发到动态 举报
写回复
用AI写文章
20 条回复
切换为时间正序
请发表友善的回复…
发表回复
sghcpt 2010-11-02
  • 打赏
  • 举报
回复
To dengzikun
这不太明白,"你处理的是RGB32数据,所以图象数据实际上是这样存储的
5 6 7 8
1 2 3 4
"
那为什么1 2 3 4 保存的视频数据是头部范围的数据?而 5 6 7 8就保存脚部范围的数据?
我看的一些资料说图片的扫描是根据nHeight的正负来的,我在graphedit哪里看到nHeight是正的.那么它应该在脚部开始扫描,那么它扫描的时候应该是(对于一副正常的视频图片,头部在上面,脚部在下面),那么它得到的数据应该是脚部的数据,也就是说在内存中首先存储的是脚部的数据了?也就是说,对于
5 6 7 8
1 2 3 4
的数据, 1 2 3 4 保存的数据应该是脚部的,为什么是头部的数据了?
dengzikun 2010-11-02
  • 打赏
  • 举报
回复
你的代码中,图象处理的逻辑应该没有问题.

你处理的是RGB32数据,所以图象数据实际上是这样存储的
5 6 7 8
1 2 3 4

经过你的FILTER处理后应该是这样的.
5 6
1 2
7 8
3 4

播放时,因为是RGB数据,需做颠倒处理,就是这样了

3 4
7 8
1 2
5 6
所以你看到的图象就是上面这样了。
sghcpt 2010-11-02
  • 打赏
  • 举报
回复
To dengzikun
我读入一个6.mpg的文件,我看了一下它的Format是MPEG Video。经过下面的操作,是在graphedit哪里的链接图.
6.mpg --> mpeg-1 Stream Splitter --> MPEG Video Decoder --> MyFilter --> ffdshow video encoder --> AVI Mux --> 29.avi
我用ffdshow哪里的播放器mpc播放的时候,发现本来应该是这样的视频图片
1 2 3 4
5 6 7 8
经过我的MyFilter操作,应该变成
1 2
5 6
3 4
7 8
但是却变成了下面
3 4
7 8
1 2
5 6
它们链接的时候经过我的MyFilter的时候,是字媒体类型RGB32.请问是什么原因引起的?
在我的MyFilter中,图片处理是这样的.
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)] = pBuffer1[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)] = pBuffer2[k + n * (nWidth / 2)];
}
if (pBuffer1)
{
delete pBuffer1;
pBuffer1 = NULL;
}
if (pBuffer2)
{
delete pBuffer2;
pBuffer2 = NULL;
}
}
}
dengzikun 2010-11-02
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 sghcpt 的回复:]
请问,在视频处理的那个阶段遇到一个一个问题,我就是在Transform哪里处理视频数据,但在保存为0avi文件后,为什么视频会颠倒过的?对于yuv的视频不会颠倒过来,但对于rgb或者Cinepack等媒体格式就会颠倒过来,请问是什么引起的,应该怎么处理了?
[/Quote]

YUV与RGB的扫描方式不同,所以图象会颠倒.
一般播放器都能正确处理这个问题.

当然,一些编码的问题或者解码器的兼容问题
会导致播放器不能正确处理,如果你用的解码FILTER
有图象反转功能,打开这个功能即可,印象中FFDSHOW
FILTER就有这个功能.实在不行,自己在FILTER中实现
也可.
sghcpt 2010-11-02
  • 打赏
  • 举报
回复
怎么没有人回答的呀.我顶...............
sghcpt 2010-11-02
  • 打赏
  • 举报
回复
多谢dengzikun,结贴.
dengzikun 2010-11-02
  • 打赏
  • 举报
回复
5 6 7 8
1 2 3 4
是存储格式,1 2 3 4是上半身数据,在内存中,指针指向5,
逐行显示的时候,应该先显示 1 2 3 4,
再显示 5 6 7 8.

sghcpt 2010-11-02
  • 打赏
  • 举报
回复
To dengzikun
不好意思,还是不明白.我最想知道的是(对于一副图片来说,上面是上半身,下面的下半身)
1 2 3 4 指的是上半身数据还是下半身数据?在内存的存储上,指针是指向5了还是指向1了?
dengzikun 2010-11-02
  • 打赏
  • 举报
回复
原始的RGB数据是这么存储的
5 6 7 8
1 2 3 4

应该处理成这样
7 8
3 4
5 6
1 2

显示的时候一颠倒,应该这样

1 2
5 6
3 4
7 8
sghcpt 2010-11-02
  • 打赏
  • 举报
回复
To dengzikun
"
你处理的是RGB32数据,所以图象数据实际上是这样存储的
5 6 7 8
1 2 3 4

经过你的FILTER处理后应该是这样的.
5 6
1 2
7 8
3 4

播放时,因为是RGB数据,需做颠倒处理,就是这样了

3 4
7 8
1 2
5 6
所以你看到的图象就是上面这样了。
"
根据你上面说的,位图是由下往上、由左向右,即图像上下颠倒存储,那么在内存中
5 6 7 8
1 2 3 4
应该第一个保存位图的地址是指向1的呀?然后是2,这样下去的.那么
1 2 3 4应该保存的是位图上身部分的数据, 5 6 7 8是保存下身部分的数据.
在我的程序是操作的结果应该是下面
1 2
5 6
3 4
7 8
那么播放时,因为是RGB数据,需做颠倒处理,应该是
7 8
3 4
5 6
1 2
应该也会上下颠倒才对的呀?请指教......但效果就是你说的那种情况,那究竟哪里不对了。

dengzikun 2010-11-02
  • 打赏
  • 举报
回复
MSDN上是说可以用nHeight来区分,
但还是有人不按套路出牌,呵呵.

一般来说,如果是RGB,就可以认为是颠倒存储的,
是YUV,就是正常存储的.
sghcpt 2010-11-02
  • 打赏
  • 举报
回复
To dengzikun
"WINDOS RGB位图图像数据的存储顺序是由下往上、由左向右,即图像上下颠倒存储.
还存在不同存储方式的位图,用nHeight来区分."
那请问我应该什么时候用nHeight来判断,什么时候不用了?
dengzikun 2010-11-02
  • 打赏
  • 举报
回复
WINDOS RGB位图图像数据的存储顺序是由下往上、由左向右,即图像上下颠倒存储.
还存在不同存储方式的位图,用nHeight来区分.
sghcpt 2010-11-01
  • 打赏
  • 举报
回复
请问,在视频处理的那个阶段遇到一个一个问题,我就是在Transform哪里处理视频数据,但在保存为0avi文件后,为什么视频会颠倒过的?对于yuv的视频不会颠倒过来,但对于rgb或者Cinepack等媒体格式就会颠倒过来,请问是什么引起的,应该怎么处理了?
tufaqing 2010-10-28
  • 打赏
  • 举报
回复
你这要四部分。第一:选择一个框架,因为要涉及到编码,用Directshow后面编码简单些,也可用windows media sdk编码成wmv,也可自己通过开源编码自己写编码器等。第二:图像处理,要对图像进行数据处理。第三:视频编码,选择一种编码器,H264,XVID,MPEG等,windows没有现成的,directshow下有些免费的,开源库也有,要自己写,不过要懂一些音视频编解码基础;第三:文件合成,AVI用directshow要现成的filter可以用,也可自己通过windows sdk提供的avi接口设置,不过也要懂音视频编解码基础,否则出错了都不知道怎么回事。
如果不是特别要求,我觉得还是编码成wmv比较好,使用directshow或windows media sdk都比其他的方便,可以跳过编码器这一步。
mumuniuniu 2010-10-28
  • 打赏
  • 举报
回复
需要写一个transform filter 将数据源扩大填充后输出 再使用系统中的编码起进行编码输出
sghcpt 2010-10-27
  • 打赏
  • 举报
回复
怎么没有人回答的,我顶..
cjabcola 2010-10-27
  • 打赏
  • 举报
回复
应该算是图像的截取,然后再拼接吧,没有相关经验,可能的思路是不是做个矩阵变换?同等高手解答!
sghcpt 2010-10-27
  • 打赏
  • 举报
回复
to cjabcola:
不好意思,可能我表达得不好.我想把一个视频问题,这个视频文件原来的一个Sample中图片的大小是宽是300,高是400,现在想把宽度的一半就是宽度在(150 ~ 300)之间,高为400的图片,移到宽为(0 ~ 150),高为400的下面.
例如 1 2 3 4 5 6 变成
1 2 3
4 5 6
这样的排列后,保存为avi文件。不知道是否说得清楚。
cjabcola 2010-10-27
  • 打赏
  • 举报
回复
不知道你具体用途,可以试一试使用FFMPEG。

2,542

社区成员

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

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