日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

【转】DICOM医学图像处理:DIMSE消息发送与接收“大同小异”之DCMTK fo-dicom mDCM

發(fā)布時間:2023/12/10 编程问答 43 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【转】DICOM医学图像处理:DIMSE消息发送与接收“大同小异”之DCMTK fo-dicom mDCM 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

轉(zhuǎn)自:https://my.oschina.net/zssure/blog/354816

背景:

? ? ? ? 從DICOM網(wǎng)絡傳輸一文開始,相繼介紹了C-ECHO、C-FIND、C-STORE、C-MOVE等DIMSE-C服務的簡單實現(xiàn),博文中的代碼給出的實例都是基于fo-dicom庫來實現(xiàn)的,原因只有一個:基于C#的fo-dicom庫具有高封裝性。對于初學者來說實現(xiàn)大多數(shù)的DIMSE-C、DIMSE-N服務幾乎都是“傻瓜式”操作——構(gòu)造C-XXX-RQ、N-XXX-RQ然后綁定相應的OnResponseReceived處理函數(shù)即可。本博文希望在前幾篇預熱的基礎上,對比DCMTK、fo-dicom、mDCM三種庫構(gòu)建DIMSE消息的具體操作,來分析一下三者對于DIMSE消息的發(fā)送和接收的實現(xiàn),為后續(xù)搭建簡易版的Dicom Server服務器做準備。

DIMSE:

? ? ? ? DIMSE,是DICOM Message Service Element的簡稱。DICOM3.0第7部分指出:DIMSE為對等DICOM應用實體進行醫(yī)學影像及相關信息交換提供了一種應用服務元素定義(Application Service Element),包括服務和協(xié)議(DIMSE Service 和DIMSE Protocol)。

DIMSE Protocol:

? ? ? ? DIMSE基于DIMSE協(xié)議來提供服務,DIMSE協(xié)議規(guī)定了構(gòu)造消息必需的編碼規(guī)則。一條DICOM MESSAGE由固定的指令集合(Command Set),外加可選擇的數(shù)據(jù)集合(Data Set)構(gòu)成,如下截圖所示:

?

?

