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

牽著老婆滿街逛

嚴以律己,寬以待人. 三思而后行.
GMail/GTalk: yanglinbo#google.com;
MSN/Email: tx7do#yahoo.com.cn;
QQ: 3 0 3 3 9 6 9 2 0 .

Windows下編譯X264多線程版本

轉載自:http://blog.csdn.net/wutong_login/article/details/7546145

這一次的文章將分析X264的多線程過程,也可以說是并行編碼過程。

 

1. 編譯并行編碼的x264

從X264的幫助命令行可以看到,添加--threads項可以調整運行的線程數,可是當我完成X264編譯,視圖對手頭的YUV進行編碼的時候,發(fā)現在自己的雙核計算機上,只能發(fā)揮50%的效率,即使使用--threads n 也無濟于事,提示就是沒有打開pthread支持。Pthreads定義了一套 C程序語言類型、函數與常量,它以 pthread.h 頭文件和一個線程庫實現。【1】

下面就把我在windows上實現pthread版本的X264編譯過程寫作如下:

 

2009年3月的66版本

1. 從http://sourceware.org/pthreads-win32/ 下載pthread的win32版本,把其中的include和lib加入到VC++的引用目錄中去。

2. 在項目屬性的“C/C++ -> 預處理器 ->預處理器”中加入HAVE_PTHREAD。

3. 在osdep.h文件,緊接著#ifdef USE_REAL_PTHREAD加入

#pragma comment(lib, "pthreadVC2.lib")

引用pthreadVC2.lib,重新編譯。

2009年10月的77版本

4. 在項目屬性的“C/C++ -> 預處理器 ->預處理器”中加入SYS_MINGW。

其它版本請自己根據可能的編譯錯誤隨機應變。調整項目屬性意味著同時調整libx264和x264兩處的屬性。

經過如上調整編譯出的X264就可以在--threads n //n>=2的時候用完CPU的潛力了。

 

2. X264的編碼基本流程

(1)接口變更

 以前曾經寫過文章介紹X264的編程架構并且分析了它的接口,現在進一步看看x264是怎么把YUV圖像編程H.264編碼的。在代碼分析中,最容易讓人頭疼的是X264代碼隨處充斥著的多線程處理和碼率控制兩方面的代碼,所以,這里將先簡化過程,忽略掉這些非主體代碼。需要說明的是,本文分析的是版本77,2009年10月的版本。

 

這里的API比版本66少了x264_nal_encode(...),該函數是將碼率封裝成NAL,現在它被放到static int x264_encoder_encapsulate_nals( x264_t *h )中,不再作為單獨API出現。而x264_encoder_encapsulate_nals(...)分別被x264_encoder_headers(...)和x264_encoder_frame_end(...)所調用,分別用于封裝參數(sps,pps)和其它數據的碼流。

 

 (2)main函數

從代碼的main()函數開始, 這個函數很簡單,就是讀取參數,然后編碼。到了版本77,相對于66版本而已,增加了參數--preset,用于定義一些預設的參數,究竟是哪個版本引入的可自行考證。在調試程序的時候,可以根據需要選擇預設參數值,如果采用默認狀態(tài),編碼的FPS會比較慢。

 

現在重點考察編碼函數static int  Encode( x264_param_t *param, cli_opt_t *opt ), 在這個函數里,將會使用到X264的API,從代碼帶注釋直接裝貼過來,就不解釋了。

首先,代碼通過x264_encoder_open( param ) 和 x264_picture_alloc( )來初始化編碼器和分配內存功輸入YUV圖像使用。接下來可以看到由兩個注釋隔開的代碼塊,它們的功能如下

 /* Encode frames */

 while(輸入圖像中的正常編碼幀){

 編碼正常的碼流

 }

/* Flush delayed frames */

編碼因為B幀而殘余的碼流(在B幀編碼中,需要參考最后一個P幀的那些B幀,這時,輸入幀已經結束,而編碼幀尚未結束)

