赞
踩
Splayer(射手影音播放器)是一款高画面、低消耗、智能化、精致美观的影音播放器。
具有如下八个独创:
独创ShaderEngineTM图像增强引擎,4倍速驱动,降低画面噪点,锐利画质呈现,低画质视频照样全屏放
独创LiveColorTM彩色增强算法,画面色彩更艳丽
独创SmartAmplifyTM智能音场平衡技术,声效更显震撼
独创FastMotionTM解码优化技术,大幅降低CPU和内存占用。多核 SSE2 SSE3 MMX GPU优化
独创PowerTravelTM旅行节电模式,降低能耗,增加笔记本的巡航时间
独创EyeCareTM护眼模式,久看不疲劳,健康最重要
独创Anti-SillyTM智能免配置,数百逻辑分支自动根据硬件配置选择最佳模式。
独创CloudMatchingTM智能显示字幕技术,外语片从此不再需要找寻匹配字幕
Splayer 是一款开源项目,项目总共有87个工程(含测试工程),如图:
效果如图:
这是我目前接触最大的项目,刚接触时不知道如何下手,于是把所有的库都大致的分析了一遍,由于缺少资料所以很多分析都带有主观,难免有瑕疵,
但我然仍贴出来,以鼓励我继续研究,我计划把Splayer集成为一个视频播放的控件,现在计划已经进行了38%,但由于工作原因,这项计划被搁置了,
但我相信我会慢慢把它完成,因为我是一个码农,o(∩_∩)o 哈哈!~~~
2012tvod项目如图:
效果如图:
进入主题了,由于Splayer项目过多,所以把它分成二个部分(主程序、类库),现在从类库开始分析了。
- libpng libpng是OSI认证开源软件,主要负责读写png文件。该库是用来创立和操作png格式的图像文件.png格式是设计来替代gif,他对于更小范围的tiff(标记图
- 象文件格式)。Splayer中类CPngIMage是对该库的应用,该类在libpng.h中。
- decss DVD解密源码,专门针对DVD安全机制设计的破解其内容混合系统的,利用decss的功能从网上下载DVD格式的数字电影,还可以用DivX软件将下载的数字电影
- 压缩存储到硬盘或光盘上。该类库需要用到BaseClasses库。 该库有五个类,分别是CDeCSSInputPin、CVobDec、CDVDSession、CLBAFile、CVobFile。
dsutil directshow工具类库,主要负责视频处理、捕获应用…等操作。该类库需要用到BaseClasses库和foundation库。该库还有类:IDSMPropertyBagImpl 编码器选项设置接口、CDSMResource、IDSMResourceBagImpl、CDSMChapter、IDSMChapterBagImpl、CDSMChapterBag、CFontInstaller 字体的初始化、CGolombBuffer、CH264Nalu、CHdmvClipInfo、CMediaTypeEx、CNullRenderer、CNullVideoRenderer、CNullUVideoRenderer、CNullAudioRenderer、CNullUAudioRenderer、CNullTextRenderer、CCpuID。其中DSUtil.h 包含很多视频操作函数。
foundation 该库是一个辅助库,内含:base64编解码、同步类CriticalSection/AutoCSLock、文件路径操作类FilePath、信息输出类LogController、加载资源类ResLoader、定义字符串Strings、多线程辅助模块ThreadHelperImpl、实例生成模块LazyInstanceImpl。
id3lib 该库是用于读、写和操纵ID3v1和ID3v2标签的对于媒体类型的文件,它能够调用id3lib库来获取诸如作者,唱片年代,风格等tag信息,如果是视频媒体文件,它还会抓图。
libssf 该库为一个操作 影视字幕以及特效的类库。
lyriclib 该库为歌词匹配类库。
subpic 该库为操作位图类库(例如 字幕图片显示)。
sqlitepp 该库是一个C++封装的 SQLite组件,开源、免费。目的是使用面向对象的方式来简化SQLite的使用,具有面向对象的访问方式。程序将通过它生成数据库,该数据库是settings.db 负责记录设置信息。
subtitles 该库是操作视频字幕的库。
svplib 该库是一个 字幕获取功能库,内含:CSVPEqualizer、CSVPRarLib 压缩包rar文件操作、CSVPSubfilterLib、CSVPToolBox 文件路径操作类。
yaml-cpp 是一个 开源的YAML 解析器。
CmdUI 是一个界面设置属性的对话框
ResizableLib 为一个界面库,可以根据父窗口的位置和大小动态调整控件窗口的大小。
sizecbar 为实现浮动工具条!
TreePropSheet 为树控件目录即文件目录
Updater 程序的升级程序
libmad 该库是一个MPEG音频解码库,是一个高-品质的??的的的MPEG音频解码器。目前,它支持MPEG-1和MPEG-2扩展到较低的采样频率,以及所谓的MPEG 2.5格式,是一个独立库。
filters 该库是滤波函数库等,该库主要有程序类CFilterApp、CInternalPropertyPageWnd属性窗体、CInternalPropertyPage属性页、CInternalPropertyPageTempl模块、CPinInfoWnd。
liba52 该库是一个解码ATSC A/52流的库,还包括一个MPEG-1和MPEG-2节目流复用器(音频和视频)。编码的环绕立体声缩混 大多数用户明显增加任意缩混扬声器配置,并实施动态范围压缩。
libdts 该库是一个DTS相干声学解码器库 负责解码DTS相干声学流,用于一个跨平台的视频播放和流VLC媒体播放器。
zlib 该库是一个压缩算法的库,提供数据压缩用的函式库。
libfaad 该库是软高级音频(AAC)解码器,含丁苯橡胶解码。其中in_mp4 - Winamp的MPEG-4 AAC文件输入插件,QCD的 - 典型的球员的AAC插件,QCDMp4 - 典型的播放器MP4插件,XMMS - XMMS的AAC插件,MPEG4IP - 为MPEG4IP播放器插件。
libdirac 该库是一个开源的视频编解码器。它采用了传统的混合视频编解码器架构,是与小波转换而不是通常的块转换。运动补偿使用重叠的块,以减少区块会扰乱变换编码阶段的文物。
baseclasses 该库是DirectX 自带的一个库,是微软推出的一套基于Windows系统的多媒体应用程式接口APIs函式。
libflac 该库是FLAC文件解码器的一个库,是无损音频编解码器库。
libavcodec 该库是非常先进的音频/视频编解码库,用于各种类型声音/图像编解码,无法使用VS2008编译。
libvorbisidec 该库是Ogg文件编解码器。
libmpeg2 该库是一个解码MPEG-2和MPEG-1视频的库。
SyncClock 该库是同步卡与服务器的时间设置库,该库主要有:CSyncClock、CSyncClockFilter。
BaseMuxer 该库为输入/输出流混合器基库,合成器可将特定的音视频流合成为特定的媒体容器格式,并交给文件写滤镜写入到磁盘中,从而最终实现媒体格式的转换。特定的合成器需要与特定的音视频编码器配合才能起作用,只不过有些合成器比较挑食,只能容纳一种类型的音视频编码,而有些合成器胃口很好,可容纳的多种音视频编码,如WMV和ASF的合成器只能容纳下WMA音频和WMV视频,而AVI的合成器则可以容纳从非压缩的RGB视频及PCM音频到高压缩率的DivX视频及MP3音频,至于MKV和DSM的合成器,几乎算是万能合成器了,该库主要有CBaseMuxerFilter、CBaseMuxerInputPin、CBaseMuxerOutputPin、CBaseMuxerRawOutputPin。
DSMMuxer 介绍同上,该库主要有CDSMMuxerFilter类
MatroskaMuxer 介绍同上,是负责将音频流和视频流合成为MKV格式,但要输出,还需要一个文件写出滤镜(File writer),它负责把“Matroska Muxer”合成的结果写入到磁盘当中,该类库主要有CMatroskaMuxerInputPin、CMatroskaMuxerOutputPin、CMatroskaMuxerFilter等类。
wavdest 主要用于将采集到的视频流写入到指定的文件,文件格式是.WAV。该库主要有CWavDestOutputPin、CWavDestFilter等类
streamdrivethru 该库是驱动流通过输入/输出引脚过滤器,该库主要有CStreamDriveThruInputPin、CStreamDriveThruOutputPin、CStreamDriveThruFilter等类。
AviSplitter 该库是AVI的滤镜分离器,默认用System的,因稳定性和兼容性最好;Gabest的可以读下载不完整的AVI文件;而Haali的支持多音轨的切换。该库涉及:BaseSplitter库、BaseClasses库,该库主要有:CAviFile、CAviPlotterWnd、CAviReportWnd、CAviSplitterOutputPin、CAviSplitterFilter、
CAviSourceFilter。
basesplitter 该库是分词基类,该库涉及dsutil、unrar、AudioSwitcher类库,该库主要有:CAsyncFileReader、CAsyncUrlReader、Packet、CPacketQueue、CBaseSplitterInputPin、CBaseSplitterOutputPin、CBaseSplitterFilter、CBaseSplitterFile、CBaseSplitterFileEx、CMultiFiles。
diracSplitter 该库是dirac滤镜分离器库,该库涉及:BaseSplitter库、BaseClasses库,该库主要有CDiracSplitterFilter、CDiracSourceFilter、CDiracVideoDecoder、CDiracSplitterFile。
DSMSplitter 该库是dsm滤镜分离器库,该库涉及:BaseSplitter库、BaseClasses库,该库主要有CDSMSplitterFilter、CDSMSourceFilter、CDSMSplitterFile等类。
EASplitter 该库是ea滤镜分离器库,该库涉及:BaseSplitter库、BaseClasses库、DSUtil库、ffmpeg库等,该库主要有CEAFile、CEASpliterFilter、CEASourceFilter。
flvsplitter 该库是flv滤镜分离器库,该库涉及:BaseSplitter库、BaseClasses库、DSUtil库、libVP62(flash vp6解码器)库,该库主要有CFLVSplitterFilter、CFLVSourceFilter、VP62。
MatroskaSplitter 该库是MKV滤镜分离器库(MKV视频的分离器),该库主要涉及:BaseSplitter库、BaseClasses库、DSUtil库。该库类较多。
mp4splitter 该库是MP4滤镜分离器库,该库主要涉及:BaseSplitter库、BaseClasses库、DSUtil库、Zlib库。该库主要有:CMP4SplitterFilter、CMP4SourceFilter、CMPEG4VideoSplitterFilter、CMPEG4VideoSourceFilter、CMP4SplitterFile……等等。
MpaSplitter 该库是Mpa滤镜分离器库,该库主要涉及:BaseSplitter库、BaseClasses库、DSUtil库。该库主要有:CMpaSplitterFilter、CMpaSplitterFile等类。
MpegSplitter 该库是MPEG滤镜分离器库,一个MPEG的分割工具,可将大尺寸MPEG文件分割成数个小尺寸的MPEG文件。该库主要涉及:BaseSplitter库、BaseClasses库、DSUtil库。该库主要有:CMpegSplitterFilter、CMpegSourceFilter、CMpegSplitterFile、CMpegSplitterSettingsWnd等类。
WMVSpliter 该库为WMV滤镜分离器库,WMA是一种视频编码格式,该库主要有StreamOnAsyncReader、ptr_shared_count(线程安全的共享数)、StreamInput、WMFOutputPin(输出引脚,提供的解码器的压缩数据)、IEncapsulatedAccess(分配缓冲区WMF时,我们需要返回一个IMediaSample对象周围的包装/INSSBuffer的接口)、EncapsulateSample、WMFDemuxFilter(分析器过滤器本身)、
NutSplitter 该库主要涉及:BaseSplitter库、BaseClasses库、DSUtil库。该库主要有:CNutFile、CNutSplitterFilter、CNutSourceFilter等类。
OggSplitter 该库是Ogg滤镜分离器库,Ogg是一种新的音频压缩格式,类似于MP3等的音乐格式。该库主要涉及:BaseSplitter库、BaseClasses库、DSUtil库。该库主要有:OggPage类、COggFile类、OggPacket类、COggSplitterOutputPin类、COggVorbisOutputPin类、COggDirectShowOutputPin类、COggS treamOutputPin类、COggSplitterFilter类、COggSourceFilter类…等等。
RealMediaSplitter 该库是real滤镜分离器库,是real播放器为除realplay外播放器播放real格式,比如RM,RMVB等等格式的播放插件.有了这个插件,其他播放器才能够播放REAL格式的视频,音频等文件.
RoQSplitter 该库是分离式联轴器的旋转编码器,该库主要有CRoQSplitterFilter、CRoQSourceFilter、CRoQVideoDecoder、CRoQAudioDecoder等类。
ssfsplitter 该库是特效字幕d的滤镜分离器,该库主要有CSSFSplitterFilter、CSSFSourceFilter等类。
asyncreader 该库是读取网络上的编码后的视频数据库,读取后交给解码filter。该库主要有:CAsyncStream、CAsyncIo、CAsyncOutputPin、CAsyncReader。
cddareader 该库是开源滤镜MPC,DTS技术编码的音频具有细节丰富、定位精确的特点,是传统CD和Dolby环绕声效的后继者。该库主要有:CCDDAStream、CCDDAReader类。
cdxareader 该库为系统滤镜,该库主要有CCDXAStream、CCDXAReader类。
udpreader 该库为系统滤镜,该库主要有CUDPStream、CUDPReader类。
vtsreader 该库为系统滤镜,该库主要有CVTSStream、CVTSReader类。
MpcAudioRenderer 该库为使用WASAPI音频输出MPC音频渲染器,该库主要有CMpcAudioRenderer类。
basesource 该库是解码文件的基础库,该库主要有:CBaseSource、CBaseStream等类。
dtsac3source该库是DTS/AC3输出滤镜的库,DTS(Digital Theater Systems)是一种高质量的多声道音频编码方式,目前主要用作DVD的伴音。DTS 5.1的最大码率(Bitrate)与LPCM(LPCM是数位非经压缩的声音规格,音质佳,所占容量空间较大)相同,可达1536Kbps,远高于目前另一种流行的多声道编码系统──Dolby Digital AC3的 448Kbps,虽然同样是有损压缩,但它可提供更为逼真,细节更为丰富的音响效果。用DVD中DTS音轨来制作音乐CD无疑是非常理想的。该库主要有:CDTSAC3Source、CDTSAC3Stream等类。
flicsource 该库是处理fli文件的库,主要有CFLICSource、CFLICStream等类。
flacsource 该库是音频压缩编解码库,其特点是无损压缩。不同于其他有损压缩编码如MP3 及 AAC,它不会破坏任何原有的音频资讯,所以可以还原音乐光盘音质。该库主要有:CFlacSource、CFlacStream类。该库主要牵涉
shoutcastsource 该库是采用了MPEG Layer 3(MP3)技术,实现了因特网上的音频流的实时广播或者点播。该库主要有:CShoutcastSource、CShoutcastStream等类。
d2vsource 该库为d2v输出滤镜的库,d2v即数字化视频,该库主要有CMPEG2Dec、CD2VSource、CMPEG2Dec等类。
subtitlesource 该库为字幕输出滤镜的库,该库主要有CSubtitleSource、CSubtitleStream等类。
audioswitcher 该库是一个自动切换扬声器的库,涉及主程序的eqPerset负责设置音频,该库主要有:AudioStreamResampler、CAudioSwitcherFilter、CStreamSwitcherPassThru、CStreamSwitcherAllocator、CStreamSwitcherInputPin、CStreamSwitcherOutputPin、CStreamSwitcherFilter。
Mpeg2DecFilter 该库是为测试程序是libmpeg2。它解码MPEG-1和MPEG-2视频流,还包括一个MPEG-1和MPEG-2解复用器节目流。该库牵涉:BaseVideoFilter.lib libmpeg2.lib dsutil.lib 等库,该库主要有:IMpeg2DecFilter接口、CMpeg2Info、CMpeg2Dec、CMpeg2DecFilter、CMpeg2DecInputPin、CMpeg2DecOutputPin、CSubpicInputPin、CMpe g2DecSettingsWnd等类。
avi2ac3filter 该库为AC3音效辅助插件库,目前DVDrip在制作音频部分时普遍采用两种方式:MP3格式压缩音轨和保留DVD中原有的AC3音频文件。一般来说,Windows操作系统已经自带了MP3的解码器——Fhg Radium MP3 codec,因此采用MP3格式做的DVDrip音频我们都可以听到。但对于以AC3音频文件制作的DVDrip,我们就只能看到图像而听不到声音了,该库主要有CAVI2AC3Filter类。
bufferfilter 该库为滤镜输出缓冲区库,该库主要有CBufferFilter、CBufferFilterOutputPin等类。
decssfilter 该库为CSS滤镜,对常规的CSS的一个扩展子集,可以使应用对象(文字,图片...)产生类似于PHOTOSHOP中的模糊,通透,边缘发光等效果。该库主要有CDeCSSFilter类。
Mpeg2DecFilter 该库为mpeg1、mpeg2解码过滤器,该库主要有CMpeg2Info、CMpeg2Dec、CMpeg2DecFilter、CMpeg2DecInputPin、CMpeg2DecOutputPin、CSubpicInputPin、CClosedCaptionOutputPin、CMpeg2DecSettingsWnd等类。
MpaDecFilter 该库为MPC H264/VC1硬解码器(主音频解码器),该库主要有CMpaDecFilter、CMpaDecInputPin、CMpaDecSettingsWnd等类。
basevideofilter 该库为解码视频播放过滤器基库,该库主要有CBaseVideoFilter、CBaseVideoInputAllocator、CBaseVideoInputPin、CBaseVideoInputPin、CBaseVideoOutputPin等类。
MPCVideoDec 该库为主视频解码类库,该库主要有CMPCAudioDecFilter、CMPCVideoDecFilter、CMPCVideoDecSettingsWnd等类。
svpfilter 该库为字幕滤镜类库,该库主要有CSVPSubFilter类。
mplayerc为主程序,主程序自绘控件,以及应用视频音频编解码播放,此处就简单的看看涉及视频播放主要有哪些类!
- //渲染操作图像基类 定义如下
- class CBaseGraph
- : public CUnknown
- , public IGraphBuilder2 //IGraphBuilder接口允许应用程序调用时的过滤器图表管理器试图建立一个完整的过滤器图表
- , public IMediaControl //IMediaControl接口提供控制的数据流通过过滤器图的方法。它包括运行,暂停和停止图形的方法
- , public IMediaEventEx //其中包含了用于检索事件通知和用于重写筛选器图形的默认事件处理的方法
- , public IMediaSeeking //IMediaSeeking接口包含寻求内流的位置,并设置播放速度的方法
- , public IVideoWindow //IVideoWindow接口设置视频窗口的属性。应用程序可以使用它来 设置窗口的所有者窗口的位置和尺寸,和其他属性。
- , public IBasicVideo //IBasicVideo接口设置视频属性,如目标和源矩形。
- , public IBasicAudio //IBasicAudio接口控制音频流的音量和平衡。
- , public IAMOpenProgress //IAMOpenProgress接口报告的文件打开操作的进度,使应用程序能够取消操作。
- , public IGraphEngine //渲染引擎接口
- //播放flash类
- class CShockwaveGraph : public CBaseGraph
- class CMacrovisionKicker
- : public CUnknown
- , public IKsPropertySet //IKsPropertySet接口的最初目的是作为一种有效的方式来设置和检索WDM驱动程序的设备属性,使用KSProxy翻译用户模式COM方法调用进入内核模式属性的WDM流类驱动程序所使用的设置
interface __declspec(uuid("165BE9D6-0929-4363-9BA3-580D735AA0F6")) IGraphBuilder2 : public IFilterGraph2
- //IFilterGraph2接口扩展IFilterGraph的的IGraphBuilder接口,其中包含建立过滤器图表的方法。
- //筛选器图形管理器实现了这个接口。应用程序可以使用它建立图表时,利用它提供的其他方法的优势。
class __declspec(uuid("96F3E0BE-1BA4-4E79-973D-191FE425C86B")) CDeinterlacerFilter : public CTransformFilter
- //CTransformFilter类是为实施变换过滤器的基类。这个类是专为实施变换过滤器与一个输入引脚和一个输出引脚。
- //它使用的输入引脚和输出引脚独立的分配器。要创建一个过滤器,数据处理,使用CTransInPlaceFilter类。
- //DX7分配器演示
- class CDX7AllocatorPresenter
- : public ISubPicAllocatorPresenterImpl //图像分配操作接口
- //DX9分配器演示
- class CDX9AllocatorPresenter
- : public ISubPicAllocatorPresenterImpl //图像分配操作接口
- //DXR分配器演示
- class CDXRAllocatorPresenter:
- public ISubPicAllocatorPresenterImpl //图像分配操作接口
- //EVR方式输出
- class COuterEVR:
- public CUnknown,
- public IVMRffdshow9,
- public IVMRMixerBitmap9, //使应用程序从位图或Direct3D表面上的视频流,混合静态图像,当使用视频混合渲染过滤器(VMR-9)。
- public IBaseFilter //IBaseFilter接口是DirectShow过滤器的主界面
- //EVR分配器演示
- class CEVRAllocatorPresenter:
- public CDX9AllocatorPresenter,
- public IMFGetService, //查询指定的服务接口的对象。
- public IMFTopologyServiceLookupClient, //初始化视频混合器或演示。此接口由混频器和演示,使他们能够增强视频渲染器(EVR)查询接口指针。
- public IMFVideoDeviceID, //返回视频渲染组件支持的设备标识符。实现此接口由混频器和增强视频渲染器(EVR)的主持人。
- public IMFVideoPresenter, //增强视频渲染器(EVR)提供了一个默认的视频演示,应用程序可以实现自定义的主持人。
- public IDirect3DDeviceManager9, //使两个线程共享相同的Direct3D 9设备,并提供访问的DirectX视频加速(DXVA)功能的设备。
- public IMFAsyncCallback, //回调接口的异步方法完成时通知应用程序。
- public IQualProp, //IQualProp接口提供视频渲染性能信息检索的方法。
- public IMFRateSupport, //查询范围的支持,包括反向播放的播放率。
- public IMFVideoDisplayControl, //控制如何增强型视频渲染器(EVR)显示视频。
- public IEVRTrustedVideoPlugin //1启用插件在增强视频渲染器(EVR)与保护媒体工作的组成部分。
- //映射过滤器
- class CFilterMapper2 :
- protected CUnknown,
- public IFilterMapper2 //注册和取消注册的过滤器,并在注册表中找到过滤器。
- //过滤器重叠 (找最近的过滤器)
- class FilterOverride
- //FG过滤器
- class CFGFilter
- //FG过滤器注册
- class CFGFilterRegistry :
- public CFGFilter
- //FG过滤器文件
- class CFGFilterFile :
- public CFGFilter
- //FG过滤器视频渲染
- class CFGFilterVideoRenderer :
- public CFGFilter
- //FG过滤器管理
- class CFGManager
- : public CUnknown
- , public IGraphBuilder2
- , public IGraphBuilderDeadEnd
- , public CCritSec //CCritSec类提供了一个线程锁。
- //添加过滤器
- class CFGManagerCustom : public CFGManager
- //视频播放时触发 寻找和链接过滤器
- class CFGManagerPlayer
- : public CFGManagerCustom
- //DVD播放时触发 添加对应的过滤器以及渲染图像
- class CFGManagerDVD
- : public CFGManagerPlayer
- //视频捕捉触发
- class CFGManagerCapture
- : public CFGManagerPlayer
- //合成器
- class CFGManagerMuxer
- : public CFGManagerCustom
- //FG聚合 可以根据riid查询对应的接口
- class CFGAggregator
- : public CUnknown
- //同步锁
- class CGenlock
- //QT视图操作接口
- interface __declspec(uuid("A6AE36F7-A6F2-4157-AF54-6599857E4E20")) IQTVideoSurface : public IUnknown
- //视频解码设置类 读取显卡信息
- class MPCVideoDecSetting
- //VMR9方式输出
- class COuterVMR9:
- public CUnknown,
- public IVideoWindow, //视频窗口接口
- public IBasicVideo2, //视频渲染过滤器和视频混合渲染过滤器实现这个接口,但通过过滤器图表管理器的应用程序接口暴露。
- public IVMRWindowlessControl, //IVMRWindowlessControl界面控制视频混合渲染过滤器(VMR-7)如何呈现在一个容器内窗口的视频流
- public IVMRffdshow9,
- public IVMRMixerBitmap9 //IVMRMixerBitmap9接口,使应用程序从位图或Direct3D表面上的视频流,混合静态图像,当使用视频混合渲染过滤器(VMR-9)
- //像素着色器编译器
- class CPixelShaderCompiler
- //QT7分配器演示
- class CQT7AllocatorPresenter
- : public CDX7AllocatorPresenter //
- , public IQTVideoSurface //qt视图操作接口
- //QT9分配器演示
- class CQT9AllocatorPresenter:
- public CDX9AllocatorPresenter,
- public IQTVideoSurface //QT视图操作接口
- //实现QuickTime多媒体文件播放
- class CQuicktimeWindow : public CPlayerWindow
- //QuickTime多媒体文件渲染
- class CQuicktimeGraph :
- public CBaseGraph, //基类渲染
- public IVideoFrameStep //实现单帧前进后退
- //实现RealMedia多媒体文件播放
- class CRealMediaPlayer
- : public CUnknown
- , public IRMAErrorSink //错误处理接口
- , public IRMAClientAdviseSink //能够使 RealPlayer的上层感知内核中播放 状态的改变以及其他相关信息
- , public IRMAAuthenticationManager //可以控制网络上多个数码复合机的认证数据,并能对每个用户的认证数据进行简单有效的设置。
- , public IRMASiteSupplier //rma站点提供接口
- , public IRMAPassiveSiteWatcher //通过站点观察接口
- , public IRMAAudioHook //音频钩子接口
- //RealMedia媒体视频视图操作
- class CRealMediaVideoSurface
- : public CUnknown
- , public IRMAVideoSurface //视图操作接口
- //RM7分配器演示
- class CRM7AllocatorPresenter
- : public CDX7AllocatorPresenter
- , public IRMAVideoSurface //视图操作接口
- //RM9分配器演示
- class CRM9AllocatorPresenter:
- public CDX9AllocatorPresenter,
- public IRMAVideoSurface //RMA视图操作接口
- //VMR7分配器演示
- class CVMR7AllocatorPresenter
- : public CDX7AllocatorPresenter
- , public IVMRSurfaceAllocator //分配器演示使用这个接口进行通信的VMR
- , public IVMRImagePresenter //IVMRImagePresenter9接口来实现的默认分配器演示视频混合呈现过滤器(VMR-9),VMR-9使用此接口通知分配器演示的,它应该呈现的视频帧中所提供的Direct3D表面。
- , public IVMRWindowlessControl //显示窗口控制接口
- //VMR9分配器演示
- class CVMR9AllocatorPresenter
- : public CDX9AllocatorPresenter,
- public IVMRSurfaceAllocator9, //分配器演示使用这个接口进行通信的VMR
- public IVMRImagePresenter9, //IVMRImagePresenter9接口来实现的默认分配器演示视频混合呈现过滤器(VMR-9),VMR-9使用此接口通知分配器演示的,它应该呈现的视频帧中所提供的Direct3D表面。
- public IVMRWindowlessControl9 //显示窗口控制接口
- class __declspec(uuid("96F3E0BE-1BA4-4E79-973D-191FE425C86B")) CDeinterlacerFilter
- : public CTransformFilter // 用来浏览视频 时候旋转
- class __declspec(uuid("E2BA9B7B-B65D-4804-ACB2-89C3E55511DB")) CTextPassThruFilter :
- public CBaseFilter,
- public CCritSec
主程序是如何播放的?先来看看主程序的几个成员函数:
- // Operations 准备视频播放操作
- bool OpenMediaPrivate(CAutoPtr<OpenMediaData> pOMD);
- // 准备关闭当前视频操作
- void CloseMediaPrivate();
- //创建渲染对象
- void OpenCreateGraphObject(OpenMediaData* pOMD);
- //路径操作
- HRESULT OpenMMSUrlStream(CString szFn);
- //打开目标文件
- void OpenFile(OpenFileData* pOFD);
- //打开DVD
- void OpenDVD(OpenDVDData* pODD);
- //打开视频捕捉
- void OpenCapture(OpenDeviceData* pODD);
- //通用渲染
- void OpenCustomizeGraph();
- //初始化视频操作
- void OpenSetupVideo();
- //初始化音频操作
- void OpenSetupAudio();
这些函数进行了视频相关操作!~
当打开文件时触发
- m_pGraphThread = (CGraphThread*)AfxBeginThread(RUNTIME_CLASS(CGraphThread));
- if(m_pGraphThread)
- m_pGraphThread->SetMainFrame(this);
销毁时触发
- if(m_pGraphThread)
- {
- CAMEvent e;
- m_pGraphThread->PostThreadMessage(CGraphThread::TM_EXIT, 0, (LPARAM)&e);
- if(!e.Wait(5000))
- {
- TRACE(_T("ERROR: Must call TerminateThread() on CMainFrame::m_pGraphThread->m_hThread\n"));
- TerminateThread(m_pGraphThread->m_hThread, -1);
- }
- }
- 打开文件流程分析:
- void CMainFrame::OnFileOpenQuick()
- {
- 正在加载或列表未生成 则直接返回
- if(m_iMediaLoadState == MLS_LOADING || !IsWindow(m_wndPlaylistBar)) return;
-
- 近期文件列表
- CRecentFileList& MRU = AfxGetAppSettings().MRU;
-
- CString szLastFile; 最后一次看的视频文件
-
- MRU.ReadList(); 读取列表的文件路径
-
- if(MRU.GetSize() > 0){
- szLastFile = MRU[0]; 把读取的文件信息取出
- }
-
- CString filter;
- CAtlArray<CString> mask;
- 从设置里面读取过滤的设置
- AfxGetAppSettings().Formats.GetFilter(filter, mask);
-
- COpenFileDlg fd(mask, true, NULL, szLastFile,
- OFN_EXPLORER|OFN_ENABLESIZING|OFN_HIDEREADONLY|OFN_ALLOWMULTISELECT|OFN_ENABLEINCLUDENOTIFY,
- filter, this);
- if(fd.DoModal() != IDOK) return; 显示出打开文件对话框
-
- CAtlList<CString> fns;
-
- POSITION pos = fd.GetStartPosition();
- while(pos) fns.AddTail(fd.GetNextPathName(pos)); 把选中的文件加入进来
-
- bool fMultipleFiles = false;
-
- 判断是否多选 或选中的是目录
- if(fns.GetCount() > 1
- || fns.GetCount() == 1
- && (fns.GetHead()[fns.GetHead().GetLength()-1] == '\\'
- || fns.GetHead()[fns.GetHead().GetLength()-1] == '*'))
- {
- fMultipleFiles = true;
- }
-
- 猜测 关闭Media
- SendMessage(WM_COMMAND, ID_FILE_CLOSEMEDIA);
-
- ShowWindow(SW_SHOW);
- SetForegroundWindow();
-
- 列表打开文件
- m_wndPlaylistBar.Open(fns, fMultipleFiles);
-
- 播放列表个数为一 且可见 并且不是自由的 则显示或隐藏
- if(m_wndPlaylistBar.GetCount() == 1 && m_wndPlaylistBar.IsWindowVisible() && !m_wndPlaylistBar.IsFloating())
- {
- ShowControlBar(&m_wndPlaylistBar, FALSE, TRUE);
- }
-
- OpenCurPlaylistItem(); 打开当前列表选中项
- }
-
- 进入 OpenCurPlaylistItem 函数分析 参数为树节点 默认为零
- void CMainFrame::OpenCurPlaylistItem(REFERENCE_TIME rtStart)
- {
- 如果列表中没有 则直接退出
- if(m_wndPlaylistBar.GetCount() == 0) return;
-
- CPlaylistItem pli;
- 得到当前选中项 如果没有则选中第一项
- if(!m_wndPlaylistBar.GetCur(pli)) m_wndPlaylistBar.SetFirst();
- if(!m_wndPlaylistBar.GetCur(pli)) return;
-
- AppSettings& s = AfxGetAppSettings();
-
- if(rtStart == 0){
- CString fn;
- fn = pli.m_fns.GetHead(); 获得文件路径
-
- // SVP_LogMsg5(L"GetFav Start1 %s", fn);
- favtype ft ;
- ft = FAV_FILE;
-
- if (!fn.IsEmpty() && s.autoResumePlay){
- 文件存在 且 自动恢复播放
- std::string str = Strings::WStringToString(fn.GetBuffer());
- CString szMatchmd5 = HashController::GetInstance()->GetMD5Hash(str.c_str(), str.length()).c_str();
-
- SVP_LogMsg5(L"GetFav Start %s", szMatchmd5);
-
- CAtlList<CString> sl;
- s.GetFav(ft, sl, TRUE); 得到以前保存的数据
-
- CString PosStr ;
- POSITION pos = sl.GetHeadPosition(); 获得
- while(pos){ //判断以前是否播放过
- PosStr = sl.GetNext(pos) ;
- if( PosStr.Find(szMatchmd5 + _T(";")) == 0 ){
- break;
- }else{
- PosStr.Empty();
- }
- }
- if(!PosStr.IsEmpty()){ 如果未播放 则记录
-
-
- int iPos = PosStr.ReverseFind( _T(';') );
- if(iPos >= 0){
- CString s2 = PosStr.Right( PosStr.GetLength() - iPos - 1 );
- _stscanf(s2, _T("%I64d"), &rtStart); // pos
- }
- SVP_LogMsg5(L"Got %f", double(rtStart) );
- }
- 是否恢复退出时的状态
- m_is_resume_from_last_exit_point = TRUE;
- //SVP_LogMsg5(L"GetFav Done");
- }
- }else if(rtStart == -1){
- rtStart = 0;
- }
-
- 打开媒体文件 根据OpenMediaData*初始化 OpenMediaData里面保存了路径和rtStart
- CAutoPtr<OpenMediaData> p(m_wndPlaylistBar.GetCurOMD(rtStart));
-
- if(p) OpenMedia(p); 根据CAutoPtr<OpenMediaData> 进行打开播放
- }
-
-
- 进入OpenMedia进行 打开播放
- void CMainFrame::OpenMedia(CAutoPtr<OpenMediaData> pOMD)
- {
- // shortcut
- if(OpenDeviceData* p = dynamic_cast<OpenDeviceData*>(pOMD.m_p))
- {
- 如果是DeviceData数据
- if(m_iMediaLoadState == MLS_LOADED && pAMTuner
- && m_VidDispName == p->DisplayName[0] && m_AudDispName == p->DisplayName[1])
- {
- m_wndCaptureBar.m_capdlg.SetVideoInput(p->vinput);
- m_wndCaptureBar.m_capdlg.SetVideoChannel(p->vchannel);
- m_wndCaptureBar.m_capdlg.SetAudioInput(p->ainput);
- return;
- }
- }
-
- 如果当前正在播放则关闭
- if(m_iMediaLoadState != MLS_CLOSED)
- CloseMedia();
-
- 更改状态
- m_iMediaLoadState = MLS_LOADING; // HACK: hides the logo
- m_wndView.Invalidate();
-
- AppSettings& s = AfxGetAppSettings();
-
- bool fUseThread = true;
-
- if(OpenFileData* p = dynamic_cast<OpenFileData*>(pOMD.m_p))
- {
- 如果是打开的文件
- if(p->fns.GetCount() > 0)
- {
- 解码类型
- engine_t e = s.Formats.GetEngine(p->fns.GetHead());
- 如果是DirectShow 类型 只有.ram .rm .ra .qt .mov .ram 不需要
- fUseThread = e == DirectShow /*|| e == RealMedia || e == QuickTime*/;
- }
- }
- else if(OpenDeviceData* p = dynamic_cast<OpenDeviceData*>(pOMD.m_p))
- {
- fUseThread = false;
- }
-
- 如果渲染线程存在 且 需要使用线程 且 需要打开工作线程
- if(m_pGraphThread && fUseThread&&AfxGetAppSettings().fEnableWorkerThreadForOpening)
- m_pGraphThread->PostThreadMessage(CGraphThread::TM_OPEN, 0, (LPARAM)pOMD.Detach());
- else
- OpenMediaPrivate(pOMD);
- }
-
- 进入 CGraphThread::TM_OPEN 事件 用一个新的线程打开播放文件
- void CGraphThread::OnOpen(WPARAM wParam, LPARAM lParam)
- {
- if(m_pMainFrame)
- {
- CAutoPtr<OpenMediaData> pOMD((OpenMediaData*)lParam);
- m_pMainFrame->OpenMediaPrivate(pOMD);
- }
- }
-
- 进入OpenMediaPrivate 分析
- bool CMainFrame::OpenMediaPrivate(CAutoPtr<OpenMediaData> pOMD)
- {
- CString err, aborted(_T("Aborted"));
- AppSettings& s = AfxGetAppSettings(); 获得设置信息
-
- {
- 打开关闭锁
- CAutoLock mOpenCloseLock(&m_csOpenClose);
- s.bIsIVM = false;
- s.szCurrentExtension.Empty();
-
- 如果状态不是关闭 且 不是正在加载 则出错
- 一定要是加载状态 或是关闭状态
- if(m_iMediaLoadState != MLS_CLOSED && m_iMediaLoadState != MLS_LOADING)
- {
- ASSERT(0);
- return(false);
- }
-
- s.bExternalSubtitleTime = false;
-
- 设置Slider
- m_wndSeekBar.SetRange(0, 100);
-
- 记录
- s.szFGMLog.Empty();
-
- 设置声道
- s.SetNumberOfSpeakers(s.iDecSpeakers , -1);
-
- 正在加载状态
- m_iMediaLoadState = MLS_LOADING;
-
- 2.5秒加载
- SetTimer(TIMER_LOADING, 2500, NULL);
-
- 不显示关闭
- // FIXME: Don't show "Closed" initially
- PostMessage(WM_KICKIDLE); 调用主线程更新的东西
-
- m_fUpdateInfoBar = false;
-
- try
- {
- 打开终止 异常
- if(m_fOpeningAborted) throw aborted;
-
- if(OpenFileData* pOFD = dynamic_cast<OpenFileData*>(pOMD.m_p))
- {
- 文件不存在异常
- if(pOFD->fns.IsEmpty()) throw ResStr(IDS_MSG_THROW_FILE_NOT_FOUND);
-
- CString fn = pOFD->fns.GetHead();
-
- 取出格式
- s.szCurrentExtension = fn.Right(4).MakeLower();
-
- 格式比较
- .ivm格式
- if(s.szCurrentExtension == _T(".ivm"))
- s.bIsIVM = true;
-
- s.bDisableSoftCAVCForce = false;
-
- .mkv格式
- if(!(s.useGPUAcel && s.bHasCUDAforCoreAVC) && !s.bDisableSoftCAVC
- && s.szCurrentExtension == _T(".mkv"))
- {
- FILE* fp;
- if ( _wfopen_s( &fp, fn, _T("rb")) == 0)
- {
- char matchbuf[0x4000];
- size_t iRead = fread(matchbuf, sizeof( char ), 0x4000 ,fp);
- if( iRead > 200 && find_string_in_buf(matchbuf, iRead-100, "wpredp=2") > 0 )
- s.bDisableSoftCAVCForce = true;
-
- fclose(fp);
- }
- }
-
- int i = fn.Find(_T(":\\"));
- if(i > 0)
- {
- 判断文件所在盘
- CString drive = fn.Left(i+2);
- UINT type = GetDriveType(drive);
- CAtlList<CString> sl;
-
- 可移动的 驱动
- if(type == DRIVE_REMOVABLE || type == DRIVE_CDROM && GetCDROMType(drive[0], sl) != CDROM_Audio)
- {
- int ret = IDRETRY;
- while(ret == IDRETRY)
- {
- WIN32_FIND_DATA findFileData;
- HANDLE h = FindFirstFile(fn, &findFileData);
- if(h != INVALID_HANDLE_VALUE)
- {
- FindClose(h);
- ret = IDOK;
- }
- else
- {
- CString msg;
- msg.Format(ResStr(IDS_MSG_WARN_NOT_FOUND_AND_PLS_INSERT_DISK), fn);
- ret = AfxMessageBox(msg, MB_RETRYCANCEL);
- }
- }
-
- if(ret != IDOK) throw aborted;
- }else{
- 否则是本地盘 判断文件是否存在
- CSVPToolBox svpTool;
- if(!svpTool.ifFileExist(fn, true)){
- //SVP_LogMsg5(L"SVP 文件不存在" );
- throw ResStr(IDS_MSG_THROW_FILE_NOT_EXIST);
- }
- }
- }
- }
-
- 打开终止异常
- if(m_fOpeningAborted) throw aborted;
-
- 创建渲染对象 关键一
- OpenCreateGraphObject(pOMD); 待分析
-
- 打开终止异常
- if(m_fOpeningAborted) throw aborted;
-
- m_pCAP2 = NULL;
- m_pCAP = NULL;
- m_pSVPSub = NULL;
-
- 判断打开的文件的类型 待分析
- if(OpenFileData* p = dynamic_cast<OpenFileData*>(pOMD.m_p)) OpenFile(p);
- else if(OpenDVDData* p = dynamic_cast<OpenDVDData*>(pOMD.m_p)) OpenDVD(p);
- else if(OpenDeviceData* p = dynamic_cast<OpenDeviceData*>(pOMD.m_p)) OpenCapture(p);
- else throw _T("Can't open, invalid input parameters");
-
- 查找相关接口
- pGB->FindInterface(__uuidof(ISubPicAllocatorPresenter), (void**)&m_pCAP, FALSE);
- pGB->FindInterface(__uuidof(ISubPicAllocatorPresenterRender), (void**)&m_pCAPR, TRUE);
- pGB->FindInterface(__uuidof(ISubPicAllocatorPresenter2), (void**)&m_pCAP2, TRUE);
- pGB->FindInterface(__uuidof(IVMRMixerControl9),(void**)&m_pMC, TRUE);
-
- 如果未找到 则用另外一种方法查找
- if(!m_pCAP){
- CComQIPtr<ISubPicAllocatorPresenter> pCAP = FindFilter(__uuidof(CSVPSubFilter), pGB);
- if(pCAP){
- m_pCAP = pCAP;
- CComQIPtr<ISVPSubFilter> pSVPSub= pCAP;
- if(pSVPSub)
- m_pSVPSub = pSVPSub;
- }
- }
-
- 如果找到 则进行相关操作
- if (m_pMC)
- {
- if (SetVMR9ColorControl(s.dBrightness, s.dContrast, s.dHue, s.dSaturation) == FALSE)
- OsdMsg_SetShader();
- else
- {
- CString szMsg;
- szMsg.Format(ResStr(IDS_OSD_MSG_BRIGHT_CONTRAST_CHANGED), s.dBrightness, s.dContrast);
- SendStatusMessage(szMsg, 3000);
- }
- SetShaders(true);
- }
-
- // === EVR !
- pGB->FindInterface(__uuidof(IMFVideoDisplayControl), (void**)&m_pMFVDC, TRUE);
- if (m_pMFVDC)
- {
- RECT Rect;
- ::GetClientRect (m_wndView.m_hWnd, &Rect);
- m_pMFVDC->SetVideoWindow (m_wndView.m_hWnd);
- m_pMFVDC->SetVideoPosition(NULL, &Rect);
- }
-
- 打开终止异常
- if(m_fOpeningAborted) throw aborted;
-
- 打开自定义大小的图像
- OpenCustomizeGraph(); 待分析
-
- 打开终止异常
- if(m_fOpeningAborted) throw aborted;
-
- 打开初始化视频
- OpenSetupVideo(); 待分析
-
- 打开终止异常
- if(m_fOpeningAborted) throw aborted;
-
- 打开初始化音频
- OpenSetupAudio(); 待分析
-
- 打开终止异常
- if(m_fOpeningAborted) throw aborted;
-
- 打开终止异常
- if(m_fOpeningAborted) throw aborted;
-
- 改变声道
- if(m_iAudioChannelMaping)
- OnAudioChannalMapMenu(IDS_AUDIOCHANNALMAPNORMAL+m_iAudioChannelMaping); 待分析
-
- 加载完毕
- m_iMediaLoadState = MLS_LOADED;
-
- 记录开始播放时间
- time(&m_tPlayStartTime);
-
- 发送暂停消息
- PostMessage(WM_COMMAND, ID_PLAY_PAUSE); 待分析
-
- 如果是打开 则发送播放消息
- if(!(AfxGetAppSettings().nCLSwitches&CLSW_OPEN))
- PostMessage(WM_COMMAND, ID_PLAY_PLAY); 待分析
-
- AfxGetAppSettings().nCLSwitches &= ~CLSW_OPEN;
-
- if(OpenFileData* p = dynamic_cast<OpenFileData*>(pOMD.m_p))
- {
- 如果有记录 则跳到记录位置
- if(p->rtStart > 0)
- PostMessage(WM_RESUMEFROMSTATE, (WPARAM)PM_FILE, (LPARAM)(p->rtStart/10000)); // REFERENCE_TIME doesn't fit in LPARAM under a 32bit env.
- }
- else if(OpenDVDData* p = dynamic_cast<OpenDVDData*>(pOMD.m_p))
- {
- if(p->pDvdState)
- PostMessage(WM_RESUMEFROMSTATE, (WPARAM)PM_DVD, (LPARAM)(CComPtr<IDvdState>(p->pDvdState).Detach())); // must be released by the called message handler
- }
- else if(OpenDeviceData* p = dynamic_cast<OpenDeviceData*>(pOMD.m_p))
- {
- m_wndCaptureBar.m_capdlg.SetVideoInput(p->vinput);
- m_wndCaptureBar.m_capdlg.SetVideoChannel(p->vchannel);
- m_wndCaptureBar.m_capdlg.SetAudioInput(p->ainput);
- }
-
- 进行加载字幕
- if(m_pCAP && (!m_fAudioOnly || m_fRealMediaGraph))
- {
- POSITION pos = pOMD->subs.GetHeadPosition();
- while(pos){ LoadSubtitle(pOMD->subs.GetNext(pos));}
- }
-
- 当前进程是不是主线程
- if(::GetCurrentThreadId() == AfxGetApp()->m_nThreadID)
- {
- OnFilePostOpenmedia();
- }
- else
- {
- PostMessage(WM_COMMAND, ID_FILE_POST_OPENMEDIA); 待分析
- }
-
- 初始化标题
- OpenSetupWindowTitle(pOMD->title); 待分析
-
- 初始化打开时间
- time_t tOpening = time(NULL);
-
- 当状态不是加载完成或正在加载 则循环 还在加载前则循环
- while(m_iMediaLoadState != MLS_LOADED
- && m_iMediaLoadState != MLS_CLOSING // FIXME
- )
- {
- if( (time(NULL) - tOpening) > 10)
- throw aborted;
- Sleep(50);
- }
- }
- catch(LPCTSTR msg)
- {
- err = msg;
- }
- catch(CString msg)
- {
- err = msg;
- }
- }
-
- if(!err.IsEmpty())
- {
- 存在错误
- SendStatusMessage(err, 3000);
- CloseMediaPrivate();
- m_closingmsg = err;
-
- OpenFileData* p = dynamic_cast<OpenFileData*>(pOMD.m_p);
- if(p && err != aborted)
- {
- m_wndPlaylistBar.SetCurValid(false);
- if(m_wndPlaylistBar.GetCount() > 1)
- {
- CPlaylistItem pli[2];
- m_wndPlaylistBar.GetCur(pli[0]);
- m_wndPlaylistBar.SetNext();
- m_wndPlaylistBar.GetCur(pli[1]);
- if(pli[0].m_id != pli[1].m_id)
- {
- //CAutoPtr<OpenMediaData> p(m_wndPlaylistBar.GetCurOMD());
- //if(p) OpenMediaPrivate(p);
- }
- }
- }
- }
- else
- {
- m_wndPlaylistBar.SetCurValid(true); 列表设置
- }
-
- 调用主线程更新的东西
- PostMessage(WM_KICKIDLE); // calls main thread to update things
- return(err.IsEmpty());
- }
-
- ————————————————————————————————————————————
- 2.5秒 循环载入
- case TIMER_LOADING:
- {
- KillTimer(TIMER_LOADING);
- if (IsSomethingLoading())
- {
- SetTimer( TIMER_LOADING , 1000, NULL);
- CString msg;
- if (m_fBuffering)
- {
- BeginEnumFilters(pGB, pEF, pBF)
- {
- if (CComQIPtr<IAMNetworkStatus, &IID_IAMNetworkStatus> pAMNS = pBF)
- {
- long BufferingProgress = 0;
- if (SUCCEEDED(pAMNS->get_BufferingProgress(&BufferingProgress)) && BufferingProgress > 0 && BufferingProgress < 99)
- {
- msg.Format(ResStr(IDS_CONTROLS_BUFFERING), BufferingProgress);
- SendStatusMessage(msg,1000);
- SVP_LogMsg5(msg);
- }
- break;
- }
- }
- EndEnumFilters
- }
- else if (pAMOP)
- {
- __int64 t = 0, c = 0;
- if (SUCCEEDED(pAMOP->QueryProgress(&t, &c)) && t > 0 && c < t)
- {
- msg.Format(ResStr(IDS_CONTROLS_BUFFERING), c*100/t);
- SendStatusMessage(msg,1000);
- SVP_LogMsg5(msg);
- }
- }
- else
- SendStatusMessage(ResStr(IDS_CONTROLS_OPENING), 1000);
- }
- }
- break;
-
- 进入CMainFrame::OpenCreateGraphObject 分析
- void CMainFrame::OpenCreateGraphObject(OpenMediaData* pOMD)
- {
- 解码接口不为空
- ASSERT(pGB == NULL);
- m_fCustomGraph = false;
- m_fRealMediaGraph = m_fShockwaveGraph = m_fQuicktimeGraph = false;
-
- AppSettings& s = AfxGetAppSettings();
-
- if(OpenFileData* p = dynamic_cast<OpenFileData*>(pOMD))
- {
- 获得解码类型
- engine_t engine = s.Formats.GetEngine(p->fns.GetHead());
-
- std::wstring ct = ContentType::Get(p->fns.GetHead());
-
- if(ct == L"video/x-ms-asf")
- {
- // TODO: put something here to make the windows media source filter load later
- }
- else if (ct == L"audio/x-pn-realaudio"
- || ct == L"audio/x-pn-realaudio-plugin"
- || ct == L"audio/x-realaudio-secure"
- || ct == L"video/vnd.rn-realvideo-secure"
- || ct == L"application/vnd.rn-realmedia"
- || ct.find(L"vnd.rn-") != ct.npos
- || ct.find(L"realaudio") != ct.npos
- || ct.find(L"realvideo") != ct.npos)
- {
- // TODO: go fuck this!!!
- engine = RealMedia;
- }
- else if (ct == L"application/x-shockwave-flash")
- {
- engine = ShockWave;
- }
- else if (ct == L"video/quicktime"
- || ct == L"application/x-quicktimeplayer")
- {
- engine = QuickTime;
- }
- if (engine == RealMedia)
- engine = DirectShow;
-
- SVP_LogMsg5(L"got content type %s %d", ct.c_str(), engine );
-
- HRESULT hr;
- CComPtr<IUnknown> pUnk;
-
- if(engine == RealMedia)
- {
- if(!(pUnk = (IUnknown*)(INonDelegatingUnknown*)new CRealMediaGraph(m_wndView.m_hWnd, hr)))
- throw _T("Out of memory");
-
- if(SUCCEEDED(hr) && !!(pGB = CComQIPtr<IGraphBuilder>(pUnk)))
- m_fRealMediaGraph = true;
- }
- else if(engine == ShockWave)
- {
- if(!(pUnk = (IUnknown*)(INonDelegatingUnknown*)new CShockwaveGraph(m_wndView.m_hWnd, hr)))
- throw _T("Out of memory");
-
- if(FAILED(hr) || !(pGB = CComQIPtr<IGraphBuilder>(pUnk)))
- throw _T("Can't create shockwave control");
-
- m_fShockwaveGraph = true;
- }
- else if(engine == QuickTime)
- {
- if(!(pUnk = (IUnknown*)(INonDelegatingUnknown*)new CQuicktimeGraph(m_wndView.m_hWnd, hr)))
- throw _T("Out of memory");
-
- if(SUCCEEDED(hr) && !!(pGB = CComQIPtr<IGraphBuilder>(pUnk)))
- m_fQuicktimeGraph = true;
- }
-
- m_fCustomGraph = m_fRealMediaGraph || m_fShockwaveGraph || m_fQuicktimeGraph;
-
- if(!m_fCustomGraph)
- {
- 视频播放解码 生成接口
- pGB = new CFGManagerPlayer(_T("CFGManagerPlayer"), NULL, s.SrcFilters, s.TraFilters, m_wndView.m_hWnd);
- }
- }
- else if(OpenDVDData* p = dynamic_cast<OpenDVDData*>(pOMD))
- {
- pGB = new CFGManagerDVD(_T("CFGManagerDVD"), NULL, s.SrcFilters, s.TraFilters, m_wndView.m_hWnd);
- }
- else if(OpenDeviceData* p = dynamic_cast<OpenDeviceData*>(pOMD))
- {
- pGB = new CFGManagerCapture(_T("CFGManagerCapture"), NULL, s.SrcFilters, s.TraFilters, m_wndView.m_hWnd);
- }
-
- if(!pGB)
- {
- throw _T("Failed to create the filter graph object");
- }
-
- pGB->AddToROT();
-
- 把视频解码接口赋值给其它
- pMC = pGB; pME = pGB; pMS = pGB; // general
- pVW = pGB; pBV = pGB; // video
- pBA = pGB; // audio
- pFS = pGB;
-
- if(!(pMC && pME && pMS)
- || !(pVW && pBV)
- || !(pBA))
- {
- throw ResStr(IDS_MSG_THROW_BROKEN_DIRECTX_SUPPORT);
- }
-
- 发送WM_GRAPHNOTIFY 消息
- if(FAILED(pME->SetNotifyWindow((OAHWND)m_hWnd, WM_GRAPHNOTIFY, 0)))
- {
- throw _T("Could not set target window for graph notification");
- }
-
- m_pProv = (IUnknown*)new CKeyProvider(); 键盘提供者接口
-
- if(CComQIPtr<IObjectWithSite> pObjectWithSite = pGB)
- pObjectWithSite->SetSite(m_pProv); 键盘站点 捕获键盘消息
-
-
- m_pCB = new CDSMChapterBag(NULL, NULL); dstuil库中类
- }
-
- 进入OpenFile分析
- void CMainFrame::OpenFile(OpenFileData* pOFD)
- {
- if(pOFD->fns.IsEmpty()) 文件为空 则抛出异常
- throw _T("Invalid argument");
-
- AppSettings& s = AfxGetAppSettings(); 获得设置信息
-
- bool fFirst = true;
-
- POSITION pos = pOFD->fns.GetHeadPosition();
- while(pos)
- {
- CString fn = pOFD->fns.GetNext(pos);
-
- fn.Trim();
- if(fn.IsEmpty() && !fFirst)
- break;
-
- CString fnLower = fn;
- fnLower.MakeLower();
-
- HRESULT hr = -1;
- 如果不是mms://路径或mmsh://路径
- if(FAILED(hr) && ( fnLower.Find(_T("mms://")) == 0 || fnLower.Find(_T("mmsh://")) == 0 )){ //
- //render mms our own way
- hr = OpenMMSUrlStream(fn);
- }
- if(FAILED(hr)) 渲染文件 持续了很长时间
- hr = pGB->RenderFile(CStringW(fn), NULL);
-
- 如果是网络文件 则大概网络流
- if(FAILED(hr) && ( fnLower.Find(_T("http") == 0 || fnLower.Find(_T("https://")) == 0
- || fnLower.Find(_T("udp://")) == 0 || fnLower.Find(_T("tcp://")) == 0)) ){ //
- //render mms our own way
- hr = OpenMMSUrlStream(fn);
- }
-
- /* not sure why this is not work for http youku etc 不知道这是为什么不适用于HTTP优酷等
- HRESULT hr = -1;
- if( ( fn.MakeLower().Find(_T("mms://")) == 0 || fn.MakeLower().Find(_T("mmsh://")) == 0 || (fn.MakeLower().Find(_T("http:")) == 0 && fn.MakeLower().Find(_T(":8902")) > 0 ))){
- //render mms our own way
- hr = OpenMMSUrlStream(fn);
- }
- if(FAILED(hr))
- hr = pGB->RenderFile(CStringW(fn), NULL);
- */
-
- 依然失败 则寻找错误 记录错误
- if(FAILED(hr))
- {
- if(fFirst)
- {
- //if(s.fReportFailedPins)
- {
- CComQIPtr<IGraphBuilderDeadEnd> pGBDE = pGB;
- if(pGBDE && pGBDE->GetCount()) CMediaTypesDlg(pGBDE, this).DoModal();
- }
-
- CString err;
-
- switch(hr)
- {
- case E_ABORT: err = ResStr(IDS_MSG_THROW_OPRATION_CANCELED); break;
- case E_FAIL: case E_POINTER: default:
- err.Format(ResStr(IDS_MSG_THROW_UNABLE_OPEN_FILE) , hr);
- break;
- case E_INVALIDARG: err = ResStr(IDS_MSG_THROW_ILLEGE_FILENAME); break;
- case E_OUTOFMEMORY: err = ResStr(IDS_MSG_THROW_OUTOF_MEMORY); break;
- case VFW_E_CANNOT_CONNECT: err = ResStr(IDS_MSG_THROW_UNABLE_DECODE); break;
- case VFW_E_CANNOT_LOAD_SOURCE_FILTER: err = ResStr(IDS_MSG_THROW_UNSUPPORT_SOURCE); break;
- case VFW_E_CANNOT_RENDER: err = ResStr(IDS_MSG_THROW_FAIL_CREATE_RENDER); break;
- case VFW_E_INVALID_FILE_FORMAT: err = _T("Invalid file format"); break;
- case VFW_E_NOT_FOUND: err = ResStr(IDS_MSG_THROW_FILE_NOT_FOUND); break;
- case VFW_E_UNKNOWN_FILE_TYPE: err = ResStr(IDS_MSG_THROW_UNKNOWN_FILE_TYPE); break;
- case VFW_E_UNSUPPORTED_STREAM: err = ResStr(IDS_MSG_THROW_UNSUPPORT_STREAM_TYPE); break;
- }
-
- throw err;
- }
- }
-
- 是否保存记录
- if(s.fKeepHistory)
- {
- if(this->m_lastUrl == fn){ 本次与上次是否相同
- CRecentFileList* pMRU = &s.MRUUrl;
- pMRU->ReadList();
- pMRU->Add(fn);
- pMRU->WriteList();
- this->m_lastUrl.Empty();
- }else{
- 不同则写入
- CRecentFileList* pMRU = fFirst ? &s.MRU : &s.MRUDub;
- pMRU->ReadList();
- pMRU->Add(fn);
- pMRU->WriteList();
- }
- }
-
- if(fFirst) 第一次运行? 搜索字幕
- {
- AppSettings& s = AfxGetAppSettings();
- pOFD->title = fn;
- m_fnCurPlayingFile = fn;
- //是否有字幕? 沒有则下载字幕
- CSVPToolBox svpTool;
- //搜索目录下同名字幕
- CAtlArray<CString> subSearchPaths;
- subSearchPaths.Add(_T("."));
- subSearchPaths.Add(s.GetSVPSubStorePath());
- subSearchPaths.Add(svpTool.GetPlayerPath(L"SVPSub"));
- subSearchPaths.Add(_T(".\\subtitles"));
- subSearchPaths.Add(_T(".\\Subs"));
- subSearchPaths.Add(_T("c:\\subtitles"));
-
- CAtlArray<SubFile> ret;
-
- POSITION pos = pOFD->subs.GetHeadPosition();
- while(pos){
- POSITION cur = pos;
- CString szSubFn = pOFD->subs.GetNext(pos);
- if(!svpTool.ifFileExist(szSubFn))
- pOFD->subs.RemoveAt(cur);
- }
- CSVPRarLib svpRar;
- if( svpRar.SplitPath(fn) ){
- GetSubFileNames(svpRar.m_fnRAR, subSearchPaths, ret);
- CAtlArray<SubFile> ret2;
- GetSubFileNames(svpRar.m_fnInsideRar, subSearchPaths, ret2);
- ret.Append(ret2);
- }else{
- GetSubFileNames(fn, subSearchPaths, ret);
- //AfxMessageBox(fn);
- }
- for(int i = 0; i < ret.GetCount(); i++){
- SubFile szBuf = ret.GetAt(i);
- //AfxMessageBox(szBuf.fn);
- if ( pOFD->subs.Find( szBuf.fn ) == NULL && svpTool.ifFileExist(szBuf.fn)){
- pOFD->subs.AddTail(szBuf.fn);
- //AfxMessageBox(szBuf.fn);
- }
- }
- //AfxMessageBox(_T("1"));
- if ( pOFD->subs.GetCount() <= 0){
- // AfxMessageBox(_T("2"));
-
-
-
-
- if(s.autoDownloadSVPSub){
- CPath fPath(fn);
- CString szExt;
- szExt.Format(_T(" %s;"),fPath.GetExtension());
- if(s.CheckSVPSubExts.Find(szExt) >= 0 ){
- SVPSubDownloadByVPath(fn);
- }else{
- //SendStatusMessage( _T("正在播放的文件类型看来不需要字幕,终止自动智能匹配"), 1000);
- }
- }
- }
- }
- fFirst = false;
-
- if(m_fCustomGraph) break;
- } 智能匹配字幕结束
-
- //if(s.fReportFailedPins)
- { 如果绘图挂了 类型对话框弹出
- CComQIPtr<IGraphBuilderDeadEnd> pGBDE = pGB;
- if(pGBDE && pGBDE->GetCount()) CMediaTypesDlg(pGBDE, this).DoModal();
- }
-
- if(!(pAMOP = pGB))
- {
- BeginEnumFilters(pGB, pEF, pBF)
- if(pAMOP = pBF) break;
- EndEnumFilters
- }
-
- if(FindFilter(__uuidof(CShoutcastSource), pGB))
- m_fUpdateInfoBar = true;
-
- SetupChapters(); 初始化章节
-
- 枚举 寻找IKeyFrameInfo 接口
- CComQIPtr<IKeyFrameInfo> pKFI;
- BeginEnumFilters(pGB, pEF, pBF)
- if(pKFI = pBF) break;
- EndEnumFilters
- UINT nKFs = 0, nKFsTmp = 0;
- if(pKFI && S_OK == pKFI->GetKeyFrameCount(nKFs) && nKFs > 0)
- {
- m_kfs.SetCount(nKFsTmp = nKFs);
- if(S_OK != pKFI->GetKeyFrames(&TIME_FORMAT_MEDIA_TIME, m_kfs.GetData(), nKFsTmp) || nKFsTmp != nKFs)
- m_kfs.RemoveAll();
- }
-
- m_iPlaybackMode = PM_FILE;
- }
-
- 进入SetupChapters() 初始化章节
- void CMainFrame::SetupChapters()
- {
- ASSERT(m_pCB); 解码不为空
-
- m_pCB->ChapRemoveAll();
-
- 查找过滤接口 并添加到pBFs
- CInterfaceList<IBaseFilter> pBFs;
- BeginEnumFilters(pGB, pEF, pBF)
- pBFs.AddTail(pBF);
- EndEnumFilters
-
- POSITION pos;
-
- 循环遍历过滤接口 进行追加操作 具体什么 待分析
- pos = pBFs.GetHeadPosition();
- while(pos && !m_pCB->ChapGetCount())
- {
- IBaseFilter* pBF = pBFs.GetNext(pos);
-
- CComQIPtr<IDSMChapterBag> pCB = pBF;
- if(!pCB) continue;
-
- for(DWORD i = 0, cnt = pCB->ChapGetCount(); i < cnt; i++)
- {
- REFERENCE_TIME rt;
- CComBSTR name;
- if(SUCCEEDED(pCB->ChapGet(i, &rt, &name)))
- m_pCB->ChapAppend(rt, name);
- }
- }
-
- 循环遍历过滤接口 进行追加操作 具体什么 待分析
- pos = pBFs.GetHeadPosition();
- while(pos && !m_pCB->ChapGetCount())
- {
- IBaseFilter* pBF = pBFs.GetNext(pos);
-
- CComQIPtr<IChapterInfo> pCI = pBF;
- if(!pCI) continue;
-
- CHAR iso6391[3];
- ::GetLocaleInfoA(LOCALE_USER_DEFAULT, LOCALE_SISO639LANGNAME, iso6391, 3);
- CStringA iso6392 = ISO6391To6392(iso6391);
- if(iso6392.GetLength() < 3) iso6392 = "eng";
-
- UINT cnt = pCI->GetChapterCount(CHAPTER_ROOT_ID);
- for(UINT i = 1; i <= cnt; i++)
- {
- UINT cid = pCI->GetChapterId(CHAPTER_ROOT_ID, i);
-
- ChapterElement ce;
- if(pCI->GetChapterInfo(cid, &ce))
- {
- char pl[3] = {iso6392[0], iso6392[1], iso6392[2]};
- char cc[] = " ";
- CComBSTR name;
- name.Attach(pCI->GetChapterStringInfo(cid, pl, cc));
- m_pCB->ChapAppend(ce.rtStart, name);
- }
- }
- }
-
- 循环遍历过滤接口 进行追加操作 具体什么 待分析
- pos = pBFs.GetHeadPosition();
- while(pos && !m_pCB->ChapGetCount())
- {
- IBaseFilter* pBF = pBFs.GetNext(pos);
-
- CComQIPtr<IAMExtendedSeeking, &IID_IAMExtendedSeeking> pES = pBF;
- if(!pES) continue;
-
- long MarkerCount = 0;
- if(SUCCEEDED(pES->get_MarkerCount(&MarkerCount)))
- {
- for(long i = 1; i <= MarkerCount; i++)
- {
- double MarkerTime = 0;
- if(SUCCEEDED(pES->GetMarkerTime(i, &MarkerTime)))
- {
- CStringW name;
- name.Format(L"Chapter %d", i);
-
- CComBSTR bstr;
- if(S_OK == pES->GetMarkerName(i, &bstr))
- name = bstr;
-
- m_pCB->ChapAppend(REFERENCE_TIME(MarkerTime*10000000), name);
- }
- }
- }
- }
-
- 循环遍历过滤接口 进行追加操作 具体什么 待分析
- pos = pBFs.GetHeadPosition();
- while(pos && !m_pCB->ChapGetCount())
- {
- IBaseFilter* pBF = pBFs.GetNext(pos);
-
- if(GetCLSID(pBF) != CLSID_OggSplitter)
- continue;
-
- BeginEnumPins(pBF, pEP, pPin)
- {
- if(m_pCB->ChapGetCount()) break;
-
- if(CComQIPtr<IPropertyBag> pPB = pPin)
- {
- for(int i = 1; ; i++)
- {
- CStringW str;
- CComVariant var;
-
- var.Clear();
- str.Format(L"CHAPTER%02d", i);
- if(S_OK != pPB->Read(str, &var, NULL))
- break;
- int h, m, s, ms;
- WCHAR wc;
- if(7 != swscanf(CStringW(var), L"%d%c%d%c%d%c%d", &h, &wc, &m, &wc, &s, &wc, &ms))
- break;
- CStringW name;
- name.Format(L"Chapter %d", i);
- var.Clear();
- str += L"NAME";
- if(S_OK == pPB->Read(str, &var, NULL))
- name = var;
- m_pCB->ChapAppend(10000i64*(((h*60 + m)*60 + s)*1000 + ms), name);
- }
- }
- }
- EndEnumPins
- }
- m_pCB->ChapSort();
- }
-
- 进入OpenCustomizeGraph 自定义图像大小
- void CMainFrame::OpenCustomizeGraph()
- {
- 总共有enum {PM_NONE, PM_FILE, PM_DVD, PM_CAPTURE}种模式
-
- PM_CAPTURE 模式 不支持自定义图像大小
- if(m_iPlaybackMode == PM_CAPTURE) return;
-
- CleanGraph(); 清楚画像
-
- if(m_iPlaybackMode == PM_FILE) 文件模式
- {
- if(m_pCAP) {
- if(AfxGetAppSettings().fAutoloadSubtitles) {
- AddTextPassThruFilter(); 进行了很多连接 需要分析
- }
- }
- }
-
- 同步视频
- AppSettings& s = AfxGetAppSettings();
- if (s.m_RenderSettings.bSynchronizeVideo)
- {
- HRESULT hr;
- m_pRefClock = DNew CSyncClockFilter(NULL, &hr);
- CStringW name;
- name.Format(L"SyncClock Filter");
- pGB->AddFilter(m_pRefClock, name);
-
- CComPtr<IReferenceClock> refClock;
- m_pRefClock->QueryInterface(IID_IReferenceClock, reinterpret_cast<void**>(&refClock));
- CComPtr<IMediaFilter> mediaFilter;
- pGB->QueryInterface(IID_IMediaFilter, reinterpret_cast<void**>(&mediaFilter));
- mediaFilter->SetSyncSource(refClock);
- mediaFilter = NULL;
- refClock = NULL;
-
- m_pRefClock->QueryInterface(IID_ISyncClock, reinterpret_cast<void**>(&m_pSyncClock));
- }
-
- BeginEnumFilters(pGB, pEF, pBF)
- {
- 查找CLSID_OggSplitter 控件
- if(GetCLSID(pBF) == CLSID_OggSplitter)
- {
- 查找IAMStreamSelect接口
- if(CComQIPtr<IAMStreamSelect> pSS = pBF)
- {
- LCID idAudio = AfxGetAppSettings().idAudioLang;
- if(!idAudio) idAudio = GetUserDefaultLCID();
- LCID idSub = AfxGetAppSettings().idSubtitlesLang;
- if(!idSub) idSub = GetUserDefaultLCID();
-
- DWORD cnt = 0;
- pSS->Count(&cnt);
- for(DWORD i = 0; i < cnt; i++)
- {
- AM_MEDIA_TYPE* pmt = NULL;
- DWORD dwFlags = 0;
- LCID lcid = 0;
- DWORD dwGroup = 0;
- WCHAR* pszName = NULL;
- if(SUCCEEDED(pSS->Info((long)i, &pmt, &dwFlags, &lcid, &dwGroup, &pszName, NULL, NULL)))
- {
- CStringW name(pszName), sound(L"Sound"), subtitle(L"Subtitle");
-
- if(idAudio != -1 && (idAudio&0x3ff) == (lcid&0x3ff) // sublang seems to be zeroed out in ogm...
- && name.GetLength() > sound.GetLength()
- && !name.Left(sound.GetLength()).CompareNoCase(sound))
- {
- if(SUCCEEDED(pSS->Enable(i, AMSTREAMSELECTENABLE_ENABLE)))
- idAudio = -1;
- }
-
- if(idSub != -1 && (idSub&0x3ff) == (lcid&0x3ff) // sublang seems to be zeroed out in ogm...
- && name.GetLength() > subtitle.GetLength()
- && !name.Left(subtitle.GetLength()).CompareNoCase(subtitle)
- && name.Mid(subtitle.GetLength()).Trim().CompareNoCase(L"off"))
- {
- if(SUCCEEDED(pSS->Enable(i, AMSTREAMSELECTENABLE_ENABLE)))
- idSub = -1;
- }
-
- if(pmt) DeleteMediaType(pmt);
- if(pszName) CoTaskMemFree(pszName);
- }
- }
- }
- }
- }
- EndEnumFilters
-
- CleanGraph();
- }
-
- 进入OpenSetupVideo() 初始化视频
- void CMainFrame::OpenSetupVideo()
- {
- 只自动?
- m_fAudioOnly = true;
-
- if (m_pMFVDC) // EVR
- {
- EVR 不支持
- m_fAudioOnly = false;
- }
- else if(m_pCAPR)
- {
- 获得视频大小
- CSize vs = m_pCAPR->GetVideoSize();
- m_fAudioOnly = (vs.cx <= 0 || vs.cy <= 0);
- }
- else
- {
- 否则其它
- {
- long w = 0, h = 0;
-
- if(CComQIPtr<IBasicVideo> pBV = pGB)
- {
- pBV->GetVideoSize(&w, &h);
- }
-
- if(w > 0 && h > 0)
- {
- m_fAudioOnly = false;
- }
- }
-
- if(m_fAudioOnly)
- {
- BeginEnumFilters(pGB, pEF, pBF)
- {
- long w = 0, h = 0;
-
-
- if(CComQIPtr<IVideoWindow> pVW = pBF)
- {
- long lVisible;
- if(FAILED(pVW->get_Visible(&lVisible)))
- continue;
-
- pVW->get_Width(&w);
- pVW->get_Height(&h);
- }
-
- if(w > 0 && h > 0)
- {
- m_fAudioOnly = false;
- break;
- }
- }
- EndEnumFilters
- }
- }
-
- if(m_fShockwaveGraph) flash控件
- {
- m_fAudioOnly = false;
- }
-
- if(m_pCAP)
- {
- SetShaders();
- }
- // else
- {
- // TESTME
-
- pVW->put_Owner((OAHWND)m_wndView.m_hWnd);
- pVW->put_WindowStyle(WS_CHILD|WS_CLIPSIBLINGS|WS_CLIPCHILDREN);
- pVW->put_MessageDrain((OAHWND)m_hWnd);
-
- for(CWnd* pWnd = m_wndView.GetWindow(GW_CHILD); pWnd; pWnd = pWnd->GetNextWindow())
- pWnd->EnableWindow(FALSE); // little trick to let WM_SETCURSOR thru
- }
- }
-
- 进入SetShaders( BOOL silent ) 设置着色
- void CMainFrame::SetShaders( BOOL silent )
- {
- if(!m_pCAPR) return; 不存在则直接返回
-
- AppSettings& s = AfxGetAppSettings();
-
- CAtlStringMap<const AppSettings::Shader*> s2s;
-
- POSITION pos = s.m_shaders.GetHeadPosition();
- while(pos)
- {
- const AppSettings::Shader* pShader = &s.m_shaders.GetNext(pos); 关键取值
- s2s[pShader->label] = pShader;
- }
- if(!silent){
- m_pCAPR->SetPixelShader(NULL, NULL);
- if (m_pCAP2)
- m_pCAP2->SetPixelShader2(NULL, NULL, true);
- }
-
- CAtlList<CString> labels;
-
- pos = m_shaderlabels.GetHeadPosition();
- while(pos)
- {
- const AppSettings::Shader* pShader = NULL;
- if(s2s.Lookup(m_shaderlabels.GetNext(pos), pShader))
- {
- CStringA target = pShader->target;
- CStringA srcdata = pShader->srcdata;
-
- HRESULT hr = m_pCAPR->SetPixelShader(srcdata, target );
-
- if(FAILED(hr))
- {
- //m_pCAP->SetPixelShader(NULL, NULL);
- if (m_pCAP2)
- hr = m_pCAP2->SetPixelShader2(srcdata, target, true);
- if(FAILED(hr)){
- // if (m_pCAP2)
- // m_pCAP2->SetPixelShader2(NULL, NULL, true, !silent);
- if(!silent)
- {
- CString label = pShader->label;
- OsdMsg_SetShader(&label);
- }
- }
- return;
- }
- labels.AddTail(pShader->label);
- }
- }
-
- if(m_iMediaLoadState == MLS_LOADED)
- {
- CString str = Implode(labels, '|');
- str.Replace(_T("|"), _T(", "));
- if(!silent) SendStatusMessage(_T("Shader: ") + str, 3000);
- }
- if(!silent){
- if (SetVMR9ColorControl(s.dBrightness , s.dContrast, 0, 0, true) == FALSE)
- OsdMsg_SetShader();
- }
- }
-
- 进入OpenSetupAudio() 初始化音频
- void CMainFrame::OpenSetupAudio()
- {
- 赋值
- pBA->put_Volume(m_wndToolBar.Volume);
-
- // FIXME
- // 又是从设置中取得数据
- int balance = AfxGetAppSettings().nBalance;
- int sign = balance>0?-1:1;
- balance = max(100-abs(balance), 1);
- balance = (int)((log10(1.0*balance)-2)*5000*sign);
- balance = max(min(balance, 10000), -10000);
- pBA->put_Balance(balance);
- }
-
- 进入CMainFrame::OpenSetupWindowTitle 初始化标题
- void CMainFrame::OpenSetupWindowTitle(CString fn)
- {
- CString title(MAKEINTRESOURCE(IDR_MAINFRAME));
-
- AppSettings& s = AfxGetAppSettings();
-
- int i = s.iTitleBarTextStyle;
-
- if(!fn.IsEmpty() && (i == 0 || i == 1))
- {
- if(i == 1)
- {
- if(m_iPlaybackMode == PM_FILE)
- {
- fn.Replace('\\', '/');
- CString fn2 = fn.Mid(fn.ReverseFind('/')+1);
- if(!fn2.IsEmpty()) fn = fn2;
-
- if(s.fTitleBarTextTitle)
- {
- BeginEnumFilters(pGB, pEF, pBF)
- {
- if(CComQIPtr<IAMMediaContent, &IID_IAMMediaContent> pAMMC = pBF)
- {
- CComBSTR bstr;
- if(SUCCEEDED(pAMMC->get_Title(&bstr)) && bstr.Length())
- {
- fn = CString(bstr.m_str);
- break;
- }
- }
- }
- EndEnumFilters
- }
- }
- else if(m_iPlaybackMode == PM_DVD)
- {
- fn = _T("DVD");
- }
- else if(m_iPlaybackMode == PM_CAPTURE)
- {
- fn = _T("Live");
- }
- }
- title = fn + _T(" - ") + title;
- }
- //CString szBuild;
- //szBuild.Format(_T(" (Build %s)"),SVP_REV_STR);
- //title += szBuild;
- //SetWindowText(title);
- m_szTitle = title;
- RedrawNonClientArea();
- }
-
- 在OpenMediaPrivate()中
- PostMessage(WM_COMMAND, ID_PLAY_PAUSE);
- if(!(AfxGetAppSettings().nCLSwitches&CLSW_OPEN))
- PostMessage(WM_COMMAND, ID_PLAY_PLAY);
-
- 紧紧只是更新UI?
- ON_UPDATE_COMMAND_UI(ID_PLAY_PLAY, OnUpdatePlayPauseStop)
-
- 进入OnUpdatePlayPauseStop 分析
- void CMainFrame::OnUpdatePlayPauseStop(CCmdUI* pCmdUI)
- {
- OAFilterState fs = m_fFrameSteppingActive ? State_Paused : GetMediaState();
-
- UI消息
- pCmdUI->SetCheck(fs == State_Running && pCmdUI->m_nID == ID_PLAY_PLAY
- || fs == State_Paused && pCmdUI->m_nID == ID_PLAY_PAUSE
- || fs == State_Stopped && pCmdUI->m_nID == ID_PLAY_STOP
- || (fs == State_Paused || fs == State_Running) && pCmdUI->m_nID == ID_PLAY_PLAYPAUSE);
-
- bool fEnable = false;
-
- if(fs >= 0)
- {
- if(m_iPlaybackMode == PM_FILE || m_iPlaybackMode == PM_CAPTURE)
- {
- fEnable = true;
-
- 不能进入暂停状态,从停止使用rm
- if(fs == State_Stopped && pCmdUI->m_nID == ID_PLAY_PAUSE && m_fRealMediaGraph) fEnable = false; // can't go into paused state from stopped with rm
- else if(m_fCapturing) fEnable = false;
- else if(m_fLiveWM && pCmdUI->m_nID == ID_PLAY_PAUSE) fEnable = false;
- }
- else if(m_iPlaybackMode == PM_DVD)
- {
- fEnable = m_iDVDDomain != DVD_DOMAIN_VideoManagerMenu
- && m_iDVDDomain != DVD_DOMAIN_VideoTitleSetMenu;
-
- if(fs == State_Stopped && pCmdUI->m_nID == ID_PLAY_PAUSE) fEnable = false;
- }
- }
- if(pCmdUI->m_nID == ID_PLAY_PLAY || pCmdUI->m_nID == ID_PLAY_PLAYPAUSE) fEnable = true;
- pCmdUI->Enable(fEnable);
- }
-
- ON_COMMAND(ID_PLAY_PAUSE, OnPlayPause)
- void CMainFrame::OnPlayPause()
- //支持ffdshow的排队。
- //为了避免暂停黑掉,我们以锁定g_ffdshowReceive同步与ReceiveMine的。
- void CMainFrame::OnPlayPause()
- {
- // Support ffdshow queueing.
- // To avoid black out on pause, we have to lock g_ffdshowReceive to synchronize with ReceiveMine.
- time(&m_tPlayPauseTime);
- if(queueu_ffdshow_support)
- {
- CAutoLock lck(&g_ffdshowReceive);
- return OnPlayPauseI();
- }
- OnPlayPauseI();
- }
-
- 进入OnPlayPauseI()分析
- void CMainFrame::OnPlayPauseI()
- {
- if(m_iMediaLoadState == MLS_LOADED) 已经加载
- {
- if(m_iPlaybackMode == PM_FILE)
- {
- pMC->Pause(); 停止
- }
- else if(m_iPlaybackMode == PM_DVD)
- {
- pMC->Pause();
- }
- else if(m_iPlaybackMode == PM_CAPTURE)
- {
- pMC->Pause();
- }
-
- SetTimer(TIMER_STREAMPOSPOLLER, 40, NULL);
- SetTimer(TIMER_STREAMPOSPOLLER2, 500, NULL);
- SetTimer(TIMER_STATS, 1000, NULL);
-
- KillTimer(TIMER_IDLE_TASK);
- SetTimer(TIMER_IDLE_TASK, 30000, NULL);
-
- SetAlwaysOnTop(AfxGetAppSettings().iOnTop); 设置置顶
- }
- MoveVideoWindow();
- }
-
- 移动视频窗体
- void CMainFrame::MoveVideoWindow(bool fShowStats)
- {
- 视频已经加载 不是自动 窗体可见
- if(m_iMediaLoadState == MLS_LOADED && !m_fAudioOnly && IsWindowVisible())
- {
- AppSettings &s = AfxGetAppSettings();
- CRect wr;
-
- if(!m_fFullScreen && (s.bUserAeroUI() || (!s.bUserAeroUI() && ( s.nCS & CS_TOOLBAR ))) )
- {
- m_wndView.GetClientRect(wr);
- }
- else
- {
- GetWindowRect(&wr);
- // HACK
- CRect r;
- m_wndView.GetWindowRect(&r);
- wr -= r.TopLeft();
- }
- CRect vr = CRect(0,0,0,0);
-
- OAFilterState fs = GetMediaState();
- if(fs == State_Paused || fs == State_Running || fs == State_Stopped && (m_fShockwaveGraph || m_fQuicktimeGraph))
- {
- CSize arxy = GetVideoSize();
-
- int iDefaultVideoSize = AfxGetAppSettings().iDefaultVideoSize;
-
- CSize ws =
- iDefaultVideoSize == DVS_HALF ? CSize(arxy.cx/2, arxy.cy/2) :
- iDefaultVideoSize == DVS_NORMAL ? arxy :
- iDefaultVideoSize == DVS_DOUBLE ? CSize(arxy.cx*2, arxy.cy*2) :
- wr.Size();
-
- int w = ws.cx;
- int h = ws.cy;
-
- if(!m_fShockwaveGraph) //&& !m_fQuicktimeGraph)
- {
- if(iDefaultVideoSize == DVS_FROMINSIDE || iDefaultVideoSize == DVS_FROMOUTSIDE)
- {
- h = ws.cy;
- w = MulDiv(h, arxy.cx, arxy.cy);
-
- if(iDefaultVideoSize == DVS_FROMINSIDE && w > ws.cx
- || iDefaultVideoSize == DVS_FROMOUTSIDE && w < ws.cx)
- {
- w = ws.cx;
- h = MulDiv(w, arxy.cy, arxy.cx);
- }
- }
- }
-
- CSize size(
- (int)(m_ZoomX*w),
- (int)(m_ZoomY*h));
-
- CPoint pos(
- (int)(m_PosX*(wr.Width()*3 - m_ZoomX*w) - wr.Width()),
- (int)(m_PosY*(wr.Height()*3 - m_ZoomY*h) - wr.Height()));
-
- /* CPoint pos(
- (int)(m_PosX*(wr.Width() - size.cx)),
- (int)(m_PosY*(wr.Height() - size.cy)));
- */
- vr = CRect(pos, size);
- }
-
- wr |= CRect(0,0,0,0);
- vr |= CRect(0,0,0,0);
-
- //CString szLog;
- //szLog.Format(_T("WVSize3 %d %d %d %d %d %d %d "), wr.Width(), wr.Height(), vr.Width(), vr.Height(), m_AngleX , m_AngleY , m_AngleZ);
- //SVP_LogMsg(szLog);
- if(m_pCAPR)
- {
- m_pCAPR->SetPosition(wr, vr);
- m_pCAPR->SetVideoAngle(Vector(DegToRad(m_AngleX), DegToRad(m_AngleY), DegToRad(m_AngleZ)));
- }
- else
- {
- HRESULT hr;
- hr = pBV->SetDefaultSourcePosition();
- hr = pBV->SetDestinationPosition(vr.left, vr.top, vr.Width(), vr.Height());
- hr = pVW->SetWindowPosition(wr.left, wr.top, wr.Width(), wr.Height());
-
- if (m_pMFVDC) m_pMFVDC->SetVideoPosition (NULL, wr);
- }
- //SVP_LogMsg5(_T("MoveVideoWindow %d ") , wr.Height());
- m_wndView.SetVideoRect(wr);
-
- if(fShowStats && vr.Height() > 0)
- {
- CString info(L"正在使用智能拖拽功能。可在画面右上角进行拖拽");
- // info.Format(_T("Pos %.2f %.2f, Zoom %.2f %.2f, AR %.2f"), m_PosX, m_PosY, m_ZoomX, m_ZoomY, (float)vr.Width()/vr.Height());
- SendStatusMessage(info, 3000);
- }
- }
- else
- {
- m_wndView.SetVideoRect();
- }
-
- CRect r;
- m_wndView.GetClientRect(r);
- if(m_iMediaLoadState == MLS_LOADED){
- float fViewRatio = (float)r.Width() / r.Height();
- CSize vsize = GetVideoSize();
- float fVideoRatio = (float)vsize.cx / vsize.cy;
- m_fScreenHigherThanVideo = (fViewRatio < fVideoRatio );
- }
- }
-
- 仅仅只是更新UI
- void CMainFrame::OnUpdatePlayPauseStop(CCmdUI* pCmdUI)
- {
- OAFilterState fs = m_fFrameSteppingActive ? State_Paused : GetMediaState();
-
- pCmdUI->SetCheck(fs == State_Running && pCmdUI->m_nID == ID_PLAY_PLAY
- || fs == State_Paused && pCmdUI->m_nID == ID_PLAY_PAUSE
- || fs == State_Stopped && pCmdUI->m_nID == ID_PLAY_STOP
- || (fs == State_Paused || fs == State_Running) && pCmdUI->m_nID == ID_PLAY_PLAYPAUSE);
-
- bool fEnable = false;
-
- if(fs >= 0)
- {
- if(m_iPlaybackMode == PM_FILE || m_iPlaybackMode == PM_CAPTURE)
- {
- fEnable = true;
-
- if(fs == State_Stopped && pCmdUI->m_nID == ID_PLAY_PAUSE && m_fRealMediaGraph) fEnable = false; // can't go into paused state from stopped with rm
- else if(m_fCapturing) fEnable = false;
- else if(m_fLiveWM && pCmdUI->m_nID == ID_PLAY_PAUSE) fEnable = false;
- }
- else if(m_iPlaybackMode == PM_DVD)
- {
- fEnable = m_iDVDDomain != DVD_DOMAIN_VideoManagerMenu
- && m_iDVDDomain != DVD_DOMAIN_VideoTitleSetMenu;
-
- if(fs == State_Stopped && pCmdUI->m_nID == ID_PLAY_PAUSE) fEnable = false;
- }
- }
- if(pCmdUI->m_nID == ID_PLAY_PLAY || pCmdUI->m_nID == ID_PLAY_PLAYPAUSE) fEnable = true;
- pCmdUI->Enable(fEnable);
- }
-
- // play 播放事件
- void CMainFrame::OnPlayPlay()
- {
- if(m_iMediaLoadState == MLS_LOADED) 必须载入
- {
- if(GetMediaState() == State_Stopped) { m_iSpeedLevel = 0; time(&m_tPlayStartTime);} 记录
- try
- {
- if(m_iPlaybackMode == PM_FILE) 文件格式
- {
- time_t ttNow;
- time(&ttNow);
- if( m_tPlayPauseTime > m_tPlayStartTime){
- m_tPlayStartTime += (ttNow - m_tPlayPauseTime);
- }
- if(m_fEndOfStream){ 如果文件流没有 则停止
- SendMessage(WM_COMMAND, ID_PLAY_STOP);
- Sleep(1500);
- }
- pMC->Run(); 运行
- }
- else if(m_iPlaybackMode == PM_DVD) DVD格式
- {
- double dRate = 1.0;
- //if(m_iSpeedLevel != -4 && m_iSpeedLevel != 0)
- // dRate = pow(2.0, m_iSpeedLevel >= -3 ? m_iSpeedLevel : (-m_iSpeedLevel - 8));
- dRate = 1.0 + m_iSpeedLevel * 0.1;
- pDVDC->PlayForwards(dRate, DVD_CMD_FLAG_Block, NULL);
- pDVDC->Pause(FALSE);
- pMC->Run();
- }
- else if(m_iPlaybackMode == PM_CAPTURE) CAPTURE 格式
- {
- pMC->Stop(); // audio preview won't be in sync if we run it from paused state
- pMC->Run();
- }
- }
- catch (...)
- {
- SendMessage(WM_COMMAND, ID_FILE_CLOSEMEDIA); 异常 就关闭视频
- return;
- }
- SetTimer(TIMER_STREAMPOSPOLLER, 40, NULL); 位置信息
- SetTimer(TIMER_STREAMPOSPOLLER2, 500, NULL); 位置2信息
- SetTimer(TIMER_STATS, 1000, NULL); 状态信息
-
- if(m_fFrameSteppingActive) // FIXME 第一次 设置声音
- {
- m_fFrameSteppingActive = false;
- pBA->put_Volume(m_VolumeBeforeFrameStepping);
- }
-
- SetAlwaysOnTop(AfxGetAppSettings().iOnTop); 置顶
- m_wndColorControlBar.CheckAbility(); 控件状态位置等信息
- MoveVideoWindow(); 移动视频
- }else if(m_iMediaLoadState == MLS_CLOSED){ 如果是关闭状态 则重新播放
- if(m_WndSizeInited >= 2){
- if(m_wndPlaylistBar.GetCount()){
- OpenCurPlaylistItem();
- //}else
- // SendMessage(WM_COMMAND, ID_FILE_OPENMEDIA);
- }
- }
- }
- //KillTimer(TIMER_SNAP);
- //SetTimer(TIMER_SNAP, 10000, NULL);
- }
-
- 进入OnFilePostOpenmedia() 分析
- void CMainFrame::OnFilePostOpenmedia()
- {
- OpenSetupClipInfo(); 初始化剪切板信息
- //A-B Control
- m_aRefTime = 0;
- m_bRefTime = 0;
- ABControlOn = FALSE;
-
- OpenSetupCaptureBar(); 初始化控件
-
- AppSettings& s = AfxGetAppSettings();
- m_wndColorControlBar.CheckAbility(); 检查能力
-
- if(m_wndToolBar.IsVisible())
- ShowControls(AfxGetAppSettings().nCS | CS_SEEKBAR, false); 显示控件
-
- __int64 rtDur = 0;
- pMS->GetDuration(&rtDur); 从视频接口获得当前位置
- m_wndPlaylistBar.SetCurTime(rtDur); 设置控件位置
-
- if(m_iPlaybackMode == PM_CAPTURE)
- {
- ShowControlBar(&m_wndPlaylistBar, FALSE, TRUE);
- ShowControlBar(&m_wndCaptureBar, TRUE, TRUE);
- }
-
- / /重要:不能调用任何窗口封邮件之前
- / /这一点上,它会僵局时OpenMediaPrivate
- / /仍在运行,并创建渲染窗口
- / /相同的工作者线程
- std::wstring szFileHash = HashController::GetInstance()->GetSPHash(m_fnCurPlayingFile);
-
- CString FPath = szFileHash.c_str();
-
- 加载第二字幕
- if(m_pCAP && (!m_fAudioOnly || m_fRealMediaGraph))
- {
- if(m_pSubStreams.GetCount() == 0){
- if ( !m_wndPlaylistBar.m_pl.szPlayListSub.IsEmpty() ){
- int delayms = 0 - m_wndPlaylistBar.GetTotalTimeBeforeCur();
- LoadSubtitle(m_wndPlaylistBar.m_pl.szPlayListSub, delayms , true);
- }
- }
-
- if(s.fEnableSubtitles && m_pSubStreams.GetCount() > 0){
- BOOL HavSubs1 = FALSE;
-
- Sql 操作 搜索历史记录
- if(AfxGetMyApp()->sqlite_local_record ){
- CString szSQL;
- szSQL.Format(L"SELECT subid FROM histories WHERE fpath = \"%s\" ", FPath);
- int subid = AfxGetMyApp()->sqlite_local_record->get_single_int_from_sql(szSQL.GetBuffer(), -1);
- if(subid >= 0){
- //SVP_LogMsg5(L"subid %d %d", subid, m_pSubStreams.GetCount());
- int i = subid;
-
- 字幕流?
- POSITION pos = m_pSubStreams.GetHeadPosition();
- while(pos && i >= 0)
- {
- 循环查找
- CComPtr<ISubStream> pSubStream = m_pSubStreams.GetNext(pos);
-
- if(i < pSubStream->GetStreamCount())
- {
- SendStatusMessage(ResStr(IDS_OSD_MSG_RESTORE_TO_LAST_REMEMBER_SUBTITLE_TRACK),3000);
- CAutoLock cAutoLock(&m_csSubLock);
- pSubStream->SetStream(i);
- SetSubtitle(pSubStream);
- HavSubs1 = true;
- break;
- }
- i -= pSubStream->GetStreamCount();
- }
- }
- }
-
- 字幕流?
- if(!HavSubs1 && !s.sSubStreamName1.IsEmpty()){
- POSITION pos = m_pSubStreams.GetHeadPosition();
- while(pos){
- CComPtr<ISubStream> pSubStream = m_pSubStreams.GetNext(pos);
- if(!pSubStream) continue;
- for(int i = 0, j = pSubStream->GetStreamCount(); i < j; i++)
- {
- WCHAR* pName = NULL;
- if(SUCCEEDED(pSubStream->GetStreamInfo(i, &pName, NULL)))
- {
- CString name(pName);
- //SVP_LogMsg5(L"sub2 %s", name);
- if( name == s.sSubStreamName1){
- SetSubtitle( pSubStream);
- HavSubs1 = true;
- }
- CoTaskMemFree(pName);
- if(HavSubs1)
- break;
- }
- }
- if(HavSubs1)
- break;
- }
- }
-
- 设置字幕流
- if(!HavSubs1){
- POSITION pos = m_pSubStreams.GetHeadPosition();
- while(pos){
- CComPtr<ISubStream> pSubStream = m_pSubStreams.GetNext(pos);
- if(!pSubStream) continue;
- for(int i = 0, j = pSubStream->GetStreamCount(); i < j; i++)
- {
- WCHAR* pName = NULL;
- if(SUCCEEDED(pSubStream->GetStreamInfo(i, &pName, NULL)))
- {
- CString name(pName);
- //SVP_LogMsg5(L"sub2 %s", name);
- if( name.Find(L"plain text") > 0){ //Apple Text Media Handler (plain text)
- SetSubtitle( pSubStream);
- HavSubs1 = true;
- }
- CoTaskMemFree(pName);
- if(HavSubs1)
- break;
- }
- }
- if(HavSubs1)
- break;
- }
- }
-
- 字幕流
- if(!HavSubs1)
- SetSubtitle(m_pSubStreams.GetHead());
-
- if(s.fAutoloadSubtitles2 && m_pSubStreams2.GetCount() > 1 ){
- BOOL HavSubs = false;
- if(AfxGetMyApp()->sqlite_local_record ){
- CString szSQL;
- szSQL.Format(L"SELECT subid2 FROM histories WHERE fpath = \"%s\" ", FPath);
- int subid = AfxGetMyApp()->sqlite_local_record->get_single_int_from_sql(szSQL.GetBuffer(), -1);
- if(subid >= 0){
- //SVP_LogMsg5(L"subid %d %d", subid, m_pSubStreams.GetCount());
- int i = subid;
- POSITION pos = m_pSubStreams2.GetHeadPosition();
- while(pos && i >= 0)
- {
- CComPtr<ISubStream> pSubStream = m_pSubStreams2.GetNext(pos);
- if(i < pSubStream->GetStreamCount())
- {
- CAutoLock cAutoLock(&m_csSubLock);
- pSubStream->SetStream(i);
- SetSubtitle2(pSubStream);
- //SendStatusMessage(ResStr(IDS_OSD_MSG_RESTORE_TO_LAST_REMEMBER_SUBTITLE2_TRACK),3000);
- HavSubs = true;
- break;
- }
- i -= pSubStream->GetStreamCount();
- }
- }
- }
-
- 字幕流
- if(!HavSubs && !s.sSubStreamName2.IsEmpty()){
- POSITION pos = m_pSubStreams2.GetHeadPosition();
- while(pos){
- CComPtr<ISubStream> pSubStream = m_pSubStreams2.GetNext(pos);
-
- if(!pSubStream) continue;
-
- for(int i = 0, j = pSubStream->GetStreamCount(); i < j; i++)
- {
- WCHAR* pName = NULL;
- if(SUCCEEDED(pSubStream->GetStreamInfo(i, &pName, NULL)))
- {
- CString name(pName);
- //SVP_LogMsg5(L"sub2 %s", name);
- if((!s.sSubStreamName2.IsEmpty() && name == s.sSubStreamName2) ){
- SetSubtitle2( pSubStream);
- HavSubs = true;
- }
- CoTaskMemFree(pName);
- if(HavSubs)
- break;
- }
- }
- if(HavSubs)
- break;
- }
- }
-
- 字幕流
- if(!HavSubs){
- POSITION pos = m_pSubStreams2.GetHeadPosition();
- while(pos){
- CComPtr<ISubStream> pSubStream = m_pSubStreams2.GetNext(pos);
-
- if(!pSubStream) continue;
-
- for(int i = 0, j = pSubStream->GetStreamCount(); i < j; i++)
- {
- WCHAR* pName = NULL;
- if(SUCCEEDED(pSubStream->GetStreamInfo(i, &pName, NULL)))
- {
- CString name(pName);
- //SVP_LogMsg5(L"sub2 %s", name);
- if( ( name.Find(_T("en")) >= 0 || name.Find(_T("eng")) >= 0 || name.Find(_T("英文")) >= 0) ){
- SetSubtitle2( pSubStream);
- HavSubs = true;
- }
- CoTaskMemFree(pName);
- if(HavSubs)
- break;
- }
- }
- if(HavSubs)
- break;
- }
- }
- if(!HavSubs){
- POSITION pos = m_pSubStreams2.GetHeadPosition();
- m_pSubStreams2.GetNext(pos);
- if(pos)
- SetSubtitle2( m_pSubStreams2.GetNext(pos));
- }
- }
- }
- //make sure the subtitle displayed
- UpdateSubtitle(true); 设置字幕流
- UpdateSubtitle2(true); 设置字幕流
- }
-
- 根据Sql查找历史 发送状态
- if(AfxGetMyApp()->sqlite_local_record ){
- CString szSQL;
- szSQL.Format(L"SELECT audioid FROM histories WHERE fpath = \"%s\" ", FPath);
- //SVP_LogMsg5(szSQL);
- int audid = AfxGetMyApp()->sqlite_local_record->get_single_int_from_sql(szSQL.GetBuffer(), -1);
- if(audid > 0){
- SVP_LogMsg5(L"audid %d subs %d", audid, m_pSubStreams.GetCount());
- CComQIPtr<IAMStreamSelect> pSS = FindFilter(__uuidof(CAudioSwitcherFilter), pGB);
- if(!pSS) pSS = FindFilter(L"{D3CD7858-971A-4838-ACEC-40CA5D529DC8}", pGB);
- if( pSS)
- {
- pSS->Enable(audid, AMSTREAMSELECTENABLE_ENABLE);
- SendStatusMessage(ResStr(IDS_OSD_MSG_RESTORE_TO_LAST_REMEMBER_AUDIO_TRACK),3000);
- }
- }
- }
-
- 根据SQL 设置字幕
- if (AfxGetMyApp()->sqlite_local_record)
- {
- CString szSQL;
- if (s.fEnableSubtitles ){
- szSQL.Format(L"SELECT subid FROM histories_stream WHERE fpath = \"%s\" ", FPath);
- int subid = AfxGetMyApp()->sqlite_local_record->get_single_int_from_sql(szSQL.GetBuffer(), -1);
- if(subid > 0){
- OnPlayLanguage(subid);
- }
- }
- szSQL.Format(L"SELECT audioid FROM histories_stream WHERE fpath = \"%s\" ", FPath);
- int audid = AfxGetMyApp()->sqlite_local_record->get_single_int_from_sql(szSQL.GetBuffer(), -1);
- if(audid > 0){
- OnPlayLanguage(audid);
- }
- }
-
- if(!m_pCAP && m_fAudioOnly){ / /这是我们第一次检测,这是仅音频文件
-
- m_wndView.m_strAudioInfo.Empty();
- //This is silly
- if(!m_fLastIsAudioOnly)
- ShowControlBar(&m_wndPlaylistBar, FALSE, TRUE);
-
- KillTimer(TIMER_TRANSPARENTTOOLBARSTAT);
- SetTimer(TIMER_TRANSPARENTTOOLBARSTAT, 20,NULL);
- rePosOSD(); 重新计算位置
- }
-
- {
- WINDOWPLACEMENT wp;
- wp.length = sizeof(wp);
- GetWindowPlacement(&wp); 记录窗体位置
-
- // restore magnification 只有音频的情况下
- if(IsWindowVisible() && AfxGetAppSettings().fRememberZoomLevel
- && !(m_fFullScreen || wp.showCmd == SW_SHOWMAXIMIZED || wp.showCmd == SW_SHOWMINIMIZED))
- {
- if(m_fAudioOnly && m_fLastIsAudioOnly){
- }else{
- ZoomVideoWindow(); 全屏播放
- // m_fFullScreen意思现在是指当前播放模式是全屏还是非全屏,如果是全屏就会在Toogle中变为非全屏,反之亦然
- if (!m_fFullScreen)
- {
- PlayerPreference* pref = PlayerPreference::GetInstance();
- bool bToBeFullScreen = pref->GetIntVar(INTVAR_TOGGLEFULLSCRENWHENPLAYBACKSTARTED);
- if (bToBeFullScreen) 是否全屏
- {
- ToggleFullscreen(true, true);
- SetCursor(NULL);
- }
- }
- }
- m_fLastIsAudioOnly = m_fAudioOnly;
- }
- }
-
- if(!m_fAudioOnly && (s.nCLSwitches&CLSW_FULLSCREEN)) 全屏时
- {
- SendMessage(WM_COMMAND, ID_VIEW_FULLSCREEN);
- s.nCLSwitches &= ~CLSW_FULLSCREEN;
- }
- m_bDxvaInUse = false;
- m_bMustUseExternalTimer = false;
- m_haveSubVoted = false;
- m_DXVAMode = _T("");
- 视频解码接口
- CComQIPtr<IMPCVideoDecFilter> pMDF = FindFilter(__uuidof(CMPCVideoDecFilter), pGB);
- if(pMDF){
- GUID* DxvaGui = NULL;
- DxvaGui = pMDF->GetDXVADecoderGuid();
- if (DxvaGui != NULL)
- {
- m_DXVAMode = GetDXVAMode (DxvaGui);
- m_bDxvaInUse = (m_DXVAMode != _T("Not using DXVA"));
- }
- }else if(FindFilter(L"{09571A4B-F1FE-4C60-9760-DE6D310C7C31}", pGB)) {
- if(s.bHasCUDAforCoreAVC){
- m_bDxvaInUse = true;
- m_DXVAMode = _T("CoreAVC");
- }
- }
- /*
- CComQIPtr<IWMReaderAdvanced2> pWMR = FindFilter(__uuidof(IWMReaderAdvanced2), pGB);
- if(pWMR){
- pWMR->SetPlayMode(WMT_PLAY_MODE_STREAMING);
- AfxMessageBox(L"1");
- }*/
- if(FindFilter(L"{FA10746C-9B63-4B6C-BC49-FC300EA5F256}", pGB)){
- m_bEVRInUse = true;
- }
- if( FindFilter(L"{6F513D27-97C3-453C-87FE-B24AE50B1601}", pGB)){//m_bEVRInUse
- SVP_LogMsg5(L"Has Divx H264 Dec and EVR so use External Timer");
- m_bMustUseExternalTimer = true;
- }
-
- RedrawNonClientArea(); 重新绘画客户区
-
- if(m_iPlaybackMode == PM_FILE){ 回放模式
- if(!s.bDontNeedSVPSubFilter && !m_pCAP && s.iSVPRenderType && !m_fAudioOnly ){
- s.iSVPRenderType = 0;
- SendStatusMessage( ResStr(IDS_OSD_MSG_DEVICE_NOT_SUPPORT_VIDEO_QMODE), 2000);
- }
-
- if(m_fAudioOnly && m_fnCurPlayingFile.Find(L"://") < 0){
- 只有音频时 查找歌词
- //find lyric file
- m_LyricFilePaths.RemoveAll();
- CAtlArray<CString> lrcSearchPaths;
- lrcSearchPaths.Add(_T("."));
- lrcSearchPaths.Add(s.GetSVPSubStorePath());
-
- CAtlArray<LrcFile> ret;
- int bGotLrc = 0 ;
- m_Lyric.GetLrcFileNames( m_fnCurPlayingFile , lrcSearchPaths, ret);
- if( ret.GetCount() ){
- LrcFile oLrcFile = ret.GetAt(0);
- if( m_Lyric.LoadLyricFile( oLrcFile.fn) >= 0) 装载歌词
- {
- //maybe we should do something here?
- if(m_Lyric.m_has_lyric)
- bGotLrc = 1;
- }
- }
- if( !bGotLrc && s.autoDownloadSVPSub ) { 没有歌词 但自动下载
- //debug
- //m_Lyric.LoadLyricFile(L"D:\\-=SVN=-\\test.lrc");
-
- m_Lyric.Empty();
- //download it by thead
- m_Lyric.title = GetClipInfo(IDS_INFOBAR_TITLE).c_str();
- m_Lyric.artist = GetClipInfo(IDS_INFOBAR_AUTHOR).c_str();
- m_Lyric.album = GetClipInfo(IDS_INFOBAR_DESCRIPTION).c_str();
- m_Lyric.m_sz_current_music_file = m_fnCurPlayingFile;
- //m_Lyric.m_stop_downloading = 1;
- //TerminateThread(m_lyricDownloadThread , 0);
- 启动线程下载
- m_lyricDownloadThread = AfxBeginThread(lyric_fetch_Proc, &m_Lyric, THREAD_PRIORITY_LOWEST, 0, CREATE_SUSPENDED);
- m_lyricDownloadThread->m_pMainWnd = AfxGetMainWnd();
- m_lyricDownloadThread->ResumeThread();
- }
- }
- }
- // send sphash to remote 发送sphash到远程
- m_wndToolBar.HideMovieShareBtn(TRUE);
- UserShareController::GetInstance()->HideCommentPlane();
- UserShareController::GetInstance()->CloseShooterMedia();
- if(IsSomethingLoaded() && !m_fAudioOnly && (UINT)((INT64)rtDur/10000000) > 90)
- {
- m_movieShared = false;
- m_wndToolBar.HideMovieShareBtn(FALSE);
- SetTimer(TIMER_MOVIESHARE, 300000, NULL);
- }
- KillTimer(TIMER_IDLE_TASK);
- }
-
- 进入CMainFrame::OpenSetupCaptureBar 分析
- void CMainFrame::OpenSetupCaptureBar() 初始化头导航
- {
- 初始化控件
- if(m_iPlaybackMode == PM_CAPTURE)
- {
- if(pVidCap && pAMVSCCap)
- {
- CComQIPtr<IAMVfwCaptureDialogs> pVfwCD = pVidCap;
-
- if(!pAMXBar && pVfwCD)
- {
- m_wndCaptureBar.m_capdlg.SetupVideoControls(m_VidDispName, pAMVSCCap, pVfwCD);
- }
- else
- {
- m_wndCaptureBar.m_capdlg.SetupVideoControls(m_VidDispName, pAMVSCCap, pAMXBar, pAMTuner);
- }
- }
-
- if(pAudCap && pAMASC)
- {
- CInterfaceArray<IAMAudioInputMixer> pAMAIM;
- BeginEnumPins(pAudCap, pEP, pPin)
- {
- if(CComQIPtr<IAMAudioInputMixer> pAIM = pPin)
- pAMAIM.Add(pAIM);
- }
- EndEnumPins
- m_wndCaptureBar.m_capdlg.SetupAudioControls(m_AudDispName, pAMASC, pAMAIM);
- }
- }
-
- BuildGraphVideoAudio(
- m_wndCaptureBar.m_capdlg.m_fVidPreview, false,
- m_wndCaptureBar.m_capdlg.m_fAudPreview, false);
- }
-
- 进入CMainFrame::BuildGraphVideoAudio 分析
- bool CMainFrame::BuildGraphVideoAudio(int fVPreview, bool fVCapture, int fAPreview, bool fACapture)
- {
- if(!pCGB) return(false); 不存在直接返回 关键是pCGB另一个
-
- SaveMediaState;
-
- HRESULT hr;
-
- pGB->NukeDownstream(pVidCap);
- pGB->NukeDownstream(pAudCap);
-
- CleanGraph();
-
- if(pAMVSCCap) hr = pAMVSCCap->SetFormat(&m_wndCaptureBar.m_capdlg.m_mtv);
- if(pAMVSCPrev) hr = pAMVSCPrev->SetFormat(&m_wndCaptureBar.m_capdlg.m_mtv);
- if(pAMASC) hr = pAMASC->SetFormat(&m_wndCaptureBar.m_capdlg.m_mta);
-
- CComPtr<IBaseFilter> pVidBuffer = m_wndCaptureBar.m_capdlg.m_pVidBuffer;
- CComPtr<IBaseFilter> pAudBuffer = m_wndCaptureBar.m_capdlg.m_pAudBuffer;
- CComPtr<IBaseFilter> pVidEnc = m_wndCaptureBar.m_capdlg.m_pVidEnc;
- CComPtr<IBaseFilter> pAudEnc = m_wndCaptureBar.m_capdlg.m_pAudEnc;
- CComPtr<IBaseFilter> pMux = m_wndCaptureBar.m_capdlg.m_pMux;
- CComPtr<IBaseFilter> pDst = m_wndCaptureBar.m_capdlg.m_pDst;
- CComPtr<IBaseFilter> pAudMux = m_wndCaptureBar.m_capdlg.m_pAudMux;
- CComPtr<IBaseFilter> pAudDst = m_wndCaptureBar.m_capdlg.m_pAudDst;
-
- bool fFileOutput = (pMux && pDst) || (pAudMux && pAudDst);
- bool fCapture = (fVCapture || fACapture);
-
- if(pAudCap)
- {
- AM_MEDIA_TYPE* pmt = &m_wndCaptureBar.m_capdlg.m_mta;
- int ms = (fACapture && fFileOutput && m_wndCaptureBar.m_capdlg.m_fAudOutput) ? AUDIOBUFFERLEN : 60;
- if(pMux != pAudMux && fACapture) SetLatency(pAudCap, -1);
- else if(pmt->pbFormat) SetLatency(pAudCap, ((WAVEFORMATEX*)pmt->pbFormat)->nAvgBytesPerSec * ms / 1000);
- }
-
- CComPtr<IPin> pVidCapPin, pVidPrevPin, pAudCapPin, pAudPrevPin;
- BuildToCapturePreviewPin(pVidCap, &pVidCapPin, &pVidPrevPin, pAudCap, &pAudCapPin, &pAudPrevPin);
-
- // if(pVidCap)
- {
- bool fVidPrev = pVidPrevPin && fVPreview;
- bool fVidCap = pVidCapPin && fVCapture && fFileOutput && m_wndCaptureBar.m_capdlg.m_fVidOutput;
-
- if(fVPreview == 2 && !fVidCap && pVidCapPin)
- {
- pVidPrevPin = pVidCapPin;
- pVidCapPin = NULL;
- }
-
- if(fVidPrev)
- {
- m_pCAP = NULL;
- m_pCAP2 = NULL;
- m_pCAPR = NULL;
- pGB->Render(pVidPrevPin);
- pGB->FindInterface(__uuidof(ISubPicAllocatorPresenter), (void**)&m_pCAP, FALSE);
- pGB->FindInterface(__uuidof(ISubPicAllocatorPresenterRender), (void**)&m_pCAPR, TRUE);
- pGB->FindInterface(__uuidof(ISubPicAllocatorPresenter2), (void**)&m_pCAP2, TRUE);
- }
-
- if(fVidCap)
- {
- IBaseFilter* pBF[3] = {pVidBuffer, pVidEnc, pMux};
- HRESULT hr = BuildCapture(pVidCapPin, pBF, MEDIATYPE_Video, &m_wndCaptureBar.m_capdlg.m_mtcv);
- }
-
- pAMDF = NULL;
- pCGB->FindInterface(&PIN_CATEGORY_CAPTURE, &MEDIATYPE_Video, pVidCap, IID_IAMDroppedFrames, (void**)&pAMDF);
- }
-
- // if(pAudCap)
- {
- bool fAudPrev = pAudPrevPin && fAPreview;
- bool fAudCap = pAudCapPin && fACapture && fFileOutput && m_wndCaptureBar.m_capdlg.m_fAudOutput;
-
- if(fAPreview == 2 && !fAudCap && pAudCapPin)
- {
- pAudPrevPin = pAudCapPin;
- pAudCapPin = NULL;
- }
-
- if(fAudPrev)
- {
- pGB->Render(pAudPrevPin);
- }
-
- if(fAudCap)
- {
- IBaseFilter* pBF[3] = {pAudBuffer, pAudEnc, pAudMux ? pAudMux : pMux};
- HRESULT hr = BuildCapture(pAudCapPin, pBF, MEDIATYPE_Audio, &m_wndCaptureBar.m_capdlg.m_mtca);
- }
- }
-
- if((pVidCap || pAudCap) && fCapture && fFileOutput)
- {
- if(pMux != pDst)
- {
- hr = pGB->AddFilter(pDst, L"File Writer V/A");
- hr = pGB->ConnectFilter(GetFirstPin(pMux, PINDIR_OUTPUT), pDst);
- }
-
- if(CComQIPtr<IConfigAviMux> pCAM = pMux)
- {
- int nIn, nOut, nInC, nOutC;
- CountPins(pMux, nIn, nOut, nInC, nOutC);
- pCAM->SetMasterStream(nInC-1);
- // pCAM->SetMasterStream(-1);
- pCAM->SetOutputCompatibilityIndex(FALSE);
- }
-
- if(CComQIPtr<IConfigInterleaving> pCI = pMux)
- {
- // if(FAILED(pCI->put_Mode(INTERLEAVE_CAPTURE)))
- if(FAILED(pCI->put_Mode(INTERLEAVE_NONE_BUFFERED)))
- pCI->put_Mode(INTERLEAVE_NONE);
-
- REFERENCE_TIME rtInterleave = 10000i64*AUDIOBUFFERLEN, rtPreroll = 0;//10000i64*500
- pCI->put_Interleaving(&rtInterleave, &rtPreroll);
- }
-
- if(pMux != pAudMux && pAudMux != pAudDst)
- {
- hr = pGB->AddFilter(pAudDst, L"File Writer A");
- hr = pGB->ConnectFilter(GetFirstPin(pAudMux, PINDIR_OUTPUT), pAudDst);
- }
- }
-
- REFERENCE_TIME stop = MAX_TIME;
- hr = pCGB->ControlStream(&PIN_CATEGORY_CAPTURE, NULL, NULL, NULL, &stop, 0, 0); // stop in the infinite
-
- CleanGraph();
-
- OpenSetupVideo();
- OpenSetupAudio();
-
- RestoreMediaState;
-
- return(true);
- }
-
- OnFilePostOpenmedia() 中 SetTimer(TIMER_MOVIESHARE, 300000, NULL);
- case TIMER_MOVIESHARE:
- {
- KillTimer(TIMER_MOVIESHARE);
- if (IsSomethingLoaded() && !m_fAudioOnly && !m_movieShared) 已经加载 不是音频 文件不共享
- {
- m_movieShared = true;
- std::wstring uuid, moviehash;
- SPlayerGUID::GenerateGUID(uuid);
- UserShareController* usc = UserShareController::GetInstance();
- usc->CreateCommentPlane();
- moviehash = HashController::GetInstance()->GetSPHash(m_fnCurPlayingFile);
- usc->ShareMovie(uuid, moviehash, m_fnCurPlayingFile.GetString());
- }
- }
- break;
-
- 进入CMainFrame::ZoomVideoWindow 分析
- void CMainFrame::ZoomVideoWindow(double scale)
- {
- if(m_iMediaLoadState != MLS_LOADED) return; 没有装载 直接退出 ?
-
- AppSettings& s = AfxGetAppSettings();
-
- if(s.bUserAeroUI()){ 用户区域UI
- m_lTransparentToolbarStat = 0;
- m_wndFloatToolBar->ShowWindow(SW_HIDE);
- }
-
- BOOL bThisIsAutoZoom = false; 自动大小
-
- if(scale <= 0)
- {
- bThisIsAutoZoom = true;
- scale =
- s.iZoomLevel == 0 ? 0.5 :
- s.iZoomLevel == 1 ? 1.0 :
- s.iZoomLevel == 2 ? 2.0 :
- s.iZoomLevel == 3 ? GetZoomAutoFitScale() :
- 1.0;
- m_last_size_of_current_kind_of_video.cx = -1;
- m_last_size_of_current_kind_of_video.cy = -1;
- }
-
- if(m_fFullScreen) 如果全屏 则全屏
- {
- OnViewFullscreen();
- }
-
- MINMAXINFO mmi;
- OnGetMinMaxInfo(&mmi);
-
- CRect r;
- int w = 0, h = 0;
-
- if(!m_fAudioOnly) 不是音频
- {
- CSize arxy = m_original_size_of_current_video = GetVideoSize();
- long lWidth = int(arxy.cx * scale + 0.5);
- long lHeight = int(arxy.cy * scale + 0.5);
- CString string_remember_windows_size_for_this_video_size_parm;
- string_remember_windows_size_for_this_video_size_parm.Format(L"ORGSIZE%dx%d", m_original_size_of_current_video.cx, m_original_size_of_current_video.cy );
- AppSettings& s = AfxGetAppSettings();
- long lPerfWidth = m_last_size_of_current_kind_of_video.cx = AfxGetMyApp()->GetProfileInt(ResStr(IDS_R_SETTINGS)+L"REMENBERWNDSIZE", string_remember_windows_size_for_this_video_size_parm+L"W", -1);
- long lPerfHeight = m_last_size_of_current_kind_of_video.cy = AfxGetMyApp()->GetProfileInt(ResStr(IDS_R_SETTINGS)+L"REMENBERWNDSIZE", string_remember_windows_size_for_this_video_size_parm+L"H", -1);
-
- DWORD style = GetStyle();
-
- CRect r3 ,r4;
- GetWindowRect(r3);
- m_wndView.GetWindowRect(r4);
- //GetClientRect(&r1);
- //m_wndView.GetClientRect(&r2);
- int wDelta = 0;
- int hDelta = 0;
-
- wDelta = r3.Width() - r4.Width();
- hDelta = r3.Height() - r4.Height();
-
- if(style&WS_CAPTION)
- {
- //h += GetSystemMetrics(SM_CYCAPTION);
- //w += 2; h += 2; // for the 1 pixel wide sunken frame
- //w += 2; h += 3; // for the inner black border
- }
-
- GetWindowRect(r);
-
- if (lHeight + hDelta < 280 || lWidth + wDelta < 480) {
- int w1 = 480 - wDelta;
- int h1 = 280 - hDelta;
- SVP_ASSERT(w1 > 0);
- SVP_ASSERT(h1 > 0);
-
- // Re-evaluate current 'w' and 'h' to keep aspect ratio
- int h2 = arxy.cy * w1 / arxy.cx, w2 = arxy.cx * h1 / arxy.cy;
- // Choose by the fitting rectangle.
- if (h2 + hDelta >= 280) {
- w = 480;
- h = h2 + hDelta;
- } else {
- w = w2 + wDelta;
- h = 280;
- }
-
-
- } else {
- h = lHeight + hDelta;
- w = lWidth + wDelta;
- }
-
-
- if(bThisIsAutoZoom && 0){
- double mratio = (double)lHeight/lWidth;
- //SVP_LogMsg5(L"%d %d %f %d %d %f",h , w, w * mratio + (h - lHeight), lHeight, lWidth, mratio);
- h = max(h , w * mratio + (h - lHeight));
- }
-
-
- if(bThisIsAutoZoom && lPerfWidth > 240 && lPerfHeight > 120)
- {
- //Only do this if its auto zoom
- w = lPerfWidth;
- h = lPerfHeight;
- }
- }
- else
- {
- GetWindowRect(r);
-
-
- //w = r.Width(); //;mmi.ptMinTrackSize.x;
- //h = r.Height();//;mmi.ptMinTrackSize.y;
- w = 320;
- if(s.bUserAeroUI()){
- w /= 0.9;
- }
- h = 110;
-
-
- AppSettings& s = AfxGetAppSettings();
- long lPerfWidth = m_last_size_of_current_kind_of_video.cx = AfxGetMyApp()->GetProfileInt(ResStr(IDS_R_SETTINGS)+L"REMENBERWNDSIZE", L"ORGSIZE0x0W", -1);
- long lPerfHeight = m_last_size_of_current_kind_of_video.cy = AfxGetMyApp()->GetProfileInt(ResStr(IDS_R_SETTINGS)+L"REMENBERWNDSIZE", L"ORGSIZE0x0H", -1);
-
-
- w = max(w, lPerfWidth);
- h = max(h, lPerfHeight);
-
-
- }
-
-
- // center window
- //if(!s.fRememberWindowPos)
- {
- CPoint cp = r.CenterPoint();
- r.left = cp.x - w/2;
- r.top = cp.y - h/2;
- }
-
-
- r.right = r.left + w;
- r.bottom = r.top + h;
-
-
- MONITORINFO mi;
- mi.cbSize = sizeof(MONITORINFO);
-
-
- 获得窗体信息
- GetMonitorInfo(MonitorFromWindow(m_hWnd, MONITOR_DEFAULTTONEAREST), &mi);
- if(r.right > mi.rcWork.right) r.OffsetRect(mi.rcWork.right-r.right, 0);
- if(r.left < mi.rcWork.left) r.OffsetRect(mi.rcWork.left-r.left, 0);
- if(r.bottom > mi.rcWork.bottom) r.OffsetRect(0, mi.rcWork.bottom-r.bottom);
- if(r.top < mi.rcWork.top) r.OffsetRect(0, mi.rcWork.top-r.top);
- CRect rcWork(mi.rcWork);
- if(r.Width() > rcWork.Width() ){
- r.left = rcWork.left;
- r.right = rcWork.right;
- }
- if(r.Height() > rcWork.Height() ){
- r.top = rcWork.top;
- r.bottom = rcWork.bottom;
- }
- if(m_fFullScreen || !s.HasFixedWindowSize())
- {
- MoveWindow(r);
- }
-
-
- //AfxMessageBox(_T("1"));
- //Sleep(200);
- // ShowWindow(SW_SHOWNORMAL);
-
-
- MoveVideoWindow();
- }
-
-
-
-
- 进入CMainFrame::ToggleFullscreen 分析
- void CMainFrame::ToggleFullscreen(bool fToNearest, bool fSwitchScreenResWhenHasTo)
- {
- CRect r;
- m_lastTimeToggleFullsreen = AfxGetMyApp()->GetPerfCounter();
- // const CWnd* pWndInsertAfter;
- DWORD dwRemove = 0, dwAdd = 0;
- DWORD dwRemoveEx = 0, dwAddEx = 0;
- HMENU hMenu;
-
-
- if(!m_fFullScreen)
- { 不是全屏
-
-
- if(m_wndPlaylistBar.IsVisible()){
- m_fPlaylistBeforeToggleFullScreen = true;
- ShowControlBar(&m_wndPlaylistBar, FALSE, TRUE);
- }
-
-
- GetWindowRect(&m_lastWindowRect);
-
-
- dispmode& dm = AfxGetAppSettings().dmFullscreenRes;
- m_dmBeforeFullscreen.fValid = false;
- if(dm.fValid && fSwitchScreenResWhenHasTo)
- {
- GetCurDispMode(m_dmBeforeFullscreen);
- SetDispMode(dm);
- }
-
-
- MONITORINFO mi;
- mi.cbSize = sizeof(MONITORINFO);
- GetMonitorInfo(MonitorFromWindow(m_hWnd, MONITOR_DEFAULTTONEAREST), &mi);
-
-
- dwRemove = WS_CAPTION|WS_THICKFRAME;
- if(fToNearest) r = mi.rcMonitor;
- else GetDesktopWindow()->GetWindowRect(&r);
- hMenu = NULL;
-
-
-
-
- }
- else
- {
- 全屏
- if( AfxGetAppSettings().htpcmode){
- return;
- }
- if( m_fPlaylistBeforeToggleFullScreen )
- ShowControlBar(&m_wndPlaylistBar, TRUE, TRUE);
-
-
- if(m_dmBeforeFullscreen.fValid)
- SetDispMode(m_dmBeforeFullscreen);
-
-
- dwAdd = (AfxGetAppSettings().fHideCaptionMenu ? 0 : WS_CAPTION) | WS_THICKFRAME;
- r = m_lastWindowRect;
- hMenu = NULL;//AfxGetAppSettings().fHideCaptionMenu ? NULL : m_hMenuDefault;
- }
-
-
-
-
-
-
- //bool fAudioOnly = m_fAudioOnly;
- //m_fAudioOnly = true;
-
-
- m_fFullScreen = !m_fFullScreen;
-
-
- SetAlwaysOnTop(AfxGetAppSettings().iOnTop);
-
-
- 修改属性 进行全屏
- ModifyStyle(dwRemove, dwAdd, SWP_NOZORDER);
- ModifyStyleEx(dwRemoveEx, dwAddEx, SWP_NOZORDER);
- ::SetMenu(m_hWnd, hMenu);
- SetWindowPos(NULL, r.left, r.top, r.Width(), r.Height(), SWP_NOZORDER|SWP_NOSENDCHANGING /*SWP_FRAMECHANGED*/);
- RedrawNonClientArea();
-
-
- KillTimer(TIMER_FULLSCREENCONTROLBARHIDER);
- KillTimer(TIMER_FULLSCREENMOUSEHIDER);
- if(m_fFullScreen)
- {
- // SVP_LogMsg5(L"Fullscreen");
- m_fHideCursor = true;
- SetTimer(TIMER_FULLSCREENMOUSEHIDER, 800, NULL);
- ShowControls(CS_NONE, false);
- }
- else
- {
- m_lastMouseMove.x = m_lastMouseMove.y = -1;
- m_fHideCursor = false;
- ShowControls(AfxGetAppSettings().nCS);
- }
-
-
- m_wndView.SetWindowPos(NULL, 0, 0, 0, 0, SWP_FRAMECHANGED|SWP_NOSIZE|SWP_NOMOVE|SWP_NOZORDER);
- //m_fAudioOnly = fAudioOnly;
-
-
- rePosOSD();
-
-
- MoveVideoWindow();
-
-
- // insert after the HWND_TOP if the player is not full screen
- if (m_fFullScreen) 全屏的话 就置顶
- ::SetWindowPos(m_hWnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOREDRAW|SWP_NOSIZE|SWP_NOMOVE);
- else
- ::SetWindowPos(m_hWnd, HWND_TOP, 0, 0, 0, 0, SWP_NOREDRAW|SWP_NOSIZE|SWP_NOMOVE);
- }
-
-
-
-
- TIMER_STREAMPOSPOLLER: 定时事件
- case TIMER_STREAMPOSPOLLER:
- if (m_iMediaLoadState == MLS_LOADED)
- _HandleTimer_StreamPosPoller();
- break;
-
-
- void CMainFrame::_HandleTimer_StreamPosPoller() 处理位置信息 比如播放进度
- {
- REFERENCE_TIME rtNow = 0, rtDur = 0;
-
-
- if (m_iPlaybackMode == PM_FILE)
- {
- pMS->GetCurrentPosition(&rtNow);
- pMS->GetDuration(&rtDur);
-
-
- if (m_rtDurationOverride >= 0)
- rtDur = m_rtDurationOverride;
-
-
- m_wndSeekBar.Enable(rtDur > 0);
- m_wndSeekBar.SetRange(0, rtDur);
- m_wndSeekBar.SetPos(rtNow);
- }
- else if (m_iPlaybackMode == PM_CAPTURE)
- {
- if (m_fCapturing && m_wndCaptureBar.m_capdlg.m_pMux)
- {
- CComQIPtr<IMediaSeeking> pMuxMS = m_wndCaptureBar.m_capdlg.m_pMux;
- if (!pMuxMS || FAILED(pMuxMS->GetCurrentPosition(&rtNow)))
- rtNow = 0;
- }
-
-
- if (m_rtDurationOverride >= 0)
- rtDur = m_rtDurationOverride;
-
-
- m_wndSeekBar.Enable(false);
- m_wndSeekBar.SetRange(0, rtDur);
- m_wndSeekBar.SetPos(rtNow);
- /*
- if (m_fCapturing)
- {
- if (rtNow > 10000i64*1000*60*60*3)
- m_wndCaptureBar.m_capdlg.OnRecord();
- }
- */
- }
-
-
- if (m_pCAP && (m_iPlaybackMode != PM_FILE || m_bMustUseExternalTimer))
- {
- g_bExternalSubtitleTime = true;
- AfxGetAppSettings().bExternalSubtitleTime = true;
- if (pDVDI)
- {
- DVD_PLAYBACK_LOCATION2 Location;
- if (pDVDI->GetCurrentLocation(&Location) == S_OK)
- {
- double fps = Location.TimeCodeFlags == DVD_TC_FLAG_25fps ? 25.0
- : Location.TimeCodeFlags == DVD_TC_FLAG_30fps ? 30.0
- : Location.TimeCodeFlags == DVD_TC_FLAG_DropFrame ? 29.97
- : 25.0;
-
-
- LONGLONG rtTimeCode = HMSF2RT(Location.TimeCode, fps);
- m_pCAP->SetTime(rtTimeCode);
- }
- else
- m_pCAP->SetTime(/*rtNow*/m_wndSeekBar.GetPos());
- }
- else
- m_pCAP->SetTime(/*rtNow*/m_wndSeekBar.GetPos());
- }
- else
- {
- g_bExternalSubtitleTime = false;
- AfxGetAppSettings().bExternalSubtitleTime = false;
- }
- }
-
-
-
-
- TIMER_STREAMPOSPOLLER2: 定时设置
- case TIMER_STREAMPOSPOLLER2:
- if (m_iMediaLoadState == MLS_LOADED) 设置位置 和 时间
- {
- __int64 start, stop, pos;
- m_wndSeekBar.GetRange(start, stop);
- pos = m_wndSeekBar.GetPosReal();
-
-
- if (ABControlOn && m_bRefTime > m_aRefTime && GetMediaState() == State_Running)
- {
- if (pos > m_bRefTime)
- //goto aRefTimer
- SeekTo(m_aRefTime, 0);
- }
- GUID tf;
- pMS->GetTimeFormat(&tf);
-
-
- if (m_iPlaybackMode == PM_CAPTURE && !m_fCapturing)
- {
- CString str = _T("Live");
- long lChannel = 0, lVivSub = 0, lAudSub = 0;
- if (pAMTuner
- && m_wndCaptureBar.m_capdlg.IsTunerActive()
- && SUCCEEDED(pAMTuner->get_Channel(&lChannel, &lVivSub, &lAudSub)))
- {
- CString ch;
- ch.Format(_T(" (ch%d)"), lChannel);
- str += ch;
- }
- //m_wndStatusBar.SetStatusTimer(str);
- m_wndToolBar.SetStatusTimer(str);
- }
- else
- {
- double pRate;
- if (E_NOTIMPL == pMS->GetRate(&pRate))
- pRate = 0;
- m_wndToolBar.SetStatusTimer(pos, stop, 0, &tf, pRate);
- //m_wndToolBar.SetStatusTimer(str);
- }
-
-
- if (m_pCAPR && GetMediaState() == State_Paused)
- m_pCAPR->Paint(true);
- }
- break;
-
-
-
-
-
-
-
-
- case TIMER_STATS: 定时 事件
- _HandleTimer_Stats(); 处理事件状态
- break;
- void CMainFrame::_HandleTimer_Stats()
- {
- m_l_been_playing_sec++;
- if (AfxGetMyApp()->IsWin7() && pTBL)
- {
- try
- {
- BOOL bHasValue = 0;
- BOOL bSetPaused = 0;
- if (IsSomethingLoaded()) 确认已经加载
- {
- //TBPF_PAUSED
- //TBPF_NORMAL
- //TBPF_INDETERMINATE
- switch (GetMediaState())
- {
- case State_Paused:
- //not using TBPF_PAUSED since it hide progress
- pTBL->SetProgressState(m_hWnd,TBPF_NORMAL);
- bSetPaused = true;
- bHasValue = true;
- break;
- case State_Running:
- pTBL->SetProgressState(m_hWnd,TBPF_NORMAL);
- bHasValue = true;
- break;
- case State_Stopped:
- pTBL->SetProgressState(m_hWnd,TBPF_NOPROGRESS);
- break;
- }
- }
- else
- pTBL->SetProgressState(m_hWnd,TBPF_NOPROGRESS);
-
-
- if (bHasValue)
- {
- __int64 iSeekStart, iSeekStop;
- m_wndSeekBar.GetRange(iSeekStart, iSeekStop);
- __int64 iSeekPos = m_wndSeekBar.GetPosReal();
- pTBL->SetProgressValue(m_hWnd, iSeekPos ,(iSeekStop - iSeekStart));
- }
- if (bSetPaused)
- pTBL->SetProgressState(m_hWnd,TBPF_PAUSED);
- }
- catch (...)
- {
- pTBL->Release();
- pTBL = NULL;
- }
- }
-
-
- if (IsSomethingLoaded() && m_fAudioOnly && (!m_Lyric.m_has_lyric || m_wndView.m_strAudioInfo.IsEmpty()))
- { 已经加载 是音频 没有歌词
- m_wndView.m_AudioInfoCounter++;
- BOOL bHaveInfo = false;
-
-
- for (int i = 0; i < 4; i++)
- {
- if ((m_wndView.m_AudioInfoCounter%4) == 0 || m_wndView.m_strAudioInfo.IsEmpty())
- {
- CString szInfo , szMusicTitle, szMusicAuthor;
- szMusicTitle = GetClipInfo(IDS_INFOBAR_TITLE).c_str();
- szMusicAuthor = GetClipInfo(IDS_INFOBAR_AUTHOR).c_str();
-
-
- switch (m_wndView.m_AudioInfoCounter/4 %4)
- {
- case 0:
- szInfo = szMusicTitle;
- break;
- case 1:
- szInfo = szMusicAuthor;
- break;
- case 2:
- szInfo = GetClipInfo(IDS_INFOBAR_DESCRIPTION).c_str();
- break;
- case 3:
- szInfo = GetClipInfo(IDS_INFOBAR_COPYRIGHT).c_str();
- break;
- }
- if (szInfo.IsEmpty())
- {
- m_wndView.m_AudioInfoCounter+=4;
- continue;
- }
- else
- {
- m_wndView.m_strAudioInfo = szInfo;
- CString szTitleItShouleBe = szMusicTitle + _T(" - ") + szMusicAuthor;
- if (szTitleItShouleBe != m_szTitle)
- {
- m_szTitle = szTitleItShouleBe;
- RedrawNonClientArea();
- }
- m_wndView.Invalidate();
- bHaveInfo = true;
- }
- }
- break;
- }
- }
-
-
- if (m_iPlaybackMode == PM_FILE)
- {
- REFERENCE_TIME rtNow = 0, rtDur = 0;
- pMS->GetCurrentPosition(&rtNow);
- pMS->GetDuration(&rtDur);
-
-
-
-
- if (m_fAudioOnly && m_Lyric.m_has_lyric)// && m_wndLycShowBox
- {
- int iLastingTime;
- CString szLyricLine = m_Lyric.GetCurrentLyricLineByTime(rtNow, &iLastingTime);
- if (!szLyricLine.IsEmpty())
- {
- wchar_t music_note[] = {0x266A, 0x0020, 0};
- szLyricLine.Insert(0, music_note);
- if (m_wndView.m_strAudioInfo != szLyricLine)
- {
- m_wndView.m_strAudioInfo = szLyricLine;
- if (iLastingTime > 0)
- m_wndView.SetLyricLasting(iLastingTime);
- else
- m_wndView.SetLyricLasting(15);
- m_wndView.Invalidate();
- }
- }
- }
-
-
- UINT iTotalLenSec = (UINT)( (INT64) rtDur / 20000000 );
- //如果视频长度大于1分钟, 而且是文件模式,而且正在播放中
- if (!m_fAudioOnly && iTotalLenSec > 180 && m_iPlaybackMode == PM_FILE && GetMediaState() == State_Running)
- {
- time_t time_now = time(NULL);
- UINT totalplayedtime = time_now - m_tPlayStartTime;
- //SVP_LogMsg5(L"time_now > ( m_tLastLogTick %f %f" , (double)time_now , (double)m_tLastLogTick);
- if (time_now > ( m_tLastLogTick + 180 ))
- { //如果和上次检查已经超n秒
- CString fnVideoFile , fnSubtitleFile;
- int subDelayMS = 0;
- fnVideoFile = m_fnCurPlayingFile;
- fnSubtitleFile = getCurPlayingSubfile(&subDelayMS);
-
-
- if (!fnSubtitleFile.IsEmpty())
- { //如果有字幕
- CString szLog;
- //szLog.Format(_T(" %s ( with sub %s delay %d ) %d sec of %d sec ( 1/2 length video = %d ) ") , fnVideoFile, fnSubtitleFile,subDelayMS, totalplayedtime , iTotalLenSec, (UINT)(iTotalLenSec/2) );
- //SVP_LogMsg(szLog);
- //if time > 50%
- if (totalplayedtime > (UINT)(iTotalLenSec/2))
- {
- if (!m_haveSubVoted && m_pCAP && rtNow > (rtDur - 3000000000i64))
- {
- //如果还没提示过vote
- //如果时间接近最末5分钟
- AppSettings& s = AfxGetAppSettings();
- if (s.bIsChineseUIUser())
- {
- //如果是中文
- if ( m_wndPlaylistBar.GetCount() <= 1)
- {
- //如果是1CD
- int nSubPics;
- REFERENCE_TIME rtSubNow, rtSubStart, rtSubStop;
- m_pCAP->GetSubStats(nSubPics,rtSubNow, rtSubStart, rtSubStop);
- if (rtSubNow > rtSubStop)
- {
- //如果没有更多字幕
- SVP_LogMsg5(L"Sub Voted Event");
- //vote之
- m_haveSubVoted = true;
- }
- }
- }
- }
- //是否已经上传过呢
- if (m_fnsAlreadyUploadedSubfile.Find(fnVideoFile+fnSubtitleFile) < 0)
- {
- //upload subtitle
- Logging(L"Uploading sub %s of %s width delay %d ms since user played %d sec of %d sec ( more than 1/2 length video ) " , fnSubtitleFile, fnVideoFile ,subDelayMS, totalplayedtime , iTotalLenSec );
- SVP_UploadSubFileByVideoAndSubFilePath(fnVideoFile , fnSubtitleFile, subDelayMS);
- m_fnsAlreadyUploadedSubfile.Append( fnVideoFile+fnSubtitleFile+_T(";") );
- }
- int subDelayMS2 = 0;
- CString fnSubtitleFile2 = getCurPlayingSubfile(&subDelayMS2);
- if (!fnSubtitleFile2.IsEmpty())
- {
- if (m_fnsAlreadyUploadedSubfile.Find( fnVideoFile+fnSubtitleFile2 ) < 0)
- {
- //upload subtitle
- Logging((L"Uploading sub2 %s of %s width delay %d ms since user played %d sec of %d sec ( more than 1/2 length video ) ") , fnSubtitleFile2, fnVideoFile ,subDelayMS2, totalplayedtime , iTotalLenSec);
- SVP_UploadSubFileByVideoAndSubFilePath(fnVideoFile , fnSubtitleFile2, subDelayMS2);
- m_fnsAlreadyUploadedSubfile.Append( fnVideoFile+fnSubtitleFile2+_T(";") );
- }
- }
- }
- }
- m_tLastLogTick = time_now;
- //SVP_LogMsg5(L"m_tLastLogTick = time_now; %f %f" , (double)time_now , (double)m_tLastLogTick);
- }
- }
- }
-
-
- CString msg;
- if (m_fBuffering)
- {
- BeginEnumFilters(pGB, pEF, pBF)
- {
- if (CComQIPtr<IAMNetworkStatus, &IID_IAMNetworkStatus> pAMNS = pBF)
- {
- long BufferingProgress = 0;
- if (SUCCEEDED(pAMNS->get_BufferingProgress(&BufferingProgress)) && BufferingProgress > 0 && BufferingProgress < 99)
- {
- msg.Format(ResStr(IDS_CONTROLS_BUFFERING), BufferingProgress);
- SendStatusMessage(msg,1000);
- SVP_LogMsg5(msg);
- }
- break;
- }
- }
- EndEnumFilters
- }
- else if (pAMOP)
- {
- __int64 t = 0, c = 0;
- if(SUCCEEDED(pAMOP->QueryProgress(&t, &c)) && t > 0 && c < t)
- {
- msg.Format(ResStr(IDS_CONTROLS_BUFFERING), c*100/t);
- SendStatusMessage(msg,1000);
- SVP_LogMsg5(msg);
- }
- }
- m_wndToolBar.m_buffering = msg;
-
-
- if (m_iPlaybackMode == PM_FILE)
- SetupChapters();
-
-
-
- if (GetMediaState() == State_Running)
- {
- if (m_fAudioOnly)
- {
- UINT fSaverActive = 0;
- if (SystemParametersInfo(SPI_GETPOWEROFFACTIVE, 0, (PVOID)&fSaverActive, 0))
- {
- SystemParametersInfo(SPI_SETPOWEROFFACTIVE, 0, 0, SPIF_SENDWININICHANGE); // this might not be needed at all...
- SystemParametersInfo(SPI_SETPOWEROFFACTIVE, fSaverActive, 0, SPIF_SENDWININICHANGE);
- }
- SetThreadExecutionState(ES_SYSTEM_REQUIRED);
- }
- else
- {
- UINT fSaverActive = 0;
- if (SystemParametersInfo(SPI_GETSCREENSAVEACTIVE, 0, (PVOID)&fSaverActive, 0))
- {
- SystemParametersInfo(SPI_SETSCREENSAVEACTIVE, 0, 0, SPIF_SENDWININICHANGE); // this might not be needed at all...
- SystemParametersInfo(SPI_SETSCREENSAVEACTIVE, fSaverActive, 0, SPIF_SENDWININICHANGE);
- }
- fSaverActive = 0;
- if (SystemParametersInfo(SPI_GETPOWEROFFACTIVE, 0, (PVOID)&fSaverActive, 0))
- {
- SystemParametersInfo(SPI_SETPOWEROFFACTIVE, 0, 0, SPIF_SENDWININICHANGE); // this might not be needed at all...
- SystemParametersInfo(SPI_SETPOWEROFFACTIVE, fSaverActive, 0, SPIF_SENDWININICHANGE);
- }
- SetThreadExecutionState(ES_DISPLAY_REQUIRED|ES_SYSTEM_REQUIRED); //this is the right way, only this work under vista . no ES_CONTINUOUS so it can goes to sleep when not playing
- }
-
-
-
-
- if (GetExStyle() & WS_EX_LAYERED)
- {
- BYTE dAlpha = 0 ;
- DWORD dwFlag = 0;
- if (AfxGetMyApp()->m_pGetLayeredWindowAttributes)
- {
- AfxGetMyApp()->m_pGetLayeredWindowAttributes(m_hWnd, NULL, &dAlpha , &dwFlag);
- if (dAlpha == 255)
- ModifyStyleEx(WS_EX_LAYERED , 0);
- }
- }
- }
-
- namespace DSObjects 操作DirectShow类库
-
-
- 空间中有
- 操作DirectShow D3D7
- CDX7AllocatorPresenter继承ISubPicAllocatorPresenterImpl
-
-
- 操作DirectShow D3D9
- CDX9AllocatorPresenter继承ISubPicAllocatorPresenterImpl
-
-
- CDXRAllocatorPresenter继承ISubPicAllocatorPresenterImpl
-
-
- VMR7分配器
- CVMR7AllocatorPresenter继承CDX7AllocatorPresenter,继承IVMRSurfaceAllocator,继承IVMRImagePresenter,继承IVMRWindowlessControl
-
-
- VMR9分配器
- CVMR9AllocatorPresenter继承CDX9AllocatorPresenter,继承IVMRSurfaceAllocator9,继承IVMRImagePresenter9, 继承IVMRWindowlessControl9
-
-
- CGenlock 管理视频和显示的同步。
-
-
- VR分配器
- CmadVRAllocatorPresenter继承ISubPicAllocatorPresenterImpl
-
-
- QT7分配器
- CQT7AllocatorPresenter继承CDX7AllocatorPresenter,继承IQTVideoSurface
-
-
- QT9分配器
- CQT9AllocatorPresenter继承CDX9AllocatorPresenter,继承IQTVideoSurface
-
-
- Quicktime格式绘图
- CQuicktimeGraph继承CBaseGraph,继承IVideoFrameStep
-
-
- Quicktime载体
- CQuicktimeWindow继承CPlayerWindow
-
-
- Real格式绘图
- CRealMediaGraph继承CBaseGraph
-
-
- Real格式播放
- CRealMediaPlayer继承CUnknown,继承IRMAErrorSink,继承IRMAClientAdviseSink,继承IRMAAuthenticationManager,继承IRMASiteSupplier,继承IRMAPassiveSiteWatcher,继承IRMAAudioHook
-
-
- Real格式播放载体
- CRealMediaPlayerWindowed继承CRealMediaPlayer
-
-
- Real格式播放载体
- CRealMediaPlayerWindowless继承CRealMediaPlayer
-
-
- Real格式视频面
- CRealMediaVideoSurface继承CUnknown,继承IRMAVideoSurface
-
-
- Real格式载体站点
- CRealMediaWindowlessSite继承CUnknown,继承IRMASite,继承IRMASite2,继承IRMASiteWindowless,继承IRMAVideoSurface
-
-
- RM7分配器
- CRM7AllocatorPresenter继承CDX7AllocatorPresenter,继承IRMAVideoSurface
-
-
- RM9分配器
- CRM9AllocatorPresenter继承CDX9AllocatorPresenter,继承IRMAVideoSurface
-
-
- Flash绘图
- CShockwaveGraph继承CBaseGraph
-
-
-
-
-
-
- 主程序有的类库:
-
-
- 链接广告的类 实现了动画效果
- AdController继承ThreadHelperImpl<AdController>
-
-
- ButtonManage 按钮管理类
-
-
- CAboutDlg继承CDialog 关于对话框
-
-
- 自定义了一个映射模版类
- template <class T = CString, class S = CString>
- class CAtlStringMap : public CAtlMap<S, T, CStringElementTraits<S> > {};
-
-
- 一个音频格式集合类
- class CAudFormatArray : public CFormatArray<AUDIO_STREAM_CONFIG_CAPS>
-
-
- 一个作者登陆框
- class CAuthDlg : public CDialog
-
-
- 视频绘画类
- class CBaseGraph继承CUnknown, 继承IGraphBuilder2, public IMediaControl, 继承IMediaEventEx, 继承IMediaSeeking, 继承IVideoWindow, 继承IBasicVideo, 继承IBasicAudio, 继承IAMOpenProgress, public IGraphEngine
-
-
-
-
- class CBtnAlign 按钮位置区域对齐类
-
-
- 自绘了Edit类 阙套了Button
- class CBtnEditCtrl继承CWindowImpl<CBtnEditCtrl, CEdit>
-
-
- CChildView继承CWnd 窗体类 实现了视频载体
-
-
- COM组件属性页站点
- CComPropertyPageSite继承CUnknown,继承IPropertyPageSite
-
-
- CConvertChapDlg继承CResizableDialog 转换章节对话框
-
-
- CConvertDlg继承CResizableDialog 转换对话框
-
-
- CConvertPropsDlg继承CResizableDialog 转换属性页对话框
-
-
- CConvertResDlg继承CResizableDialog 转换资源对话框
-
-
- 分行过滤器
- CDeinterlacerFilter继承CTransformFilter
-
-
- CDisplaySettingDetector 显示设置探测器
-
-
- CDlgChkUpdater继承CDialog 确认更新对话框
-
-
- CDropTarget 移动文件类
-
-
- EVR分配器
- CEVRAllocatorPresenter继承CDX9AllocatorPresenter,继承IMFGetService,继承IMFTopologyServiceLookupClient,继承IMFVideoDeviceID,继承IMFVideoPresenter,继承IDirect3DDeviceManager9,继承IMFAsyncCallback,继承IQualProp,继承IMFRateSupport,继承IMFVideoDisplayControl,继承IEVRTrustedVideoPlugin
-
-
- 渐变视频解码
- CFakeDirectXVideoDecoder继承CUnknown,继承IDirectXVideoDecoder
-
-
- CFavoriteAddDlg继承CCmdUIDialog 收藏对话框
-
-
- CFavoriteOrganizeDlg继承CResizableDialog 收藏组织对话框
-
-
- CFFindByDir 目录查找类
-
-
- CFFindMoreFiles 查找更多文件类
-
-
- CFGAggregator继承CUnknown FG集合类
-
-
- CFGFilter FG过滤类
-
-
- CFGFilterFile继承CFGFilter FG过滤文件
-
-
- CFGFilterInternal继承CFGFilter FG内部过滤
-
-
- CFGFilterList FG过滤列表
-
-
- CFGFilterRegistry继承CFGFilter FG过滤继承类
-
-
- CFGFilterVideoRenderer继承CFGFilter FG过滤视频渲染类
-
-
- FG管理类
- CFGManager继承CUnknown, 继承IGraphBuilder2, 继承IGraphBuilderDeadEnd, 继承CCritSec
-
-
- CFGManagerCapture继承CFGManagerPlayer FG捕捉管理类
-
-
- CFGManagerCustom继承CFGManager FG自定义管理类
-
-
- CFGManagerDVD继承CFGManagerPlayer FG_DVD管理类
-
-
- CFGManagerMuxer继承CFGManagerCustom FG 混合器管理类
-
-
- CFGManagerPlayer继承CFGManagerCustom FG视频管理
-
-
- CFileDropTarget继承COleDropTarget 文件移动类
-
-
- CFilterMapper2继承CUnknown继承IFilterMapper2 过滤映射类
-
-
- CFilterTreeCtrl继承CTreeCtrl 过滤器树列表
-
-
- CFloatEdit继承CEdit 浮动的编辑框
-
-
- 格式模块
- template<class T>
- class CFormat : public CAutoPtrArray<CFormatElem<T> >
-
-
- 格式数组模块
- template<class T>
- class CFormatArray : public CAutoPtrArray<CFormat<T> >
-
-
- 格式节点
- template<class T>
- class CFormatElem
-
-
- CGoToDlg继承CDialog 转到对话框
-
-
- CGraphCore / /我们需要打开/播放暂停/寻求/关闭/ VOL控制/子控制/音频和视频切换的类
-
-
- CGraphThread继承CWinThread 播放线程类
-
-
- CHexEdit继承CEdit 16进制编辑框
-
-
- ChkDefPlayerControlBar继承 CSVPDialog 默认播放控制航
-
-
- CIfo 文件信息类
-
-
- CInfoReport继承CDialog 信息报告对话框
-
-
- CInPlaceComboBox继承CComboBox 阙套下拉框
-
-
- CInPlaceEdit继承CEdit 阙套编辑框
-
-
- CInPlaceListBox继承CListBox 阙套列表框
-
-
- CIntEdit继承CEdit 整形编辑框
-
-
- CKeyProvider继承CUnknown,继承IServiceProvider 键盘提供者
-
-
- CLineNumberEdit继承CEdit 线数编辑框
-
-
- CLineNumberStatic继承CStatic 线数静态框
-
-
-
-
- CMacrovisionKicker继承CUnknown,继承IKsPropertySet
-
-
- 主程序
- CMainFrame继承CFrameWnd,继承CDropTarget,继承CGraphCore
-
-
-
-
- CMediaFormatCategory 媒体格式分类
-
-
- CMediaTypesDlg继承CResizableDialog 媒体类型对话框
-
-
- CMemoryDC继承CDC 内存离屏DC
-
-
- CMPlayerCApp继承CWinApp 启动类
-
-
- CNEWOSDWnd继承CWnd Osd窗体
-
-
- ContentTypeTemp 内容类型
-
-
- COpenCapDeviceDlg继承CResizableDialog 打开捕捉设备对话框
-
-
- COpenDlg继承CResizableDialog 打开对话框
-
-
- COpenFileDlg继承CFileDialog 打开文件对话框
-
-
- COpenURLDlg继承CResizableDialog 打开URL 对话框
-
-
- 输出EVR
- COuterEVR继承CUnknown,继承IVMRffdshow9,继承IVMRMixerBitmap9,继承IBaseFilter
-
-
- 输出VMR9
- COuterVMR9继承CUnknown,继承IVideoWindow,
- 继承IBasicVideo2,继承IVMRWindowlessControl,继承IVMRffdshow9,继承IVMRMixerBitmap9
-
-
- CPixelShaderCompiler 像素着色器编译器
-
-
- CPlayerCaptureBar继承baseCPlayerCaptureBar 视频捕捉条
-
-
- CPlayerCaptureDialog继承CResizableDialog //CDialog 视频捕捉对话框
-
-
- CPlayerChannelNormalizer继承CSVPDialog 视频通道正规化对话框
-
-
- CPlayerColorControlBar继承CSVPDialog 视频颜色控制条
-
-
- CPlayerEQControlBar继承CSVPDialog 视频EQ控制条
-
-
- CPlayerFloatToolBar继承CFrameWnd 视频浮动控制条
-
-
- CPlayerListCtrl继承CListCtrl 播放器列表
-
-
- CPlayerPlaylistBar继承CSizingControlBarG 播放器列表条
-
-
- CPlayerSeekBar继承CDialogBar 视频跳转条
-
-
- CPlayerShaderEditorBar继承baseCPlayerShaderEditorBar 视频着色编辑条
-
-
- CPlayerToolBar继承CToolBar 视频工具条
-
-
- CPlayerToolTopBar继承CWnd 视频上面的工具条
-
-
- CPlayerWindow继承 CWnd 视频窗体
-
-
- CPlaylist继承CList<CPlaylistItem> 播放列表
-
-
- CPlaylistItem 播放列表节点
-
-
- CPngImage继承CImage 处理png图片
-
-
- CPnSPresetsDlg继承CCmdUIDialog 预设对话框
-
-
- CPPageBase继承CCmdUIPropertyPage 基本属性页
-
-
- CPPageFileInfoClip继承CPropertyPage 文件信息属性页
-
-
- CPPageFileInfoDetails继承CPropertyPage 详细文件信息页
-
-
- CPPageFileInfoRes继承CPPageBase 文件信息资源属性页
-
-
- CPPageFileInfoSheet继承CPropertySheet 文件信息页
-
-
- CPPageFileMediaInfo继承CPropertyPage 媒体文件信息
-
-
- CPPageFormats 页格式
-
-
- CResetDVD继承CDVDSession 重设DVD
-
-
- CSaveDlg继承CCmdUIDialog 保存对话框
-
-
- CSaveTextFileDialog继承CFileDialog 保存文本文件对话框
-
-
- CSaveThumbnailsDialog继承CFileDialog 保存缩略图对话框
-
-
- CSeekBarTip继承CWnd 赚到提示信息
-
-
- CShaderAutoCompleteDlg继承CResizableDialog 着色自动完成对话框
-
-
- CShaderCombineDlg继承CResizableDialog 着色连接对话框
-
-
- CShaderEdit继承CLineNumberEdit 着色编辑框
-
-
- CShaderEditorDlg继承CResizableDialog 着色编辑对话框
-
-
- CShaderLabelComboBox继承CComboBox 着色下拉框
-
-
- CShockwaveFlash继承CWnd flash控件
-
-
- CSUIBtnList继承CList<CSUIButton*> 按钮列表
-
-
- CSUIButton 自绘按钮类
-
-
- CSVPButton继承CButton 自绘按钮
-
-
- CSVPDialog继承CWnd 自绘对话框
-
-
- CSVPSliderCtrl继承CSliderCtrl 自绘Slider
-
-
- CSVPStatic继承CStatic 自绘Static
-
-
- CSVPSubUploadDl继承CResizableDialog 字幕上传对话框
-
-
- CSVPSubVoteControlBar继承CSVPDialog
-
-
- CTextFile继承CStdioFile 操作文件类
-
-
- CTextPassThruFilter继承CBaseFilter,继承CCritSec 文本直通过滤器
-
-
- CTextPassThruInputPin继承CSubtitleInputPin 文本直通输入流
-
-
- CTextPassThruOutputPin继承CBaseOutputPin 文本直通输出流
-
-
- CTransparentControlBar继承CSVPDialog 透明控制条
-
-
- CustomDrawBtn继承CButton 自定义按钮
-
-
- CVidFormatArray继承CFormatArray<VIDEO_STREAM_CONFIG_CAPS> 视频格式集合
-
-
- CVolumeCtrl继承CSliderCtrl 声音控件
-
-
- CWebTextFile继承CTextFile 网站文本
-
-
- FileAssoc 文件关联
-
-
- FilterOverride 过滤器重叠
-
-
- FrameCfgFileManage 窗体设置文件管理
-
-
- GUIConfigManage GUI配置管理
-
-
- 哈希值管理
- HashController继承LazyInstanceImpl<HashController>
-
-
- HotkeyCmd继承ACCEL 快捷键
-
-
- HotkeyController继承LazyInstanceImpl<HotkeyController> 快捷键控制
-
-
- HotkeySchemeParser 快捷键计划分析器
-
-
- LayeredWindowUtils 窗体单元
-
-
- 实例模版
- template<class T>
- class LazyInstanceImpl
-
-
- template<class T>
- class MainFrameSPlayerCmd
-
-
- MakeMultiplyBmp
-
-
- 媒体中心管理
- MediaCenterController继承LazyInstanceImpl<MediaCenterController>
-
-
- 媒体中心视图
- MediaCenterView继承ATL::CWindowImpl<MediaCenterView>,继承MediaScrollbar,继承MediaListView
-
-
- MediaCheckDB继承ThreadHelperImpl<MediaCheckDB> 媒体确认数据库
-
-
- MediaDB 媒体数据库
-
-
- MediaListView 媒体列表视图
-
-
- MediaModel继承SourceModel<MediaData, MediaFindCondition> 媒体模式
-
-
- MediaScrollbar 媒体滚动条
-
-
- MediaSpiderAbstract继承ThreadHelperImpl<T> 媒体摘要
-
-
- MediaSpiderFolderTree继承MediaSpiderAbstract<MediaSpiderFolderTree> 媒体摘要树
-
-
- MediaSQLite 媒体SQL
-
-
- MediaTreeModel 媒体树模式
-
-
- MovieComment继承CDHtmlDialog 电影评论
-
-
- NetworkControlerImpl 网络任务控制接口
-
-
- OpenDeviceData继承OpenMediaData 设备打开方式
-
-
- OpenDVDData继承OpenMediaData DVD打开方式
-
-
- OpenFileData继承OpenMediaData 文件打开方式
-
-
- OpenMediaData 打开方式基类
-
-
- 建议选项属性页
- OptionAdvancedPage继承WTL::CPropertyPageImpl<OptionAdvancedPage>,继承WTL::CWinDataExchange<OptionAdvancedPage>
-
-
- 关联文件属性页
- OptionAssociationPage继承WTL::CPropertyPageImpl<OptionAssociationPage>,继承WTL::CWinDataExchange<OptionAssociationPage>
-
-
- 基本选项属性页
- OptionBasicPage继承WTL::CPropertyPageImpl<OptionBasicPage>,继承WTL::CWinDataExchange<OptionBasicPage>
-
-
- OptionDlg继承WTL::CPropertySheetImpl<OptionDlg> 选项对话框
-
-
- 第二字幕选项属性页
- OptionSubtitlePage继承WTL::CPropertyPageImpl<OptionSubtitlePage>,继承WTL::COwnerDraw<OptionSubtitlePage>,继承WTL::CWinDataExchange<OptionSubtitlePage>
-
-
- OSDController继承LazyInstanceImpl<OSDController> OSD控制
-
-
- OSDView继承ATL::CWindowImpl<OSDView>,继承LayeredWindowUtils<OSDView> OSD视图
-
-
- PlayerPreference继承LazyInstanceImpl<PlayerPreference> 播放器引用
-
-
- PlaylistController继承LazyInstanceImpl<PlaylistController> 播放列表控制
-
-
- PlaylistParser 播放列表分析
-
-
- 播放列表视图
- PlaylistView继承ATL::CWindowImpl<PlaylistView>,继承WTL::COwnerDraw<PlaylistView>,继承 WTL::CCustomDraw<PlaylistView>
-
-
- PlaylistViewMfcProxy继承CSizingControlBarG 播放列表代理
-
-
- SkinDownload继承CDHtmlDialog,继承ThreadHelperImpl<SkinDownload> 皮肤下载
-
-
- SkinFolderManager 皮肤管理类
-
-
- SnapUploadController继承ThreadHelperImpl<SnapUploadController> 对齐上传控制器
-
-
- 源模式模块
- template<class TDATA, class TCONDITION>
- class SourceModel
-
-
- SPlayerGUID 播放ID
-
-
- SQLliteapp 操作数据库
-
-
- ssftest 测试ssf
-
-
- SubtitleStyle 内部风格指数提供了实际的映射 字幕渲染设置接受外部字幕滤镜。它还提供Windows基于GDI画画的能力
- 模拟渲染对话框显示的目的。
-
-
- 字幕透明控制
- SubTransController继承ThreadHelperImpl<SubTransController>,继承NetworkControlerImpl
-
-
- SubTransFormat 字幕透明格式
-
-
- SUIVoteStar
-
-
- SVPLycShowBox //歌词显示面板 mouseover时显示半透明玻璃背景、关闭按钮和变色按钮,out后仅显示文字
- //默认在屏幕底部区域显示,可以通过拖拽改变位置 关闭后改为在主窗口界面内显示
-
-
- ThemePkg 主题背景
-
-
- ThemePkgController 主题背景控制
-
-
- TimeBmpManage 事件画面控制
-
-
- 上传控制
- UbdUploadController继承ThreadHelperImpl<UbdUploadController>,继承LazyInstanceImpl<UbdUploadController>
-
-
- UnCompressZip 解压控制
-
-
- 更新控制
- UpdateController继承NetworkControlerImpl,继承ThreadHelperImpl<UpdateController>,继承LazyInstanceImpl<UpdateController>
-
-
- 用户着色控制
- UserShareController继承NetworkControlerImpl,继承ThreadHelperImpl<UserShareController>,继承LazyInstanceImpl<UserShareController>
-
-
- 用户行为控制
- UsrBehaviorController继承LazyInstanceImpl<UsrBehaviorController>
-
-
- 用户行为数据
- UsrBehaviorData
-
-
- 今天主要针对 SPlayer 播放器项目的 CMPlayerc 分析
-
- mplayerc
-
- -->Model\appSQLite.h 主要负责操作sql
- 类成员成员中有两个成员
- SQLliteapp* sqlite_setting;
- SQLliteapp* sqlite_local_record;
-
- 对sqlite_setting 分析
-
- 在StoreSettingsToIni 产生一个对象
- sqlite_setting = PlayerPreference::GetInstance()->GetSqliteSettingPtr();
-
-
- 保存数据前 存在 则开始输出 BEGIN
- if(pApp->sqlite_setting){
- pApp->sqlite_setting->begin_transaction();
- }
- 保存数据后 存在 则开始输出 END
- if(pApp->sqlite_setting){
- pApp->sqlite_setting->end_transaction();
- }
-
- 读取整形数据
- if(sqlite_setting){
- return sqlite_setting->GetProfileInt( lpszSection, lpszEntry, nDefault);
- }else{
- return __super::GetProfileInt( lpszSection, lpszEntry, nDefault);
- }
- }
-
- 写入整形数据
- if(sqlite_setting){
- return sqlite_setting->WriteProfileInt( lpszSection, lpszEntry, nValue);
- }else{
- SVP_LogMsg6("dwqdwq");
- return __super::WriteProfileInt( lpszSection, lpszEntry, nValue);
- }
-
- 读取字符集数据
- if(sqlite_setting){
- return sqlite_setting->GetProfileString( lpszSection, lpszEntry,
- lpszDefault );
- }else{
- return __super::GetProfileString( lpszSection, lpszEntry,
- lpszDefault );
- }
-
-
- 写入字符集数据
- if(sqlite_setting){
- return sqlite_setting->WriteProfileString( lpszSection, lpszEntry,
- lpszValue);
- }else{
- return __super::WriteProfileString( lpszSection, lpszEntry,
- lpszValue);
- }
-
- 读取二进制数据
- if(sqlite_setting){
- return sqlite_setting->GetProfileBinary( lpszSection, lpszEntry,
- ppData, pBytes);
- }else{
- return __super::GetProfileBinary( lpszSection, lpszEntry,
- ppData, pBytes);
- }
-
-
- 写入二进制数据
- if(sqlite_setting){
- return sqlite_setting->WriteProfileBinary( lpszSection, lpszEntry,
- pData, nBytes);
- }else{
- return __super::WriteProfileBinary( lpszSection, lpszEntry,
- pData, nBytes);
- }
-
- 对sqlite_setting 分析完
- 对sqlite_local_record 分析
- 在InitInstanceThreaded(INT64 CLS64) 函数中 产生对象
-
-
- sqlite_local_record = new SQLliteapp(tmPath.m_strPath.GetBuffer())
-
- 判断是否打开数据库
- if(!sqlite_local_record->db_open)
- {
- delete sqlite_local_record;
- sqlite_local_record = NULL;
- }
-
- 执行数据库 主要是创建表
- if(sqlite_local_record)
- {
- sqlite_local_record->exec_sql(L"CREATE TABLE IF NOT EXISTS histories_stream (\"fpath\" TEXT, \"subid\" INTEGER, \"subid2\" INTEGER, \"audioid\" INTEGER, \"videoid\" INTEGER )");
- sqlite_local_record->exec_sql(L"CREATE UNIQUE INDEX IF NOT EXISTS \"hispks\" on histories_stream (fpath ASC)");
-
-
- sqlite_local_record->exec_sql(L"CREATE TABLE IF NOT EXISTS histories (\"fpath\" TEXT, \"subid\" INTEGER, \"subid2\" INTEGER, \"audioid\" INTEGER, \"stoptime\" INTEGER, \"modtime\" INTEGER )");
- sqlite_local_record->exec_sql(L"CREATE UNIQUE INDEX IF NOT EXISTS \"hispk\" on histories (fpath ASC)");
- sqlite_local_record->exec_sql(L"CREATE INDEX IF NOT EXISTS \"modtime\" on histories (modtime ASC)");
-
-
- sqlite_local_record->exec_sql(L"CREATE TABLE IF NOT EXISTS settingstring (\"hkey\" TEXT, \"sect\" TEXT, \"vstring\" TEXT )");
- sqlite_local_record->exec_sql(L"PRAGMA synchronous=OFF");
- //sqlite_local_record->end_transaction();
- }
-
- 在退出程序的时候 ExitInstance()
- if(sqlite_local_record){
- CString szSQL;
- szSQL.Format(L"DELETE FROM histories WHERE modtime < '%d' ", time(NULL)-3600*24*30);
-
- // SVP_LogMsg5(szSQL);
-
- sqlite_local_record->exec_sql(szSQL.GetBuffer());
-
- sqlite_local_record->exec_sql(L"PRAGMA synchronous=ON");
- }
- if (sqlite_local_record) delete sqlite_local_record;
- $(ConfigurationName)
以上是针对主程序播放视频的分析。
ChuckTest工程 是针对rar包里的测试项目,测试代码如下:
- int _tmain(int argc, _TCHAR* argv[])
- {
- HANDLE rar_handle = NULL;
- //std::wstring fn_rar = L"E:\\-=eMule=-\\1140746814_39741.rar";
- //std::wstring fn_rar = L"E:\\-=eMule=-\\Bride.Flight.2008.Bluray.720p.AC3.x264-CHD_新娘航班\\B2_新娘航班.part1.rar";
- //std::wstring fn_rar = L"D:\\xxxx.part1.rar";
- std::wstring fn_rar = L"E:\\-=eMule=-\\Overheard.2009.REPACK.CN.DVDRip.Xvid-XTM\\sample\\xtm-overheard.repack-sample_stored.rar";
- //std::wstring fn_rar = L"E:\\-=eMule=-\\Overheard.2009.REPACK.CN.DVDRip.Xvid-XTM\\sample\\xtm-overheard.repack-sample_s.part1.rar";
-
- std::wstring tmp_dir = L"C:\\Temp\\";
-
- struct RAROpenArchiveDataEx ArchiveDataEx;
- memset(&ArchiveDataEx, 0, sizeof(ArchiveDataEx));
-
- ArchiveDataEx.ArcNameW = (wchar_t*)fn_rar.c_str();
- //ArchiveDataEx.ArcName = "E:\\-=eMule=-\\1140746814_39741.rar";
-
- ArchiveDataEx.OpenMode = RAR_OM_EXTRACT;
- ArchiveDataEx.CmtBuf = 0;
- rar_handle = RAROpenArchiveEx(&ArchiveDataEx);
-
- const long buffsize = 1000;
- char testbuff[buffsize];
-
- if (rar_handle)
- {
- wprintf(L"RAROpenArchiveEx open successed\n");
- struct RARHeaderDataEx HeaderDataEx;
- HeaderDataEx.CmtBuf = NULL;
- while (RARReadHeaderEx(rar_handle, &HeaderDataEx) == 0)
- {
- // 正常解压该文件
- unsigned long long filesize = ((unsigned long long)HeaderDataEx.UnpSizeHigh << 32) + HeaderDataEx.UnpSize;
- int err = 0;
- std::wstring unp_tmpfile = tmp_dir + HeaderDataEx.FileNameW;
- err = RARProcessFileW(rar_handle, RAR_EXTRACT, (wchar_t*)tmp_dir.c_str(), HeaderDataEx.FileNameW);
- wprintf(L"RARProcessFileW to %s return %d size %lld %x %x\n", unp_tmpfile.c_str(), err, filesize, HeaderDataEx.UnpVer, HeaderDataEx.Method);
- }
- RARCloseArchive(rar_handle);
- }
-
- rar_handle = RAROpenArchiveEx(&ArchiveDataEx);
- if (rar_handle)
- {
- wprintf(L"RAROpenArchiveEx open successed\n");
- struct RARHeaderDataEx HeaderDataEx;
- HeaderDataEx.CmtBuf = NULL;
- while (RARReadHeaderEx(rar_handle, &HeaderDataEx) == 0)
- {
- unsigned long long filesize = ((unsigned long long)HeaderDataEx.UnpSizeHigh << 32) + HeaderDataEx.UnpSize;
- int err = 0;
- std::wstring unp_tmpfile = tmp_dir + HeaderDataEx.FileNameW;
- err = RARExtractChunkInit(rar_handle, HeaderDataEx.FileName);
- if (err != 0)
- {
- wprintf(L"RARExtractChunkInit return error %d\n", err);
- continue;
- }
-
- FILE* unp_filehandle = NULL;
- err = _wfopen_s(&unp_filehandle, unp_tmpfile.c_str(), L"rb");
- if (err)
- {
- wprintf(L"open extracted file fail %d %d\n", err, unp_filehandle);
- continue;
- }
-
-
- // 顺序测试
- int iExtractRet = 0;
- unsigned long long fpos = 0;
- do
- {
- iExtractRet = RARExtractChunk(rar_handle, (char*)testbuff, buffsize);
- // Compare
- if (compare_filebinary(unp_filehandle, fpos, testbuff, iExtractRet, 0))
- {
- wprintf(L"Sequence compare difference found at %lld for %d\n", fpos, buffsize);
- break;
- }
- //else
- // wprintf(L"Sequence compare is same %lld %d\n", fpos, iExtractRet);
-
- fpos += iExtractRet;
- } while(iExtractRet > 0);
-
- // 随机测试
- for (int i = 0; i < 100; i++)
- {
- unsigned long long ll_pos = rand() * filesize/RAND_MAX;
- RARExtractChunkSeek(rar_handle, ll_pos, SEEK_SET);
- RARExtractChunk(rar_handle, (char*)testbuff, buffsize);
- // Compare
- if (compare_filebinary(unp_filehandle, ll_pos, testbuff, iExtractRet, 0))
- {
- wprintf(L"Random compare difference found at %lld\n", ll_pos);
- break;
- }
- //else
- // wprintf(L"Random compare is same %lld\n", ll_pos);
- }
- wprintf(L"RARExtractChunk test for %s finished\n", unp_tmpfile.c_str());
- }
- RARCloseArchive(rar_handle);
- }
- wprintf(L"Test finished\n");
- scanf_s("%d");
- return 0;
- }
- //字符切换
- std::string WStringToString(const std::wstring& s)
- {
- char* ch;
- UINT bytes = WideCharToMultiByte(CP_ACP, 0, s.c_str(), -1, NULL, 0,
- NULL, NULL);
- ch = new char[bytes];
- if(ch)
- bytes = WideCharToMultiByte(CP_ACP, 0, s.c_str(), -1, ch, bytes,
- NULL, NULL);
- std::string str = ch;
- delete[] ch;
- return str;
- }
-
- //比较文件
- int compare_filebinary(FILE* filehandle, unsigned long long filepos, char* buff, unsigned long buffsize, int debug)
- {
- char *fbuf = (char *)malloc(buffsize);
- _fseeki64(filehandle, filepos, SEEK_SET);
- fread_s(fbuf, buffsize, sizeof(char), buffsize, filehandle);
- int ret = memcmp(buff, fbuf, buffsize);
-
- if (debug)
- {
- for (int i = 0;i < 100;i++)
- wprintf(L"%02x", (DWORD)buff[i] & 0xff);
- wprintf(L"\n");
- for (int i = 0;i < 100;i++)
- wprintf(L"%02x", (DWORD)fbuf[i] & 0xff);
- wprintf(L"\n");
- }
-
- free(fbuf);
- return ret;
- }
- //热键计划分析器单元测试
- int _tmain(int argc, _TCHAR* argv[])
- {
- HotkeySchemeParser parser;
- printf("HotkeySchemeParser unit test\n");
- printf("----------------------------------------------------------\n");
- printf("Populating default scheme (HotkeySchemeParser::PopulateDefaultScheme) ...\n");
- parser.PopulateDefaultScheme();
- printf("Attempting to write scheme file (HotkeySchemeParser::WriteToFile) ... ");
- if (!parser.WriteToFile(L"SPlayerHotKey.txt"))
- {
- printf("[FAILED]\n");
- return 0;
- }
- printf("[OK]\n");
- printf("Attempting to read scheme file (HotkeySchemeParser::ReadFromFile) ... ");
- if (!parser.ReadFromFile(L"SPlayerHotKey.txt"))
- {
- printf("[FAILED]\n");
- return 0;
- }
- printf("[OK]\n");
-
- //目标键
- HotkeySchemeParser target;
- target.PopulateDefaultScheme();
- printf("Comparing results (scheme name)... ");
- if (target.GetSchemeName() != parser.GetSchemeName())
- {
- printf("[ERROR]\n");
- return 0;
- }
- printf("[OK]\n");
- printf("Comparing results (list)... ");
- std::vector<HotkeyCmd> parser_list = parser.GetScheme();
- std::vector<HotkeyCmd> target_list = target.GetScheme();
- if (parser_list.size() != target_list.size())
- {
- printf("[SIZE MISMATCH]\n");
- return 0;
- }
- for (std::vector<HotkeyCmd>::iterator it1 = parser_list.begin(),
- it2 = target_list.begin();
- it1 != parser_list.end(),
- it2 != target_list.end();
- it1++, it2++)
- {
- if (it1->cmd != it2->cmd ||
- it1->key != it2->key ||
- it1->fVirt != it2->fVirt ||
- it1->appcmd != it2->appcmd ||
- it1->mouse != it2->mouse)
- {
- printf("[ERROR @ %d]\n", std::distance(parser_list.begin(), it1));
- return 0;
- }
- }
- printf("[OK]\n");
-
- return 0;
- }
sqliteppTest 是针对第三方库sqlitepp操作数据库的测试,测试代码如下:
- /* step0 init - *******************
- *first check del file Testsqlite.db*/
-
- const wchar_t *filename=L"./Testsqlite.db";
- const wchar_t *sqlc1=L"CREATE TABLE IF NOT EXISTS \"settingint\" (\"hkey\" TEXT,\"sect\" TEXT,\"sval\" INTEGER)";
- const wchar_t *sqlc2=L"CREATE TABLE IF NOT EXISTS \"settingstring\" (\"hkey\" TEXT, \"sect\" TEXT, \"vstring\" TEXT)";
- const wchar_t *sqlc3 = L"CREATE TABLE IF NOT EXISTS \"settingbin2\" (\"skey\" TEXT, \"sect\" TEXT, \"vdata\" BLOB)";
- const wchar_t *sqlc4 = L"CREATE UNIQUE INDEX IF NOT EXISTS \"pkey\" on settingint (hkey ASC, sect ASC)";
- const wchar_t *sqlc5 = L"CREATE UNIQUE INDEX IF NOT EXISTS \"pkeystring\" on settingstring (hkey ASC, sect ASC)";
- const wchar_t *sqlc6 = L"CREATE UNIQUE INDEX IF NOT EXISTS \"pkeybin\" on settingbin2 (skey ASC, sect ASC)";
-
- //定义
- TCHAR path[MAX_PATH] = {0};
- ::GetModuleFileName(NULL,path,MAX_PATH);
- CStringW strSQL(path);
- strSQL.Replace(_T("TestSqlite.exe"),_T("Testsqlite.db"));
-
- int i=0;
- std::wstring sql,sql2,sql3,sql4,sql5;
- SQLliteapp p(strSQL.GetBuffer()); //构造会创建数据库文件
-
- /* step1 : Create Table 执行sql语句 创建表 字段 数值*/
- p.exec_sql(sqlc1);
- p.exec_sql(sqlc2);
- p.exec_sql(sqlc3);
- p.exec_sql(sqlc4);
- p.exec_sql(sqlc5);
- p.exec_sql(sqlc6);
-
- std::wstring str1=L"hello";
- std::wstring str2=L"world";
-
- /* step2 int-test *******************
- *
- * write int - WriteProfileInt
- get int - GetProfileInt compare 写入 读取整形数值 比较
- ************************************/
- {
- int geti1=1;
- int geti2=100;
-
- geti1=p.WriteProfileInt(str2.c_str(),str1.c_str(),-10,false);
- int test01=p.GetProfileInt(str2.c_str(),str1.c_str(),10,false);
- if(geti1)
- printf("pass -- 1 \n");
- else
- printf("fail -- 1 \n");
- p.WriteProfileInt(str1.c_str(),str2.c_str(),geti2,false);
- geti1=p.GetProfileInt(str1.c_str(),str2.c_str(),-1,false);
- if(geti2==geti1)
- printf("pass -- 2 \n");
- else
- printf("fail -- 2 \n");
- }
-
- /* step3 string-test ***************
- *
- * write str - WriteProfileString
- get str - GetProfileString
- compare 写入 读取 字符集比较
- ************************************/
- {
- std::wstring str3s1, str3s2;
- str3s1 = L"ss";
- str3s2 = L"hello你好\n";
- str3s1 = p.GetProfileString(str2.c_str(), str1.c_str(),L"xx",false);
-
- if(str3s1 == L"xx")
- printf("pass--3\n"); // ok
- else
- printf("fail--3\n");
-
- p.WriteProfileString(str1.c_str(), str2.c_str(), str3s2.c_str());
- str3s1 = p.GetProfileString(str1.c_str(), str2.c_str(), L"xx",false);
-
- if(str3s1.compare(str3s2) == 0)
- printf("pass--4\n"); // ok
- else
- printf("fail--4\n");
- }
-
- /* step4 binrary-test **************
- *
- * write bin
- get bin - donot forget new/delete 写入 读取 二进制文件
- **************************************/
- {
- char *pp = 0; //donot forget new/delete
- char buf[100];
- char str3[] = "hello4";
- char str4[] = "world4";
-
- for(i=0;i<80;i++)
- {
- buf[i] = i * 3 % 5 + 2;
- }
-
- int bPass=0; //成功的话 bPass 返回个数
- p.GetProfileBinary(str2.c_str(), str1.c_str(),(LPBYTE*)&pp,(UINT*)&bPass,false);
-
- if( bPass == 0 )
- printf("pass--5 bin\n");
- else
- printf("fail--5 bin\n");
-
- if(i>0 && pp)
- {
- delete[] pp;
- pp = NULL;
- }
-
- p.WriteProfileBinary(str1.c_str(), str2.c_str(), (LPBYTE)buf, 80); //w 80 BYTE
- p.GetProfileBinary(str1.c_str(), str2.c_str(), (LPBYTE*)&pp, (UINT*)&bPass, false); //成功的话 bPass 返回个数
-
- if(memcmp(pp,buf,30) == 0)
- printf("pass--6 bin\n");
- else
- printf("fail--6 bin\n");
-
- if(bPass>0 && pp)
- {
- delete[] pp;
- pp = NULL;
- }
- }
分析到此就结束了!~这是我针对这SPlayer项目的简单分析!
学习的目标是成熟!~~~
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。