mplayer的libmpdemux

来源:互联网 发布:java网上商城源代码 编辑:程序博客网 时间:2024/05/16 08:45
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的,不像你我,没事就写死循环

这样读到了一坨数据,上层该解码解码,该输出输出。之后这样的循环不断进行着,
直到海枯石烂,直到地老天荒

哦老天,累死我了,大致流程是这样,很多细节木有讲,比如哎音频流视频流是怎么存
的,是一个接一个还是怎样?这些会有狗尾续貂之作。。

谢谢谢谢,大家撒花
原创粉丝点击