Encode()最后的代碼是進行編碼器關閉和內存謇恚⑼臣票嗦脛∈亢虵PS等。

 

(3)幀編碼函數Encode_frame()

在上面的兩個編碼代碼塊中,主體函數是

static int  Encode_frame( x264_t *h, hnd_t hout, x264_picture_t *pic )

這個函數將輸入每幀的YUV數據,然后諭涑鰊al包。編碼碼流的具體工作交由API

int     x264_encoder_encode( x264_t *h,x264_nal_t **pp_nal, int *pi_nal,x264_picture_t *pic_in,
x264_picture_t *pic_out )

來完成,它應該是X264中最重要的函數了。

 

(4)分析x264_encoder_encode()

 首先遇到參考幀調整好書如下,

static inline int x264_reference_update( x264_t *h )

 它會在h->frames.reference 保留需要的參考幀,然后根據參考幀隊列的大小限制,移除不使用的參考幀。

 然后根據注釋把代碼塊逐個往下分析:

  /* ------------------- Setup new frame from picture -------------------- */

  /* 1: Copy the picture to a frame and move it to a buffer */

  把幀輸入的YUV數據傳入 x264_frame_t *fenc中,然后進行一些碼率控制方式的初始化。

   /* 2: Place the frame into the queue for its slice type decision */

  把fenc放到slice決定隊列中,也輸入碼率控制的一部分

  /* 3: The picture is analyzed in the lookahead */

  分析slice類型,具體的類型決定工作將在函數void x264_slicetype_decide( x264_t *h )中處理。

  后面做碼率控制分析的時候再詳述。

  /* ------------------- Get frame to be encoded ------------------------- */
  /* 4: get picture to encode */

  去處編碼幀,放置在h->fenc中,并重新設置編碼參數。

  /* ------------------- Setup frame context ----------------------------- */
  /* 5: Init data dependent of frame type */

  根據幀類型設置i_nal_type,i_nal_ref_idc,h->sh.i_type ,如果是IDR幀,重置參考幀隊列。

  /* ------------------- Init                ----------------------------- */

  根據當前幀建立參考幀隊列,當前參考幀按編碼幀類型分別寫在h->fref0和h->fref1中。并整理好他們的排列順序,h->fref0按poc從高到低,h->fref1反之。

  /* ---------------------- Write the bitstream -------------------------- */

 寫NAL碼流

  /* Write SPS and PPS */

 寫參數集

 /* ------------------------ Create slice header  ----------------------- */

 初始化slice header參數

 /* Write frame */

 輸出slice header和slice data

 

 函數最后調用

 static int x264_encoder_frame_end( x264_t *h, x264_t *thread_current,x264_nal_t **pp_nal, int *pi_nal, x264_picture_t *pic_out )

 來做NAL裝,并且調整編碼器狀態(tài)和輸出本幀編碼的統計數據。

 

(5)static void *x264_slices_write( x264_t *h )

這個函數被x264_encoder_encode()調用作為處理slice header和slice data的編碼,這個函數主要是分出slice group中的一個slice,具體做slice編碼則在

static int x264_slice_write( x264_t *h )

這個函數的代碼塊劃分如下:

step1. 初始化NAL,調用x264_slice_header_write()根據前面的參數設置輸出slice header碼流,

step2. 如果是用CABAC,則初始化其上下文。

step3. 進入宏塊,逐個宏塊編碼:

宏塊編碼重要的是以下兩個函數:
        x264_macroblock_analyse( h );
        x264_macroblock_encode( h );

其之前的代碼是做宏塊數據的導入,其后的代碼是對編碼數據進行熵編碼,根據slicedata協議寫入碼流,更新coded_block_pattern,處理碼率控制狀態(tài)和更新CABAC上下文數據等。代碼分析到宏塊級了,就看看這個基本的編碼單位是怎么被處理的吧。


