DirectShow菜鸟报道:怎么全屏显示视频图像?

jessiepan 2008-12-23 02:32:49
之前一直有用过“暴风影音”和“QQ影音”的播放器,在播放一个VIDEO的时候,如果鼠标左键双击视频窗口图像会放大到“全屏”。但这个时候往往不是真实的“全屏”,图像的两边还有“黑边”!在播放器的视频控制里有一个这样的功能选择,“铺满视频窗口”,选择了这个功能后,视频图像才实现了真正的全屏!
我目前想要实现的就是这个效果。

手头上有一个别人写好的PC端视频播放器,VC6+ffdshow,视频的播放窗口是用一个Dialog来做的,为了要实现鼠标右键的一些弹出功能窗口。VideoWindow可以实现50%,100%,200%,全屏的窗口尺寸选择,但当图像放大到200%的时候,视频图像就不能铺满整个视频窗口,在窗口的两边出现“黑边”;全屏的时候,黑边更是如此!
我想实现类似"暴风影音“里的那种”铺满视频窗口"的效果,该怎么实现? 主要的问题是,要在别人的那套代码上做最小的改动来实现全屏,如果要把他有关DirectShow的那一段全部重写过,那就麻烦大了!而且我现在也没这个能力去重写过,只能在别人的基础上做些小的修改
...全文
4349 52 打赏 收藏 转发到动态 举报
写回复
用AI写文章
52 条回复
切换为时间正序
请发表友善的回复…
发表回复
yyangSS 2012-02-09
  • 打赏
  • 举报
回复
看看,我也有类似的问题
mlhy20060406 2010-01-12
  • 打赏
  • 举报
回复
学习了
jessiepan 2009-03-31
  • 打赏
  • 举报
回复
我这几天一直在看xvid.ax的代码,想在视频解码后,对YUV的数据修改,看看视频出来会有如何的效果,苦于基础太差,所以没什么进展!特将部分代码贴出来,希望可以有大虾帮忙答疑, 必重谢 :)

/* xvid_image_t
for non-planar colorspaces use only plane[0] and stride[0]
four plane reserved for alpha*/
typedef struct {
int csp; /* [in] colorspace; or with XVID_CSP_VFLIP to perform vertical flip */
void * plane[4]; /* [in] image plane ptrs */
int stride[4]; /* [in] image stride; "bytes per row"*/
} xvid_image_t;

typedef struct {
int version;
int general; /* [in:opt] general flags */
void *bitstream; /* [in] bitstream (read from)*/
int length; /* [in] bitstream length */
xvid_image_t output; /* [in] output image (written to) */
/* ------- v1.1.x ------- */
int brightness; /* [in] brightness offset (0=none) */
} xvid_dec_frame_t;


