青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

ts,ps,mpeg2 decoder and analysis

mepg 2, iptv, stream parse,mov,mxf,gxf,ac3,aac

  C++博客 :: 首頁 :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理 ::
  21 隨筆 :: 0 文章 :: 54 評論 :: 0 Trackbacks


 第一部分 變量及宏定義
  1.消息映射宏
   vlc_module_begin();
   …………………..
  vlc_module_end();
  2.結(jié)構(gòu)中包含函數(shù)
   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
  };//定義一個結(jié)構(gòu)來使用宏定義的公共成員
  4.定義導(dǎo)出函數(shù)
  #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.定義回調(diào)函數(shù)
  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.函數(shù)作為參數(shù)的定義方式
   Int Fun(int n,int (*pf)(int ,int),char *pstr)
  { int j =10;
  pf(n,j);
  }
  7.回調(diào)函數(shù)的聲明
  必須聲明為global,或者static
  Int vlc_callback_t (int ,int)
  {。。。。。。。。。。。}
  
  8.回調(diào)函數(shù)的使用
   Fun(0, vlc_callback_t,”test”);
  9.函數(shù)表達(dá)式
  #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.定義函數(shù)
   /* 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 )
  應(yīng)用為:
   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改變了
  }
   第二部分 程序框架實(shí)現(xiàn)
  1.播放列表文件src/playlist/playlist.c的線程
  playlist_t * __playlist_Create ( vlc_object_t *p_parent )函數(shù)中創(chuàng)建的線程,線程函數(shù)為
  static void RunThread ( playlist_t *p_playlist )
   線程思路分析:
   在RunThread里面執(zhí)行循環(huán),如果沒有任務(wù)執(zhí)行,則適當(dāng)?shù)难舆t,如果接到p_playlist- i_status != PLAYLIST_STOPPED的條件,則調(diào)用PlayItem(

p_playlist )函數(shù),在PlayItem( p_playlist )函數(shù)中從新創(chuàng)建輸入線程。
  通過void playlist_Command( playlist_t * p_playlist, playlist_command_t i_command,int i_arg )接收來自GUI界面的各種命令,然后設(shè)置p_playlist-

i_status的狀態(tài),由該狀態(tài)改變該播放列表文件主循環(huán)線程的執(zhí)行。
  2.輸入文件SRC/INPUT/INPUT.C的輸入線程
   input_thread_t *__input_CreateThread( vlc_object_t *p_parent,
   input_item_t *p_item )函數(shù)中創(chuàng)建的線程,線程函數(shù)為
  static int RunThread( input_thread_t *p_input )
   線程思路分析:
  由 input_thread_t結(jié)構(gòu)的成員分析是接收文件流還是網(wǎng)絡(luò)流,如果是文件流,則調(diào)用file module 的讀函數(shù)(pf_read)和打開函數(shù)(--).如果是network 則打

開network module 的打開函數(shù)和讀函數(shù)(pf_read)。
   在 RunThread線程函數(shù)中接收數(shù)據(jù)和調(diào)用demux 或者decode etc處理。
  一旦產(chǎn)生新的輸入,則在播放列表線程中會首先結(jié)束該輸入線程,然后從新創(chuàng)建新的輸入線程。
  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 )函數(shù)中創(chuàng)建的線程,線程函數(shù)為
  static void RunThread( vout_thread_t *p_vout)
  線程思路分析:
   在RunThread里面執(zhí)行循環(huán),任務(wù)是顯示視頻。
  4.在modules\gui\wxwindows\wxwindows.cpp中的GUI線程
  static void Run( intf_thread_t *p_intf ) 函數(shù)中創(chuàng)建的線程,線程函數(shù)為
   static void Init( intf_thread_t *p_intf )
  線程思路分析:
   在Init( intf_thread_t *p_intf )里面執(zhí)行循環(huán),創(chuàng)建新的GUI實(shí)例。Instance-》OnInit()(CreateDialogsProvider)-》DialogsProvider為運(yùn)行的對話

框。
   接收網(wǎng)絡(luò)文件的步驟
  OnOpenNet( wxCommandEvent& event )打開網(wǎng)絡(luò)文件的步驟。打開OpenDialog對話框,點(diǎn)擊Ok后調(diào)用OpenDialog::OnOk( wxCommandEvent& WXUNUSED(event)

)函數(shù),調(diào)用playlist_Command函數(shù)改變播放列表線程的狀態(tài)。
   激活線程分析:
   在wxwindow.cpp中的消息映射中 set_callbacks( OpenDialogs, Close ); 則設(shè)置了module_t- pf_activate= OpenDialogs函數(shù),
   在module.c 的__module_Need( vlc_object_t *p_this, const char *psz_capability,
   const char *psz_name, vlc_bool_t b_strict )
  函數(shù)中用到了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();
  然后設(shè)置模塊結(jié)構(gòu)的成員函數(shù)為:
  #define set_callbacks( activate, deactivate ) p_submodule- pf_activate = activate; p_submodule- pf_deactivate = deactivate
  在__module_Need函數(shù)中啟動pf_activate 激活相應(yīng)的module。


網(wǎng)絡(luò)數(shù)據(jù)流接收處理分析
  1、在input.c(src\input)文件中的主線程循環(huán)
   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、在下列函數(shù)中:
  分離出access , demux , name字符串 ;
  根據(jù)分離出的access 字符串通過module_Need函數(shù)找到acess 指針模塊;
  根據(jù)分離出的demux 字符串通過module_Need函數(shù)找到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.通過消息映射宏賦值啟動函數(shù)Activate;
  b.通過函數(shù)Activate賦值p_input->pf_demux = Demux;
  c. 通過函數(shù)module_Need( p_input, "mpeg-system", NULL, 0 ) 激活p_input->p_demux_data->mpeg.pf_read_ps( p_input, &p_data )函數(shù)(pf_read_ps)

;
  d.在InitThread函數(shù)中激活;
   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的成員函數(shù);
   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;
  }
  并且申明函數(shù)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 );
  }
  進(jìn)行讀取數(shù)據(jù)和分離工作;
  6、在system.c (module\demux\mpeg)文件中
  數(shù)據(jù)走向圖如下
  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結(jié)構(gòu)的pf_read函數(shù)成員如果是為udp.c(modules\access)的RTPChoose函數(shù)
  則在開啟access(UDP 模塊)時(shí)通過module_need 激活;
  激活網(wǎng)絡(luò)讀數(shù)據(jù)模塊 RTPChoose(modules\access\ udp.c)->Read->net_Read(src\misc\net.c);
  7、在input_programs.c(src\input)文件中
   運(yùn)行解碼器對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

 


從接收到數(shù)據(jù)流到播放視頻的過程分析

   從網(wǎng)絡(luò)接收到流->對數(shù)據(jù)流進(jìn)行視頻和音頻分離->對視頻用解碼器解碼->顯示解碼后的視頻流

 

    視頻顯示部分走勢線:分離->解碼->新的VOUT緩沖區(qū)->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)函數(shù)中激活

 

   解碼部分走勢線:

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

  注意:在解碼線程中對數(shù)據(jù)流(AUDIO 或者VIDEO)進(jìn)行解碼

詳細(xì)資料 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]

   1.

      Find the next picture to display in the heap.
   2.

      Find the current subpicture to display.
   3.

      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.
   4.

      Sleep until the specified date.
   5.

      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.
   6.

      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.

 


VLC(五) 視頻播放的基本原理

    當(dāng)初Roger看VLC代碼花了不少時(shí)間,其中很大的原因是不太了解視頻播放的基本原理。現(xiàn)在看來,幾乎所有的視頻播放器,如VLC、MPlayer、 Xine,包括

DirectShow,在播放視頻的原理和架構(gòu)上都是非常相似的,理解這個對理解VLC的源碼會有事半功倍的效果。

    大致的來說,播放一個視頻分為4個步驟:

    1.  acess 訪問,或者理解為接收、獲取、得到

    2. demux 解復(fù)用,就是把通常合在一起的音頻和視頻分離(還有可能的字幕)  

    3. decode 解碼,包括音頻和視頻的解碼

    4. output 輸出,也分為音頻和視頻的輸出(aout和vout)

    拿播放一個UDP組播的MPEG TS流來說吧,access部分負(fù)責(zé)從網(wǎng)絡(luò)接收組播流,放到VLC的內(nèi)存緩沖區(qū)中,access模塊關(guān)注IP協(xié)議,如是否IPv6、組播地址、組

播協(xié)議、端口等信息;如果檢測出來是RTP協(xié)議(RTP協(xié)議在UDP頭部簡單得加上了固定12個字節(jié)的信息),還要分析RTP頭部信息。這部分可以參看VLC源碼

/modules/access/udp.c 。在同目錄下還可以看到大量的access模塊,如file、http、dvd、ftp、smb、tcp、dshow、mms、v4l…等等

    而demux部分首先要解析TS流的信息。TS格式是MPEG2協(xié)議的一部分,概括地說,TS通常是固定188字節(jié)的一個packet,一個TS流可以包含多個program(節(jié)目)

,一個program又可以包含多個視頻、音頻、和文字信息的ES流;每個ES流會有不同的PID標(biāo)示。而又為了可以分析這些ES流,TS有一些固定的PID用來間隔發(fā)送

program和es流信息的表格:PAT和PMT表。關(guān)于TS格式的詳細(xì)信息可以去google一下。

    VLC專門做了一個獨(dú)立的庫libdvbpsi來解析和編碼TS流,而調(diào)用它的代碼可以參見VLC源碼 /modules/demux/ts.c。

    其實(shí)之所以需要demux,是因?yàn)橐粢曨l在制作的時(shí)候?qū)嶋H上都是獨(dú)立編碼的,得到的是分開的數(shù)據(jù),為了傳輸方便必須要用某種方式合起來,這就有了各種封

裝格式也就有了demux。

    demux分解出來的音頻和視頻流分別送往音頻解碼器和視頻解碼器。因?yàn)樵嫉囊粢曨l都是占用大量空間,而且冗余度較高的數(shù)據(jù),通常在制作的時(shí)候就會進(jìn)

行某種壓縮。這就是我們熟知的音視頻編碼格式,包括MPEG1(VCD)、MPEG2(DVD)、MPEG4、H.264、rmvb等等。音視頻解碼器的作用就是把這些壓縮了的數(shù)據(jù)還

原成原始的音視頻數(shù)據(jù)。VLC解碼MPEG2使用了一個獨(dú)立的庫libmpeg2,調(diào)用它的源文件是 /modules/codec/libmpeg2.c。VLC關(guān)于編解碼的模塊都放

在/modules/codec目錄下,其中包括著名的龐大的 ffmpeg。

    解碼器,例如視頻解碼器輸出的是一張一張的類似位圖格式的圖像,但是要讓人從屏幕看得到,還需要一個視頻輸出的模塊。當(dāng)然可以像一個Win32窗口程序

那樣直接把圖像畫到窗口DC上——VLC的一個輸出模塊WinGDI就是這么干的,但是通常這太慢了,而且消耗大量的CPU。在Windows下比較好的辦法是用DirectX的接

口,會自動調(diào)用顯卡的加速功能。

    這樣的功能分解使得模塊化更容易一點(diǎn),每個模塊住需要專注于自己的事;從整體來說功能強(qiáng)大而且靈活。

    但是事情總是不會那么簡單。就拿access來說,媒體的訪問是分層的,如RTSP就涉及到IPv4、TCP、UDP、RTCP、RTSP等多個層次的協(xié)議。有些視頻格式包括了

傳輸、封裝格式和編輯碼格式如MPEG系列,有些封裝格式是獨(dú)立的容器,但是很多人會誤解它是編解碼格式,如mkv、avi這些。

    音頻和視頻在demux之后就是獨(dú)立的,但是需要有一套機(jī)制把它們同步起來。同時(shí)我們需要有一套機(jī)制來控制速度、暫停、停止、跳進(jìn),獲取各種媒體信息,

這些都是很復(fù)雜而又很重要的事情。

    另外也許需要在某個地方插入一些修改,來實(shí)現(xiàn)某種效果。如音頻的EQ,視頻的亮度調(diào)整之類的,VLC專門設(shè)計(jì)了access_filter、audio_filter和

video_filter類型的模塊來做這一類事情。

    VLC比較獨(dú)特的地方是集成了原來的VLS的功能,這依賴于VLC中stream_output類型的模塊,它們可以把正在播放的視頻以某種方式重新轉(zhuǎn)碼和發(fā)送出去,如

http、UDP、文件等等。

    MPlayer的結(jié)構(gòu)與此是類似的,如/stream目錄對應(yīng)的是access的功能,/mpdemux對應(yīng)的demux功能,/libmpcodecs是解碼器,/libvo和/libao2分別是視頻和音

頻的輸出。

    DirectShow也是類似的,不過分類更多一些更復(fù)雜一點(diǎn)。DirectShow里面的模塊叫做“filter”,filter之間通過”pin”來連接。access的模塊對應(yīng)于

DirectShow中的Source FIlter,這一類Filter只有輸出pin沒有輸入pin。demux模塊對應(yīng)于splitter filter,這種filter有一個輸入pin,多個輸出pin。解碼模

塊是一類transform filter,有一個輸入pin、一個輸出pin,輸出模塊對應(yīng)于readering filter,有一個輸入pin,沒有輸出pin。當(dāng)然transform filter不一定是

解碼器,也可能是某種其他的處理。

    回到VLC的話題。每一類的模塊數(shù)量都很多,那么在打開某一個視頻時(shí),VLC如何決定采用哪一個呢?哈哈,這個以后再說 ^_^

    另外給出一個VLC的API Document,有點(diǎn)老了不過挺值得一看的,在VLC wiki上找不到了,就貼出來:http://rogerfd.cn/doc/vlcapi.htm

  

————————————————————————

作者: roger

Blog: http://rogerfd.cn

Email:roger99707@163.com

本文歡迎轉(zhuǎn)載和引用,請保留本說明并注明出處



TS,MPEG2,dvbc專家 2009-10-16 09:16 發(fā)表評論

文章來源:http://www.cnitblog.com/dvb-dvb/archive/2009/10/16/61895.html
posted on 2009-10-16 09:16 TS,MPEG2,dvbc專家 閱讀(1905) 評論(0)  編輯 收藏 引用

只有注冊用戶登錄后才能發(fā)表評論。
網(wǎng)站導(dǎo)航: 博客園   IT新聞   BlogJava   博問   Chat2DB   管理


ts,ps,mpeg2 decoder and analysis,ts分析.
青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            亚洲激情视频| 午夜影视日本亚洲欧洲精品| 亚洲国产色一区| 香港成人在线视频| 欧美日韩亚洲一区二区三区在线| 激情久久一区| 久热精品视频| 久久精品观看| 一区二区三区在线观看欧美| 久久久亚洲国产天美传媒修理工| 亚洲国产日韩欧美| 欧美激情小视频| 亚洲国产日韩欧美在线99| 欧美专区中文字幕| 欧美一区视频| 国产曰批免费观看久久久| 欧美专区第一页| 午夜视黄欧洲亚洲| 国产在线乱码一区二区三区| 欧美一区免费| 亚洲欧洲日韩综合二区| 国产欧美一区二区视频| 亚洲综合99| 一区二区三区国产| 国产精品三级视频| 欧美一区二区黄色| 亚洲线精品一区二区三区八戒| 欧美日韩精品久久| 羞羞漫画18久久大片| 亚洲一区综合| 国产欧美精品一区| 久久亚洲欧美国产精品乐播| 久久久久久久999| 亚洲国产成人久久综合一区| 亚洲国产精品久久| 国产精品久久久亚洲一区 | 国产精品永久免费| 久久久久国产成人精品亚洲午夜| 久久久久成人精品| 一区二区三区三区在线| 亚洲免费在线播放| 伊人久久亚洲美女图片| 亚洲开发第一视频在线播放| 国产精品三级久久久久久电影| 久久亚洲春色中文字幕| 欧美超级免费视 在线| 亚洲欧美日韩国产| 久久综合激情| 香蕉久久夜色精品| 老牛国产精品一区的观看方式| 亚洲婷婷免费| 久久精彩免费视频| 亚洲网友自拍| 久热精品视频在线免费观看| 亚洲欧美日韩高清| 欧美风情在线| 久久亚洲一区二区三区四区| 欧美深夜影院| 欧美3dxxxxhd| 国产免费观看久久黄| 亚洲黑丝在线| 黄色av成人| 亚洲午夜影视影院在线观看| 亚洲欧洲在线观看| 欧美一站二站| 亚洲欧美一区二区三区极速播放 | 乱中年女人伦av一区二区| 欧美日韩在线看| 欧美69视频| 国产一区视频观看| 亚洲一区二区三区高清不卡| 日韩一级片网址| 免费看黄裸体一级大秀欧美| 久久精品欧洲| 国产精品中文字幕在线观看| 亚洲精选中文字幕| 最新国产乱人伦偷精品免费网站| 亚洲欧美日韩国产综合在线| 亚洲精品一区二区三区99| 在线精品视频一区二区三四| 亚洲香蕉成视频在线观看| 亚洲精品在线视频| 你懂的国产精品| 免费日本视频一区| 韩国av一区二区三区四区| 午夜精品在线| 久久福利视频导航| 国产精品一级久久久| 亚洲一区中文字幕在线观看| 亚洲一区欧美二区| 国产精品豆花视频| 亚洲一区二区三区成人在线视频精品| 一区二区三区四区五区视频| 欧美激情在线免费观看| 亚洲激情在线| 一区二区三区色| 国产精品免费一区豆花| 一区二区成人精品 | 免费成人网www| 在线免费观看成人网| 美女脱光内衣内裤视频久久网站| 麻豆久久久9性大片| 亚洲国产欧美一区二区三区久久 | 在线亚洲一区二区| 国产精品二区影院| 亚洲欧美中文在线视频| 久久国产精品久久国产精品 | 亚洲国产视频一区| 一本到高清视频免费精品| 欧美日韩亚洲免费| 亚洲免费在线看| 久久亚洲精品一区二区| 亚洲国产日韩一区| 欧美日本国产视频| 亚洲伊人网站| 免费一级欧美在线大片| 99精品欧美一区| 国产精品久久激情| 久久精品视频免费播放| 亚洲高清资源综合久久精品| 亚洲午夜在线观看视频在线| 国产免费一区二区三区香蕉精| 久久国产免费看| 亚洲欧洲一区| 久久精品一区二区国产| 亚洲国产视频a| 欧美色精品在线视频| 久久av资源网| 99一区二区| 免费欧美日韩国产三级电影| 亚洲视频在线观看三级| 国内揄拍国内精品少妇国语| 欧美丰满高潮xxxx喷水动漫| 午夜精品久久久久| 亚洲精品一区久久久久久| 欧美在线综合| 99视频超级精品| 伊甸园精品99久久久久久| 国产精品成人va在线观看| 久久综合色播五月| 亚洲欧美在线免费| 一本久道久久综合狠狠爱| 久久免费视频网站| 香蕉久久夜色精品国产| 99精品视频网| 一本色道久久99精品综合| 国产精品久在线观看| 欧美大胆成人| 久久久精品日韩欧美| 亚洲在线播放电影| 91久久精品美女| 免费看精品久久片| 亚洲欧美日韩系列| 亚洲精品欧美精品| 影音国产精品| 国产日韩欧美一区二区三区四区| 欧美激情第10页| 老牛嫩草一区二区三区日本| 亚洲尤物影院| 一区二区三区精密机械公司| 亚洲高清久久网| 久久精品视频免费观看| 亚洲砖区区免费| 一本一本久久a久久精品综合麻豆| 在线视频成人| 伊人影院久久| 亚洲高清自拍| 一区久久精品| **网站欧美大片在线观看| 国产视频一区在线| 国产精品亚洲综合久久| 国产精品久久久久久户外露出 | 亚洲精品视频在线观看网站| 欧美国产精品久久| 久久久久久久久久看片| 久久精品99久久香蕉国产色戒| 亚洲综合电影| 午夜免费在线观看精品视频| 亚洲素人一区二区| 亚洲一级黄色片| 午夜精品免费在线| 午夜精品久久久久久久白皮肤| 亚洲欧美日本另类| 亚洲欧美日韩在线| 午夜精品短视频| 久久久国产91| 美女日韩在线中文字幕| 免费亚洲一区| 欧美成人按摩| 亚洲精品欧美极品| 一区二区欧美日韩| 亚洲宅男天堂在线观看无病毒| 国产精品久久77777| 国产免费观看久久黄| 国产日韩欧美麻豆| 国内精品福利| 亚洲日韩视频| 亚洲欧美日韩人成在线播放| 亚洲欧美激情一区二区| 久久精品国产清自在天天线|