(6)x264_macroblock_analyse( h )

這個函數就是分析宏塊以確定其宏塊分區(qū)模式,對I幀進行幀內預測和對P/B幀進行運動估計就發(fā)生在此函數,首先進行亮度編碼,緊接著是色度。同樣來一步步分析其實現。
step1. 進行碼率控制準備,x264_mb_analyse_init()函數的功能包括:初始化碼率控制的模型參數(碼率控制依然基于Lagrangian率失真優(yōu)化算法,所以初始化lambda系數),把各宏塊分類的Cost設為COST_MAX,計算MV范圍,快速決定Intra宏塊。

step2. 根據h->sh.i_type的類型(I,P,B)來分別計算宏塊模式的率失真代價,代價計算使用SATD方法,【2】中有相關介紹。通過計算SATD可以大致估計編碼碼流,作為宏塊選擇的依據。

隨機取h->mb.i_type == I_8x8的情況來分析,

            if( h->mb.b_lossless )
                x264_predict_lossless_8x8( h, p_dst, i, i_mode, edge );
            else
                h->predict_8x8[i_mode]( p_dst, edge );

            x264_mb_encode_i8x8( h, i, i_qp );

predict_8x8[i_mode]( p_dst, edge )將進行幀內預測,x264_mb_encode_i8x8( h, i, i_qp )進行DCT編碼和量化,同時進行反量化和逆DCT編碼,以備重建圖像使用。
對于I8x8和I4x4的情況一般會進行分別做3個或15個塊的預測和編碼,留下一個塊在x264_macroblock_encode( h )中再預測編碼,原因是前面的塊將作為后面編碼塊的預測依據。具體說會導致 i_pred_mode = x264_mb_predict_intra4x4_mode( h, 4*idx )的計算值發(fā)生變化。
 
P/B幀的幀間預測將在接下來的代碼段發(fā)生,具體的運動估計算法不在詳述,以后將補充X264運動估計分析。

step3. 根據i_mbrd的不同,做一些后續(xù)運算。


(7)x264_macroblock_encode( h )

在確定了宏塊分區(qū)模式后,在本函數將對I幀剩余的宏塊分區(qū)進行預測和編碼,而對P/B幀的運動補償和殘差編碼主要發(fā)生在這里。

基本流程分析到這里已經算結束了,在代碼中,會發(fā)現宏塊的預測和編碼會散布在不同的函數發(fā)生,原因是對率失真優(yōu)化的要求(對P/B幀)。所以,在X264中參考幀管理,碼率控制,幀間預測和多線程編碼都是比較有趣的探索對象。

3. 多線程代碼分析

(1)文檔解讀

分析完X264的基本架構,來看看多線程發(fā)揮力量的地方。X264自帶的多線程介紹文檔是本課題的必讀文檔,它存放在X264的DOC文件夾下。本文描述的大意是:當前的X264多線程模式已經放棄基于slice的并行編碼,轉而采用幀級和宏塊級的并行,原因是slice并行需要采用slice group,會引入而外冗余降低編碼效率。摘抄一段原文如下:

New threading method: frame-based
application calls x264
x264 runs B-adapt and ratecontrol (serial to the application, but parallel to the other x264 threads)
spawn a thread for this frame
thread runs encode in 1 slice, deblock, hpel filter
meanwhile x264 waits for the oldest thread to finish
return to application, but the rest of the threads continue running in the background
No additional threads are needed to decode the input, unless decoding+B-adapt is slower than slice+deblock+hpel, in which case an additional input thread would allow decoding in parallel to B-adapt.【3】

以上的說明意味著,X264采用B幀在編碼時不作為參考幀,所以適宜對其進行并行。

(2)運行狀況分析