/* decode frame */
HRESULT CXvidDecoder::Transform(IMediaSample *pIn, IMediaSample *pOut)
{
DPRINTF("Transform");
xvid_dec_stats_t stats;
int length;

memset(&stats, 0, sizeof(stats));
stats.version = XVID_VERSION;
if (m_create.handle == NULL)
{
if (xvid_decore_func == NULL)
return E_FAIL;
if (xvid_decore_func(0, XVID_DEC_CREATE, &m_create, 0) < 0)
{
DPRINTF("*** XVID_DEC_CREATE error");
return S_FALSE;
}
}
AM_MEDIA_TYPE * mtOut;
pOut->GetMediaType(&mtOut);
if (mtOut != NULL)
{
HRESULT result;
result = ChangeColorspace(mtOut->subtype, mtOut->formattype, mtOut->pbFormat);
DeleteMediaType(mtOut);
if (result != S_OK)
{
DPRINTF("*** ChangeColorspace error");
return result;
}
}
m_frame.length = pIn->GetActualDataLength();
if (pIn->GetPointer((BYTE**)&m_frame.bitstream) != S_OK)
{
return S_FALSE;
}
if (pOut->GetPointer((BYTE**)&m_frame.output.plane[0]) != S_OK)
{
return S_FALSE;
}
m_frame.general = XVID_LOWDELAY;
if (pIn->IsDiscontinuity() == S_OK)
m_frame.general |= XVID_DISCONTINUITY;
if (g_config.nDeblock_Y)
m_frame.general |= XVID_DEBLOCKY;
if (g_config.nDeblock_UV)
m_frame.general |= XVID_DEBLOCKUV;
if (g_config.nDering_Y)
m_frame.general |= XVID_DERINGY;
if (g_config.nDering_UV)
m_frame.general |= XVID_DERINGUV;
if (g_config.nFilmEffect)
m_frame.general |= XVID_FILMEFFECT;
m_frame.brightness = g_config.nBrightness;
m_frame.output.csp &= ~XVID_CSP_VFLIP;
m_frame.output.csp |= rgb_flip^(g_config.nFlipVideo ? XVID_CSP_VFLIP : 0);
// Paranoid check.
if (xvid_decore_func == NULL)
return E_FAIL;

repeat :
if (pIn->IsPreroll() != S_OK)
{
length = xvid_decore_func(m_create.handle, XVID_DEC_DECODE, &m_frame, &stats);
/*我在想,该怎么对&m_frame里的数据进行操作,可以达到改变视频输出效果的目的? 比如:实现视频图像的上下翻转*/
if (length < 0)
{
DPRINTF("*** XVID_DEC_DECODE");
return S_FALSE;
} else
{后面的代码省略}

m_frame.output.plane[0] 是不是修改这个部分的指针,就是指向视频解码后的 YUV 数据?
jessiepan 2009-03-26
  • 打赏
  • 举报
回复
[Quote=引用 40 楼 luckyboy101 的回复:]
引用 1 楼 wwwllg 的回复:
IVideoWindow::put_FullScreenMode
The put_FullScreenMode method enables or disables full-screen video rendering.

Syntax

HRESULT put_FullScreenMode(
long FullScreenMode
);

就这个
[/Quote]

楼上的哥们,这个帖子里已经有你相关问题的解答,请仔细看看 :) 特别是 野蛮人 老大的回复,很有帮助!呵..
你再看看 DX SDK 里的文档!
jessiepan 2009-03-26
  • 打赏
  • 举报
回复
我是楼主!以后我的回复都用蓝色来标注吧..

我想在xvid.ax filter里来把解码后的视频图像做上下的翻转,请问我该怎么实现呢? 我在graphedit里查过了,xvid解码出来的视频是YUY2的,有没有哪位大哥能给一段代码可以实现把YUY2进行翻转的? 谢谢啊!

length = xvid_decore_func(m_create.handle, XVID_DEC_DECODE, &m_frame, &stats);

这是xvid解码部分的那段代码,解码后,我该怎么去操作那个&m_frame里的数据呢??


小弟俺实在是很无知,上午看了一下YUV方面的资料,对YUV422,YUV420 等等格式的东西,还是一知半解!搞不大明白.. 哎!
hhuc2001 2009-03-23
  • 打赏
  • 举报
回复
楼主:
“实现全屏显示视频图像,并且视频可以铺满整个屏幕窗口”这个怎么实现的?
播放视屏全屏的时候我发现总是按图像比例缩放,有黑边,图片就没这个问题。
jessiepan 2009-03-21
  • 打赏
  • 举报
回复
新手:在linux下装了fenice(FENG),想进行rtp/rtcp/rtsp的研究开发,请教如何快速有效的利用好这些库?

我是楼主,有没有在研究开源流媒体服务器的朋友?live555,spook? 有意的话希望可以联系一起探讨、学习

我的联系方式:MSN:pan_guo79@hotmail.com,QQ:12091637,上班时间一般都在线!加好友请发信息:CSDN,流媒体. 谢谢!
jessiepan 2009-03-21
  • 打赏
  • 举报
回复
我是楼主!

有个比较菜的问题,想问一下:我现在用ffdshow来做的MPEG4视频解码和显示,如果我想实现视频图像的翻转,该怎么做呢?是不是需要自己写一个图像翻转的算法,做成一个filter,然后插在ffdshow.ax and VMR(video renderer)的中间呢? 还有没有别的比较简单一点的实现方法?或是有没有这方面的参考例子?.. 哪位大哥可以提供一个啊!

谢谢先了 :)

jessiepan 2009-03-19
  • 打赏
  • 举报
回复
我是楼主! 谢谢楼上的各位朋友 :) 上面的问题都解决了.

借这个帖子,想再问个问题,不知道在嵌入式LINUX平台下(嵌入式设备)大家一般用什么开源的流媒体服务器? live555, spook ? 还是另有更好的选择??

希望也可以多结交一些做流媒体,做安防行业的朋友,我的联系方式:MSN:pan_guo79@hotmail.com,QQ:12091637,上班时间一般都在线!
jessiepan 2009-03-17
  • 打赏
  • 举报
回复
我是楼主! 终于搞定了,谢谢大家 :-)

