边下边看的实现方式
作者:ClassyK 日期:2009-12-20
最近折腾了一阵子的边下边看,总算是有点眉目,能支持一部分格式的边下边看了。
这不是啥新技术,很多下载程序都有边下边看,但是它们的支持并不好。为了支持更多的文件格式,下载工具使用的是http服务器的方式来提供播放数据。这可以兼容更多的播放器,然而致命的弱点就是拖动进度条时,很可能就无限期挂起。这种方式的实现,具体可以参与easyMule的源码。
另外一种方式就是使用directshow的filter来做。为了实现对未知视频文件的边下边看,需要source filter与splitter filter,这里最好的示例就是微软在windows sdk中的memfile项目。尽管memfile有些bug,但是非常值得参考(虽然memfile的bug并不多,确是折磨了我一阵子,主要是刚开始没有耐心仔细阅读directshow的基础文档导致的)。这种方案的优势是对进度条的拖动支持很好,但是其弱点就是无法支持各种格式。不过对大部分应用而言,应当也够了。除了memfile外,如果需要rmvb,avi,mkv等格式的便下边看,可以去看看hc-mpc中的解码器部分,以便查阅为啥ms的memfile不能工作。
不过上面的方法到目前而言,也有问题我还没有解决,那就是缓冲百分比的问题。主要是每个格式的处理不同。譬如realmedia的文件,刚开始启动播放的时候,它除了读取文件头外,还需要读取文件尾。而要做一个各种格式都适合的方式,是很难的。(播放位置,以及缓冲区长度倒是可以用比特率来大概的计算出来)。
Tags: 边下边看 DirectShow
CppE4X更新
作者:ClassyK 日期:2009-08-29
字符集转换(更新)
作者:ClassyK 日期:2009-08-17
当工程中混用stl与非stl模式的时候,原来的代码容易产生问题。
主要原因是因为stl与非stl版本的函数名相同。故此稍作修改,让他们可以一定程度并存下来。
- #pragma once
- #include <malloc.h>
- #include <windows.h>
- #define USE_LIN_CHAR_SET_VARIANT char* _lin_dst = 0; wchar_t* _lin_wdst = 0; int _lin_dst_size = 0;
- #define LIN_CHAR_SET_NO_WARNING _lin_dst; _lin_wdst;_lin_dst_size;
- #define USE_LIN_CHAR_SET USE_LIN_CHAR_SET_VARIANT;LIN_CHAR_SET_NO_WARNING
- #ifdef LIN_CHAR_SET_USE_STL
- #include <string>
- std::string _w2a_s( const std::wstring& pwcsSrc, int codepage)
- {
- USE_LIN_CHAR_SET;
- _lin_dst_size = pwcsSrc.size()*3;
- _lin_dst = new (std::nothrow) char[ _lin_dst_size];
- if( _lin_dst == 0) return std::string();
- _lin_dst_size = WideCharToMultiByte( codepage, 0, pwcsSrc.c_str(), pwcsSrc.length(), _lin_dst, _lin_dst_size, 0, 0);
- if( _lin_dst_size == 0)
- {
- delete[] _lin_dst;
- return std::string();
- }
- _lin_dst[_lin_dst_size] = 0;
- std::string result = _lin_dst;
- delete[] _lin_dst;
- return result;
- }
- std::wstring _a2w_s( const std::string& pszSrc, int codepage)
- {
- USE_LIN_CHAR_SET;
- _lin_dst_size = pszSrc.size()*2;
- _lin_wdst = new (std::nothrow) wchar_t [ _lin_dst_size];
- if( _lin_wdst == 0) return std::wstring();
- _lin_dst_size = MultiByteToWideChar( codepage, 0, pszSrc.c_str(), pszSrc.length(), _lin_wdst,_lin_dst_size);
- if( _lin_dst_size == 0)
- {
- delete[] _lin_wdst;
- return std::wstring();
- }
- _lin_wdst[_lin_dst_size] = 0;
- std::wstring result = _lin_wdst;
- delete[] _lin_wdst;
- return result;
- }
- #define _utf82w( pszSrc) _a2w_s( pszSrc, CP_UTF8)
- #define _w2utf8( pszSrc) _w2a_s( pszSrc, CP_UTF8)
- #define _utf72w( pszSrc) _a2w_s( pszSrc, CP_UTF7)
- #define _w2utf7( pszSrc) _w2a_s( pszSrc, CP_UTF7)
- // 导出的宏
- #define a2w(pszSrc) _a2w_s(pszSrc, CP_ACP)
- #define w2a(tcsSrc) _w2a_s(tcsSrc, CP_ACP)
- #else
- #define _w2a( pwcsSrc, codepage) ( pwcsSrc == 0? 0:( \
- (_lin_dst = (char*)_alloca( ((_lin_dst_size = (int)wcslen( pwcsSrc))+ 1)*3))== 0? 0 : (\
- (_lin_dst_size = WideCharToMultiByte( codepage, 0, pwcsSrc, _lin_dst_size, _lin_dst, _lin_dst_size*3, 0, 0))==0? \
- ((_lin_dst[0]=0)==0 ? _lin_dst:0): (\
- (_lin_dst[_lin_dst_size] = 0) == 0? _lin_dst : 0))))
- #define _a2w( pszSrc, codepage) (pszSrc == 0? 0 : (\
- (_lin_wdst = (wchar_t*)_alloca( ((_lin_dst_size = (int)strlen( pszSrc)) + 1)*2)) == 0? 0 : (\
- (_lin_dst_size = MultiByteToWideChar( codepage, 0, pszSrc, _lin_dst_size, _lin_wdst,_lin_dst_size + sizeof(wchar_t))) == 0? \
- ((_lin_wdst[0]=0)==0? _lin_wdst:0) : (\
- (_lin_wdst[ _lin_dst_size] = 0) == 0? _lin_wdst: 0))))
- #define _utf82w( pszSrc) _a2w( pszSrc, CP_UTF8)
- #define _w2utf8( pszSrc) _w2a( pszSrc, CP_UTF8)
- #define _utf72w( pszSrc) _a2w( pszSrc, CP_UTF7)
- #define _w2utf7( pszSrc) _w2a( pszSrc, CP_UTF7)
- // 导出的宏
- #define a2w(pszSrc) _a2w(pszSrc, CP_ACP)
- #define w2a(tcsSrc) _w2a(tcsSrc, CP_ACP)
- #endif
- #ifdef UNICODE
- #define a2t(pszSrc) a2w(pszSrc)
- #define t2a(tcsSrc) w2a(tcsSrc)
- #define w2t(wcsSrc) wcsSrc;
- #define t2w(tcsSrc) tcsSrc;
- #else
- #define a2t(pszSrc) pszSrc
- #define t2a(tcsSrc) tcsSrc
- #define w2t(wcsSrc) wta(wcsSrc)
- #define t2w(tcsSrc) a2w(tcsSrc)
- #endif
- #define w2utf8(wcsSrc) _w2utf8(wcsSrc)
- #define utf82w(pszSrc) _utf82w(pszSrc)
- #define w2utf7(wcsSrc) _w2utf7(wcsSrc)
- #define utf72w(pszSrc) _utf72w(pszSrc)
- #define a2utf8(pszSrc) w2utf8(a2w(pszSrc))
- #define a2utf7(pszSrc) w2utf7(a2w(pszSrc))
- #define utf82a(pszSrc) w2a(utf82w(pszSrc))
- #define utf72a(pszSrc) w2a(utf72w(pszSrc))
- #define t2utf8(tcsSrc) w2utf8(tcsSrc)
- #define t2utf7(tcsSrc) w2utf7(tcsSrc)
- #define utf82t(pszSrc) w2t(utf82w(pszSrc))
- #define utf72t(pszSrc) w2t(utf72w(pszSrc))
单眼与距离识别
作者:ClassyK 日期:2009-07-24
前阵子有人说,人的单眼是没法测定物体和人的距离的。而对于此,我的想法是不同的。
如果把人眼看成是范焦镜头(手机上大量使用的(不带AF功能的)摄像头大部分使用的范焦镜头),那么这个说法也许正确。然而人眼不是范焦的。
想想DC的对焦功能,如果使用单反,镜头是更是有对焦环,对焦环上的刻度,会指示出当前对焦点和相机机身之间的距离。相机只需要使用一个镜头,就能识别到物品与相机的距离,关键原因就在于对焦,只有位于对焦点(及其附近)的物体,才会产生清晰的影像。对焦和精确对焦却又是不同。当使用大光圈的时候,精确对焦尤其重要,因为差以毫厘,就可能导致影像的模糊。
人眼也是如此,我们看东西的时候,眼球需要对焦,才能看到清晰的画面。这个时侯,就算只用单眼,我们也能够察觉出物体与自己之间的距离及变化。
delay load
作者:ClassyK 日期:2009-04-20
binfstream
作者:ClassyK 日期:2009-04-20
以前写了一个不知道放哪去了,就重写了一个:
- class binfstream : public std::fstream
- {
- public:
- // 一个比较丑陋的构造函数 ^_^
- binfstream( const char* file_name, int open_mode = std::fstream::in)
- : std::fstream(file_name, open_mode | std::fstream::binary | ( (open_mode & std::fstream::out ) == 0 ? 0 : std::fstream::trunc) )
- {
- }
- ~binfstream()
- {
- }
- // input
- template<typename T>
- binfstream& operator << (const T& t)
- {
- write( reinterpret_cast<const char*>(&t), sizeof T);
- return *this;
- }
- binfstream& operator << ( const char* t)
- {
- write( t, strlen(t) + 1);
- return *this;
- }
- binfstream& operator << ( const std::string s)
- {
- return operator << ( s.c_str());
- }
- // output
- template<typename T>
- binfstream& operator >> (T& t)
- {
- read( reinterpret_cast<char*>(&t), sizeof T);
- return *this;
- }
- binfstream& operator >> ( std::string &str)
- {
- char cur_char;
- while( read( &cur_char, sizeof cur_char ) )
- {
- if( cur_char == 0) break;
- str.push_back( cur_char);
- }
- return *this;
- }
- };
使用自然是以简单为主:
- #include <iostream>
- #include <fstream>
- #include <string>
- #include "binfstream.h"
- int main( int argc, char* argv[])
- {
- binfstream f( "d:\\log.txt", std::fstream::in | std::fstream::out);
- f << 3 << std::string("hello") << "world" << 1.133;
- int i;
- std::string s1;
- std::string s2;
- double d;
- f.seekp( std::fstream::beg);
- f >> i >> s1 >> s2>> d;
- std::cout << i << s1 << s2 << d;
- return 0;
- }
其中operator << 和 >> 并没有写为友元,主要是因为我。。想 偷懒
Tags: fstream
getline
作者:ClassyK 日期:2009-04-08
cppe4x
作者:ClassyK 日期:2009-03-12
源码已经上传到google code,以下是project链接 http://code.google.com/p/cppe4x
- cppe4x是一个简单的C++跨平台XML解析器,基于DOM和XPath方式实现,其目标是快速的构建xml应用。
- cppe4x非常适合快速的构建测试程序以及配置文件的读写。当前仅支持UTF8格式的XML文件。同时,cppe4x在Microsoft Windows平台下会自动进行utf8与ansi编码的双向转换。
- cppe4x最初的目标是构建与ActionScript3?中的E4X语法类似的接口,但由于C++与AS3语法的巨大差异,目前的cppe4x无法完全实现该目标。尽管如此,cppe4x还是尽量的保持了操作的简洁和有效性。
这个xml解析器的代码并不长,但是前前后后却花了好几个月的时间,结构也数次调整。也正因如此,方知一个库的构建,是如此的困难。现在,依然有很多不满意的地方。程序和文档的完善,尚需时日。
,我可以用这个功能来根据配置文件加载不同的摄像头sdk,今天在touchwin的代码上进行了试验,结果就是: 可行。