先來看看x264_pthread_create被調用的地方,只有這些地方才實實在在的創(chuàng)建了線程。

 x264_pthread_create( &h->thread_handle, NULL, (void*)x264_slices_write, h )

 x264_pthread_create( &look_h->thread_handle, NULL, (void *)x264_lookahead_thread, look_h )

 x264_pthread_create( &h->tid, NULL, (void*)read_frame_thread_int, h->next_args )

 

 由上圖的運行可以看出,在開啟了--threads 4后。x264_slices_write()可以開啟4個線程同時編碼,而同時存在一個主線程和一個x264_lookahead_thread()線程。x264_slices_write()的優(yōu)先級為低,原因是調用了

     if( h->param.i_sync_lookahead )
        x264_lower_thread_priority( 10 );

調低本線程的優(yōu)先級。read_frame_thread_int()是讀磁盤上的流數據信息,因為I/O和內存的不同步,所以應該分開線程處理。


在x264_encoder_open()中可以找到一下代碼,可以看到對于x264_slices_write()和x264_lookahead_thread()都有被分配了專有的上下文變量,供單一線程使用。

    for( i = 1; i < h->param.i_threads + !!h->param.i_sync_lookahead; i++ )
        CHECKED_MALLOC( h->thread[i], sizeof(x264_t) );


(3)如何確保按指定線程數來開啟線程編碼?

按打印實驗可以看到,假設使用--threads 4的參數選項,代碼會同時開啟4個x264_slices_write()線程,然后每編完一個幀(前面的一個線程返回后),一個新的被產生出來,使得x264_slices_write()線程總數保持在4個,這一過程的相關代碼如下:


int     x264_encoder_encode( x264_t *h,x264_nal_t **pp_nal, int *pi_nal,x264_picture_t *pic_in,
                             x264_picture_t *pic_out )
{
...
    if( h->param.i_threads > 1)
    {
        int i = ++h->i_thread_phase;
        int t = h->param.i_threads;
        thread_current = h->thread[ i%t ];
        thread_prev    = h->thread[ (i-1)%t ];
        thread_oldest  = h->thread[ (i+1)%t ];
        x264_thread_sync_context( thread_current, thread_prev );
        x264_thread_sync_ratecontrol( thread_current, thread_prev, thread_oldest );
        h = thread_current;
    }

...

    /* Write frame */
    if( h->param.i_threads > 1 )
    {
        printf("x264_pthread_create\n");
        if( x264_pthread_create( &h->thread_handle, NULL, (void*)x264_slices_write, h ) )
            return -1;
        h->b_thread_active = 1;
    }
    else
        if( (intptr_t)x264_slices_write( h ) )
            return -1;

    return x264_encoder_frame_end( thread_oldest, thread_current, pp_nal, pi_nal, pic_out );

...

}


static int x264_encoder_frame_end( x264_t *h, x264_t *thread_current,x264_nal_t **pp_nal, int *pi_nal, x264_picture_t *pic_out )
{
...
    if( h->b_thread_active )
    {
        void *ret = NULL;
        x264_pthread_join( h->thread_handle, &ret );
        if( (intptr_t)ret )
            return (intptr_t)ret;
        h->b_thread_active = 0;
    }

...

}


從以上兩個函數的代碼段可以看到,h上下文中保持的線程不會多于4個, x264_pthread_create()根據主線程的調用,創(chuàng)建出x264_slices_write線程,然后thread_oldest被指定并被率控函數判斷重設,當前的線程數還不足4的時候,thread_oldest指向新線程,h->b_thread_active為0,不能進入x264_encoder_frame_end()的相關代碼,主線程繼續(xù)循環(huán)創(chuàng)建x264_slices_write線程,當線程總數為4,這時thread_oldest指向4個線程中被判斷最快返回的那個,這時h->b_thread_active=1將進入x264_pthread_join(),那樣,該線程就將主線至于阻塞狀態(tài),直至thread_oldest完成,才能重現創(chuàng)建新線程,以此機制,保持指定數碼的編碼線程數。


