【新手紧急求助】:加载并运行OCX控件,导致IE浏览器页面崩溃的问题?

jessiepan 2010-05-31 04:07:51
用VC++6.0写了个有窗口的MFC OCX控件,实现实时网络音视频流的解码和播放,在IE6.0(IE7或IE8也会存在同样的问题)中加载该控件并运行后,可以正常的解码\播放音视频.但发现按F5刷新显示页面一次或多次后,出现IE页面崩溃! 晕啊...
错误提示如下:
iexplore.exe--应用程序错误
"0x77c1840c" 指令引用的"0x00000000"内存.该内存不能为"read"
要终止程序,请点击"确定".
要调试程序,请点击"取消".


请高手过来帮帮忙!谢了
...全文
65264 点赞 收藏 56
写回复
56 条回复
切换为时间正序
当前发帖距今超过3年,不再开放新的回复
发表回复
Leson_Yin 2012-12-28
遇到了你主题的问题,执行一下控件 ,浏览器cpu就50% 直至崩溃,我也跟着崩溃了。。。郁闷啊。。
回复
jessiepan 2011-03-11
我是楼主,呵呵,借贵宝地再问个问题。

最近,在嵌入式的处理器Ambarella A2平台上,开发H.264 1080P的ipcam,使用Live555作为StreamServer,完成视音频的RTSP、RTP传输。现在已经将A2 encode出来的video data通过有名管道推给rtsp_server,PC端用VLC1.0.1也可以打开rtsp://192.168.1.238/stream1链接,看到视频图像。

目前的问题:
rtsp_server这个进程大概每次运行不超过10分钟,有时候两三分钟,有时候五六分钟,有时候10几分钟,就会挂掉,提示:Segmentation fault!导致Vlc自动关闭,或是直接crash掉。。。?
因为代码比较多,一下子也不太好找,具体是哪个地方的问题。。初步怀疑,可能是自己写的一个FIFO Buffer哪里没写好?
想请教高手,有没有什么好的办法或是辅助工具,来调试嵌入式板子上跑的arm-linux程序呢?GDB用起来,貌似不是很方便吧。。

前几天在官网下载了valgrind-3.6.1的源代码,编译了一个arm-linux版的。
./configure --host=armv7-none-linux-gnueabi --prefix=/home/valgrind-3.6.1-armlinux CC=/usr/local/arm-2008ql/bin/arm-none-linux-gnueabi-gcc
make;make install
在ARM9板子上使用valgrind工具,如下:
# ./valgrind -tool=memcheck rtsp_server
==444== Memcheck, a memory error detector
==444== Copyright (C) 2002-2010, and GNU GPL'd, by Julian Seward et al.
==444== Using Valgrind-3.6.1 and LibVEX; rerun with -h for copyright info
==444== Command: rtsp_server
==444==
--444-- WARNING: Serious error when reading debug info
--444-- When reading debug info from /usr/local/bin/rtsp_server:
--444-- Ignoring non-Dwarf2/3/4 block in .debug_info
--444-- WARNING: Serious error when reading debug info
--444-- When reading debug info from /usr/local/bin/rtsp_server:
--444-- Only DWARF version 2, 3 and 4 line info is currently supported.
--444-- WARNING: Serious error when reading debug info
--444-- When reading debug info from /usr/local/bin/rtsp_server:
--444-- Only DWARF version 2, 3 and 4 line info is currently supported.
### unhandled dwarf2 abbrev form code 0x0
### unhandled dwarf2 abbrev form code 0x0
### unhandled dwarf2 abbrev form code 0x0
### unhandled dwarf2 abbrev form code 0x0
### unhandled dwarf2 abbrev form code 0x0
Segmentation fault