? ? ? ? 可以簡單的理解為Command Set就是本博文即將要介紹的各種服務的請求和應答消息;而Data Set可以認為類似于DCM后綴的文件,是我們希望在對等DICOM實體間進行傳輸?shù)男畔ⅰ5菑谋举|(zhì)上來說Command Set和Data Set兩者都遵循DICOM3.0協(xié)議中IOD的定義都是“以(Group Number,Element Number)對”來進行標記的Data Element元素的集合,更形象一點的說明可參考早期的博文(http://blog.csdn.net/zssureqh/article/details/9275271)。

? ? ? ? DIMSE Protocol指出Message可能會分片(fragmented,這與傳統(tǒng)的TCP/IP中的概念類似),消息的具體傳輸是基于ASSOCIATE(DICOM3.0第8部分)中的P-DATA Service(博文http://blog.csdn.net/zssureqh/article/details/41016091中有介紹)。

DIMSE Services:

? ? ? ? DIMSE服務因操作SOP類型的不同分為DIMSE-C ServicesDIMSE-N Services,DIMSE-C服務支持在對等DICOM實體間進行Composite SOP Instance操作,主要包括C-ECHO、C-FIND、C-STORE、C-MOVE、C-GET等;而DIMSE-N服務支持Normalized SOP Instance操作,主要包括N-EVENT-REPORT、N-GET、N-SET、N-CREATE、N-ACTION、N-DELETE。

?

?

? ? ? ? 從上圖可以看出DIMSE-C服務只提供操作服務,即對等DICOM實體一方請求另一方對Composite SOP Instance進行操作(operation);而DIMSE-N服務除了提供操作以外,還提供通知(notification)服務。DIMSE中的所有操作和通知都是確認服務(confirmed services),即一方發(fā)出的請求都需要得到對方的應答(原文:All DIMSE operations and notifications are confirmed services. The performing DIMSE-service-user shall report the response of each operation or notificationover the same Association?on which the operation or notification was invoked.)。每種服務具體方式不同,例如某些操作可能會觸發(fā)后續(xù)的子操作、某些操作可能需要多個響應等等,如下圖:

?

?

DCMTK、fo-dicom、mDCM構(gòu)建DIMSE-C消息:

? ? ? ? DIMSE-C服務在醫(yī)學領域應用最廣泛,常見的PACS、HIS、RIS、LIS等系統(tǒng)都會用到,而DIMSE-N服務主要應用在MPPS和DICOM打印中,日常學習中可能沒有實際應用和測試的機會,因此這里就暫時不介紹,主要以DIMSE-C消息的構(gòu)造為主,來分別介紹三種庫的具體操作。

DCMTK:

? ? ? ? 博文http://blog.csdn.net/zssureqh/article/details/41016091之前簡單介紹了一下DCMTK對于網(wǎng)絡傳輸方面的封裝,更多的是偏重于協(xié)議的各層(Layer),例如對最底層的基于TCP/IP的Dicom Upper Layer的封裝以DUL_為前綴;對實體連接層的封裝以ASC_為前綴;最頂層的是DIMSE層,以DIMSE_為前綴。本博文會從DIMSE Services中的DIMSE-C各種消息入手,介紹DCMTK對于消息的封裝和操作:

DCMTK之C-ECHO:

? ? ? ? DCMTK開源庫相較于其他兩者來說最大的優(yōu)勢是有完整的說明文檔、穩(wěn)定的維護團隊,同時也有成功的商業(yè)產(chǎn)品。在源碼中也給出了各種服務工具包,前面的好多博文都已經(jīng)介紹過DCMTK的工具包,例如針對于C-ECHO的echoscu.exe(博文后續(xù)的工程實例是用dcmqrscp.exe作為mini DICOM服務端進行測試的)

DCMTK對DIMSE-C中的各種消息的定義在dimse.h頭文件中,其中C-ECHO-RQ消息定義如下:

?

/* C-ECHO */ struct T_DIMSE_C_EchoRQ { DIC_US MessageID; /* M */ DIC_UI AffectedSOPClassUID; /* M */ T_DIMSE_DataSetType DataSetType; /* M */ } ; struct T_DIMSE_C_EchoRSP { DIC_US MessageIDBeingRespondedTo; /* M */ DIC_UI AffectedSOPClassUID; /* U(=) */ T_DIMSE_DataSetType DataSetType; /* M */ DIC_US DimseStatus; /* M */ unsigned int opts; /* which optional items are set */ #define O_ECHO_AFFECTEDSOPCLASSUID 0x0001 } ;

?

?

? ? ? ? dimse.h中對于每一種DIMSE-C服務的請求消息(request)和響應消息(response)都給出了定義,并以union方式來統(tǒng)一了DICOM Message結(jié)構(gòu),如下所示:

?

/* * Composite DIMSE Message */ struct T_DIMSE_Message { T_DIMSE_Command CommandField; /* M */ union { /* requests */ T_DIMSE_C_StoreRQ CStoreRQ; T_DIMSE_C_EchoRQ CEchoRQ; T_DIMSE_C_FindRQ CFindRQ; T_DIMSE_C_GetRQ CGetRQ; T_DIMSE_C_MoveRQ CMoveRQ; T_DIMSE_C_CancelRQ CCancelRQ; T_DIMSE_N_EventReportRQ NEventReportRQ; T_DIMSE_N_GetRQ NGetRQ; T_DIMSE_N_SetRQ NSetRQ; T_DIMSE_N_ActionRQ NActionRQ; T_DIMSE_N_CreateRQ NCreateRQ; T_DIMSE_N_DeleteRQ NDeleteRQ; /* responses */ T_DIMSE_C_StoreRSP CStoreRSP; T_DIMSE_C_EchoRSP CEchoRSP; T_DIMSE_C_FindRSP CFindRSP; T_DIMSE_C_GetRSP CGetRSP; T_DIMSE_C_MoveRSP CMoveRSP; T_DIMSE_N_EventReportRSP NEventReportRSP; T_DIMSE_N_GetRSP NGetRSP; T_DIMSE_N_SetRSP NSetRSP; T_DIMSE_N_ActionRSP NActionRSP; T_DIMSE_N_CreateRSP NCreateRSP; T_DIMSE_N_DeleteRSP NDeleteRSP; } msg; };

?

?

? ? ? ? DICOM3.0第7部分中有關于C-ECHO消息的參數(shù)說明以及具體指令編碼,正如前文所述Command同樣也是以(Group Number,Element Number)標記的Data Element元素的集合,因此按照DICOM3.0標準中的要求只要向C-ECHO-RQ或者C-ECHO-RSP指令中插入規(guī)定的Data Element元素即可。

?

?

? ? ? ? 如上圖所示,構(gòu)造T_DIMSE_CEchoRQ需要填充MessageID/Affected SOP Class UID等,具體構(gòu)造代碼如下:(代碼封裝在DIMSE_echoUser函數(shù)中)

?

T_DIMSE_Message req, rsp; T_ASC_PresentationContextID presID; const char *sopClass = UID_VerificationSOPClass; bzero((char*)&req, sizeof(req)); bzero((char*)&rsp, sizeof(rsp)); req.CommandField = DIMSE_C_ECHO_RQ; req.msg.CEchoRQ.MessageID = msgId; strcpy(req.msg.CEchoRQ.AffectedSOPClassUID, sopClass); req.msg.CEchoRQ.DataSetType = DIMSE_DATASET_NULL;

?

?

? ? ? ? 上面代碼中的rsp與我們自己構(gòu)建的req類似,唯一不同的是req是在C-ECHO SCU端構(gòu)造,而rsp是在C-ECHO SCP端構(gòu)造并通過網(wǎng)絡傳送過來的。

? ? ? (具體的測試代碼可參見博文后文給出的連接)

DCMTK之C-FIND:

? ? ? ? 下面我們看一下比較復雜的消息C-FIND,相較于C-ECHO消息,C-FIND中需要給出我們希望查詢的目標屬性列表(記住:同樣也是一個DcmDataset類型,即Dicom Element集合)。

?

?

? ? ? ? C-FIND-RQ消息的構(gòu)造代碼如下:

?

//定義臨時變量 T_ASC_PresentationContextID presId; T_DIMSE_C_FindRQ req; T_DIMSE_C_FindRSP rsp; DcmFileFormat dcmff; OFString temp_str; presId=ASC_findAcceptedPresentationContextID(assoc,abstractSyntax); //構(gòu)造C-FIND-RQ消息 bzero(OFreinterpret_cast(char*, &req), sizeof(req)); strcpy(req.AffectedSOPClassUID,abstractSyntax); req.DataSetType=DIMSE_DATASET_PRESENT; req.Priority=DIMSE_PRIORITY_LOW; req.MessageID=assoc->nextMsgID++; //構(gòu)造數(shù)據(jù)體,即我們具體希望在C-FIND SCP端獲得的信息 DcmDataset* dcmdataset=new DcmDataset(); dcmdataset->putAndInsertString(DCM_StudyInstanceUID,""); dcmdataset->putAndInsertString(DCM_StudyDate,""); dcmdataset->putAndInsertString(DCM_QueryRetrieveLevel,"STUDY"); DcmDataset *statusDetail = NULL; //在DIMSE_findUser內(nèi)部會將dcmdataset數(shù)據(jù)合并到req中,統(tǒng)一構(gòu)成T_DIMSE_Message OFCondition cond=DIMSE_findUser(assoc,presId,&req,dcmdataset,NULL,NULL,blockMode,dimse_timeout,&rsp,&statusDetail);

?

?

? ? ? ? 上述代碼比較復雜的是需要構(gòu)造參數(shù)列表中的Identifier元素,該元素包含了我們希望從C-FIND SCP服務端提供查詢獲得的屬性,上面選擇了STUDY級別的查詢,因此需要添加DCM_QueryRetrieveLevel元素、StudyInstanceUID等(DCM_QueryRetrieveLevel元素必須添加,有時候會誤認為添加了AffectedSOPClassUID后就不需要了,這是錯誤的。否則服務端會返回如下錯誤,如下圖)。

?

?

? ? ? ? 注:關于Patient、Study、Series等不同級別的查詢的詳細介紹可參考DICOM3.0標準第4部分的附錄C。

DCMTK之C-STORE:

? ? ? ? C-STORE與C-FIND類似,同樣需要添加額外的數(shù)據(jù),不同于C-FIND添加查詢屬性列表的是,C-STORE添加的是準備發(fā)送的DCM文件的數(shù)據(jù)體,即下圖中的Data Set。

?

OFCondition cond = EC_Normal; T_DIMSE_Message req, rsp; DcmDataset bzero((char*)&req, sizeof(req)); bzero((char*)&rsp, sizeof(rsp)); /* set corresponding values in the request message variable */ req.CommandField = DIMSE_C_STORE_RQ; request->DataSetType = DIMSE_DATASET_PRESENT; request->req.msg.CStoreRQ = *request;

?

?

? ? ? ? 暫時我們就只介紹C-ECHO、C-FIND和C-STORE三種服務的請求消息構(gòu)造方法,其他的類似。

fo-dicom:

? ? ? ? fo-dicom是基于C#開發(fā)的,封裝性更強,封裝思路更傾向于按DICOM消息流來進行,即fo-dicom庫開發(fā)者在實現(xiàn)了整個DIMSE消息流框架的基礎上,通過給用戶預留各階段的接口來方便用戶定制自己的實現(xiàn)。對于DIMSE消息流框架的封裝在DicomService.cs文件中(同時也有類似于DCMTK中的ASC_方面的封裝,主要指的是A-ASSOCIATE服務及協(xié)議,在DICOM3.0第8部分有詳細介紹),對于網(wǎng)絡底層的封裝放在DicomServer.cs文件中(等同于DCMTK中的DUL_層)。

? ? ? ? DICOM Message消息的基類在DicomMessage.cs文件中,然后根據(jù)請求和應答派生了兩個基類DicomRequest和DicomResponse。從fo-dicom庫的封裝以及fo-dicom對于Dataset的設計可以看出Command和Dataset都是數(shù)據(jù)集合,不同的是兩者存儲的元素類型不同。

? ? ? ? 在fo-dicom庫中構(gòu)造各類消息很方便,可謂是“傻瓜式”操作,詳情如下:

fo-dicom之C-ECHO:

?

DicomCEchoRequest cechoRQ=new DicomCEchoRequest();

?

?

? ? ? ? 一行代碼就順利的構(gòu)建了一個C-ECHO-RQ請求指令。分析源碼可知DicomCEchoRequest繼承自DicomRequest,DicomReqeust繼承自DicomMessage。逐級查看各類的構(gòu)造函數(shù)可以發(fā)現(xiàn)。雖然我們調(diào)用的是DicomCEchoRequest的默認構(gòu)造函數(shù),但是在相繼調(diào)用了基類DicomRequest(DicomCommandField.CEchoRequest, DicomUID.Verification, priority)和DicomMessage()后,順利的完成了對C-ECHO-RQ指令中各個參數(shù)構(gòu)造,其中DicomMessage中構(gòu)造了空的Command Set和DataSet,DicomRequest中對MessageID、Priority、SOPClassUID以及CommandFieldType進行了賦值,這簡直是太容易啦,不過也正因為此,剛?cè)胧值臅r候可能不知道如何來定制化自己的請求,以為fo-dicom庫留給我們的可操作性太少,其實不然,繼續(xù)往下看。

fo-dicom之C-FIND:

?

DicomCFindRequest cfind=DicomCFindRequest.CreateStudyQuery(patientId:”12345”); cfind.OnResponseReceived=(rq,rsp)=> { //接收到C-FIND-RSP響應消息后,本機C-FIND SCU進行的操作 //例如可以輸出到屏幕或其他窗口 Console.WriteLine("PatientAge:{0} PatientName:{1}", rsp.Dataset.Get<string>(DicomTag.PatientAge), rsp.Dataset.Get<string>(DicomTag.PatientName)); }

?

?

? ? ? ? 通過對比fo-dicom與DCMTK中C-FIND的構(gòu)造,是不是覺得很容易。但是越容易學習和上手的東西,倘若不掌握其本質(zhì)越容易忘。查看DicomCFindRequest.cs源碼,可以發(fā)現(xiàn)CreateStudyQuery函數(shù)已經(jīng)幫助我們添加了Study查詢級別所需的所有字段,也就是上文中提到的Identifier參數(shù)部分。代碼如下:

?

? ? ? ? 那么如果我們想像DCMTK那樣自由添加字段怎么辦?例如在已知服務端是自己定制實現(xiàn)的基礎上來查詢我們的私有字段。很簡單直接覆蓋一下CreateStudyQuery函數(shù)即可。另外fo-dicom還有一個比價便利的地方是將每種消息的回調(diào)函數(shù)直接綁定到消息中,程序?qū)懫饋肀容^方便,邏輯上更清晰。

fo-dicom之C-STORE:

?

DicomCStoreRequest cstore=new DicomCStoreRequest(@”c:\\test4.dcm”);

?

?

? ? ? ? 在DicomCStoreRequest一級只需要數(shù)據(jù)要發(fā)送的dcm文件名(全路徑名),同樣通過逐級來完成CommandSet和Dataset的賦值。基本流程如下:

?

/// <summary>/// Initializes DICOM C-Store request to be sent to SCP./// </summary>/// <param name="file">DICOM file to be sent</param>/// <param name="priority">Priority of request</param>public DicomCStoreRequest(DicomFile file, DicomPriority priority = DicomPriority.Medium) : base(DicomCommandField.CStoreRequest, file.Dataset.Get<DicomUID>(DicomTag.SOPClassUID), priority) {File = file;Dataset = file.Dataset;SOPInstanceUID = File.Dataset.Get<DicomUID>(DicomTag.SOPInstanceUID);} <span style="white-space:pre"> </span>//DicomRequest.cs文件protected DicomRequest(DicomCommandField type, DicomUID affectedClassUid, DicomPriority priority) : base() {Type = type;SOPClassUID = affectedClassUid;MessageID = GetNextMessageID();Priority = priority;Dataset = null;} <span style="white-space:pre"> </span>//DicomMessage.cs文件public DicomMessage() {Command = new DicomDataset();Dataset = null;}

?

mDCM:

? ? ? ? mDCM庫與fo-dicom庫其實是相同的,只不過fo-dicom利用了最新的C#技術來重構(gòu)mDCM。如博文http://blog.csdn.net/zssureqh/article/details/39621533中給出的mDCM庫的繼承圖所示,在頂層基類DcmNetworkBase中實現(xiàn)了DIMSE消息流的基本框架,然后按照Client和Server進行了兩路派生。mDCM的封裝有點處于DCMTK和fo-dicom之間的狀況,既未做到像DCMTK那樣完全提供各個層面底層操作函數(shù),也沒有像fo-dicom那樣更抽象的封裝

? ? ? ? 下面來看一下mDCM對各種消息的構(gòu)造:

mDCM之C-ECHO:

?

//DcmAssociation assoction;//已經(jīng)順利建立的DICOM對等實體間的連接 byte pcid=associate.FindAbstractSyntax(DicomUID.VerificationSOPClass; SenCEchoRequest(pcid,NextMessageID(),Priority);

?

? ? ? ? mDCM比較特殊,對于DIMSE-C服務請求的參數(shù)賦值流程與fo-dicom類似,大多參數(shù)賦值都在基類中完成,例如DcmClientBase中完成了MaxPDU、Priority,DicomClient完成CallingAE和CalledAE等;而對于整體請求消息的拼接卻又類似DCMTK,在SendCEchoRequest函數(shù)內(nèi)部調(diào)用CreateRequest來完成。

mDCM之C-FIND:

?

byte pcid = Associate.FindAbstractSyntax(FindSopClassUID); if (Associate.GetPresentationContextResult(pcid) == DcmPresContextResult.Accept) { DcmDataset dataset = query.ToDataset(Associate.GetAcceptedTransferSyntax(pcid)); SendCFindRequest(pcid, NextMessageID(), Priority, dataset);

?

? ? ? ? 在query.ToDataset函數(shù)內(nèi)部完成了查詢級別QueryRetrieveLevel的賦值,另外需要注意的是此時在ToDataset函數(shù)內(nèi)部調(diào)用了一個虛函數(shù)AdditonalMembers用于方便派生添加自已要查詢的Identifier元素。最終還是在SendCFindRequest函數(shù)內(nèi)部利用CreateRequest創(chuàng)建C-FIND-RQ消息(在mDCM中的類型是DcmCommand)。

mDCM之C-STORE:

?

internal void SendCStoreRequest(byte pcid, DicomUID instUid, Stream stream) {SendCStoreRequest(pcid, NextMessageID(), instUid, Priority, stream);}internal void SendCStoreRequest(byte pcid, DicomUID instUid, DcmDataset dataset) {SendCStoreRequest(pcid, NextMessageID(), instUid, Priority, dataset);}

?

? ? ? ? 在CStoreClient類內(nèi)部通過Load來載入dcm文件,提取DcmDataset數(shù)據(jù)體,然后調(diào)用SendCStoreRequest來發(fā)送C-STORE-RQ請求(DicomCStoreClient中有兩種類型的SendCStoreRequest,一種是發(fā)送DcmDataset類型數(shù)據(jù),一種是發(fā)送Stream類型數(shù)據(jù))。

總結(jié):

? ? ? ? 通過對比分析三種開源庫對DIMSE-C服務消息的構(gòu)造方式,可以更清晰的了解DCMTK、fo-dicom、mDCM三者各自的優(yōu)勢。如果想了解DICOM協(xié)議的細節(jié)及底部代碼的具體實現(xiàn),自然DCMTK是首選,其按照Dicom Upper Layer、A-ASSOCIATE、DIMSE三層來劃分的結(jié)構(gòu)更方便我們研究DICOM網(wǎng)絡傳輸?shù)臋C制。并且DCMTK最新的3.6.1版本也逐漸開始按服務來對DUL_、ASC_、DIMSE_三類函數(shù)進行封裝,已經(jīng)實現(xiàn)了C-ECHO、C-STORE服務,即DcmSCU/DcmSCP和DcmStorageSCU/DcmStorageSCP。如果想快速入手,實現(xiàn)DICOM的相關服務,fo-dicom自然是首選,想必這對于C#程序員來說輕而易舉(mDCM可以看做是DCMTK與fo-dicom的中間地帶)。

DCMTK工程實例:

百度網(wǎng)盤:http://pan.baidu.com/s/1jGvaSr8

后續(xù)博文介紹:

fo-dicom搭建簡單的DICOM Server

總結(jié)

以上是生活随笔為你收集整理的【转】DICOM医学图像处理:DIMSE消息发送与接收“大同小异”之DCMTK fo-dicom mDCM的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 亚洲综合一区在线观看 | 免费在线看污片 | 非洲黑人狂躁日本妞 | 久久久久亚洲av成人网人人软件 | 99国产在线播放 | 亚洲国产一区在线 | 三级av| 神马午夜一区 | 久久99精品久久久久婷婷 | 欧美日韩国产在线观看 | 国产成人精品av | 精品91自产拍在线观看二区 | 亚洲视频www | 精品九九九九 | 依人综合网| 日本高清视频一区二区 | 福利在线国产 | 蜜桃视频一区二区 | 国产三级aaa | 国产三级精品视频 | 成人网在线观看 | 日本一区视频在线播放 | 国产人久久人人人人爽 | 久久艹免费视频 | 香蕉视频网站入口 | 国内成人自拍 | 看一级片 | 天天曰夜夜操 | 成人黄色免费 | 国产av一区二区三区精品 | 日本一区久久 | 日本在线中文字幕专区 | 日韩av手机在线免费观看 | 亚洲综合在 | 天天操天天干天天插 | 亚洲精品一级 | 青青草原伊人 | 亚洲自拍小视频 | 福利电影在线播放 | 亚洲性图一区二区 | 一本之道久久 | 小泽玛利亚一区二区三区视频 | 在线射| 村上凉子av | 亚洲青春草 | 久久入口 | 午夜视频网站 | 放几个免费的毛片出来看 | 亚洲综合在| 影音先锋亚洲一区 | 能看毛片的网站 | 日本精品一区二区三区四区的功能 | 激情五月激情 | 激情爱爱网 | 精品国产aⅴ麻豆 | 国产91免费视频 | av嫩草| 国产主播av| 欧美日韩福利视频 | 啪啪网站免费观看 | 诱人的乳峰奶水hd | 黄色片亚洲| aa一级黄色片 | 精品国产无码在线 | 午夜激情在线播放 | 久草视频这里只有精品 | 在线看三级 | 黄色美女毛片 | 亚洲69av| 久久久久国产精品一区 | 日韩理论片| 超碰黄色 | 韩国美女黄色片 | 九九自拍 | 三上悠亚ssⅰn939无码播放 | 欧美激情15p | 亚洲天堂免费在线观看视频 | 免费欧美 | 亚洲欧美日本一区二区三区 | 午夜精品久久久久久久99老熟妇 | av男人的天堂网 | 女人扒开屁股让我添 | 蜜桃免费在线视频 | 91精品国自产| 哪个网站可以看毛片 | 97看片吧| 玖玖视频在线 | 久久九九久精品国产免费直播 | 爱爱视频网 | 久久av无码精品人妻出轨 | 少妇太紧太爽又黄又硬又爽小说 | 麻豆视频免费版 | 少妇太紧太爽又黄又硬又爽 | 国产精品交换 | 国产a久久 | 精品国产第一页 | 欧美激情视频一区二区 | 黄页av| 第一色综合 |