存档

‘Win32’ 分类的存档

Win32选择保存文件路径和打开文件夹的函数

2014年9月30日 评论已被关闭

有时候我们需要拾取打开或者保存的路径,浏览文件夹,下面是win32的接口。

MSDN:GetSaveFileName
MSDN:SHBrowseForFolder

分类: Win32 标签:

使用librtmp进行H264与AAC直播

2014年1月3日 评论已被关闭

libx264版本是128
libfaac版本是1.28

1、帧的划分

1.1 H.264帧

对于H.264而言每帧的界定符为00 00 00 01或者00 00 01。

比如下面的h264文件片断这就包函三帧数据

00 00 00 01 67 42 C0 28 DA 01 E0 08 9F 96 10 00
00 03 00 10 00 00 03 01 48 F1 83 2A 00 00 00 01
68 CE 3C 80 00 00 01 06 05 FF FF 5D DC 45 E9 BD
E6 D9 48 B7 96 2C D8 20 D9 23 EE EF …

第一帧是00 00 00 01 67 42 C0 28 DA 01 E0 08 9F 96 10 00 00 03 00 10 00 00 03 01 48 F1 83 2A
第二帧是00 00 00 01 68 CE 3C 80
第三帧是00 00 01 06 05 FF FF 5D DC 45 E9 BD E6 D9 48 B7 96 2C D8 20 D9 23 EE EF ..

帧类型有:
NAL_SLICE = 1
NAL_SLICE_DPA = 2
NAL_SLICE_DPB = 3
NAL_SLICE_DPC = 4
NAL_SLICE_IDR = 5
NAL_SEI = 6
NAL_SPS = 7
NAL_PPS = 8
NAL_AUD = 9
NAL_FILLER = 12,

我们发送RTMP数据时只需要知道四种帧类型,其它类型我都把它规类成非关键帧。
分别是
NAL_SPS(7), sps帧
NAL_PPS(8), pps帧
NAL_SLICE_IDR(5), 关键帧
NAL_SLICE(1) 非关键帧

帧类型的方式判断为界面符后首字节的低四位。
第一帧的帧类型为: 0x67 & 0x1F = 7,这是一个SPS帧
第二帧的帧类型为: 0x68 & 0x1F = 8,这是一个PPS帧
第三帧的帧类型为: 0x06 & 0x1F = 6,这是一个SEI帧

以上是我们利用帧界定符划分帧,并可以判断每一个帧的类型。

注意:如果是压缩图像成H264帧,我们就可不必进行帧界定,因为每一次压缩的输出都明确了该帧的大小(包括界定符),每一次的压缩的结果可能包函多帧。一会具体讨论。

1.2 AAC帧

对于AAC帧它的界定符是FF F1

这里我就不举例了,可通过查看AAC的二进制文件可以看到如下的帧结构。
FF F1 50 80 24 9F FD DE 04 00 00 6C 69 62 66 61 61 63 20 31 2E 32 38 00 00 42 15 95 ..

注意:那么对于AAC而言加上界定符每一帧的前7字节是帧的描述信息,也就是说AAC的祼数据是除去前面的7个字节的,在发送RTMP时,我们要去掉这7个字节。同样,如果我们是一边压缩一边发送RTMP,我们同样不需要界定帧,因为libfaac每次压缩完成的输出就是一个完整的帧数据,我们只需要将该帧打包发送即可。

综合上面的所述,如果我们只是一边压缩一边将压缩结果发送到RTMP服务器,那我们就可以不用对帧进行界定,如果我们是发送H264与AAC文件,那我们就要对帧进行界定。

2.视频与音频的编码信息

如果我们只是简答的将压缩数据打包发送给RTMP服务器,那么RTMP服务器是不可以对数据进行解码和播放的,在这之前我们要将音视频的视频的编码信息发送给RTMP服务器。很多人可能苦于寻找下面的三个编码参数而不得要领。其实要想得到也是很简单的。 阅读全文…

分类: C/C++, Win32 标签:

GBK与UTF-8之间的转化

2013年11月11日 没有评论

GBK编码与UTF-8之间的转化。
第一种是先将 GBK->Unicode->UTF-8;
第二种是通过iconv库,直接GBK->UTF-8;
Unicode编码包含所有字符集,而GBK(GB2312是GBK的一个子集),UTF-8等等都称为多字节集(Multibyte),两个多字节字符集之间的转换首先将源字符集映射到Unicode上,再将Unicode映射到目标多字节字符集上。有一个问题就是源字符集与目标字符集不可能是一一对应的,所以在转换的时候往往会有一个参数表示如果未找到对应的字符的处理情况。另外Unicode中的表示字符用wchar_t,而多字节的字符用char表示(也有多个char表示一个字符)。

windows下

C语言中有与WideCharToMultByte对应的接口是wctomb,MultiByteToWideChar对应的接口是mbtowc,但是对应的转化不能将正确的转换UTF-8。具体实现是先将当前语言为源字节集,将源字节集转化成Unicode,然后将语言设置成目标字节集将Unicode转化成目标字节集,具体参见:
setlocale: http://msdn.microsoft.com/en-us/library/aa272906(v=vs.60).aspx

利用第三方库实现,它就是大名鼎鼎的libiconv,有一个值得小心的地方,就是当目标字符集中没有源串中对的字符是可以选择继续还是忽略,所以及在open时会带上参数”//IGNORE”,要不然就遇到这种情况会停止转化。

分类: C/C++, Linux, Win32 标签:

使用原子操作实现自旋锁

2013年10月14日 没有评论

原子操作
在windows平台有InterlockedCompareExchange原子操作接口。实现对内存的互斥修改

如果对函数的解释有点疑惑,可以看一下该函数的大致实现。

自旋锁
如果我们所1代表“加锁”,0代表“未加锁”。加锁的过程是将内存值0改成1,所以我们可以利用这特性实现加锁操作和解锁操作。

知道trylock只是尝试去将0改成1,如果之前已经是1说明,锁被占用了。所以我们实现了自旋等待锁被释放。

更好的实现,用Sleep切换CPU。

对于基于linux的gcc也是有相应的“比较修改”接口__sync_bool_compare_and_swap(lock, old, set),它的参数与windows的接口有两点不一样,参数不一致,返回类型也不一样。它的trylock的实现:

example

分类: C/C++, Linux, Win32 标签:

VirtualBox从U盘启动方法

2011年12月25日 1 条评论

#进入命令行

#获取磁盘信息(这个最关键)

#打开d:/diskdrive.html ,查看DeviceID栏,获取到你的U盘DeviceID,如\\.\PHYSICALDRIVE1

#为U盘创建启动文件

# 添加磁盘d:\UsbDisk.vmdk, F12启动虚拟机,选择这个磁盘即可磁盘

分类: C/C++, Linux, Win32, 翻译, 计算机网络, 转载 标签: