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
//刷新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;
extern int m_dwWidth;
extern int m_dwHeight;
extern AVCodecID m_video_codecID;
extern AVPixelFormat m_video_pixelfromat;
extern char m_spspps[100];
extern int m_spspps_size;
//audio pram
extern int m_audio_stream_idx;
extern double m_audio_duration;
extern int m_dwChannelCount;
extern int m_dwBitsPerSample;
extern int m_dwFrequency;