想请问高手,从上面的提示信息,能看出我的程序rtsp_server是具体哪个地方有问题吗?valgrind这个工具,我还不怎么会用,请大虾指点下啊。。
回复
jessiepan 2011-01-21
这几天又把CUDA SDK的文档和cudaDecodeD3D9的代码好好看了下,原来是在执行cudaDecodeD3D9.exe后面还要带参数,"-displayvideo",好了,现在终于有图像显示出来了。
plush1_720p_10s.m2v,这个是cudaDecodeD3D9 sample里自带的视频文件,MPEG2格式,可以用cudaDecodeD3D9.exe解码和播放出来;然后我在网上随意下载的一个MPEG4视频文件(非720P和1080P),测试了下,也是OK的。
但我用网上下载的高清电影,x264压制的mkv文件,720P和1080P,测试了,均不行?在VS2008里单步调试,发现 CUresult oResult = cuvidCreateVideoSource(&hVideoSource_, sFileName.c_str(), &oVideoSourceParameters); 这个函数报错,返回 CUDA_ERROR_INVALID_SOURCE ?

还请高人过来,解答下啊!郁闷咯。。。

我的软硬件环境:双敏Nvidia Geforce GTS450显卡,显存1GB;CUDA SDK 3.2;Developer Drivers for WinXP (263.06) 32bit,这个都是从NVIDIA官网上下载的显卡驱动。
我看文档里写,CUDA Video Decoder不是都可以支持MPEG-2/VC-1/MPEG-4 ASP/H.264/AVCHD/JPEG这些格式的么?怎么我下的1080P、720P电影打不开呢??
回复
jessiepan 2011-01-13
[Quote=引用 51 楼 ncistcn 的回复:]
调试运行。报错后。看栈
[/Quote]

调试运行,报错后,看栈,发现堆栈里都是系统级的DLL,比如:ntdll.dll,kernel32.dll,断点的代码都是汇编的.经高人指点,才知道要加载一个系统DLL的符号表.谢谢"成都紫荆(狮子)"!
在VS2008的Tools\Options\Debugging\Symbols,设置一个本地磁盘的路径,用来保存系统的DLL的PDB文件.确定以后,选中堆栈里的所有内容,然后右击,有一个是Load Symbols From,选Microsoft Symbols Server,然后就要等相当 一会,等全部下载完了,以后调试的时候,栈会更清楚一些.

嗯,现在问题都解决了.
第一,分辨率改变的时候有重启解码器,不过,那段代码放的地方有问题,程序并没有执行过来?改正了;
第二,程序有使用音频输入设备,创建了waveIN Thread,但程序退出的时候,没有stop waveIN Thread.修正了该bug.

这几天下了一个GPUComputingSDK_3.2.12_win_32.exe和CudaToolkit_3.2.12_win_32.msi,想研究一下NVIDIA的CUDA.不知道这里有没有朋友在用CUDA做视频的硬编或硬解的?
运行了SDK里的samples,cudaDecodeD3D9.exe和cudaDecodeGL.exe,为何他Demo里720P的视频图像出不来呢?难道是我的显卡GeForce GTS450和CUDA SDK的代码不匹配,GPU不被支持??
回复
iloveinru 2010-12-30
同样的问题,SPS求宽高,还有解码报错~

解码报错我判断基本上应该是P帧队列的问题,如果都使用I帧好像不报错,分辨率大了P帧队列内存容易满?

SPS求宽高我直接用p[6],p[7],p[8]就可以求,但是不完全对。
回复
崇山峻岭_ 2010-12-29
调试运行。报错后。看栈
回复
dengzikun 2010-12-27
这个崩溃也许比较麻烦。可以尝试改变分辨率时,先销毁解码器,再重建。
回复
jessiepan 2010-12-27
嗯,dengzikun 老大,下载了你最新的代码,可以了.谢谢!
其实,我只需要可以动态的创建和销毁画布的功能,就行了..
D3D显示,视频撕裂的现象后来也查出来是我电脑的问题,换了台电脑,就OK了:)