(4)x264_lookahead_thread()線程的作用

在分析這個線程之前,來看看兩個重要的線程控制函數:

//喚醒等待該條件變量的所有線程。如果沒有等待的線程,則什么也不做。

#define x264_pthread_cond_broadcast  pthread_cond_broadcast

//自動解鎖互斥量(如同執(zhí)行了 pthread_unlock_mutex),并等待條件變量觸發(fā)。這時線程掛起,不占用 CPU 

時間,直到條件變量被觸發(fā)。在調用 pthread_cond_wait 之前,應用程序必須加鎖互斥量。pthread_cond_wait 函數返回前,自動重新對互斥量加鎖(如同執(zhí)行了 pthread_lock_mutex)。
#define x264_pthread_cond_wait       pthread_cond_wait

 

以下的代碼是X264中x264_lookahead_thread代碼經常阻塞的地方,

**************************代碼段A********************************************

        if( h->lookahead->next.i_size <= h->lookahead->i_slicetype_length )
        {
            while( !h->lookahead->ifbuf.i_size && !h->lookahead->b_exit_thread )
                x264_pthread_cond_wait( &h->lookahead->ifbuf.cv_fill, &h->lookahead->ifbuf.mutex );
            x264_pthread_mutex_unlock( &h->lookahead->ifbuf.mutex );
        }
        else
        {
            x264_pthread_mutex_unlock( &h->lookahead->ifbuf.mutex );
            x264_lookahead_slicetype_decide( h );
        }

這里是等待滿足!h->lookahead->ifbuf.i_size && !h->lookahead->b_exit_thread 的條件,后一條件在正常編碼過程是TRUE,因為不會無故退出線程。那么這里等待的其實是ifbuf.i_size為非0.查找相關代碼,

 

這里的 ifbuf.i_size條件是在x264_synch_frame_list_push()得到滿足的,這里在得到一個輸入的新編碼幀后將發(fā)出信號。

    slist->list[ slist->i_size++ ] = frame;
    x264_pthread_cond_broadcast( &slist->cv_fill );

在代碼段A中,if( h->lookahead->next.i_size <= h->lookahead->i_slicetype_length )條件中,i_slicetype_length表示為了進行slice type的判斷而緩存的幀,它的值有取決于h->frames.i_delay,由代碼的初始化設定值決定(默認為40)。也就是說預存40幀的數值,進行slice type決定用。暫時不詳細分析slice type判斷的具體實現,它的大概思想是根據碼率,GOP和失真狀況的權衡,來進行幀類型選擇,在類似實時通信場合,不允許B幀的使用,也不可能預存那么多幀,這樣的處理沒有意義。


回頭看這里的處理意義,是阻塞線程,等待后續(xù)的輸入幀,然后利用處理規(guī)則來決定其slice type,為slice編碼準備幀。


(5)宏塊級別的并行

在數據結構x264_frame_t中,有變量x264_pthread_cond_t  cv; 該變量分別在下面的兩個函數里被封裝了阻塞和喚醒:

void          x264_frame_cond_broadcast( x264_frame_t *frame, int i_lines_completed );
void          x264_frame_cond_wait( x264_frame_t *frame, int i_lines_completed );

考查它們被調用的地方,

************代碼B****************from x264_macroblock_analyse( )->x264_mb_analyse_init()

int thresh = pix_y + h->param.analyse.i_mv_range_thread;
for( i = (h->sh.i_type == SLICE_TYPE_B); i >= 0; i-- )
{
    x264_frame_t **fref = i ? h->fref1 : h->fref0;
    int i_ref = i ? h->i_ref1 : h->i_ref0;
    for( j=0; j<i_ref; j++ )
    {
        x264_frame_cond_wait( fref[j], thresh );
        thread_mvy_range = X264_MIN( thread_mvy_range, fref[j]->i_lines_completed - pix_y );
    }
}

