当前位置: 首页 > news >正文

鹰潭市网站建设_网站建设公司_Sketch_seo优化

网站建设江苏,公司网址正确格式,平面设计图网站,安卓网页视频下载调用Xvid编码器流程(基于xvid1.1.0) 编者按#xff1a;本文为Xvid最新源代码V1.1.0版本的学习笔记#xff0c;内 部资料#xff0c;仅供学习参考#xff0c;未经授权#xff0c;不得转载 xvid有两种编码方式#xff1a;single pass和twopass single pass模式编码简…调用Xvid编码器流程(基于xvid1.1.0) 编者按本文为Xvid最新源代码V1.1.0版本的学习笔记内 部资料仅供学习参考未经授权不得转载 xvid有两种编码方式single pass和twopass single pass模式编码简单速度也快但最终效果不如twopass。 twopass就是视频压制需要经过两次编码分别为twopass1st pass简称1pass和twopass2nd pass简称2pass 1pass时编码器会用最高质量编码采集可供第2次运算参考的画面信息而在2 pass时。编码器会根据第一次压缩获得的信息和用户指定的文件大小自动分配比特率使需要高流量的运动画面分配到更多的空间更高的比特率来保证画面质量。相对的对于那些不包含太多运动信息的静态画面则用较低的比特率。追求画质的朋友当然会选择这种方式但运算比single pass更费时。 接下来介绍一些基本概念 Q值——量化值它被用来描述1帧的质量每帧都有一个Q值取值范围在131之间。Q值越小画质越好比特率越大 Iframe——关键帧常被缩写为IF。关键帧是构成一个帧组的第一帧。IF保留了一个场景的所有信息 Pframe——未来单项预测帧缩写为PF只储存与之前一个已解压画面的差值 Bframe——双向预测帧缩写为BF除了参考之前解压的画面以外也会参考后一帧的画面信息 编码流程 各变量的设置创建xvid_enc_frame_t和xvid_enc_stats_t分别用于传入参数和统计编码结果。 具体过程 设置传入图像数据和图像色彩空间 设置传出的码流 设置vol的标志 设置帧的编码类型 设置量化因子 设置运动估计算法集合 设置vop的标志 编码器提供的函数 1                         xvid_global(NULL, XVID_GBL_INIT, xvid_gbl_init, NULL); 含义根据cpu的特性使用相应汇编优化的函数 2 xvid_encore(NULL, XVID_ENC_CREATE, xvid_enc_create, NULL); 含义初始化编码器。 具体过程 创建编码器句柄并根据传入的参数设置各变量的值并且分配要使用的内存用于存放重建帧参考帧1/2像素精度。以及各种临时变量。并且做好码率控制的初始化。 3 xvid_encore(enc_handle, XVID_ENC_ENCODE, xvid_enc_frame, xvid_enc_stats); 目的编码一帧 具体过程 { 初始化写码流。 如果有必要转换色彩空间并且把原始图像拷贝到有边框的图像空间但是没有扩展边框。 将重建帧交换成参考帧 从帧队列中获取当前帧 设置Encoder结构体的current结构体的vol_flagsvop_flagsmotion_flagsfcodebcode和quant字段。 调用call_plugins在里面调用rc_single_before做码率控制的初始化以及对current结构体的其他变量进一步设置通过帧号或者MEanalysis函数分析来确定编码类型并且根据用户的设置作修正。 MEanalysis的原理是如果某个宏块的残差的sad大于该宏块的平均值的偏离那么使用intra方式否则使用inter方式然后对这些宏块进行统计得到整帧的编码方式。 如果编码类型是I_VOP { 设置Encoder-mbParam-vol_flags 设置Encoder-mbParam.par 根据vol_flags设置vop_flags 调用FrameCodeI以I帧的方式编码 调用call_plugins在里面调用rc_single_after进行码率控制。 } 如果编码类型是P_VOP { 用mbParam.vol_flags固定pEnc-current-vol_flags 调用FrameCodeP以P帧的方式编码 调用call_plugins在里面调用rc_single_after进行码率控制。 } }// xvid_encore 编者按本文为Xvid最新源代码V1.1.0版本的学习笔记内部资料仅供学习参考未经授权不得转载 xvid有两种编码方式single pass和twopass single pass模式编码简单速度也快但最终效果不如twopass。 twopass就是视频压制需要经过两次编码分别为twopass1st pass简称1pass和twopass2nd pass简称2pass 1pass时编码器会用最高质量编码采集可供第2次运算参考的画面信息而在2 pass时。编码器会根据第一次压缩获得的信息和用户指定的文件大小自动分配比特率使需要高流量的运动画面分配到更多的空间更高的比特率来保证画面质量。相对的对于那些不包含太多运动信息的静态画面则用较低的比特率。追求画质的朋友当然会选择这种方式但运算比single pass更费时。 接下来介绍一些基本概念 Q值——量化值它被用来描述1帧的质量每帧都有一个Q值取值范围在131之间。Q值越小画质越好比特率越大 Iframe——关键帧常被缩写为IF。关键帧是构成一个帧组的第一帧。IF保留了一个场景的所有信息 Pframe——未来单项预测帧缩写为PF只储存与之前一个已解压画面的差值 Bframe——双向预测帧缩写为BF除了参考之前解压的画面以外也会参考后一帧的画面信息 编码流程 各变量的设置创建xvid_enc_frame_t和xvid_enc_stats_t分别用于传入参数和统计编码结果。 具体过程 设置传入图像数据和图像色彩空间 设置传出的码流 设置vol的标志 设置帧的编码类型 设置量化因子 设置运动估计算法集合 设置vop的标志 编码器提供的函数 1 xvid_global(NULL, XVID_GBL_INIT, xvid_gbl_init, NULL); 含义根据cpu的特性使用相应汇编优化的函数 2 xvid_encore(NULL, XVID_ENC_CREATE, xvid_enc_create, NULL); 含义初始化编码器。 具体过程 创建编码器句柄并根据传入的参数设置各变量的值并且分配要使用的内存用于存放重建帧参考帧1/2像素精度。以及各种临时变量。并且做好码率控制的初始化。 3 xvid_encore(enc_handle, XVID_ENC_ENCODE, xvid_enc_frame, xvid_enc_stats); 目的编码一帧 具体过程 { 初始化写码流。 如果有必要转换色彩空间并且把原始图像拷贝到有边框的图像空间但是没有扩展边框。 将重建帧交换成参考帧 从帧队列中获取当前帧 设置Encoder结构体的current结构体的vol_flagsvop_flagsmotion_flagsfcodebcode和quant字段。 调用call_plugins在里面调用rc_single_before做码率控制的初始化以及对current结构体的其他变量进一步设置 通过帧号或者MEanalysis函数分析来确定编码类型并且根据用户的设置作修正。 MEanalysis的原理是如果某个宏块的残差的sad大于该宏块的平均值的偏离那么使用intra方式否则使用inter方式然后对这些宏块进行统计得到整帧的编码方式。 如果编码类型是I_VOP { 设置Encoder-mbParam-vol_flags 设置Encoder-mbParam.par 根据vol_flags设置vop_flags 调用FrameCodeI以I帧的方式编码 调用call_plugins在里面调用rc_single_after进行码率控制。 } 如果编码类型是P_VOP { 用mbParam.vol_flags固定住pEnc-current-vol_flags 调用FrameCodeP以P帧的方式编码 调用call_plugins在里面调用rc_single_after进行码率控制。 } }// xvid_encore 4 static int FrameCodeI(Encoder * pEnc, Bitstream * bs) 目的将一帧图像编码成一个I帧 具体过程 以XVID_PLG_FRAME参数调用call_plugins该函数目前的作用是设置dquant可以在该函数中设置最好质量。 调用SetMacroblockQuants为每个宏块设置量化因子所以也可以在这里设置最好质量 调用BitstreamWriteVolHeader写vol 调用set_timecodes设置时间编码。 调用BitstreamPad填充bit至字节对齐 调用BitstreamWriteVopHeader填写vop头 依次读取每一个宏块进行编码 { 调用CodeIntraMB设置编码模式为intra将所有和运动有关的变量设为0 调用MBTransQuantIntra进行变换编码 { 调用MBTrans8to16将像素的表示方法从8bit扩大到16bit 调用MBfDCT对像素进行变换编码 调用MBQuantIntra对dct系数进行intra方式的量化 调用MBDeQuantIntra对dct系数进行intra方式的反量化 调用MBiDCT将恢复的dct系数进行反变换 调用MBTrans16to8将恢复的16bit像素饱和到8bit组成重建宏块 }//MBTransQuantIntra 调用MBPrediction作acdc预测 { 调用get_dc_scaler函数得到量化系数 调用predict_acdc得到预测方向以及在该预测方向上的和当前块的同一量化水平的预测值 调用calc_acdc_bits以确定是只使用DC预测还是DCAC预测。原理是分别作DC预测和DCAC预测分别计算在这2种情况下需要的码流长度以确定哪种方式更节约码流。 调用CodeCoeffIntra_CalcBits用于确定各种方式下的码流长度 根据预测模式的不同恢复成相应的系数 最后计算该宏块的cbp }//MBPrediction 调用MBCoding将宏块编制成码流 { 调用CodeBlockIntra将intra宏块编制成码流 { 编码mcbpc 编码ac预测标记 编码cbpy 对于6个块里的每个块 首先编码DC系数 调用CodeCoeffIntra对剩下的63个系数进行编码 }//CodeBlockIntra }//MBCoding }//依次读取每一个宏块进行编码 填充bit直到字节对齐 5 static int FrameCodeP(Encoder * pEnc, Bitstream * bs) 含义将一帧图片编码成P帧具体过程 { 如果参考帧还没有设置边框那么就调用image_setedges设置边框 如果需要半像素运动估计那么就调用image_interpolate进行插值 将一帧填充边框后的参考帧分成8*8的小块对于每个小块进行插值如下 调用interpolate8x8_halfpel_h进行水平插值 调用interpolate8x8_halfpel_v进行垂直插值 调用interpolate8x8_halfpel_hv进行对角线插值 用参数XVID_PLG_FRAME调用call_plugins该函数目前的作用是设置dquant可以在该函数中设置最好质量。 调用SetMacroblockQuants为每个宏块设置量化因子所以也可以在这里设置最好质量 调用MotionEstimation做运动估计 { 使用MotionFlags变量保存要使用的运动算法集合 使用skip_thresh保存要达到skip模式的阀值 使用Data保存运动估计要用到的相应变量 对于每个宏块依次执行如下操作 { 调用sad16v计算本宏块与参考帧对应位置宏块的亮度的残差将其保存在pMB-sad16中并按照4个块的方式分别存放pMB-sad8[0-3]中 用sad00记录最大亮度块残差的4倍 如果还需要考虑色差块的因素 调用sad8两次分别计算u分量和v分量的残差都加入pMB-sad16中并且也加入sad00中 如果该宏块的量化差值为0并且sad00又没有超过skip模式的阀值 如果已经考虑了色差因素或者使用xvid_me_SkipDecisionP确认符合skip模式。 调用ZeroMacroblockP将其编码为skip模式并置标记pMB-mode MODE_NOT_CODED 根据采用的运动估计算法不同做相应的设置 调用SearchP做该宏块的运动估计 { 确定是否使用inter4v模式并记录之 调用get_range确定运动搜索的范围并记录在Data中 调用get_pmvdata2以获得左上右上的运动向量以及它们对应的sad存入pmv[1-3]和Data-temp[1-3]。然后计算它们的中值并且存放于pmv[0]并且把最小的sad存放于Data-temp[0] 设置Data的当前宏块的yuv字段。设置Data-RefP[0-5]为参考帧的同一宏块的整像素y水平半象素y垂直半象素y对角线yuv。 设置Data-lambda16和Data-lambda8其含义可能是运动向量对带宽的占用折合到sad的值 设置qpel和方向 如果采用qpel调用get_qpmv2计算用qple方式下的估计中值存入ata-predMV否则Data-predMV为0。 调用d_mv_bits计算mv需要的编码bit用于修正pMB-sad16和pMB-sad8[0]并将Data-iMinSAD[0-4]设置为pMB-sad16和pMB-sad8[0-3]也就是0向量对应的各SAD。 如果不采用率失真决策模型并且不是当前帧的第一宏块那么使用一种方法设置阀值threshA否则阀值threshA为512。 调用PreparePredictionsP对pmv作进一步的设置做运算前的准备。 { 设置pmv[0]为0向量 设置pmv[1]为中值向量的偶数值 设置pmv[2]为参考帧相同位置宏块的第0块运动向量的偶数值 如果该宏块有左边宏块设置pmv[3]为左边宏块的第1块的运动向量的偶数值否则为0 如果该宏块有上面宏块设置pmv[4]为上面宏块的第2块的运动向量的偶数值否则为0 如果该宏块有右上宏块设置pmv[5]为右上宏块的第2块的运动向量的偶数值否则为0 如果该宏块有右下宏块设置pmv[6]为参考帧的相同宏块的右下宏块的第0块的运动向量的偶数值否则为0。 }//PreparePredictionsP 如果使用inter4v设置CheckCandidate为CheckCandidate16否则设置为CheckCandidate16no4v 逐一检查mpv[1-6]这六个最可能运动向量如果发现他们与以前的运动不同就调用CheckCandidate做运动估计过程如下 { 检查要做运动估计的运动向量是否越界 通过该运动向量获得所指向数据块的指针 调用sad16v记录下4个8*8块的SAD值存入data-temp[0-3]中并将他们的和存入临时变量sad中。 对sad和data-temp[0]做基于运动向量的修正。 如果要考虑色差因素调用xvid_me_ChromaSAD计算额外的SAD累加至sad中。 如果sad小于data-iMinSAD[0]那么设置data-iMinSAD[0]data-currentMV[0]和data-dir。注意此时的data-dir记录的不是钻石搜索的方向而是当前向量是pmv数组的第几个元素。 逐一检查data-temp[0-3]如果他们小于data-iMinSAD[1-4]那么修改data-iMinSAD[1-4]和data-currentMV[1-4] }//CheckCandidate 如果当前最优运动向量即Data-iMinSAD[0]小于threshA或者当前最优运动向量等于参考帧相同位置宏块的运动向量并且对应的SAD值又比他的小 就不再做inter4v的搜索 否则就做inter4v的搜索 { 使用make_mask逐一检查存放于pmv的所有运动向量察看是否位于欲搜索的钻石形的顶点。如果是则在mask变量中标记之。 根据MotionFlags确定使用的搜索函数根据当前设置MainSearchPtr xvid_me_AdvDiamondSearch 调用xvid_me_AdvDiamondSearch进行搜索过程如下 { bDirection既表明了上次尝试的方向又表明本次可以尝试的方向 xy为钻石搜索的位置的中心点坐标 for(;;) { 如果可以尝试左边那么调用CheckCandidate尝试左边 如果可以尝试右边那么调用CheckCandidate尝试右边 如果可以尝试上边那么调用CheckCandidate尝试上边 如果可以尝试下边那么调用CheckCandidate尝试下边 如果有更好的方向 { bDirection 更好的方向 如果更好的方向是左右方向那么测试该位置的上下方向 否则那么测试该位置的左右方向 如果这次又找到了更好的方向 将更好的方向累加到bDirection 将更好的位置存入xy } 否则 { 根据去搜索临近未搜索的点具体规则如下 如果bDirection 2表明搜索方向是趋向右边的那么搜索当前中心点的右上点和右下点。 如果bDirection 1表明搜索方向是趋向左边的那么搜索当前中心点的左上点和左下点。 如果bDirection 24表明搜索方向是趋向右上的那么再搜索当前中心点的左上点右上点和右下点。 如果bDirection 4表明搜索方向是趋向上边的那么搜索当前中心点的左上点和右上点。 如果bDirection 8表明搜索方向是趋向下边的那么搜索当前中心点的左下点和右下点。 如果bDirection 14表明搜索方向是趋向左上的那么再搜索当前中心点的左下点左上点和右上点。 如果bDirection 28表明搜索方向是趋向右下的那么再搜索当前中心点的左下点左上点和右上点。 如果bDirection 18表明搜索方向是趋向左下的那么再搜索当前中心点的左上点左下点和右下点。 否则的话则认为本轮搜索没有找到更好的点那么再搜索当前中心点的左上点左下点右上点右下点。 } 如果没有找到更好的方向从函数中返回 更新bDirection为更好的方向 更新xy为更好的位置 }//for(;;) }//xvid_me_AdvDiamondSearch 如果运动估计算法使用了XVID_ME_EXTSEARCH16那么 { 设置startMV Data-predMV 设置backupMV为当前最佳运动向量 如果startMV和backupMV不相等 { 调用CheckCandidate计算位置为startMV的SAD 调用xvid_me_DiamondSearch做以startMV为起点的搜索过程如下 { for(;;) { 如果可以尝试左边那么调用CheckCandidate尝试左边 如果可以尝试右边那么调用CheckCandidate尝试右边 如果可以尝试上边那么调用CheckCandidate尝试上边 如果可以尝试下边那么调用CheckCandidate尝试下边 如果没有更好的方向退出 bDirection 更好的方向 xy 更好的位置 如果更好的方向是左右方向那么测试该位置的上下方向 否则那么测试该位置的左右方向 如果这次又找到了更好的方向 { bDirection 更好的方向 xy 更好的位置 } } }//xvid_me_DiamondSearch 将这次搜索结果和上次搜索结果比较记录最佳的SAD和位置。 }//如果startMV和backupMV不相等 设置startMV {11} 设置backupMV为当前最佳运动向量 如果startMV和backupMV不相等 { 调用CheckCandidate计算位置为startMV的SAD 调用xvid_me_DiamondSearch做以startMV为起点的搜索过程如下 将这次搜索结果和上次搜索结果比较记录最佳的SAD和位置。 } }//如果运动估计算法使用了XVID_ME_EXTSEARCH16 }//否则就做inter4v的搜索 如果没有采用1/4像素运动估计算法 { 如果采用了XVID_ME_HALFPELREFINE16算法 调用xvid_me_SubpelRefine 按顺时针方向8次调用CheckCandidate16得到最好的1/2像素位置 } 否则 略 如果当前SAD足够小那么inter4v 0 如果采用inter4v { 4次调用Search8来搜索4个8*8块的最佳运动向量每一次搜索的规则如下 { 如果采用1/4像素运动估计略。否则 调用get_pmv2取得本块的中值 计算第一块以外快的d_mv_bits 用Data-lambda8修正该块当前的SAD但是第0块是不用修正的。 如果使用了XVID_ME_EXTSEARCH8 | XVID_ME_HALFPELREFINE8 | XVID_ME_QUARTERPELREFINE8那么 { Data-RefP[0-3] 参考帧的整像素水平半象素垂直半象素对角线半象素的对应宏块的对应块的起始地址。 Data-Cur 当前帧的当前宏块的当前块的起始地址 利用get_range得到运动搜索的范围 根据MotionFlags的指示设定运动估计MainSearchPtr的算法当前设置为MainSearchPtr xvid_me_AdvDiamondSearch。 调用xvid_me_AdvDiamondSearch做运动估计其中做SAD的函数是CheckCandidate8该函数类似于CheckCandidate16 如果不采用1/4像素运动估计并且又采用了XVID_ME_HALFPELREFINE8那么调用xvid_me_SubpelRefine 按顺时针方向8次调用CheckCandidate8得到最好的1/2像素位置 如果采用了1/4像素运动估计略 }// XVID_ME_EXTSEARCH8 | XVID_ME_HALFPELREFINE8 | XVID_ME_QUARTERPELREFINE8 如果采用1/4运动估计 略 否则 记录pMB-pmvs[block] 当前找到的最佳位置与预测位置的差值 将这次的搜索存入相应OldData的字段以及pMB的相应字段 }// Search8 如果考虑色差的因素并且又不考虑率失真算法 { 根据是否采用1/4像素运动估计算出色差的运动向量 计算uv的SAD将其作为Data-iMinSAD[1]的修正 } } //如果采用inter4v 否则Data-iMinSAD[1]为足够大的值 }//SearchP 调用ModeDecision_SAD确定该宏块的类型 判断该宏块要采取的编码方式MODE_INTERMODE_INTER4VMODE_NOT_CODEDMODE_INTRA 调用motionStatsPVOP做一些统计工作 具体过程略 }//对于每个宏块依次执行如下操作 做一些最后的设置 }//MotionEstimation 调用set_timecodes设置时间戳 调用BitstreamWriteVopHeader写VOP头 具体过程略 对于每一个宏块依次执行如下操作 { 如果该宏块的编码模式是MODE_INTRA或者MODE_INTRA_Q { 调用CodeIntraMB设置编码模式为intra将所有和运动有关的变量设为0 调用MBTransQuantIntra进行变换编码 调用MBCoding将该宏块编制成码流 Continue } 调用MBMotionCompensation做运动补偿 { 如果编码模式是MODE_NOT_CODED 用参考帧的相应宏块替代当前帧的当前宏块 Return 如果编码模式是MODE_NOT_CODED或者MODE_INTER或者MODE_INTER_Q { 如果mb-mcsel不为0 做GMC的处理 Return 计算运动向量dxdy 调用compensate16x16_interpolate进行运动补偿 { 如果采用1/4像素运动估计 略 否则调用get_ref计算用于运动补偿的参考宏块的指针 调用4次transfer_8to16sub做亮度块的运动补偿使得临时数组里存放的是残差而原始图像里存放的是参考快的数据。 }//compensate16x16_interpolate 计算出用于色差运动补偿的dxdy }//MODE_NOT_CODED或者MODE_INTER或者MODE_INTER_Q 否则那就是MODE_INTER4V { 根据是否使用1/4像素运动估计计算出4个色度块的运动向量 以这4个运动向量为参数调用4次compensate8x8_interpolate 该操作类似于compensate16x16_interpolate不同在于一次只计算一个块。 计算出用于色差运动补偿的dxdy } 调用CompensateChroma计算色差块的运动补偿 { 调用interpolate8x8_switch2计算出u的插值 调用interpolate8x8_halfpel_v或者interpolate8x8_halfpel_h或者interpolate8x8_halfpel_hv做实际的插值操作或者直接返回 调用transfer_8to16sub_c做u份量的运动补偿 调用interpolate8x8_switch2计算出v的插值 调用interpolate8x8_halfpel_v或者interpolate8x8_halfpel_h或者interpolate8x8_halfpel_hv做实际的插值操作或者直接返回 调用transfer_8to16sub_c做v份量的运动补偿 }//CompensateChroma }//MBMotionCompensation 如果需要编码那么用MBTransQuantInter进行编码并把结果返回给pMB-cbp { 调用MBfDCT进行宏块变换编码 调用6次fdct 调用MBQuantInter进行量化 { 对于宏块里的每一块 { 调用quant_h263_inter进行量化 如果在量化后前三个系数为0并且系数的绝对值之和小于阀值那么标记该块为全0块将标记存入cbp。否则标记为非全0块也将标记存入cbp } }//MBQuantInter 调用MBDeQuantInter反量化 { 确定要使用的反量化函数 对于六个块里的每个块如果cbp表示许可都调用dequant_h263_inter反量化 }//MBDeQuantInter 调用MBiDCT做反离散余弦变换 对于六个块里的每个块如果cbp表示许可都调用idct_int32反量化 调用MBTrans16to8将恢复出的残差构成重建图像 { 确定具体执行的函数分为transfer_16to8copy和transfer_16to8add 找到该宏块的yuv分量起始地址 对于六个块里的每个块如果cbp表示许可调用相应得函数执行重建。 }// MBTrans16to8 }//MBTransQuantInter 如果无残差并且编码方式为MODE_INTER并且帧方式是P帧并且向量2分量都为0那么可以考虑skip模式 如果可以考虑skip模式则做进一步检验如果检验通过那么 { 编码模式为MODE_NOT_CODED并且在码流里做标记 Continue } 调用MBCoding将这个宏块写入码流 { 写入非NOT_CODED标记 调用CodeBlockInter写入码流 { 编码mcbpc 编码cbpy 调用CodeVector编码运动向量 对六个块如果cbp只是需要编码调用CodeCoeffInter进行编码 }//CodeBlockInter }// MBCoding }//对于每一个宏块依次执行如下操作 更新fcode 为下一帧的编码做简单的更新设置 统计该帧编码长度 }// FrameCodeP
http://www.ihoyoo.com/news/135547.html

