VLC 学习计划---文档阅读(转摘)大赞

来源:互联网 发布:主流软件开发工具 编辑:程序博客网 时间:2024/06/07 01:00







http://blog.163.com/kefeng_1984/blog/static/16661527200967105748687/







博客 
发现
小组
风格
 
 
网易轻博客LOFTER
退出
反馈
 
消息(2) 
<div id="topbar_personalCenterArea" "="" class="nbw-im fr personalCenter" style="float: right; position: relative; zoom: 1; width: 94px; "> 个人中心 
 
使用此风格
 关注
引用
推荐
你敢来我就送!印像派照片券、DIY台历和马克杯,招行i理财通通免费送!   显示下一条  |  关闭http://blog.163.com/kefeng_1984/blog/static/16661527200967105748687/

“真情流露”你 我 他......

让我们从这里开始,为灾区的人民贡献我们的点滴力量。

  • 首页
  • 日志
  • 相册
  • 音乐
  • 收藏
  • 博友
  • 关于我
 
 
 
 
 

日志

 
 
驳倒一珂
  加博友   关注他
 
他的网易微博

最新日志

  • 线程守卫
  • 转帖:学士硕士博士毕业论文
  • 大学毕业生档案人事关系答疑
  • 从头学习Drupal--基本概念和
  • 如何测试摄像机(监控上使用
  • 红外摄像机

        随机阅读

        • 奥斯卡大奖揭晓,再看历年经典光影回放
        • 源远流长的官办工程采购怪相
        • 归真堂首个开放日 见证“活熊取胆”过程
        • 另类造型教母天后王菲全解读
        • 为公务车自主品牌化叫好
        • 企业安全不能“唯技术论”还要靠策略

        首页推荐

        • 婚前处女与不如婚后贞女
        • 女博士想抓住性福的烦恼
        • 日本女高中生性产业(图)
        • 北京经济抹杀外地人贡献
        • 中国乒乓居然输给印度人
        • 女生裸身跳楼与不慎坠楼
        更多>>


        VLC 学习计划---文档阅读(转摘)  

        2009-07-07 10:57:48|  分类: VLC|字号 订阅

        一 videolan-howto-en-html

        该文档完全描述了VideoLAN "流"的解决方法.

        VideoLAN 项目包括两个软件.

        1) VLC:以前是视频流接收的客户端,但是现在也可以作为服务端工作.

        2) VLS:视频服务端,能发送 MPEG-1, MPEG-2 and MPEG-4 files, DVDs, digital satellite channels, digital terrestial television channels and live videos on the network in unicast or multicast.

        1.VLC 在REDHAT 下的安装

        从下面的链接中下载 vlc的包和包所需要的库,把他们都放在同一个目录.

        http://www.videolan.org/vlc/download-redhat.html

        源代码安装:

        源代码安装需要的库如下:

        libdvbpsi (compulsory) ,

        mpeg2dec (compulsory) ,

        libdvdcss if you want to be able to read encrypted DVDs ,

        libdvdplay if you want to have DVD menu navigation ,

        a52dec if you want to be able to decode the AC3 (i.e. A52) sound format often used in DVDs ,

        ffmpeg, libmad, faad2 if you want to read MPEG 4 / DivX files ,

        libogg & libvorbis if you want to read Ogg Vorbis files .

        2.VLC在命令行下接收流

        Receive an unicast stream

        % vlc -vvv udp:

        Receive a multicast stream

        % vlc -vvv udp:@239.255.12.42

        where 239.255.12.42 is the multicast IP address you want to join.

        Receive an HTTP/FTP/MMS stream

        Use one of the following command lines:

        % vlc -vvv http://example/stream.xyz

        where http://example/stream.xyz is the HTTP address of the stream;

        % vlc -vvv ftp://example/stream.xyz

        where ftp://example/stream.xyz is the FTP address of the stream;

        % vlc -vvv ms://viptvr.yacast.fr/encoderfranceinfo

        where mms://viptvr.yacast.fr/encoderfranceinfo is the MMS address of the stream.

        Receive a RTP stream available through RTSP

        % vlc -vvv rtsp://www.hardradio.com/tonbeme.mov

        where rtsp://www.hardradio.com/tonbeme.mov is the address of the stream.

        Receive a stream described by an SDP file

        % vlc -vvv http://server.example.org/stream.sdp

        3.VLC在命令行下发送流

        % vlc -vvv video1.xyz --sout udp:192.168.0.42 --ttl 12

        where:

        *video1.xyz is the file you want to stream,

        *192.168.0.42 is either:

        o the IP address of the machine you want to unicast to;

        o or the DNS name the machine you want to unicast to;

        o or a multicast IP address.

        *12 is the value of the TTL (Time To Live) of your IP packets (which means that the stream will be able to cross 11 routers).

        If you want to stream the file continuously, add the --loop option.

        4.VLC 高级应用(VLC's stream output (transcoding, multiple streaming, etc...))

        语法: Please refer to the" command line interface" chapter of the "VLC user guide "to learn the syntax of VLC's stream output.

        例子:

        ----编码方面的例子

        Transcode the input stream and send it to a multicast IP address with the associated SAP announce:

        % vlc -vvv input_stream --sout '#transcode{vcodec=mp4v,acodec=mpga,vb=800,ab=128,deinterlace}:

        standard{access=udp,mux=ts,url=239.255.12.42,sap,name="TestStream"}'

        Display the input stream, transcode it and send it to a multicast IP address with the associated SAP announce:

        % vlc -vvv input_stream --sout '#duplicate{dst=display,dst=

        "transcode{vcodec=mp4v,acodec=mpga,vb=800,ab=128,deinterlace}:

        standard{access=udp,mux=ts,url=239.255.12.42,sap,name="TestStream"}"}'

        Transcode the input stream, display the transcoded stream and send it to a multicast IP address with the associated SAP announce:

        % vlc -vvv input_stream --sout '#transcode{vcodec=mp4v,acodec=mpga,vb=800,ab=128,deinterlace}:

        duplicate{dst=display,dst=standard{access=udp,mux=ts,url=239.255.12.42,sap,name="TestStream"}}'

        --多种流的例子

        Send a stream to a multicast IP address and a unicast IP address:

        % vlc -vvv input_stream --sout '#duplicate{dst=

        standard{access=udp,mux=ts,url=239.255.12.42,sap,name="TestStream"},

        dst=standard{access=udp,mux=ts,url=192.168.1.2}}'

        Display the stream and send it to two unicast IP addresses:

        % vlc -vvv input_stream --sout '#duplicate{dst=display,dst=

        standard{access=udp,mux=ts,url=192.168.1.12},

        dst=standard{access=udp,mux=ts,url=192.168.1.42}}'

        Send parts of a multiple program input stream:

        % vlc -vvv multiple_program_input_stream

        --sout '#duplicate{dst=standard{access=udp,mux=ts,url=239.255.12.42},select="program=12345",

        dst=standard{access=udp,mux=ts,url=239.255.12.43}, select="video,program=1234-2345"}'

        This command sends the program of the input stream which id is 12345 to 239.255.12.42 and all video programs with id between 1234 and 2345 to 239.255.12.43.

        Transcoding and multiple streaming

        Transcode the input stream, display the transcoded stream and send it to a multicast IP address with the associated SAP announce and an unicast IP address:

        % vlc -vvv input_stream --sout '#transcode{vcodec=mp4v,acodec=mpga,vb=800,ab=128,deinterlace}:

        duplicate{dst=display,dst=standard{access=udp,mux=ts,url=239.255.12.42,sap,name="TestStream"},

        dst=standard{access=udp,mux=ts,url=192.168.1.2}}'

        Display the input stream, transcode it and send it to two unicast IP addresses:

        % vlc -vvv input_stream --sout '#duplicate{dst=display,

        dst="transcode{vcodec=mp4v,acodec=mpga,vb=800,ab=128}:

        duplicate{dst=standard{access=udp,mux=ts,url=192.168.1.2},

        dst=standard{access=udp,mux=ts,url=192.168.1.12}"}'

        Send the input stream to a multicast IP address and the transcoded stream to another multicast IP address with the associated SAP announces:

        % vlc -vvv input_stream --sout '#duplicate{dst=

        standard{access=udp,mux=ts,url=239.255.1.2,sap,name="OriginalStream"},

        dst="transcode{vcodec=mp4v,acodec=mpga,vb=800,ab=128}:

        standard{access=udp,mux=ts,url=239.255.1.3,sap,name="TranscodedStream"}"}'

         二、二进制包安装及使用

        1.在RH9上的安装需要

             1).RH9的升级包.

             2).FC2的RPM包

            详细说明清参见:http://www.videolan.org/vlc/download-redhat.html

            以上VLC 版本为:0.7.2

        2.下载RH9的升级包

            http://download.videolan.org/pub/videolan/vlc/0.7.2/rpm/redhat/rh9/

        3.下载FC2的RPM包

          http://download.videolan.org/pub/videolan/vlc/0.7.2/rpm/fedora/fc2/

           二进制包为:  vlc-binary.tar.gz

        4.将RH9的升级包和 vlc-binary.tar.gz放在同一个目录.

           ~#tar -zxvf   vlc-binary.tar.gz

           ~#tar -zxvf   redhat9-updates.tar.gz

         5.安装

           ~#rpm -Uv  vlc/* --force --nodeps

        6.使用

            1) 在REDHAT->AUDIO AND VIDEO->VLAN MEDIA PLAYER 可以打开

             2)或者在BASH 中打开vlc,使用命令行选项直接启动,参见videolan-how-to-en.

        7.未测试出的功能

              在局域网内的同一网段内的两台PC上不能用MULTICAST 进行VIDEO

              传输.

        三、 VLC及其他播放器

        一.rm格式的播放器:

          下载地址:http://www.real.com/linux/?src=020923home_cn_cn

          安装方式:~#./realplayer.bin

                打开方式:

             命令行:~#realplay

                            GUI:redhat->audio and video->other app->realplayer  

        二.mp3 播放器:xmms-1.2.8.tar.gz

              安装方式:./configure & make &make install

        三. 经验:从源码编译安装Mplayer 1.0pre5

         来自:http://yangchengkai.blogchina.com/blog/refer.177855.html

          

          Mplayer/gmplayer是目前Linux下广范使用的媒体播放器,一个字--强!但由于它一般以Tarball的格式发布,安装比较BT,许多朋友都在找rpm的版本,但来源不同的rpm版本往往无法自己定制许多特性,比如中文支持等,而且容易造成rpm包的依赖问题,所以有不少朋友最终对 Mplayer又爱又恨...-_-!!

        其实自己编译mplayer并不是什么太难的事,只是过程比较麻烦,但基本还是遵循tarball的安装步骤,有关这个的文章Sir里已经有了不少,自己这篇就不打算往Sir里贴了,且留在这里和大家分享...:)

        首先是下载最新的mplayer的tarball,即1.0pre5:

        http://www4.mplayerhq.hu/homepage/design7/dload.html

        接下来是下载解码器包,一般只要下载Essential Codes就足够了,要放rmvb需要reallib的解码器,我一般用xine放rmvb:

        http://www4.mplayerhq.hu/homepage/design7/codecs.html

        还有mplayer的字体文件:

        http://www4.mplayerhq.hu/homepage/design7/dload.html

        这里大家不用到"其他字体"里下载中文字体,待会可以用simsun.ttf替代.

        当然,还要下载Skin文件给gmplayer用:

        http://ftp5.mplayerhq.hu/mplayer/Skin/

        建议用default blue或者neutron,当然,你也可以下载其他的Skin.

        我们先把下载的所有文件cp到/opt/目录下,然后开始具体安装步骤.

        1.首先安装解码器:

        tar -jxvf essential-20040916.tar.bz2

        tar -jxvf rp9codecs-20040626.tar.bz2

        cp -rf rp9codecs-20040626/* essential-20040916/

        mv essential-20040916 /usr/lib/codes

        以上命令把解码器包安装到了/usr/lib/codes,其实就是把解压后的目录ren&mv了过去.

        2.编译安装mplayer:

        tar -jxvf MPlayer-1.0pre5.tar.bz2

        cd MPlayer-1.0pre5

        ./configure --enable-gui --with-codecsdir=/usr/lib/codecs --with-win32libdir=/usr/lib/codecs --with-reallibdir=/usr/lib/codecs --language=zh_CN

        以上几个参数解释一下:

        --enable-gui:打开图形界面支持,就是gmplayer

        --with-codecsdir=/usr/lib/codecs:指明解码器的目录

        --with-win32libdir=/usr/lib/codecs:指明windows的媒体文件解码器目录位置

        --with-reallibdir=/usr/lib/codecs:指明real媒体文件的解码器目录位置,要用gmplayer放rmvb必须指定这条.

        --language=zh_CN:设定系统界面语言为中文

        在configure之前可以运行./configure --help查看支持的特性设定,可以根据自己需求选择,以上只是最基本的啦.

        make

        make install

        3.安装字体文件:

        tar -jxvf font-arial-iso-8859-1.tar.bz2

        mv font-arial-iso-8859-1/ /usr/local/share/mplayer/font/

        cd /usr/local/share/mplayer/font/

        如果你的系统用simsun美化过,则直接

        ln -s ***/simsun.ttf subfont.ttf

        注意,这里的***是指simsun的具体位置,为了保险起见,建议在~/.mplayer/里也做同样的链接.

        要是系统没有美化过,试试

        ln -s /usr/share/fonts/zh_CN/TrueType/gbsn001p.ttf subfont.ttf

        这样中文字幕就搞定了.

        4.安装Skin:

        超级简单,把skin包解压后mv到/usr/local/share/mplayer/Skin就可以了,注意一定要有一个skin叫做default,不然gmplayer无法运行.

        OK,目前为止所有工作结束,运行gmplayer/mplayer看看,Enjoy it!:)

        PS:要是你用xine,在setup里可以把codes的目录指定同mplayer一样,这样可以节省点空间^_^

        5.nvidia driver 驱动安装:

           下载:http://www.nvidia.com/object/linux_display_ia32_1.0-4363.html

            安装:

                      进入LEVEL 2  ,init 2

           配置: 在/etc/X11/XF86config

                   load 'nv'  改成 load 'nvidia'

                   load 'dri' 改成 load 'GLcore'

         在文字模式下:

        #vim /etc/X11/XF86Config

        找到Driver "nv",改为“nvidia”

        去除 Load "dri"

        Load "GLcore"

        保存后退出,再进入X桌面

        看到NVIDIA画面就OK了

          四、在EMACS中使用GDB调试

        一 .EMACS 中调试

          1、using the clipboard

                        M-x  menu-bar-enable-clipboard

                (make cut,copy,pasty menu items,use the clipboard)

          2、using “wheel”mice

                      M-x   mouse-wheel-mode

                 (激活中间的滚动键)

          3、退出出任何命令状态

                 C-g

         

          4、进入编译模式

               M-x  compile 或者从菜单-》TOOLS-》COMPILE

          5、用COMPILE 模式

               C-x  `       (搜索出错的源代码行)

               <RET>    (光标定位在compile buffer 的出错提示行上,按〈RET〉键,会跳到出错的源代码行)

              C-u C-x ` 在compile buffer 列出同样的错误。

           6、用GREP 搜索

               一、M-x grep    进入搜索

                      参数为 a grep-style regexp(using in single-quotes to quote the shell's special characters)follows bye file names;

               二、 C-x  `       (搜索出错的源代码行 --grep  搜索出来的同种错误)

                 <RET>    (光标定位在grep  buffer 的出错提示行上,按〈RET〉键,会跳到出错的源代码行)

        二、GUD 调试

           1、进入

                M-x gdb

           2、命令

                C-x <SPC>     在指针所在源代码行上设置断点

            说明 C-c 在GUD BUFFER,而C-x C-a 在gud buffer and source buffer 都行

            3、  C-c    C-l

                    C-x C-a   C-l   到达最后一行

            4、C-c   C-s

                  C-x C-a  C-s      gud-step

            5、C-c   C-n

                  C-x C-a  C-n      gud-next

             6、C-c C-r

                    C-x C-a  C-r  gud-cont  执行到下一个断点

              7、C-c  C-d

                    C-x C-a  C-d   gud-remove 删除当前断点

        三、GDB 命令

            1、调试命令

                  step         next          continue          untile

             2、设置断点

                   break file.c:foo

                   break  file.c:11

                   break +12

                   break -12        如果执行到某一行,+表示往前,-表示向后

                  断点信息

                     info breakpoint

                     enable <breakpoint number>

                     disable  <breakpoint number>

                    断点条件

                      break <args> if <cond>

                      condition <break number> <cond>

                      delete  breakpoints <break number> 

                     clear

            3、显示源代码

                   list 使用同断点

            4、查看变量

                  print /fmt  <expr>

             5、查看内存

                  x /<fmt>  <addr>

             6、切换目录

                     cd

             7、添加源文件路径

                   dir <path>

             8、显示

                   如果有    char msg[25];

                                   int *arr=(int *)mollac(len*sizeof(int));

          

                    则    display msg

                            display *arr@len

                     或者  p msg

                               p  *arr@len

                 9、跳转执行

                     jump linespec

                     jump  <addr>

        四、Makefile 文件

        //mt.h

        #ifdef _cplusplus

        extern "c" {

        #endif

        int add(int a,int b);

        int substract(int num,int n,int *ret);

        #ifdef _cplusplus

        }

        #endif

        -----------------------------------------------

        //math.c

        #include"mt.h"

        int add(int a,int b)

         {  return (a+b);}

        int subtract(int num,int n,int *ret)

        {*ret=num-n;

        return *ret;

        }

        -----------------------------------------------

        //msg.h

        #ifdef _cplusplus

        extern "c" {

        #endif

        void prnmsg(char *msg);

        #ifdef _cplusplus

        }

        #endif

        -----------------------------------------------

        //msg.c

        #include<stdio.h>

        #include"msg.h"

        void prnmsg(char * msg)

        {  printf("%s\n",msg);}

        -----------------------------------------------

        //comm.h

        #include"mt.h"

        #include"msg.h"

        -----------------------------------------------

        //vlc.c

        #include<stdlib.h>

        #include<stdio.h>

        #include"comm.h"

        int main(int argc,char *argv[])

        {

           int i,j,sum;

           int *p_iret;

         

          char  msg[256];

            printf("hellow,this is a test program\n");

           

            i=15;

            j=10;

            sum=add(i,j);

          

           sprintf(msg,"number=%d",sum);

            prnmsg(msg);

         

           subtract(i,j,p_iret);

           sprintf(msg,"substract=%d",*p_iret);

           prnmsg(msg);

           

           sprintf(msg,"this has modify=%d",*p_iret);

           prnmsg(msg);

           return 0;

        }

        -----------------------------------------------

        //Makefile

        vlc:vlc.o math.o msg.o

            gcc -g -o $@ vlc.o  math.o msg.o

        math.o:math.c mt.h

            gcc -g -c -o $@ math.c

        msg.o:msg.c msg.h

            gcc -g -c msg.c

        vlc.o:vlc.c comm.h

            gcc -g -c  vlc.c

        clean:

            rm -rvf msg.o math.o vlc.o vlc

         

        vlc学习计划(5)--VLC程序宏及线程分析

        第一部分             变量及宏定义

        1.消息映射宏

                               vlc_module_begin();

                                   …………………..

        vlc_module_end();

        2.结构中包含函数

               struct input_thread_t

        {

            VLC_COMMON_MEMBERS

         

            /* Thread properties */

            vlc_bool_t              b_eof;

            vlc_bool_t              b_out_pace_control;

         

            /* Access module */

            module_t *       p_access;

            ssize_t       (* pf_read ) ( input_thread_t *, byte_t *, size_t );

            int           (* pf_set_program )( input_thread_t *, pgrm_descriptor_t * );

            int           (* pf_set_area )( input_thread_t *, input_area_t * );

            void          (* pf_seek ) ( input_thread_t *, off_t );

        }

        3.宏与换行符妙用

        #define VLC_COMMON_MEMBERS                                                  \

        /** \name VLC_COMMON_MEMBERS                                                \

         * these members are common for all vlc objects                             \

         */                                                                         \

        /**@{*/                                                                     \

            int   i_object_id;                                                      \

            int   i_object_type;                                                    \

            char *psz_object_type;                                                  \

            char *psz_object_name;                                                  \

                                                                                                       \

         /** Just a reminder so that people don't cast garbage */                \

            int be_sure_to_add_VLC_COMMON_MEMBERS_to_struct;                        \

        /**@}*/                   

         

        #define VLC_OBJECT( x ) \

        ((vlc_object_t *)(x))+

        0*(x)->be_sure_to_add_VLC_COMMON_MEMBERS_to_struct

         

        struct vlc_object_t

        {

            VLC_COMMON_MEMBERS

        };//定义一个结构来使用宏定义的公共成员

         

        4.定义导出函数

        #ifndef __PLUGIN__

        #   define VLC_EXPORT( type, name, args ) type name args

        #else

        #   define VLC_EXPORT( type, name, args ) struct _u_n_u_s_e_d_

            extern module_symbols_t* p_symbols;

        #endif

        5.定义回调函数

         

        typedef int ( * vlc_callback_t ) ( vlc_object_t *,      /* variable's object */

                                           char const *,            /* variable name */

                                           vlc_value_t,                 /* old value */

                                           vlc_value_t,                 /* new value */

         

                                           void * );                /* callback data */                                                

         

        6.函数作为参数的定义方式

             Int Fun(int n,int (*pf)(int ,int),char *pstr)

        {   int j =10;

        pf(n,j);

        }

         

        7.回调函数的声明

        必须声明为global,或者static

         

        Int   vlc_callback_t (int ,int)

        {。。。。。。。。。。。}

              

        8.回调函数的使用

               Fun(0, vlc_callback_t,"test");

         

        9.函数表达式

        #define input_BuffersInit(a) __input_BuffersInit(VLC_OBJECT(a))

        void * __input_BuffersInit( vlc_object_t * );

         

        #define module_Need(a,b,c,d) __module_Need(VLC_OBJECT(a),b,c,d)

        VLC_EXPORT( module_t *, __module_Need, ( vlc_object_t *, const char *, const char *, vlc_bool_t ) );

         

        10.定义函数

           /* Dynamic array handling: realloc array, move data, increment position */

        #define INSERT_ELEM( p_ar, i_oldsize, i_pos, elem )                           \

            do                                                                        \

            {                                                                         \

                if( i_oldsize )                                                       \

                {                                                                     \

                    (p_ar) = realloc( p_ar, ((i_oldsize) + 1) * sizeof( *(p_ar) ) );  \

                }                                                                     \

                else                                                                  \

                {                                                                     \

                    (p_ar) = malloc( ((i_oldsize) + 1) * sizeof( *(p_ar) ) );         \

                }                                                                     \

                if( (i_oldsize) - (i_pos) )                                           \

                {                                                                     \

                    memmove( (p_ar) + (i_pos) + 1,                                    \

                             (p_ar) + (i_pos),                                        \

                             ((i_oldsize) - (i_pos)) * sizeof( *(p_ar) ) );           \

                }                                                                     \

                (p_ar)[i_pos] = elem;                                                 \

                (i_oldsize)++;                                                        \

            }                                                                         \

            while( 0 )

         

         

        应用为:

             INSERT_ELEM( p_new->p_libvlc->pp_objects,

                             p_new->p_libvlc->i_objects,

                             p_new->p_libvlc->i_objects,

                             p_new );

         

         

        11.改变地址的方式传递其值

        stream_t *input_StreamNew( input_thread_t *p_input )

        {    stream_t *s = vlc_object_create( p_input, sizeof( stream_t ) );

            input_stream_sys_t *p_sys;

            if( s )

            {

                s->p_sys = malloc( sizeof( input_stream_sys_t ) );

                p_sys = (input_stream_sys_t*)s->p_sys;

                p_sys->p_input = p_input;

            }

        return s;//注解:s->p_sys改变了

        }

         

                                    第二部分  程序框架实现

        1. 播放列表文件src/playlist/playlist.c的线程

        playlist_t * __playlist_Create ( vlc_object_t *p_parent )函数中创建的线程,线程函数为

        static void RunThread ( playlist_t *p_playlist )

           线程思路分析:

             在RunThread里面执行循环,如果没有任务执行,则适当的延迟,如果接到p_playlist->i_status != PLAYLIST_STOPPED的条件,则调用PlayItem( p_playlist )函数,在PlayItem( p_playlist )函数中从新创建输入线程。

         

        通过void playlist_Command( playlist_t * p_playlist, playlist_command_t i_command,int i_arg )接收来自GUI界面的各种命令,然后设置p_playlist->i_status的状态,由该状态改变该播放列表文件主循环线程的执行。

         

        2. 输入文件SRC/INPUT/INPUT.C的输入线程

            input_thread_t *__input_CreateThread( vlc_object_t *p_parent,

                                              input_item_t *p_item )函数中创建的线程,线程函数为

        static int RunThread( input_thread_t *p_input )

           线程思路分析:

        由 input_thread_t结构的成员分析是接收文件流还是网络流,如果是文件流,则调用file module 的读函数(pf_read)和打开函数(--).如果是network 则打开network   module 的打开函数和读函数(pf_read)。

            在 RunThread线程函数中接收数据和调用demux 或者decode etc处理。

        一旦产生新的输入,则在播放列表线程中会首先结束该输入线程,然后从新创建新的输入线程。

         

        3. 视频输出文件src/video_output/ video_output.c的线程

        vout_thread_t * __vout_Create( vlc_object_t *p_parent,

                                       unsigned int i_width, unsigned int i_height,

                                       vlc_fourcc_t i_chroma, unsigned int i_aspect )函数中创建的线程,线程函数为

        static void RunThread( vout_thread_t *p_vout)

        线程思路分析:

             在RunThread里面执行循环,任务是显示视频。

         

        4. 在modules\gui\wxwindows\wxwindows.cpp中的GUI线程

         static void Run( intf_thread_t *p_intf ) 函数中创建的线程,线程函数为

                     static void Init( intf_thread_t *p_intf )

         

        线程思路分析:

             在Init( intf_thread_t *p_intf )里面执行循环,创建新的GUI实例。Instance-》OnInit()(CreateDialogsProvider)-》DialogsProvider为运行的对话框。

         

             接收网络文件的步骤

        OnOpenNet( wxCommandEvent& event )打开网络文件的步骤。打开OpenDialog对话框,点击Ok后调用OpenDialog::OnOk( wxCommandEvent& WXUNUSED(event) )函数,调用playlist_Command函数改变播放列表线程的状态。

         

          激活线程分析:

                 在wxwindow.cpp中的消息映射中 set_callbacks( OpenDialogs, Close ); 则设置了module_t->pf_activate= OpenDialogs函数,

                在module.c 的__module_Need( vlc_object_t *p_this, const char *psz_capability,

                                  const char *psz_name, vlc_bool_t b_strict )

        函数中用到了pf_activate激活GUI对话框;

            在video_output.c 的static void RunThread( vout_thread_t *p_vout)线程中,也用到了pf_activate激活GUI对话框;

         

         

        5. 开始所有module 的精髓

                 消息映射宏

                               vlc_module_begin();

                                  set_callbacks( NetOpen, NULL );

        vlc_module_end();

        然后设置模块结构的成员函数为:

        #define set_callbacks( activate, deactivate )                                 \

                       p_submodule->pf_activate = activate;                                      \

                         p_submodule->pf_deactivate = deactivate

         

        在__module_Need函数中启动pf_activate  激活相应的module。

         

         

        1. 我的理解:

        macro of message map

         

        2./*********

        *定义一个公共的结构

        *并把激活本模块的函数传给该结构的函数成员

        ************************/

        vlc_module_begin();

        set_callbacks( NetOpen, NULL );

        vlc_module_end();

         

        设置模块结构的pf_activate成员函数为NetOpen:

        #define set_callbacks( activate, deactivate ) \

        p_submodule->pf_activate = activate; \

        p_submodule->pf_deactivate = deactivate

         

        所以当通过函数module_need激活模块的时候,就是通过pf_activate来启动模块的!

        vlc_module_begin()起到了一个消息传递的作用!

         

        vlc学习计划(6)--网络数据流接收处理过程分析

        网络数据流接收处理分析

         

        1、在input.c(src\input)文件中的主线程循环

         

              Thread in charge of processing the network packets and demultiplexing

         

        RunThread( input_thread_t *p_input )

         

        {

         

                  InitThread( p_input ) ;

         

        …………………………………………………….

         

             input_SelectES( p_input, p_input->stream.p_newly_selected_es );

         

                      …………………………………………………….

         

              /* Read and demultiplex some data. */

         

             i_count = p_input->pf_demux( p_input );

         

         

         

        }

         

        2、在下列函数中:

         

        分离出access  , demux  , name字符串 ;

        根据分离出的access  字符串通过module_Need函数找到acess 指针模块;

        根据分离出的demux  字符串通过module_Need函数找到demux  指针模块;

         static int InitThread( input_thread_t * p_input )

         

        {

         

             msg_Dbg( p_input, "access `%s', demux `%s', name `%s'",

         

                     p_input->psz_access, p_input->psz_demux, p_input->psz_name );

         

         

         

            /* Find and open appropriate access module */

         

            p_input->p_access = module_Need( p_input, "access",

         

                                             p_input->psz_access, VLC_TRUE );

         

         …………………………………………………….

         

          while( !input_FillBuffer( p_input ) )

         

          …………………………………………………….

         

            /* Find and open appropriate demux module */

         

            p_input->p_demux =

         

                module_Need( p_input, "demux",

         

                             (p_input->psz_demux && *p_input->psz_demux) ?

         

                             p_input->psz_demux : "$demux",

         

                             (p_input->psz_demux && *p_input->psz_demux) ?

         

                             VLC_TRUE : VLC_FALSE );

         

        …………………………………………………….

         

        }

         

        3、在ps.c (module\demux\mpeg)文件中

         

        a.通过消息映射宏赋值启动函数Activate;

         

        b.通过函数Activate赋值p_input->pf_demux = Demux;

         

        c. 通过函数module_Need( p_input, "mpeg-system", NULL, 0 ) 激活p_input->p_demux_data->mpeg.pf_read_ps( p_input, &p_data )函数(pf_read_ps);

         

        d.在InitThread函数中激活;

         

         

         

                static int Activate( vlc_object_t * p_this )

         

        {

         

              /* Set the demux function */

         

        p_input->pf_demux = Demux;

         

        p_input->p_private = (void*)&p_demux->mpeg;

         

            p_demux->p_module = module_Need( p_input, "mpeg-system", NULL, 0 );

         

        }

         

        4、在system.c (module\demux\mpeg)文件中

         

                 赋值解码模块mpeg_demux_t的成员函数;

         

             static int Activate ( vlc_object_t *p_this )

         

        {

         

            static mpeg_demux_t mpeg_demux =

         

                            { NULL, ReadPS, ParsePS, DemuxPS, ReadTS, DemuxTS };

         

            mpeg_demux.cur_scr_time = -1;

         

            memcpy( p_this->p_private, &mpeg_demux, sizeof( mpeg_demux ) );

         

         

         

            return VLC_SUCCESS;

         

        }

         

        并且申明函数static ssize_t ReadPS( input_thread_t * p_input, data_packet_t ** pp_data );

         

         

         

        5、在ps.c (module\demux\mpeg)文件中

         

        Demux( input_thread_t * p_input )

         

        {

         

        i_result = p_input->p_demux_data->mpeg.pf_read_ps( p_input, &p_data );

         

              p_input->p_demux_data->mpeg.pf_demux_ps( p_input, p_data );

         

        }

         

        进行读取数据和分离工作;

         

        6、在system.c (module\demux\mpeg)文件中

         

        数据走向图如下

         

        ReadPS-> PEEK-> input_Peek(src\input\input_ext-plugins.c)-> input_FillBuffert 通过 i_ret = p_input->pf_read( p_input,

         

                                      (byte_t *)p_buf + sizeof(data_buffer_t)

         

                                       + i_remains,

         

                                      p_input->i_bufsize );

         

        input_thread_t结构的pf_read函数成员如果是为udp.c(modules\access)的RTPChoose函数

         

        则在开启access(UDP 模块)时通过module_need 激活;

         

         激活网络读数据模块 RTPChoose(modules\access\ udp.c)->Read->net_Read(src\misc\net.c);

         

         

         

        7、在input_programs.c(src\input)文件中

         

                 运行解码器对ES流解码

         

           int input_SelectES( input_thread_t * p_input, es_descriptor_t * p_es )

         

        {

         

              p_es->p_dec = input_RunDecoder( p_input, p_es );

         

          

         

        }

         

         input_SelectES(src\input\input_programs.c)->input_RunDecoder(src\input\input_dec.c)->DecoderThread->DecoderDecode ->vout_DisplayPicture

        vlc学习计划(7)--从接收到数据流到播放视频的过程分析

        从接收到数据流到播放视频的过程分析

         

           从网络接收到流->对数据流进行视频和音频分离->对视频用解码器解码->显示解码后的视频流

         

         

         

            视频显示部分走势线:分离->解码->新的VOUT缓冲区->VOUT线程

         

        Demux(modules\demux\mpeg\ps.c)->DemuxPs(modules\demux\mpeg\system.c)-> ParsePS->input_SelectES(src\input\input_programs.c)->input_RunDecoder(src\input\input_dec.c)->CreateDecoder->

         

        vout_new_buffer->vout_Request(src\video_output\video_output.c)->vout_Create->RunThread->vout_RenderPicture(src\video_output\vout_pictures.c)->pf_display

         

         

         

        注意:p_dec->pf_vout_buffer_new = vout_new_buffer的pf_vout_buffer_new在ffmpeg_NewPictBuf(modules\codec\ffmpeg\video.c)函数中激活

         

         

         

           解码部分走势线:

         

        Demux(modules\demux\mpeg\ps.c)->DemuxPs(modules\demux\mpeg\system.c)-> ParsePS->input_SelectES(src\input\input_programs.c)->input_RunDecoder(src\input\input_dec.c)->CreateDecoder->

         

        DecoderThread

         

          注意:在解码线程中对数据流(AUDIO 或者VIDEO)进行解码

         

        详细资料 http://developers.videolan.org/vlc/    VLC API documentation  或者VLC developer documentation

         

         

         

        Chapter 5.  The video output layer

        Data structures and main loop

        Important data structures are defined in include/video.h and include/video_output.h. The main data structure is picture_t, which describes everything a video decoder thread needs. Please refer to this file for more information. Typically, p_data will be a pointer to YUV planar picture.

         

        Note also the subpicture_t structure. In fact the VLC SPU decoder only parses the SPU header, and converts the SPU graphical data to an internal format which can be rendered much faster. So a part of the "real" SPU decoder lies in src/video_output/video_spu.c.

         

        The vout_thread_t structure is much more complex, but you needn't understand everything. Basically the video output thread manages a heap of pictures and subpictures (5 by default). Every picture has a status (displayed, destroyed, empty...) and eventually a presentation time. The main job of the video output is an infinite loop to : [this is subject to change in the near future]

         

        Find the next picture to display in the heap.

         

        Find the current subpicture to display.

         

        Render the picture (if the video output plug-in doesn't support YUV overlay). Rendering will call an optimized YUV plug-in, which will also do the scaling, add subtitles and an optional picture information field.

         

        Sleep until the specified date.

         

        Display the picture (plug-in function). For outputs which display RGB data, it is often accomplished with a buffer switching. p_vout->p_buffer is an array of two buffers where the YUV transform takes place, and p_vout->i_buffer_index indicates the currently displayed buffer.

         

        Manage events.

         

        Methods used by video decoders

        The video output exports a bunch of functions so that decoders can send their decoded data. The most important function is vout_CreatePicture which allocates the picture buffer to the size indicated by the video decoder. It then just needs to feed (void *) p_picture->p_data with the decoded data, and call vout_DisplayPicture and vout_DatePicture upon necessary.

         

        picture_t * vout_CreatePicture ( vout_thread_t *p_vout, int i_type, int i_width, int i_height ) : Returns an allocated picture buffer. i_type will be for instance YUV_420_PICTURE, and i_width and i_height are in pixels.

         

        Warning

        If no picture is available in the heap, vout_CreatePicture will return NULL.

         

        vout_LinkPicture ( vout_thread_t *p_vout, picture_t *p_pic ) : Increases the refcount of the picture, so that it doesn't get accidently freed while the decoder still needs it. For instance, an I or P picture can still be needed after displaying to decode interleaved B pictures.

         

        vout_UnlinkPicture ( vout_thread_t *p_vout, picture_t *p_pic ) : Decreases the refcount of the picture. An unlink must be done for every link previously made.

         

        vout_DatePicture ( vout_thread_t *p_vout, picture_t *p_pic ) : Gives the picture a presentation date. You can start working on a picture before knowing precisely at what time it will be displayed. For instance to date an I or P picture, you must wait until you have decoded all previous B pictures (which are indeed placed after - decoding order != presentation order).

         

        vout_DisplayPicture ( vout_thread_t *p_vout, picture_t *p_pic ) : Tells the video output that a picture has been completely decoded and is ready to be rendered. It can be called before or after vout_DatePicture.

         

        vout_DestroyPicture ( vout_thread_t *p_vout, picture_t *p_pic ) : Marks the picture as empty (useful in case of a stream parsing error).

         

        subpicture_t * vout_CreateSubPicture ( vout_thread_t *p_vout, int i_channel, int i_type ) : Returns an allocated subpicture buffer. i_channel is the ID of the subpicture channel, i_type is DVD_SUBPICTURE or TEXT_SUBPICTURE, i_size is the length in bytes of the packet.

         

        vout_DisplaySubPicture ( vout_thread_t *p_vout, subpicture_t *p_subpic ) : Tells the video output that a subpicture has been completely decoded. It obsoletes the previous subpicture.

         vout_DestroySubPicture ( vout_thread_t *p_vout, subpicture_t *p_subpic ) : Marks the subpicture as empty.

        分享到:         
        阅读(1034)| 评论(0)| 引用 (0) |举报

        相关文章

        • vlc学习计划(5)--VLC程序宏及线程分析2010-08-27 10:10:10
        • vlc学习计划(6)--网络数据流接收处理过程分析2010-08-27 10:11:00

        最近读者

        jack_incredible
        jack_inc
         
        panhw1755
        panhw175
         
        luckxiaoyong83
        luckxiao
         
        pipiy2011
        pipiy201
         
        薄冰藕荷
        薄冰藕荷
         
        wyf1554
        wyf1554
         
        eeillc
        eeillc
         
        hkxljt
        hkxljt

        评论

        jack_incredible
         
        网易微博
         
         
         
         
         
         
         
         
         
         
         
        公司简介 - 联系方法 - 招聘信息 - 客户服务 - 隐私政策 - 博客风格 - 手机博客 - VIP博客 - 订阅此博客

        网易公司版权所有 ©1997-2012



        原创粉丝点击