**************************代碼C************************************from x264_fdec_filter_row()

if( h->param.i_threads > 1 && h->fdec->b_kept_as_ref )
{ 

    x264_frame_cond_broadcast( h->fdec, mb_y*16 + (b_end ? 10000 : -(X264_THREAD_HEIGHT <<h->sh.b_mbaff)) );
}

從上面的代碼段可以看到沒完成圖像一行的編碼,便會使用mb_y*16 -X264_THREAD_HEIGH的值來嘗試喚醒x264_pthread_cond_wait( &frame->cv, &frame->mutex ),要判斷的條件是 

mb_y*16 -X264_THREAD_HEIGH < thresh = pix_y + h->param.analyse.i_mv_range_thread;

后者作為一個設想的閾值,用于確保依賴于本幀的后續(xù)幀在編碼時,本幀已經編碼出若干行宏塊,以后續(xù)編碼幀的基礎,那樣可以設想的情形如下圖,不過X264是以編碼完整行為單位的。

本文的分析道這里告一段落,對于幀間多線程分析和宏塊的并行優(yōu)化,或按自己的應用做代碼裁剪,可以通過改正上面的(4)(5)代碼段來實現,在當前(四核CPU)的X264測試中,已有代碼確實能夠很好的利用多核資源,并行編碼的話題會隨硬件的升級而不斷探索下去。

