ChinaFFmpeg

 找回密码
 立即注册

QQ登录

只需一步,快速开始

查看: 16573|回复: 12

[Windows] av_codec_open2()失败问题

[复制链接]
发表于 2013-11-5 09:48:01 | 显示全部楼层 |阅读模式
应用背景:
共8路视频监控,每次播放4路,播放10s, 然后切换另外4路监控,如此循环, 程序中使用4个线程进行解码,在开始时,程序正常,执行一段时间后(可能半小时, 也可能一小时),av_codec_open2执行失败, 返回错误码-22,且导致崩溃,弹出系统的, 后经查资料, 发现av_codec_open2非线程安全, 于是给av_codec_open2添加临界区:
[C++] 纯文本查看 复制代码
	
CCriticalSection csH264;//全局
AVCodecContext *m_pCodecCtx;
int decode(....) //解码函数
{
    if (m_pCodecCtx == NULL)
    { 
        AVCodec *pCodec = avcodec_find_decoder(CODEC_ID_H264);
        if (!pCodec)
        return 0; 
        m_pCodecCtx = avcodec_alloc_context3(pCodec); 
        if(!m_pCodecCtx)
            return 0;
       csH264.Lock();//对open2加锁保护
       if (avcodec_open2(m_pCodecCtx, pCodec, NULL) < 0)
       {
              reset();
              csH264.Unlock();
              return 0; 
       }
       csH264.Unlock();

       ......//avcodec_alloc_frame
}





但是添加完锁之后发现, 依然会有失败导致的崩溃问题, 只不过时间久了点,后来又在上面代码的reset()函数中加了锁,reset函数主要是释放资源用
[C++] 纯文本查看 复制代码
int CodecH264::reset()
{
	csH264.Lock();
	if(m_pCodecCtx)
	{
		   avcodec_close(m_pCodecCtx); 
		av_free(m_pCodecCtx);
		m_pCodecCtx = NULL;
	}
	if(m_pFrame)
	{
		av_frame_free(&m_pFrame);
		m_pFrame = NULL;
	}
	csH264.Unlock();




通过对reset也加锁之后, 崩溃问题消失, 对于avcodec_open2加锁, 是有据可依, 但不知道为何非要对reset函数也加锁呢? 请高手解答,谢谢!


本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
回复

使用道具 举报

发表于 2013-11-5 12:19:12 | 显示全部楼层
因为你是做线程控制的吧,reset会free ctx和frame,而其他任务有可能会用到,这个时候你把它free了,就出问题了
回复 支持 反对

使用道具 举报

 楼主| 发表于 2013-11-5 15:52:38 | 显示全部楼层
T-Bagwell 发表于 2013-11-5 12:19
因为你是做线程控制的吧,reset会free ctx和frame,而其他任务有可能会用到,这个时候你把它free了,就出问 ...

每个线程都有单独的ctx和frame, 只有临界区是全局变量
回复 支持 反对

使用道具 举报

发表于 2013-11-5 17:50:32 | 显示全部楼层
m_pCodecCtx 这个是什么呢?看上去像是global区域的
回复 支持 反对

使用道具 举报

 楼主| 发表于 2013-11-5 18:07:32 | 显示全部楼层
T-Bagwell 发表于 2013-11-5 17:50
m_pCodecCtx 这个是什么呢?看上去像是global区域的

这个是个成员变量, 每次视频开始的时候会初始化, 结束的时候就reset释放了
回复 支持 反对

使用道具 举报

发表于 2013-11-5 22:37:32 | 显示全部楼层
查下 -22 是什么错误;估计你共用内存了。
回复 支持 反对

使用道具 举报

发表于 2013-11-5 22:38:13 | 显示全部楼层
搞2个线程看看。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2013-11-6 09:19:27 | 显示全部楼层
keyix 发表于 2013-11-5 22:38
搞2个线程看看。

-22 是个参数错误, 1个线程是没问题的, 2个线程没试过, 所以怀疑是ffmpeg的问题还是我的问题
回复 支持 反对

使用道具 举报

 楼主| 发表于 2013-11-6 09:19:48 | 显示全部楼层
keyix 发表于 2013-11-5 22:38
搞2个线程看看。

-22 是个参数错误, 1个线程是没问题的, 2个线程没试过, 所以怀疑是ffmpeg的问题还是我的问题
回复 支持 反对

使用道具 举报

发表于 2013-11-6 10:12:02 | 显示全部楼层
wangbingwf 发表于 2013-11-6 09:19
-22 是个参数错误, 1个线程是没问题的, 2个线程没试过, 所以怀疑是ffmpeg的问题还是我的问题  ...

应该是你的问题
因为我也多线程玩过,或者你不free试试,应该就不会有这个问题了,但是会泄漏其实就是因为你free了,然后其他的thread用到了共用内存了,就-EINVAL了
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|Archiver|ChinaFFmpeg

GMT+8, 2024-4-20 23:26 , Processed in 0.086312 second(s), 16 queries .

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表