Software-Catalog Archive:

Page 1 of 212

ffmpeg API 笔记:使用libavcodec/libavformat/libswscale

Update 2010.1.5: 其实研究ffmpeg不用找什么教程,第一步应该是下载ffmpeg的源码包。下面提到的An FFmpeg and SDL Tutorial确实有讲解,但是教程总是跟不上代码的变化的,所以直接看可工作代码最好;ffmpeg的结构很分明,后台是几个库:libxxx,前台是三个程序ffmpeg, ffplay, ffserver,那篇教程说的就是ffplay的实现。一个播放器,其实重点不是解码,解码的东西是lib去做的,主要是做声音视频的时钟同步。ffplay的代码可以说是一个可用播放器最简单的实现了,源码里面有个output_example.c,可以说是最基本的api示范吧。ffmpeg是转换编码解码转换程序,因为涉及重新采样等等,所以代码量也不少的。


这两天"调研"了下ffmpeg的API,不得不承认被雷倒:ffmpeg又是一个很geek的项目,纯社区开发,基于逆向,功能强大,但是文档极度有限,想了解API?看源码去…… 网上关于ffmpeg API的资料,无非是ffmpeg文档里面的两个链接,Using libavformat and libavcodec by
Martin Böhme(以及其Update,介绍了新引入的API)跟An FFmpeg and SDL Tutorial
by Stephen Dranger;两个tutorial基于ffmpeg 0.4.8,现在ffmpeg发布的版本是0.5.0,好像数值相差不大,不过0.4.8是5年前的了(相比之下wine用了15年版本号才到达1.0,有过之余无不及),两个教程里面的代码在0.5.0下一编译,哇,一堆错误,可不仅有些api函数变了,有些结构成员压根就没了,头文件的位置更是不一样(各个库分家了)……所以我调试了好几个小时,终于把例子的代码弄好(其实Martin Böhme那篇有一段09年加入的更新说明,链接了有相关的解决办法,我一开始没注意,几个小时自己解决,不过也有收获)。

最后我调试好的代码流程:打开一个视频文件,抓取前5帧保存为文件;
基于Stephen Dranger的Tutorial1源码在此:GoogleCode

av_register_all();//初始化ffmpeg库,如果系统里面的ffmpeg没配置好这里会出错
av_open_input_file();
av_find_stream_info();//查找文件的流信息
dump_format();//dump只是个调试函数,输出文件的音、视频流的基本信息了,帧率、分辨率、音频采样等等
for(...);//遍历文件的各个流,找到第一个视频流,并记录该流的编码信息
sws_getContext();//根据编码信息设置渲染格式
avcodec_find_decoder();//在库里面查找支持该格式的解码器
avcodec_open();//打开解码器
pFrame=avcodec_alloc_frame();//分配一个帧指针,指向解码后的原始帧
pFrameRGB=avcodec_alloc_frame();//分配一个帧指针,指向存放转换成RGB后的帧
avpicture_fill(pFrameRGB);//给pFrameRGB帧加上分配的内存;
while true{
     av_read_frame();//读取一个帧(到最后帧则break)
     avcodec_decode_video();//解码该帧
     sws_scale();//把该帧转换(渲染)成RGB
     SaveFrame();//对前5帧保存成ppm图形文件(这个是自定义函数,非API)
     av_free_packet();//释放本次读取的帧内存
}
avcodec_close();
av_close_input_file();

用到的API就这么多,当然实际代码稍复杂一点;ppm图像是类似BMP的非压缩格式,SaveFrame就是相当于把pFrameRGB的内存拷贝进文件,写文件并不复杂;

调试过程的问题,首先是头文件,ffmpeg 0.5.0的API已经拆分成好几个独立的库,用pacman -Ql ffmpeg看了下文件分布,在include下好几个目录都是它的,看名字可以大概猜出他们的功能:

libavcodec:CODEC其实是Coder/Decoder的缩写,也就是编码解码器;
libavdevice:对输出输入设备的支持;
libavformat:对音频视频格式的解析
libavutil:集项工具;
libpostproc:后期效果处理;
libswscale:视频场景比例缩放、色彩映射转换;

修改好头文件包含,终于少了些not declared错误;

Martin Böhme那篇教程的代码是使用g++编译的,虽然代码是C风格;在我修改了头文件以及一些错误之后,居然链接出错,av_register_all什么的函数统统undefined reference,想到ffmpeg是纯C实现,以及以前用g++编译GTK出现回呼函数找不到的经历,相信又是g++的function mangling搞的,Google了一下,解决方法是把几个头文件包含在exterc "C"里面

