mplayer源码分析(zt)

 

原文地址:mplayer源码分析(一)作者:青草梦想2


       我们原来的播放软件,用了mplayer中的库,但是是通过了多次的转接。十分的复杂。于是决定直接去看mplayer的代码。

mplayer代码库下有很多libxxx的目录,是各个解码器针对某一种格式的代码。然后有一个库来综合他们,如此按照层次在综合到总的codec。

比如 mpeg2格式。  在libmpeg中有一个mpeg2_parse函数,这个函数提供给了libmpcodecs中的decode函数使用。而这个decode函数 将会在libavcodec里被调用。

在libmpcodec中有一个宏,这个宏在vd_internal.h中。如下
#define LIBVD_EXTERN(x) vd_functions_t mpcodecs_vd_##x = {
 &info,
 init,
        uninit,
 control,
 decode
};

可以看出,每个引用这个头文件并使用这个宏的文件中都会产生一个名字类似,后缀不同的变量。
比如在vd_libmpeg2.c中有这样的声明:
#include "vd_internal.h"

//#undef MPEG12_POSTPROC

static vd_info_t info =
{
 "MPEG 1/2 Video decoder libmpeg2-v0.4.0b",
 "libmpeg2",
 "A'rpi & Fabian Franz",
 "Aaron & Walken",
 "native"
};

LIBVD_EXTERN(libmpeg2)

生成的这个变量就叫做mpcodecs_vd_libmpeg2 ,这个变量被用在了lib_mpcodecs/vd.c 的数组mpcodecs_vd_drivers中。
这是一种函数的组织方式。一种编译期的插件机制。是很好的模块化。

顺着这条线继续走,发现原来这个变量用在了mplayer的显示上和lib_mpcodeces的init_video里。

int init_video(sh_video_t *sh_video,char* codecname,char* vfm,int status);

这个函数的参数中有一个codecname,函数中就做过一个查表工作,找到对应的codec。
然后调用他的init方法,并把自己参数中的的sh_video传给他,由他来初始化。

在ini_video中还发现了一个控制动态连接和静态连接的宏。看来是支持动态连接。

这个ini_video被init_best_video调用。

each stream 's read is define in his fill_buffer.and this fun is save in his stream_st

the stream_st is transport from stream manager and init by each special stream .

it was called by stream_fill_buffer.

in stream_fill_buffer,we can see that , it judge by type ,and do different thing .
when it's a file ,call read ,when it's a net stream call stream->fill_buffer
when it's a demux call demux_read_data.

it's samed that ,it is the master of demux.

we also see that cash_stream_fill_buffer call it .
and cash_stream_fill_buffer was called by a inline func stream_read .

I guess it's the export fun of stream for it's name is too good !

search caller of this func . i see a list of demux .  I should read demux code next time  ^_^

---------
another line : open_stream_plugin

this parse option ,alloc memory for stream_st ,call open of stream_info_t.

we had see this struct before . every stream has a var of this type.
and descipbe itself , the name ,the protocal it support .

this struct has only one function pointer . the open function!

let see ,who call the fun open_stream_plugin

it's the func open_stream_full,let's see it !

   stream_t* open_stream_full(char* filename,int mode, char** options, int* file_format);

in the func ,we see a loop of deep two. it mean's for each protocal supported by each plugin.
we find one that support this file. and if found , it call open_stream_plugin .

ok.we finish this func.

We find a only caller of this fun in Open.c, open_stream(..)

it check the args  if it's not a playlist ,it type was set to unknow.if filename is null,return null

then it call open_stream_full. the caller of open_stream has too much .but we find a caller is
the main in mplayer .then we got the end !

  main -> open_stream -> open_full_stream -> open_stream_plugin -> plugin's open .

-----------------------------
line codec

let's see struct AVCodec
 */
typedef struct AVCodec {
    const char *name;
    enum CodecType type;
    enum CodecID id;
    int priv_data_size;
    int (*init)(AVCodecContext *);
    int (*encode)(AVCodecContext *, uint8_t *buf, int buf_size, void *data);
    int (*close)(AVCodecContext *);
    int (*decode)(AVCodecContext *, void *outdata, int *outdata_size,
                  uint8_t *buf, int buf_size);
    int capabilities;
#if LIBAVCODEC_VERSION_INT < ((50<<16)+(0<<8)+0)
    void *dummy; // FIXME remove next time we break binary compatibility
#endif
    struct AVCodec *next;
    void (*flush)(AVCodecContext *);
    const AVRational *supported_framerates; ///array of supported framerates, or NULL if

any, array is terminated by {0,0}
    const enum PixelFormat *pix_fmts;       ///array of supported pixel formats, or NULL if

unknown, array is terminanted by -1
} AVCodec;

we can see that there are init and close ,encode and decode func. next pointer show that it

must be a list ! and output format in pix_fmts.

 

 

----------------------------
line video out

i search directx and found in libvo. Be puzzled of all the fun and var is static and how

other use it ,until i found a macro LIBVO_EXTERN

#define LIBVO_EXTERN(x) vo_functions_t video_out_##x =
{
 &info,
 preinit,
 config,
 control,
 draw_frame,
 draw_slice,
      draw_osd,
 flip_page,
 check_events,
 uninit
};

this method was found be used when we first aniyst this project .
I found it ! it's LIBVD_EXTERN !

the LIBVO_EXTERN is declare in video_out_internal.h

from the macro ,we can see that ,a video out must have init and uninit . control ,and the most important "draw_frame".  the draw_osd  I think is for show subtitle. or other.

I will stop this ,and read document once again . I found that the document contain more infomation of architecture

你可能感兴趣的:(Stream,struct,video,buffer,fun,Codec)