不过,现在又发现一个比较棘手的新问题:
在更改视频分辨率的时候,偶尔会发生avcodec_decode_video函数报内存访问错误?
//解码
int CVideoDecode::DecodeYV12(unsigned char *szImage, int nImageLen)
{
if(!m_bInitDecode)
return -1 ;

nGet = avcodec_decode_video(pDCodecCtx, pDPicture, &frameFinished,
szImage, nImageLen);
int size;
size = avpicture_get_size(pDCodecCtx->pix_fmt,pDCodecCtx->width,pDCodecCtx->height);
if (videoFrameBufferYUV == NULL)
{
videoFrameBufferYUV = (uint8_t *)av_malloc(size);
}

if ( frameFinished != 0)
{
int size;
size = avpicture_get_size(pDCodecCtx->pix_fmt,pDCodecCtx->width,pDCodecCtx->height);
// read the data to the buffer
avpicture_layout((AVPicture *)pDPicture,pDCodecCtx->pix_fmt,pDCodecCtx->width,pDCodecCtx->height,videoFrameBufferYUV,size);
}

return nGet ;
}

//停止解码器
void CVideoDecode::stopDecode()
{
if(m_bInitDecode)
{
avcodec_close(pDCodecCtx);
av_freep(&videoFrameBufferYUV);
av_free(pDPicture);
videoFrameBufferYUV = NULL;
m_bInitDecode = FALSE ;
}
}