posted on 2013-01-22 16:28 楊粼波 閱讀(1910) 評論(0)  編輯 收藏 引用

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <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>
            亚洲精品亚洲人成人网| 欧美一区二视频| 欧美电影打屁股sp| 欧美.www| 亚洲午夜羞羞片| 午夜精品视频在线观看一区二区| 国产视频一区欧美| 欧美成人资源| 欧美午夜剧场| 美女日韩欧美| 欧美日韩三级| 六月婷婷久久| 欧美日韩一区二区高清| 欧美伊人久久大香线蕉综合69| 欧美一区二区三区成人| 亚洲精选久久| 欧美一区二区三区四区在线观看地址 | 国产精品入口福利| 狂野欧美激情性xxxx欧美| 欧美高清视频在线| 欧美一区二区三区在线观看| 免费短视频成人日韩| 亚洲欧美日韩网| 久久精品欧洲| 亚洲在线黄色| 你懂的成人av| 欧美中文字幕久久| 亚洲欧美影音先锋| 欧美va亚洲va国产综合| 亚洲国产一区二区精品专区| 一本色道精品久久一区二区三区 | 国产精品盗摄久久久| 久久婷婷影院| 国产精品一二三| 亚洲人成在线播放| 国产精品一区免费在线观看| 亚洲娇小video精品| 国内精品亚洲| 午夜精品亚洲| 亚洲在线一区二区| 欧美国产一区视频在线观看 | 亚洲一区二区三区在线视频| 久久伊人一区二区| 久久精品综合网| 国产伦精品一区| 亚洲视频综合在线| 亚洲视频导航| 欧美日韩国产一级片| 欧美激情免费在线| 亚洲电影免费在线| 久久美女艺术照精彩视频福利播放| 亚洲欧美日韩爽爽影院| 欧美色偷偷大香| 99热精品在线| 亚洲视频在线观看视频| 欧美久久电影| 亚洲人成小说网站色在线| 亚洲精品影院在线观看| 欧美成人精品h版在线观看| 蜜臀99久久精品久久久久久软件| 国产一区清纯| 欧美在线观看一二区| 欧美在线免费看| 国产一区美女| 久久午夜视频| 欧美激情aaaa| 亚洲日本视频| 欧美日韩视频在线一区二区观看视频 | 在线日韩精品视频| 欧美成人久久| 日韩视频在线观看免费| 一区二区三区高清视频在线观看| 欧美精品首页| 亚洲特黄一级片| 久久成人精品| 亚洲电影在线看| 欧美日本精品在线| 一区二区三区高清不卡| 性久久久久久久久久久久| 国产欧美精品日韩精品| 久久精品免费看| 亚洲激情在线观看视频免费| 亚洲一区久久| 国内精品国语自产拍在线观看| 久久视频在线看| 亚洲精品一二三| 欧美在线亚洲在线| 亚洲国产成人tv| 欧美午夜精品久久久| 欧美一区二区三区四区夜夜大片| 欧美成人69| 国产一区二区欧美日韩| 亚洲电影天堂av| 亚洲视频在线一区| 国产综合久久| 欧美人与禽猛交乱配视频| 亚洲欧美另类在线观看| 亚洲大片在线| 欧美一级大片在线免费观看| 亚洲国产成人一区| 国产精品黄页免费高清在线观看| 久久精品99国产精品| 日韩午夜电影av| 欧美成人乱码一区二区三区| 国产精品99久久不卡二区| 好吊成人免视频| 国产精品激情av在线播放| 麻豆久久久9性大片| 亚洲欧美视频一区| 日韩亚洲国产精品| 欧美成人免费观看| 欧美专区亚洲专区| 在线一区观看| 91久久亚洲| 狠狠色丁香久久婷婷综合_中| 欧美日韩成人精品| 美女在线一区二区| 欧美在线看片| 午夜精品999| 一本一本久久a久久精品综合妖精| 欧美福利视频在线| 裸体丰满少妇做受久久99精品| 亚洲女人天堂成人av在线| 日韩亚洲欧美中文三级| 在线观看日韩精品| 黄色成人在线网址| 国产亚洲高清视频| 国产日韩在线播放| 国产伦精品一区二区三区照片91| 欧美精品日韩www.p站| 欧美aa国产视频| 欧美 日韩 国产 一区| 久久夜色精品国产欧美乱| 久久精品一区二区三区四区| 欧美一区高清| 午夜在线一区| 欧美在线不卡| 欧美在线观看视频| 久久久久国产精品一区| 久久久久久有精品国产| 久久久一本精品99久久精品66| 久久国产黑丝| 久久国产成人| 美女在线一区二区| 欧美韩日一区二区| 欧美视频中文一区二区三区在线观看 | 欧美尤物巨大精品爽| 久久国产精品久久久久久久久久| 欧美一级大片在线免费观看| 香蕉成人久久| 久久国产精品网站| 欧美成人中文字幕| 欧美日韩爆操| 国产精品一区在线观看你懂的| 国产亚洲欧美日韩美女| 在线 亚洲欧美在线综合一区| 亚洲国产乱码最新视频| 亚洲美女毛片| 香港成人在线视频| 鲁大师成人一区二区三区| 欧美激情免费在线| 在线亚洲一区观看| 久久不射网站| 欧美激情一区二区久久久| 国产精品av久久久久久麻豆网| 国产精品久久久久一区二区三区共| 国产欧美一区二区精品婷婷| 免费看成人av| 欧美女激情福利| 久久精品欧美| 米奇777超碰欧美日韩亚洲| 欧美黑人在线播放| 国产精品久久久久久久久婷婷| 国产视频精品va久久久久久| 在线免费精品视频| 国产精品99久久久久久有的能看| 午夜精品理论片| 欧美刺激性大交免费视频| 99视频有精品| 久久久精品日韩| 国产精品theporn88| 黄色成人av| 亚洲男女毛片无遮挡| 免费亚洲电影| 亚洲一区免费网站| 欧美va天堂va视频va在线| 国产麻豆综合| 日韩午夜电影在线观看| 久久久精品网| 99re在线精品| 久久在线免费视频| 国产女人18毛片水18精品| 亚洲剧情一区二区| 久久久国产视频91| 夜夜狂射影院欧美极品| 欧美a级在线| 在线视频成人| 久久精品视频在线看| 亚洲视频精品| 欧美日本亚洲|