分类: LINUX
2009-06-24 19:41:39
:转载时请以超链接形式标明文章原始出处和作者信息及本声明
http://dugchin.blogbus.com/logs/41440827.html
mplayer的libmpdemux
q:mplayer有个libmpdemux目录,谷歌金山词霸都查不到这个词,到底是什么意思嘛
a:作为一个通过了cet-6的有为青年,我告诉你,这个是这样分词的,lib-mp-demux
这下能看懂了吧,library-mplayer-demuxer的缩写
他是mplayer的流分路器
q:单词是明白了,"流分路器"可把我搞糊涂了。。
a:这个也是需要分词的,凭着哥们我当年高考语文79/150的成绩,可以准确的告诉你,
这个是流--分路器。
流这个概念可能有人不理解,没关系。你看片时有图像有声音这没错吧,这图像声音
行话分别称为视频流,音频流,说白了就是你电影里的两类资源。有的片分别又有中
英文2个配音,那么这里就有2个音频资源,你可以选择喜欢的,想听亚美爹,就选日
文资源,想听oh my god fvck就选英文资源
话说不管你的片里有几个这样的资源,他一般都是在同一个文件里的,当然还有外置
的音频,这个暂且不表。这些资源在一个文件里,那么就要有办法把他们区分开来,
libmpdemux就是用来干这个的了
q:哦明白了。
=============== 五百年后 ===============
a:哎你难道没有问题了吗?你难道不想知道丫的到底是怎么把视频音频流区分开的吗
q:哦好吧,那请问丫是怎么区分的?
a:咳,既然你这么好学上进,我就勉为其难给你解释一下
q:切
a:在这个物欲横流的时代,人们为了金钱和权利的优越感,开发出来多种文件格式,
包括现在我们常用的rm,avi,mkv等等。
这些文件格式是不同的,身在江湖的我通过mplayer的代码知道了这一点。你可以
不关心mplayer的代码到底怎样,但文件格式的不同,这是需要牢记的
文件有所不同,那么必然就是里边视频音频资源的存储方式,存储位置不同了,因为
废话,除了这些一个电影也没有其他太重要的东西了
文件的不同,让mplayer的开发者们首先想到的是一个单词interface,江湖人称接口。
没错,libmpdemux也有一组接口供上层调用,于是在demuxer.h里有了
typedef struct demuxers_desc_st {
。。。。。。
/// Check if can demux the file, return DEMUXER_TYPE_xxx on success
int (*check_file)(struct demuxer_st *demuxer); ///< Mandatory if safe_check ==
1, else optional
/// Get packets from file, return 0 on eof
int (*fill_buffer)(struct demuxer_st *demuxer, demux_stream_t *ds); ///<
Mandatory
/// Open the demuxer, return demuxer on success, NULL on failure
struct demuxer_st* (*open)(struct demuxer_st *demuxer); ///< Optional
/// Close the demuxer
void (*close)(struct demuxer_st *demuxer); ///< Optional
// Seek
void (*seek)(struct demuxer_st *demuxer, float rel_seek_secs, float audio_delay,
int flags); ///< Optional
// Control
int (*control)(struct demuxer_st *demuxer, int cmd, void *arg); ///< Optional
} demuxer_desc_t;
这几个接口有必要解释一下
check_file: 一般文件都会在文件头部写一个标记,告诉大家我是个xxx
比如你看一个avi,可能就会发现
F:\v>od -c bb.avi | more
0000000 R I F F 332 333 253 + A V I L I S T
R I F F 332 333 253 + A V I 是他的标记
看一个rmvb,就有
F:\v>od -c a.rmvb | more
0000000 . R M F \0 \0 \0 022 \0 001 \0 \0 \0 \0 \0 \0
这个 . R M F 就是他的标记
读到了这个标记,就可以初步(??)认为我们发现了某个类型的文件
open:发现了文件格式后,demuxer的责任就是读取文件头,这就是open的职责。
文件头里有很多有用的信息,比如码率啦什么的,需要关注的就是在这里会读到关于
流的信息,比如流的id,这个是之后区分流时要用到的
fill_buffer:显然这个是用来读取流内容到某个缓冲区的,音频流到音频流的缓冲,视
频流到视频流的缓冲
seek:用于定位,这个定位可不是普通的定位,这是需要定位到某个边界,不能说直接
定位到了某处然后下边不能操作了。因为这些音频视频都是一坨一坨存储的,不控制的
话,可能就seek到了某一坨的中间,这样出错了不要紧,但精彩镜头错过了就不好了
control:这个用于获取时间长度啦,在多个音频间切换啦什么的
在mplayer的开发者们花了一百多年定好了接口后,伊们开始了开发。文件一个个出现
了,demux_avi.c, demux_real.c等等,明眼人一看就知道是干嘛的
demuxer就这样做好了准备,当上层说了一句,官人我要后,demuxer就调
用fill_buffer开始了工作。要音频给音频,要视频给视频。
mplayer.c里大致是这样的
while (!eof)
{
。。。。
播放音频
播放视频
。。。。
}
可能有人问,你说播放就播放,那我怎么就知道音频视频到底在哪里?
别急,这就来了。
比如播放视频,上层请求时,会把之前在open时读到的视频流id作为参数传过来,
而demux_real.c 中,是大致这样的
while (!eof)
{
读到这一坨的长度
读到这一坨的流id
if (和音频流id匹配)
当做音频流处理
if (和视频流id匹配)
当做视频流处理
}
不用怀疑,这中间都是有break的,不像你我,没事就写死循环
这样读到了一坨数据,上层该解码解码,该输出输出。之后这样的循环不断进行着,
直到海枯石烂,直到地老天荒
哦老天,累死我了,大致流程是这样,很多细节木有讲,比如哎音频流视频流是怎么存
的,是一个接一个还是怎样?这些会有狗尾续貂之作。。
谢谢谢谢,大家撒花