相关文章:

  • 江西合创建设工程有限公司 网站百度地图开发网站
  • wordpress多站点管理wordpress the_post分类id
  • 济宁网站建设第一品牌站长工具seo综合查询烟雨楼
  • 网站制作青岛公司网页定制多少钱
  • 市区网站建设情况北京商场面积排名
  • 企业做国外网站多少钱如何在wordpress底部添加友情链接
  • 织梦网站调整wordpress用的什么主题
  • 龙岗南联网站建设公司服装网络营销是什么
  • 网站建设和推广话术网站开发开源软件
  • 做网站图片不够大网站做支付需要准备什么东西吗
  • 网站建设主动型电话销售话术user post wordpress
  • 我要建立网站网页设计制作音乐排行榜
  • 广州建设网站外包宁波seo整体优化
  • 男人和女人在床上做那个网站网站开发交什么税
  • ipv6域名解析 做网站百度首页网址
  • angularjs 网站开发安卓市场2022最新版下载
  • 怎么设置自己的网站常州优化网站
  • 四川手机响应式网站建设设计wordpress 二次元
  • 鞍山做网站优化四川手机网站有哪些
  • 做推广网站的文章外贸网站优化价格
  • 如何根据流量选择网站wordpress中文广告插件
  • 南通网站建设ntwsd单品商城网站源码
  • 合肥效果好的网站推广南昌做seo的公司有哪些
  • 网站超级链接怎么做自己做衣服网站
  • 做网站内嵌地图织梦模板添加网站地图
  • 网站排行榜查询银川做网站的有哪些
  • 小说网站防盗做的好处网站做优化一开始怎么做
  • 大好网站计算机网站开发开题报告范文
  • 一个网站怎么做2个服务器网站信息员队伍建设
  • 网站备案会过期吗电子商务网站建设与管理试卷