da s
1:原理
ffmpeg读取出来一个包如果是视频包放入视频包队列,如果是音频包放入音频包队列。
视频:从视频队列中取出一个包解码根绝帧率或pts等等算出一帧数据的持续时间将这一帧数据放入VideoPicture这个结构体的bmp中,这只是内存,还未到显示,根据,Sleep()控制时间显示这一帧视频,并算出下一次刷新的时间,此时消耗了一个VideoPicture这个结构体的bmp。重新循环。
音频:从音频队列中取出一个包解码,SDL_AudiOSpec这个结构体SDL已经算出了一帧音频的持续时间,所以音频将解码后的数据放入SDL缓存的末尾,并传给声卡,声卡消耗数据的大小和时间是前面能算出来的,所以一直在播放。
2:程序初始化InitProgram()
程序启动做的初始化 打开编解码库 SDL初始化等,音视频全局结构体StreamState初始化,获取全屏的屏幕宽高,设置SDL事件状态。全局结构体StreamState只初始化一次,以及成员变量的清零等。
3:程序释放UinitProgram()
音视频全局结构体StreamState释放。关闭编解码库 ,sdl库释放,以及成员变量的清零等。
4:变量的初始化InitVariable()
这里除了需要将变量设成默认值之外 还要做
//创建全局条件变量互斥变量
m_streamstate->pictq_mutex = SDL_CreateMutex();
m_streamstate->pictq_cond = SDL_CreateCond();
//刷新packet初始化
av_init_packet(&m_flush_pkt);
m_flush_pkt.data = (uint8_t *)(intptr_t)"FLUSH";
5:变量的释放UinitVariable()
要将成员变量的值最处理清零或设成默认值,还有一些工作
还要将音视频的解码线程关掉
6:获取程序初始化的时候控件的位置Access_control_position()
这个的作用是当改变窗口大小的时候需要将控件的大小以及位置做调整
7:On_Size
这里首先做控件的调整
获取要显示窗口宽高
8:文件打开获取信息OnBnClickedButtonLoad()
extern int m_video_stream_idx; //视频在文件中的流标号
extern double m_dbFrameRate; //视频帧率
extern double m_video_duration; //视频单帧持续时间 秒(s)
extern int m_dwWidth; //宽
extern int m_dwHeight; //高
extern AVCodecID m_video_codecID; //视频编码类型
extern AVPixelformat m_video_pixelfromat; //视频yuv类型
extern char m_spspps[100]; //spspps_buf
extern int m_spspps_size; //spspps_size
//audio pram
extern int m_audio_stream_idx; //音频在文件中的流标号
extern double m_audio_duration; //音频单帧持续时间 秒(s)
extern int m_dwChannelCount; //声道
extern int m_dwBitsPerSample; //样本
extern int m_dwFrequency;
本文说明再用dup做重定向的时候遇到的一些坑做一些总结。
1:FFMPEG的所有输出信息,都为错误输出流,用STDOUT_FILENO是捕获不到任何消息,必须用STDERR_FILENO,这里是个大坑;
2:子进程pid == 0 这一段代码走完返回后还会将主进程调用本函数之后的代码走一遍;
3:循环sleep要刷新fflush(stdout);才能在标准输出中输出到管道否则失败;
4:传入execvp的第二个参数argv类型为,char * execargv[LVSM_DEFAULT_STRING_LEN];当把前面的各个参数写入后 ,必须这样写execargv[pos] = NULL;否则失败,不能sprintf(execargv[pos],"%s",(char*)(0));或者,sprintf(execargv[pos],"%d",0);
5:代码中有匿名管道改成非阻塞的,否则read会卡住不返回。
本文说明再用dup做重定向的时候遇到的一些坑做一些总结。
1:FFMPEG的所有输出信息,都为错误输出流,用STDOUT_FILENO是捕获不到任何消息,必须用STDERR_FILENO,这里是个大坑;
2:子进程pid == 0 这一段代码走完返回后还会将主进程调用本函数之后的代码走一遍;
3:循环sleep要刷新fflush(stdout);才能在标准输出中输出到管道否则失败;
4:传入execvp的第二个参数argv类型为,char * execargv[LVSM_DEFAULT_STRING_LEN];当把前面的各个参数写入后 ,必须这样写execargv[pos] = NULL;否则失败,不能sprintf(execargv[pos],"%s",(char*)(0));或者,sprintf(execargv[pos],"%d",0);
5:代码中有匿名管道改成非阻塞的,否则read会卡住不返回。
本文说明再用dup做重定向的时候遇到的一些坑做一些总结。
1:FFMPEG的所有输出信息,都为错误输出流,用STDOUT_FILENO是捕获不到任何消息,必须用STDERR_FILENO,这里是个大坑;
2:子进程pid == 0 这一段代码走完返回后还会将主进程调用本函数之后的代码走一遍;
3:循环sleep要刷新fflush(stdout);才能在标准输出中输出到管道否则失败;
4:传入execvp的第二个参数argv类型为,char * execargv[LVSM_DEFAULT_STRING_LEN];当把前面的各个参数写入后 ,必须这样写execargv[pos] = NULL;否则失败,不能sprintf(execargv[pos],"%s",(char*)(0));或者,sprintf(execargv[pos],"%d",0);
5:代码中有匿名管道改成非阻塞的,否则read会卡住不返回。
本文说明再用dup做重定向的时候遇到的一些坑做一些总结。
1:FFMPEG的所有输出信息,都为错误输出流,用STDOUT_FILENO是捕获不到任何消息,必须用STDERR_FILENO,这里是个大坑;
2:子进程pid == 0 这一段代码走完返回后还会将主进程调用本函数之后的代码走一遍;
3:循环sleep要刷新fflush(stdout);才能在标准输出中输出到管道否则失败;
4:传入execvp的第二个参数argv类型为,char * execargv[LVSM_DEFAULT_STRING_LEN];当把前面的各个参数写入后 ,必须这样写execargv[pos] = NULL;否则失败,不能sprintf(execargv[pos],"%s",(char*)(0));或者,sprintf(execargv[pos],"%d",0);
5:代码中有匿名管道改成非阻塞的,否则read会卡住不返回。
本文说明再用dup做重定向的时候遇到的一些坑做一些总结。
1:FFMPEG的所有输出信息,都为错误输出流,用STDOUT_FILENO是捕获不到任何消息,必须用STDERR_FILENO,这里是个大坑;
2:子进程pid == 0 这一段代码走完返回后还会将主进程调用本函数之后的代码走一遍;
3:循环sleep要刷新fflush(stdout);才能在标准输出中输出到管道否则失败;
4:传入execvp的第二个参数argv类型为,char * execargv[LVSM_DEFAULT_STRING_LEN];当把前面的各个参数写入后 ,必须这样写execargv[pos] = NULL;否则失败,不能sprintf(execargv[pos],"%s",(char*)(0));或者,sprintf(execargv[pos],"%d",0);
5:代码中有匿名管道改成非阻塞的,否则read会卡住不返回。
本文说明再用dup做重定向的时候遇到的一些坑做一些总结。
1:FFMPEG的所有输出信息,都为错误输出流,用STDOUT_FILENO是捕获不到任何消息,必须用STDERR_FILENO,这里是个大坑;
2:子进程pid == 0 这一段代码走完返回后还会将主进程调用本函数之后的代码走一遍;
3:循环sleep要刷新fflush(stdout);才能在标准输出中输出到管道否则失败;
4:传入execvp的第二个参数argv类型为,char * execargv[LVSM_DEFAULT_STRING_LEN];当把前面的各个参数写入后 ,必须这样写execargv[pos] = NULL;否则失败,不能sprintf(execargv[pos],"%s",(char*)(0));或者,sprintf(execargv[pos],"%d",0);
5:代码中有匿名管道改成非阻塞的,否则read会卡住不返回。
本文说明再用dup做重定向的时候遇到的一些坑做一些总结。
1:FFMPEG的所有输出信息,都为错误输出流,用STDOUT_FILENO是捕获不到任何消息,必须用STDERR_FILENO,这里是个大坑;
2:子进程pid == 0 这一段代码走完返回后还会将主进程调用本函数之后的代码走一遍;
3:循环sleep要刷新fflush(stdout);才能在标准输出中输出到管道否则失败;
4:传入execvp的第二个参数argv类型为,char * execargv[LVSM_DEFAULT_STRING_LEN];当把前面的各个参数写入后 ,必须这样写execargv[pos] = NULL;否则失败,不能sprintf(execargv[pos],"%s",(char*)(0));或者,sprintf(execargv[pos],"%d",0);
5:代码中有匿名管道改成非阻塞的,否则read会卡住不返回。
本文说明再用dup做重定向的时候遇到的一些坑做一些总结。
1:FFMPEG的所有输出信息,都为错误输出流,用STDOUT_FILENO是捕获不到任何消息,必须用STDERR_FILENO,这里是个大坑;
2:子进程pid == 0 这一段代码走完返回后还会将主进程调用本函数之后的代码走一遍;
3:循环sleep要刷新fflush(stdout);才能在标准输出中输出到管道否则失败;
4:传入execvp的第二个参数argv类型为,char * execargv[LVSM_DEFAULT_STRING_LEN];当把前面的各个参数写入后 ,必须这样写execargv[pos] = NULL;否则失败,不能sprintf(execargv[pos],"%s",(char*)(0));或者,sprintf(execargv[pos],"%d",0);
5:代码中有匿名管道改成非阻塞的,否则read会卡住不返回。
本文说明再用dup做重定向的时候遇到的一些坑做一些总结。
1:FFMPEG的所有输出信息,都为错误输出流,用STDOUT_FILENO是捕获不到任何消息,必须用STDERR_FILENO,这里是个大坑;
2:子进程pid == 0 这一段代码走完返回后还会将主进程调用本函数之后的代码走一遍;
3:循环sleep要刷新fflush(stdout);才能在标准输出中输出到管道否则失败;
4:传入execvp的第二个参数argv类型为,char * execargv[LVSM_DEFAULT_STRING_LEN];当把前面的各个参数写入后 ,必须这样写execargv[pos] = NULL;否则失败,不能sprintf(execargv[pos],"%s",(char*)(0));或者,sprintf(execargv[pos],"%d",0);
5:代码中有匿名管道改成非阻塞的,否则read会卡住不返回。
本文说明再用dup做重定向的时候遇到的一些坑做一些总结。
1:FFMPEG的所有输出信息,都为错误输出流,用STDOUT_FILENO是捕获不到任何消息,必须用STDERR_FILENO,这里是个大坑;
2:子进程pid == 0 这一段代码走完返回后还会将主进程调用本函数之后的代码走一遍;
3:循环sleep要刷新fflush(stdout);才能在标准输出中输出到管道否则失败;
4:传入execvp的第二个参数argv类型为,char * execargv[LVSM_DEFAULT_STRING_LEN];当把前面的各个参数写入后 ,必须这样写execargv[pos] = NULL;否则失败,不能sprintf(execargv[pos],"%s",(char*)(0));或者,sprintf(execargv[pos],"%d",0);
5:代码中有匿名管道改成非阻塞的,否则read会卡住不返回。
本文说明再用dup做重定向的时候遇到的一些坑做一些总结。
1:FFMPEG的所有输出信息,都为错误输出流,用STDOUT_FILENO是捕获不到任何消息,必须用STDERR_FILENO,这里是个大坑;
2:子进程pid == 0 这一段代码走完返回后还会将主进程调用本函数之后的代码走一遍;
3:循环sleep要刷新fflush(stdout);才能在标准输出中输出到管道否则失败;
4:传入execvp的第二个参数argv类型为,char * execargv[LVSM_DEFAULT_STRING_LEN];当把前面的各个参数写入后 ,必须这样写execargv[pos] = NULL;否则失败,不能sprintf(execargv[pos],"%s",(char*)(0));或者,sprintf(execargv[pos],"%d",0);
5:代码中有匿名管道改成非阻塞的,否则read会卡住不返回。
本文说明再用dup做重定向的时候遇到的一些坑做一些总结。
1:FFMPEG的所有输出信息,都为错误输出流,用STDOUT_FILENO是捕获不到任何消息,必须用STDERR_FILENO,这里是个大坑;
2:子进程pid == 0 这一段代码走完返回后还会将主进程调用本函数之后的代码走一遍;
3:循环sleep要刷新fflush(stdout);才能在标准输出中输出到管道否则失败;
4:传入execvp的第二个参数argv类型为,char * execargv[LVSM_DEFAULT_STRING_LEN];当把前面的各个参数写入后 ,必须这样写execargv[pos] = NULL;否则失败,不能sprintf(execargv[pos],"%s",(char*)(0));或者,sprintf(execargv[pos],"%d",0);
5:代码中有匿名管道改成非阻塞的,否则read会卡住不返回。
本文说明再用dup做重定向的时候遇到的一些坑做一些总结。
1:FFMPEG的所有输出信息,都为错误输出流,用STDOUT_FILENO是捕获不到任何消息,必须用STDERR_FILENO,这里是个大坑;
2:子进程pid == 0 这一段代码走完返回后还会将主进程调用本函数之后的代码走一遍;
3:循环sleep要刷新fflush(stdout);才能在标准输出中输出到管道否则失败;
4:传入execvp的第二个参数argv类型为,char * execargv[LVSM_DEFAULT_STRING_LEN];当把前面的各个参数写入后 ,必须这样写execargv[pos] = NULL;否则失败,不能sprintf(execargv[pos],"%s",(char*)(0));或者,sprintf(execargv[pos],"%d",0);
5:代码中有匿名管道改成非阻塞的,否则read会卡住不返回。
相关阅读
jQuery 属性 jQuery Accordion jQuery Validate jQuery Validate 插件为表单提供了强大的验证功能,让客户端表单验证变得更简
Android中Adapter的notifyDataSetInvalidated()和noti
notifyDataSetChanged方法通过一个外部的方法控制如果适配器的内容改变时需要强制调用getView来刷新每个Item的内容。public void
The Summary of Resigned After 15 Days
自从6月25日离职以来,身体时好时坏,这15天里我主要照着书学习了springcloud 的 分布式配置中心搭建, 链路追踪sleuth 的搭建,利用sp
@Test public void testIplan() { Map<String,Map<String,List<IPlan>>> iPlanMap = iPlanDao.getIPlans().stream().collect
1.注册表项:regedit2.组策略:gpedit.msc3. windows服务:services.msc