代码里面的错误还涉及一些结构成员的变化,比如

pFormatCtx->streams[i]->codec.codec_type==CODEC_TYPE_VIDEO

就有个类型错误,因为0.5.0里面的codec已经是指针,而不是结构了,要把.换成->,而相应地获得解码器指针,不再需要&:

pCodecCtx=&pFormatCtx->streams[videoStream]->codec;

原教程提到一个视频码率的rate的Hack:

    // Hack to correct wrong frame rates that seem to be generated by some codecs<br />    if(pCodecCtx->frame_rate>1000 && pCodecCtx->frame_rate_base==1)<br />        pCodecCtx->frame_rate_base=1000;

好吧现在frame_rate跟frame_rate_base压根就没了,去掉算了;

最麻烦的变化还是原代码里面的img_convert,就是解码出一个帧的数据后,需要转换成RGB格式才能写入文件,然而这个函数在0.5.0里面彻底没了。尝试把img_convert完全注释掉,把原始帧img_convert写入文件,还算可喜的是能够看到图形,只是被分成三个画面的通道图形罢了;

Google了一番,还是回到 Stephen Dranger的An FFmpeg and SDL Tutorial第八节,介绍了swscale的接口,虽然里面的例子是转换成SDL所用的YUV,而不是RGB;注意到其使用的参数PIX_FMT_YUV420P,跟img_convert所用的PIX_FMT_RGB24有相同前序,就试试照样花虎了;
给sws_getContext传入源格式的H/W,格式,输出格式的H/W,PIX_FMT_RGB24格式,其中有个参数flags的解释是 specify which algorithm and options to use for rescaling,是选择在缩放过程中是使用线性还是双立方等算法(参数文档没说,要找看源码去),这里照抄了例子里面的SWS_BICUBIC。获得这个SwsContext,类似python的re.compile,再用这个转换器去转换每一个帧,所以后面每次解码了帧后,调用sws_scale,跟原来的img_convert倒是挺像;

也就是说,以后如果需要对视频进行4:3跟16:9的转换,就是在sws_getContext的参数里面做设置了;

最后整个程序正常,会把视频的前5帧抓成图像了,只是会有个小警告:

[swscaler @ 0x1d8f670]No accelerated colorspace conversion found.

估计是转换成RGB,swscale里面没有特别优化的算法?

目前发现程序运行的时候CPU占用很高,是因为程序还没有控制帧速的时钟,只会用尽CPU的性能不断的读取解码;

PT修改过可编译通过(ffmpeg 5.0/gcc 4.4.2/ubuntu 9.10)的前三个Tutorial代码可在Google Code查看下载。(编译方法请看各个文件头部的注释说明)

Tags: , , , ,

暂无评论

Win32版本的锐捷客户端zRuijie4GZHU

花了几天时间,将zRuijie4GZHU的代码用Win32 API封装好了。

怎么突然给“万恶“的Windows开发程序呢,呵呵算是一时冲动好了,因为此前对Windows的API基本一无所知,虽然大二的时候C++的课程教了一点MFC,不过离开底层API来说MFC,真的很腾云驾雾,转眼就全忘记了,交课程报告时候用VS的Wizard大概地弄个两个窗口,甚至说不清一个控件是怎么被创建的……画上去的?嘿嘿……

这次做Win的程序算是为了了解一下Win下面的模式,程序使用纯SDK API来写。开着虚拟机,开始的时候用Dev CPP来做,但没一会就忍不了那个编辑器的白痴了,还好Devcpp提供了项目的Makefile,于是用Notepad++来弄代码,开着个cmd窗口来编辑;最后还是把代码弄到Linux来,装了个mingw来cross,用gvim来写代码才有快感。程序的resources使用ResEd来做,很不错的小东西,用wine来跑一点问题都没,哈。

写win32过程我想最多的就是GTK,感觉Win32那些API很有考古的感觉,比如说指针类型,不知道有没有人统计过究竟微软发明了多少个类型,LPSTR,LPCSTR,INT_PTR,LPVOID TMD匈牙利命名法,就不能用好看一点的名称~

对比起来,win32最原始的地方应该是消息处理过程吧,看着形态怪异的DlgProc,很郁闷的感觉;GTK只需要按事件类型来注册回呼函数,所以我写的的Proc基本都是用函数把处理过程引了出来。

代码依然扔在Google Code:http://code.google.com/p/zruijie4gzhu/

Tags: ,

评论 (1)