FFDSHOW做视频解码的依赖库:ffdshow.ax(1372KB),libavcodec.dll(828KB),libmplayer.dll(144KB) 这是我裁减过后的文件大小.
注册表依赖: [HKEY_LOCAL_MACHINE\SOFTWARE\GNU\ffdshow] 这个注册表下记录了 ffdshow 的安装路径
[HKEY_CURRENT_USER\Software\GNU\ffdshow],[HKEY_CURRENT_USER\Software\GNU\ffdshow\default] 这个下面是记录 ffdshow 的初始化值。


现在还想把 FFDSHOW 再裁减得更小点,不知道有没有哪位高手知道如何把 ffdshow 工程里dialog、subtitles、xiph、decss等等那些目录全部都去掉?..

希望也可以多结交一些做流媒体,做安防行业的朋友, 我的联系方式: Msn:pan_guo79@hotmail.com ,QQ:12091637 , 上班时间一般都在线!
愿大家可以一起进步! thanks
zhoumingjie 2009-03-17
  • 打赏
  • 举报
回复
可以考虑用下 IBasicVideo::SetDestinationPosition
jessiepan 2009-03-13
  • 打赏
  • 举报
回复
谢谢楼上的朋友! 这个问题已经解决了, 现在可以实现全屏显示视频图像,并且视频可以铺满整个屏幕窗口.

裁减ffdshow也搞了好几天了,暂时定下来最后的版本,编译出来的ffdshow.ax 为1372KB,libavcodec.dll 828KB.现在要做的工作就是把ffdshow.ax and libavcodec.dll打包成CAB包,然后通过IE可以直接下载和安装里面的解码库,完成PC端的图像解码和显示.

现在问题又来了,CAB包里的文件可以通过IE远端下载,并且注册AX,但ffdshow貌似还是使用不了?经过一天的测试,发现ffdshow在使用的时候还依赖注册表? ffdshow注册表路径是[HKEY_CURRENT_USER\Software\GNU],把这个注册表信息导入,在某些电脑上ffdshow可以使用,在某些电脑上还是用不了?

以前一直以为要使用ffdshow完成PC端的MPEG4视频解码和显示,只需要ffdshow.ax and libavcodec.dll这两个文件就够了,现在看来还不完全是那么简单了..
但在 INF 文件里,要如何完成注册表信息的导入或是写注册表的工作呢? 有没有做过CAB包的高手,请指导一下偶啊!
我就是用IExpress这个小工具来生成CAB包的.
luckyboy101 2009-03-12
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 wwwllg 的回复:]
IVideoWindow::put_FullScreenMode
The put_FullScreenMode method enables or disables full-screen video rendering.

Syntax

HRESULT put_FullScreenMode(
long FullScreenMode
);
[/Quote]
就这个
jessiepan 2009-03-10
  • 打赏
  • 举报
回复
我是楼主.

这一两天继续做ffdshow的裁减,把部分video filter去掉了,现在编译出来的ffdshow.ax 为1372KB(之前是1880KB),离最开始的期望目标 1MB 左右,似乎是不太遥远了:)加油哦!

做完裁减,接着做裁减后ffdshow的功能性测试,使用该ffdshow.ax filter解码live图像连续播放两个小时,没有出现黑屏\断线现象.验证裁减后的ffdshow是基本上能够符合我们的应用需求的.

接下来,我还想问个问题,我手头上有ffdshow和xvid的源代码,但一般的多媒体播放程序怎么基于ffdshow\xvid的源代码用VC进行调试呢?难道是用F9设置断点,用F11跟踪进去? ffdshow.ax、xvid.ax 的filter在DSHOW的filter graph里,可以这样调试吗? 请问各位大虾有什么高招? 指导一下小菜菜偶啊!

jessiepan 2009-03-07
  • 打赏
  • 举报
回复
[Quote=引用 37 楼 czbever 的回复:]
IVideoWindow::put_FullScreenMode
可能是这个接口没实现吧
[/Quote]

谢谢楼上的朋友! 这个问题已经解决了, 现在可以实现全屏显示视频图像,并且视频可以铺满整个屏幕窗口.

昨天一天都在做ffdshow的裁减,把部分audio filter去掉了,现在编译出来的ffdshow.ax 为1880KB(没裁减之前的是ffdshow.ax 2076KB),并且解码LIVE图像已经连续播放3个小时,没有出现黑屏\断线现象.

今天打算做video filter部分的裁减, 最终目标是打算把ffdshow裁减到 1MB 左右!