//启动解码器
BOOL CVideoDecode::startDecode(int nVideoCode)
{
if(m_bInitDecode)
return TRUE ;

//解码
if(nVideoCode == 1)
pDCodec = avcodec_find_decoder(CODEC_ID_MPEG4) ;
else if(nVideoCode == 2)
pDCodec = avcodec_find_decoder(CODEC_ID_H264) ;
else if(nVideoCode == 3)
pDCodec = avcodec_find_decoder(CODEC_ID_MJPEG) ;
else
{
::MessageBox(NULL,"启动解码失败:找不到对应的解码库!","初始化解码过程提
示!",MB_ICONWARNING|MB_OK) ;
return FALSE ;
}

pDCodecCtx = avcodec_alloc_context();
pDPicture = avcodec_alloc_frame();

if(avcodec_open(pDCodecCtx,pDCodec)<0)
{
::MessageBox(NULL,"启动解码失败:打开库失败!","初始化解码过程提
示!",MB_ICONWARNING|MB_OK) ;
return FALSE ;
}

m_bInitDecode = TRUE ;
return TRUE ;
}
更改完分辨率后,偶尔(请注意:不是每一次!)执行到下面的解码函数时,会报错?
nGet = avcodec_decode_video(pDCodecCtx, pDPicture, &frameFinished,
szImage, nImageLen);
Unhandled exception at 0x6ada5f20 in IEXPLORE.EXE: 0xC0000005: Access violation reading location 0x06a392e8.

我在每次更改完分辨率后,代码里会先stopDecode,然后startDecode,重新启动解码器.不知道,是啥原因会导致avcodec_decode_video报内存错误呢??
回复
dengzikun 2010-12-23
1.简单处理的话,不改变画布的分辨率,把图像铺满整个画布即可,这会导致图像缩放。
2.去我博客下载新的代码,支持多窗口的,多个画布。
回复
jessiepan 2010-12-23
刚仔细测试了下,具体情况分为以下两种:
第一,当初始化的视频分辨率为720P时,按你的理解,即:创建的画布大小为1280*720;更改分辨率为720*480后,视频并没有铺满整个视频显示窗口,而只是占据了显示窗口的一部分,从左上角开始,尺寸比例,大概为720*480 比 1280*720,原始窗口的一部分。

第二种情况,我想老大你应该也猜得到了。当初始化的视频分辨率为720*480时,按你的理解,即:创建的画布大小为720*480;更改分辨率为1280*720后,视频并没有显示完整出来。而只是将原本720P的视频显示出了一部分,720*480。

导致这两种情况发生,引用老大你自己的话,就是,创建的画布大小和在画布上进行的绘画分辨率不匹配造成的?第一种情况是,画布大了,所以绘画并没有完全充满整个画布;第二种情况是,画布小了,所以绘画的内容没有全部显示出来。。

dengzikun 老大,小弟的想法是,CreateBackBuffer是不是在视频显示的分辨率改变后,也要重新创建一次呢? 为何你提供的D3DVideoRender DLL里,没有DestroyBackBuffer?是不是需要DestroyDevice后,重新创建一次CreateDevice D3D?
老大,你以前没测试过更改视频分辨率的这种情况吗??
回复
dengzikun 2010-12-23
CreateBackBuffer创建的相当于是画布,所有的绘画都是在画布中进行的。

你说改变分辨率后的图像不对,具体是什么情况。
回复
jessiepan 2010-12-23
嗯。有空的话,在Win7下搭一个开发环境,再编译,测试看看。。

老大,分辨率的问题,重新创建一个image buffer,还是不行?你帮我看看,部分代码如下:
BOOL CVideoRenderD3D::Init(HWND hWnd,int width,int height)
{
if(m_bDrawInitSuccFlag)
return FALSE ;//已经初始化

m_hwnd = hWnd;
if(m_pD3DVRInterfac)
return TRUE ;

m_pD3DVRInterfac = D3D_VIDEO_RENDER::D3D_Video_Render_Create () ;
if ( m_pD3DVRInterfac == NULL )
{
return false ;
}

if ( !m_pD3DVRInterfac->CreateBackBuffer(m_hwnd, width, height))
{
return false ;
}

RECT rect ;
rect.left = 0;
rect.top = 0;
rect.right = rect.left + width ;
rect.bottom = rect.top + height ;

bool bret = m_pD3DVRInterfac->CreateImageBuffer( &dwImageIndex, width, height, ID3DVRInterface::CS_I420, &rect ) ;
if ( !bret )
{
return false ;
}

m_bDrawInitSuccFlag = TRUE ;
return true;
}

BOOL CVideoRenderD3D::ChangeRes(int width,int height)
{

if ( m_pD3DVRInterfac == NULL )
{
return false ;
}

m_pD3DVRInterfac->DestroyImageBuffer(dwImageIndex);

RECT rect ;
rect.left = 0;
rect.top = 0;
rect.right = rect.left + width ;
rect.bottom = rect.top + height ;
bool bret = m_pD3DVRInterfac->CreateImageBuffer( &dwImageIndex, width, height, ID3DVRInterface::CS_I420, &rect ) ;
if ( !bret )
{
return false ;
}

return true;
}

在改变分辨率的时候,我是先执行DestroyImageBuffer,然后再执行CreateImageBuffer,重新创建一次
image buffer。不过,貌似改变分辨率后的视频图像,不对。。

dengzikun 老大,是不是改变分辨率后,跟这个BackBuffer,也有关系啊?我看,CreateBackBuffer这个函数的参数里,不是也有width和height吗?现在这两个值是变化了的。。。
回复
dengzikun 2010-12-22
没有在WIN7下跑过,所以具体是什么问题不好说,只能说在WIN7重新编译看
是什么问题。

分辨率的问题,你可以重新创建一个image buffer即可。
回复
jessiepan 2010-12-22
win7下没有试过,有人也反应说有问题。

据说dx9在win7下是模拟执行。你可以编译后试试,别忘了告诉我结果。
==============================================================
老大,貌似这种说法不太对吧?我在Win7下跑了几个DX SDK9.0a里D3D9的samples,是正常的。而且很多用D3D9写的游戏,不是在WinXP和Win7下都可以运行的么?
我在 Win7 下装了一个[古墓丽影-10周年纪念版].Tomb_Raider_Anniversary-HATRED的游戏,玩起来,感觉很cool啊!

dengzikun 老大,在用你那个D3DVideoRender的时候,还发现个小麻烦!如果我渲染的视频尺寸大小需要经常变换,该如何处理呢?比如:视频分辨率本来是1080P,现在要改成720P,或D1,CIF的话,是不是你D3DVideoRender的代码里,当初没考虑过这个问题?。。
我目前测试了下你的代码,是不行的 :(
回复
dengzikun 2010-12-15
[Quote=引用 41 楼 jessiepan 的回复:]
我的电脑配置,
CPU: 英特尔 Core i5 760 2.80GHz
主板: 华硕P7H55
内存: 海盗船 DDR3 1600MHz,4GB
显卡: 双敏Nvidia Geforce GTS450,显存1GB
硬盘: 日立,1TB
显示器:飞利浦 Philips 224E(21.7英寸)

不知道是不是我显卡有点问题,又或是NV显卡 260.63 驱动程序的问题?
我再在其……
[/Quote]

win7下没有试过,有人也反应说有问题。

据说dx9在win7下是模拟执行。你可以编译后试试,别忘了告诉我结果。
回复
jessiepan 2010-12-15
我的电脑配置,
CPU: 英特尔 Core i5 760 2.80GHz
主板: 华硕P7H55
内存: 海盗船 DDR3 1600MHz,4GB
显卡: 双敏Nvidia Geforce GTS450,显存1GB
硬盘: 日立,1TB
显示器:飞利浦 Philips 224E(21.7英寸)

不知道是不是我显卡有点问题,又或是NV显卡 260.63 驱动程序的问题?
我再在其他电脑上测试,再查查看..

dengzikun 老大,我想再请教你下,为何你VR_Test的Demo程序在 WIN7(我安装的是中文旗舰版)下运行,视频图像出不来,是黑屏;而且过一段时间后,WIN7下报视频驱动程序停止工作的错误呢?应该在WIN7下可以向下兼容的吧? D3D9 写的程序,在 WIN7 跑不了么??
回复
dengzikun 2010-12-14
你的显卡跑1080P应该没问题。
主板应该也不差吧,我以前遇到过主板导致的撕裂问题。

你下载新的DX9 SDK试试。

D3DPRESENT_INTERVAL_ONE就是做垂直同步,防撕裂的。

也可以试着修改显卡的一些3D属性,如垂直同步,三缓冲等。

我的GeForce 9800 GT跑720P, 1080P没有问题。
回复
jessiepan 2010-12-14
dengzikun 老大,不好意思!今天再仔细测试了一下D3D的显示程序,发现在运动量不是很大的情况下,竟然有画面撕裂的现象??晕... 我显示的视频大小是1080P的,1920*1080.
前几天可能是没仔细测试,只看了显示静态画面的效果..

我这的测试环境是,VC++ 2008(SP1) + D3D9.0a SDK 编译,NVIDIA GeForce GTS450 显卡,驱动程序版本是260.63
是我显卡的问题,还是驱动程序的问题,又或是DX SDK的版本太低了的原因?

m_PresentParams.PresentationInterval = D3DPRESENT_INTERVAL_ONE;
这个D3D的初始化,这样写,应该是不会有画面撕裂的效果出现才对呀..?
回复
dengzikun 2010-12-13
[Quote=引用 36 楼 jessiepan 的回复:]
enum GEOMETRIC_TRANSFORMATION
{
Upper_Down_Flip = 1, // 图像上下翻转
Not_Upper_Down_Flip = 2,
Left_Right_Mirror = 3, // 图像左右镜像
Upper_Right_Mirror = 4 // 图像左右镜像并且上下翻转
};

呵呵,dengzikun 老大,在你原来代码的基础上加了……
[/Quote]

所谓不支持全屏,是指D3D中的应用程序独占显卡的全屏模式。
这里实现的全屏,如你所说,是把窗口放大为全屏,和独占模式的全屏相比,是伪全屏。
回复
CyberLogix 2010-12-13
指针地址无效,
回复
加载更多回复
相关推荐
发帖
多媒体/流媒体开发
创建于2007-08-27

2458

社区成员

专题开发/技术/项目 多媒体/流媒体开发
申请成为版主
帖子事件
创建了帖子
2010-05-31 04:07
社区公告
暂无公告