通过Wine使用Sogou浏览器的教育网加速代理

此前用wireshark嗅探研究过Sogou浏览器的代理功能,没什么头绪,有访客留言说用Process Explorer瞧瞧Sogou的进程,今天有空看了下,果然,有一个子进程是用-proxy参数启动的,打开了本地的8081和8082端口在监听,用其他浏览器连8081,发现就是普通的透明代理,而8082则是一个自动配置代理的PAC(Javascript)。

虽然现在我的Ubuntu下已经有了一堆翻墙用的代理软件(没边、门、eTunnel……),但经常速度不甚理想,而且学校校园网的电信出口经常被挤爆,而教育网出口是空的,所以使用Sogou提供的免费教育网代理是个不错的解决办法。

把Sogou弄到Ubuntu下的Wine环境没有任何难度,把Sogou的安装文件夹全部复制到~/.wine/drive_c/sogou下,运行的很正常:

pentie@pentie-desktop:~$ wine "C:\sogou\SogouExplorer.exe" -proxy
fixme:win:EnumDisplayDevicesW ((null),0,0x32f3c4,0x00000000), stub!
fixme:wtsapi:WTSRegisterSessionNotification Stub 0x1002a 0x00000000
fixme:mountmgr:harddisk_ioctl unsupported ioctl 74080
fixme:mountmgr:harddisk_ioctl unsupported ioctl 2d1400
fixme:mountmgr:harddisk_ioctl unsupported ioctl 2d0c10
PID:8
PORT:8081
CPORT:8082
PAC:http://127.0.0.1:8082/proxy.pac?t=626
RET:SUCCESS

在配置Firefox的FoxyProxy,可以像平常那样添加127.0.0.1:8081作为代理,但既然提供了PAC,不妨试试:在Automatic proxy configuration URL内添入“http://127.0.0.1:8082/”,按Test,说找到PAC,解析成功!确定后右下角也出现FoxyProxy的提示。此时在Firefox中打开的网页都是通过Sogou的免费代理了!不过发觉现在的代理速度没此前那么快了。

Ubuntu中有一个工具可以配置全局代理,gnome-network-preferences,运行它可以轻松的让apt-get、telnet之类的程序通过代理来连接外网。

再一次提醒的是,Sogou浏览器代理是“透明代理”,它会转发你的真实IP,没有任何匿名功能,因为他们的服务器也在国内(北京),因此也不会有翻墙功能。

参考了别人的网志:http://dan.febird.net/2008/12/firefox.html

已知缺陷:在流量和连接数比较大时(比如刷开Google Reader),wine出来的SogouExplorer进程占用大量CPU资源,可能是某链接库匹配问题,以致这个方法的实用性不是很高。

Tags: , , , , , , ,

评论 (7)

在Ubuntu下安装Flash播放插件

Flash Player 10.0.22.87今日发布,包括Linux版本。经过安装试用,比之前Flash 10的首发版本改进很多,虽然看Flash视频的CPU占有率还是有点偏高,但至少保证了画面的流畅度,即使全屏播放也很流畅。

下面是我在Ubuntu下安装这个新版的Flash插件的过程。虽然也是有deb安装包发布,但依然需要自己动手才能用上。

http://www.adobe.com/go/getflashplayer

从上面Adobe的官方地址下载到新版的安装文件,install_flash_player_10_linux.deb,如一般软件那样安装完成,但此时的Flash插件并未在Firefox中生效

Flash Player的有效文件只有一个,libflashplayer.so,无论你下载什么安装包,里面都只是这个文件。在Ubuntu下,deb包把这个文件安装到

/usr/lib/adobe-flashplugin/libflashplayer.so

然而,Firefox使用的插件目录是

/usr/lib/firefox-addons/plugins

Firefox当然是找不到新版的Flash了。

首先检查下/usr/lib/firefox-addons/plugins有没有旧版的libflashplayer.so,是文件还是链接,修改时间:

ls -l /usr/lib/firefox-addons/plugins

如果有一个libflashplayer.so文件,则将其删除:

sudo rm -v /usr/lib/firefox-addons/plugins/libflashplayer.so

然后往/usr/lib/firefox-addons/plugins里面建立一个指向Flash插件的链接(这样有利于以后升级Flash插件):

sudo ln -s /usr/lib/adobe-flashplugin/libflashplayer.so /usr/lib/firefox-addons/plugins

重新运行Firefox,进入http://www.adobe.com/products/flash/about/,应该能看到提示当前安装的版本是10.0.22.87了。