裁减ffdshow是一件很痛苦的事情,去掉一个文件,要编译一次,然后要把相关引用的代码做屏蔽或是改动. 不知道有没有朋友在做这方面的工作?大家交流一下啊..
我的联系方式: MSN:pan_guo79@hotmail.com ,QQ:12091637 , 上班时间一般都在线!
希望大家可以一起学习,共同进步! thanks
jessiepan 2009-03-06
  • 打赏
  • 举报
回复
[Quote=引用 35 楼 rightorwrong 的回复:]
我现在也遇到了ffdshow播放视频时出现卡,花的现象。我是H264编码
这种现象我认为这是对接收过来的网络数据没有处理,应该对接收的数据进行帧的判断,接收到一帧才才应该给ffdshow

不过我们做的mpeg4是用裁剪过的ffdshow,没有出现你说的问题,如黑屏
[/Quote]

敢问这位大哥,你们裁减过的ffdshow是多大的, ffdshow.ax和libavcodec.dll分别是多大呢? 是你们自己裁减的吗?能不能教教小弟我啊?

我现在用完整版的ffdshow播放rtp网络视频流也不会有黑屏了,libavcodec.dll 828KB, ffdshow.ax 2076KB. 只是用低版本的ffdshow or xvid会有黑屏的现象..

谢谢楼上的大哥了! 如果你们裁减过的ffdshow符合我们的需求,能不能把你们裁减过后的ffdshow.ax and libavcodec.dll发给我来测试一下啊?thanks...
czbever 2009-03-06
  • 打赏
  • 举报
回复
IVideoWindow::put_FullScreenMode
可能是这个接口没实现吧
jessiepan 2009-03-05
  • 打赏
  • 举报
回复
[Quote=引用 31 楼 wwwllg 的回复:]
把这段代码去掉,看看效果先。
[/Quote]

老大,这段代码去掉了,效果是:过了一段时间,live视频图像卡在那里不动了,而且过了几分钟,我想下一个视频的关键帧应该也该到了吧,但图像依然没有被更新... 至少我看了10分钟,图像都一直卡在那里没动过

昨天测试,低版本的ffdshow果然也存在和xvid一样的问题,rtp丢帧,然后解码失败.. 看样子,做流媒体传输,rtp确实是不咋的!传输不可靠么?..

再次谢谢"野蛮人"老大!

希望也可以多结交一些做流媒体,做安防行业的朋友, 我的联系方式: Msn:pan_guo79@hotmail.com ,QQ:12091637 , 上班时间一般都在线!
希望大家可以一起进步! thanks
rightorwrong 2009-03-05
  • 打赏
  • 举报
回复
我现在也遇到了ffdshow播放视频时出现卡,花的现象。我是H264编码
这种现象我认为这是对接收过来的网络数据没有处理,应该对接收的数据进行帧的判断,接收到一帧才才应该给ffdshow

不过我们做的mpeg4是用裁剪过的ffdshow,没有出现你说的问题,如黑屏
jessiepan 2009-03-05
  • 打赏
  • 举报
回复
绕了一大圈,最后又绕回到ffdshow上来了,所有的问题归结为:ffdshow的裁减!? 因为ffdshow+rtp这样的组合,至少能保证在内网或是网络环境较好的条件下,流媒体的实现是相对来说稳定的,可以让人接受的. 至于公网上的效果如何,稳定性能不能让人接受,暂且咱先不说吧 ..

从http://sourceforge.net 上下载了这个版本ffdshow_beta1_20061211_src的源代码,在VS2003的环境下进行编译.针对libavcodec部分做了简单的裁减,将不需要的编码器全部去掉,解码器也只留下了mpeg4(xvid),其他的能裁减掉的也都尽可能去掉了.最后编译出来的大小为 libavcodec.dll 828KB, ffdshow.ax 2076KB. 我想要的结果是希望可以把 ffdshow.ax 裁减到 1MB 左右? 但因为ffdshow整个架构比较庞大,比较复杂,实在是不知道裁减它该从哪里入手? 主要是删除掉部分程序文件时,相关要改动的地方实在是太多了... 晕得很啊!..

在这里,希望可以得到有过裁减ffdshow经验的大虾的指点! 谢谢先了.

其实在这也希望可以多结交一些做流媒体,做安防行业网络视频监控的朋友, 我的联系方式: MSN:pan_guo79@hotmail.com ,QQ:12091637 , 上班时间一般都在线!
希望大家可以一起学习,共同进步! thanks
加载更多回复(32)

2,543

社区成员

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

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