以后如果Flash Player再出新版,直接安装deb,就完成整个更新了。

Opera浏览器好像会自动找到Flash插件,没要我费神就用上了。

Tags: , , ,

评论 (1)

推荐《Linux 101 Hacks》

《Linux 101 Hacks》是一本关于 Linux 使用技巧的免费电子书籍。本书总计 140 页,包含 12 章,讲解了 101 个 hack,涉及的内容包括 Linux 命令精要、日期处理、定制命令提示符、系统管理、Bash 脚本、Apachectl 及 Httpd 例解、系统监视与性能等等,总之很值得一看。

其中最为实用的,大概 4(基本命令)、7(归档打包)、9(系统配置)、10(Apache服务配置)和12(系统控制)几章。虽说都是一些命令的使用,但是要比什么xx命令手册要好。手册即使再详细,也不可能告诉你“把60天以内没改动过的文件归档”的命令。101 Hacks很多这些实用的命令配搭技巧,尤其适合像我这样的菜鸟。

比如说,Hack 5介绍的cd -命令,之前我一直想找怎么切换上一个目录(在弄配置或者改源文件的时候很有用),搜索后知道pushd、popd这些,感觉不实用(实际使用时很难想到),原来cd就带有了这个功能。

Shell实在太强大了,估计没哪本书能够写完,也没哪个人能够学完,根据我的经验,即使把Man手册背下来都没用的,马上会忘记。但是在需要用到的时候,比如find,不记得用法,看看help,靠,几十页,这时把Hack抄出来看就很好,简单明了,而且容易记住。

虽然全书是英文,但是应该属于最易读的那种,打算去打印点把这本书打印出来,反正学校打印资料便宜。

此书免费发行,作者为 Ramesh Natarajan,可从其个人 Blog 上下载Linux 101 Hacks

Tips:作者在下载时想让你订阅他的RSS才拿到下载地址,点击RSS图标进去拉到最后就看到了,好像每次都不同,lovelinux,linux-is-the-best都有……tricks...

Tags: , ,

暂无评论

配置VirtualBox虚拟机通过NAT方式对外提供Web服务

使用虚拟机常常是为了调试服务器,因为在桌面系统安装服务程序,一来容易有安全问题,更重要是容易拖慢系统。

VirtualBox作为一款轻快的开源虚拟机软件,自从被Sun公司收购后,更新相当频繁,功能也逐渐完善,比起VMware动辄几百M的安装文件,VirtualBox几十M的身材而功能丝毫不在VMware之下,而且性能远远高出VMware。

如果把虚拟机作为服务器调试工具,VM默认是使用桥接方式连接虚拟机和主机,安装完后虚拟机直接对主机可见,调试很方便,但是VBox则默认是NAT方式,主机完全访问不了虚拟机。

除了设置VBox为桥接方式外(有点麻烦),另一更加简捷的方式是给虚拟机开端口。这和使用家用路由器映射端口原理是一样的,经过路由器后,局域网内的机器对公网外是不可见的,但是通过添加端口映射,公网就可以访问到内网的机器。

VirtualBox 的User Manual(2.1.4版)在6.4.1介绍了这个方法:使用VBox自带的VBoxManage工具设置端口映射。下面是介绍一个例子:

...
[阅读全文...]

Tags: , , ,

评论 (3)

隐私嗅探者——Driftnet

Driftnet是一款数据嗅探软件,它感兴趣的内容可能和你一样:别人正在查看的图片、视频、音频……意味着,你可以通过Driftnet,将你电脑所处的网络广播域中所有人未经加密传输的图像一一显示出来……特别在无线WiFi网络中。

加密连接对很多人来说没什么概念:“我又不是做FBI的,干吗要弄什么加密!”,但很多人见到这个软件的运行效果之后,都赶紧打开他的无线网络的加密……
...
[阅读全文...]

Tags: , , , ,

暂无评论

Google Chrome for Mac 截图泄出

Mac、Linux版的Chrome可谓万众期待,现在,移植工作已经接近尾声。

日前Mike Pinkerton透露了Mac版本的移植细节,按目前的状况来看,Mac版肯定会先于Linux版发布。

“我们在本周初制定了渲染的工作列表,目标是在本周内生成能够生成能够运行的版本,但是在今天已经将本周的工作完成,还添加了打开和关闭标签页时的动态效果。”

从截图上看,界面还有一些元素没有完善(新页面按钮),但基本上都定型了。

原文链接:Google OS
apt-blog.net PT编译

Tags: , ,

评论 (7)

Page 1 of 212