石家庄网站定制模板建站画册设计理念

张小明 2026/1/19 18:58:58
石家庄网站定制模板建站,画册设计理念,海伦市网站,青海省住房与城乡建设厅网站背景 需要将h264/h265编码转成svac 思路 先将采集过来的h264或者h265进行分析#xff0c;看是否可以进行转码#xff0c;如果可行#xff0c;则交由中星微的转码设备进行svac转码#xff0c;如果是rockship平台的话#xff0c;因为要求性能要尽可能的高#xff0c;就不经…背景需要将h264/h265编码转成svac思路先将采集过来的h264或者h265进行分析看是否可以进行转码如果可行则交由中星微的转码设备进行svac转码如果是rockship平台的话因为要求性能要尽可能的高就不经由ffmpeg来调用mpp了而是直接调用mpp接口来进行h264-h265的转码如果是普通的x86平台的话考虑到通用性用的ffmpg的库来进行的转码调用svac的软库来进行转码需要将这两种平台的差异抽象出来方便上层应用来调用代码//lencoder.h #ifndef _LENCODER_H_ #define _LENCODER_H_ #include stdint.h #ifdef __cplusplus extern C { #endif enum H265_FRAME_TYPE { TRAIL_R 1, BLA_W_LP 16, BLA_W_RADL 17, BLA_N_LP 18, IDR_W_RADL 19, IDR_N_LP 20, VPS_NUT 32, SPS_NUT 33, PPS_NUT 34, PREFIX_SEI_NUT 39, SUFFIX_SEI_NUT 40, }; enum H264_FRAME_TYPE { NAL_SLICE 1, NAL_SLIC_DPA 2, NAL_SLICE_DPB 3, NAL_SLICE_DPC 4, NAL_SLICE_IDR 5, NAL_SEI 6, NAL_SPS 7, NAL_PPS 8, NAL_AUD 9, NAL_FILLER 12, }; #define LENCODER_STATUS_OK 0X00000000 #define LENCODER_STATUS_ERR 0X01000000 #define LENCODER_NO_SPACE_ERR LENCODER_STATUS_ERR 1 #define LENCODER_CREATE_ENCODER_ERR LENCODER_STATUS_ERR 2 #define LENCODER_PREFETCH_ENCODER_ERR LENCODER_STATUS_ERR 3 #define LENCODER_NO_IDLE_ERR LENCODER_STATUS_ERR 4 #define LENCODER_TRANSOCER_ERR LENCODER_STATUS_ERR 5 #define LENCODER_UNKNOWN_NALU_TYPE LENCODER_STATUS_ERR 6 #define LENCODER_CONTINUING LENCODER_STATUS_ERR 7 #define LENCODER_LOST_DEVICE LENCODER_STATUS_ERR 8 #define LENCODER_OPEN_FAILED_DEVICE LENCODER_STATUS_ERR 9 #define LENCODER_UNKNOWN_ENCODER_TYPE LENCODER_STATUS_ERR 10 #define LENCODER_EMPTY_FRAME_TYPE LENCODER_STATUS_ERR 11 #define LENCODER_MPP_CREATE_ERR LENCODER_STATUS_ERR 12 #define LENCODER_MPP_WRITE_ERR LENCODER_STATUS_ERR 13 #define LENCODER_MPP_GET_NULL LENCODER_STATUS_ERR 14 #define LENCODER_MPP_WRITE_FULL LENCODER_STATUS_ERR 15 #define LENCODER_LOAD_CFG_ERR LENCODER_STATUS_ERR 16 #define LENCODER_LOAD_CFG_VALUE_ERR LENCODER_STATUS_ERR 17 typedef struct lencoder_context_t * lencoder_context; typedef struct lencoder_mpp_context_t * lencoder_mpp_context; typedef struct lencoder_t * lencoder; /* typedef struct lencoder_frame_t { int frame_type; //1 I帧 2 P帧 unsigned char *frame; int frame_len; }lencoder_frame; */ int lencoder_init(lencoder *coder); int lencoder_maxnum_get(lencoder coder); int lencoder_open_ext(lencoder coder, lencoder_context *context, int fmt, unsigned char *pbuf, int buflen, int bit_rate, int fps, int gop); int lencoder_open(lencoder coder, lencoder_context *context, int fmt, unsigned char *pbuf, int buflen); //1 I帧 2 P帧 //while(lencoder_get_frame(ctx, frame, frame_len, frame_type) LENCODER_STATUS_OK) { // //free(frame); //} int lencoder_get_frame_ext(lencoder_context context, unsigned char **frame, unsigned int *frame_len, int *frame_type, int *iskey, int64_t *pts, int64_t *dts); int lencoder_get_frame(lencoder_context context, unsigned char **frame, unsigned int *frame_len, int *frame_type); int lencoder_transcode(lencoder_context context, unsigned char *in, int in_len); void lencoder_close(lencoder coder, lencoder_context *context); int lencoder_mpp_open(lencoder coder, lencoder_mpp_context *context); // brief 指定待转码的编码格式以及解码后再编码格式 // param coder 句柄 // param context 转码会话 // param src_fmt 1.H264 2.H265 // param dst_fmt 1.H264 2.H265 // return LENCODER_STATUS_OK 否则返回错误码 int lencoder_mpp_open_ext(lencoder coder, lencoder_mpp_context *context, int src_fmt, int dst_fmt); int lencoder_mpp_get_frame(lencoder_mpp_context context, unsigned char **out, int *out_len); int lencoder_mpp_transcode(lencoder_mpp_context context, unsigned char *in, int in_len); void lencoder_mpp_close(lencoder_mpp_context *context); int lencoder_decoder_get(lencoder coder); void lencoder_destroy(lencoder *coder); #ifdef __cplusplus } #endif #endif#include lencoder.h#include locale.h#define LENCODER_CFG_FILE “/usr/local/media_encoder.json”#if defined(i386) || defined(_M_IX86) || defined(x86_64)#include string.h#include stdlib.h#include stdio.h#include “x86/soft_encoder.h”#else#include “arm/vimicro_encoder.h”#include “arm/mpp_encoder.h”#include json-c/json.h#endif#if defined(i386) || defined(_M_IX86) || defined(x86_64)struct lencoder_t {encoder_soft s;unsigned char *resive;};struct lencoder_context_t {int first;encoder_soft_context ctx;};#elsestruct lencoder_context_t {usb_list *usb;int first;int current_num;int hasread;svac_frame *frameout;int frame_count;USBDEC_VIDEO_FORMAT srcfmt;};struct lencoder_mpp_context_t {mpp_encoder encoder;int first;int nobuffer;mpp_encoder decoder;};struct lencoder_t {encoder_usb vimirco;int maxnum;};#endif#if defined(i386) || defined(_M_IX86) || defined(x86_64)#elseint load_media_cfg(mpp_encoder coder){int ret LENCODER_STATUS_OK;struct json_object *cfg NULL, *watertext NULL;uint8_t text_water_enable, text_r, text_g, text_b;uint8_t text_fontsize, text_x, text_y;char text_context[128];char text_font_file[64];cfg json_object_from_file(LENCODER_CFG_FILE); if(!cfg) { return LENCODER_LOAD_CFG_ERR; } if(json_object_get_type(cfg) ! json_type_object) { json_object_put(cfg); return LENCODER_LOAD_CFG_VALUE_ERR; } watertext json_object_object_get(cfg, text); if(json_object_get_type(watertext) ! json_type_object) { json_object_put(watertext); json_object_put(cfg); return LENCODER_LOAD_CFG_VALUE_ERR; } json_object_object_foreach(watertext, key, val) { if(!key) { continue; } if(strcmp(key, enable) 0) { text_water_enable (uint8_t)json_object_get_int(val); } if(strcmp(key, color_r) 0) { text_r (uint8_t)json_object_get_int(val); } if(strcmp(key, color_g) 0) { text_g (uint8_t)json_object_get_int(val); } if(strcmp(key, color_b) 0) { text_b (uint8_t)json_object_get_int(val); } if(strcmp(key, content) 0) { snprintf(text_context, 128, %s, json_object_get_string(val)); } if(strcmp(key, position_x) 0) { text_x (uint8_t)json_object_get_int(val); } if(strcmp(key, position_y) 0) { text_y (uint8_t)json_object_get_int(val); } if(strcmp(key, font_size) 0) { text_fontsize (uint8_t)json_object_get_int(val); } if(strcmp(key, font_file) 0) { strcpy(text_font_file, json_object_get_string(val)); } } encoder_mpp_set_text_watertext(coder, text_context, text_r, text_g, text_b, text_fontsize, text_x, text_y, text_font_file, text_water_enable); json_object_put(cfg); return ret;}#endifint lencoder_init(lencoder *coder){int ret LENCODER_STATUS_OK, max_num 0;lencoder t;setlocale(LC_CTYPE, ); t (lencoder)malloc(sizeof(struct lencoder_t)); if (!t) { ret LENCODER_NO_SPACE_ERR; goto EndP; } memset(t, 0, sizeof(struct lencoder_t));#if defined(i386) || defined(_M_IX86) || defined(x86_64)ret soft_encoder_create(t-s);if(ret ! SOFT_ENCODER_OK) {ret LENCODER_CREATE_ENCODER_ERR;free(t);goto EndP;}#elseret vimicro_encoder_create((t-vimirco), max_num);if (ret 1) {free(t);ret LENCODER_CREATE_ENCODER_ERR;goto EndP;}t-maxnum max_num;#endif*coder t; ret LENCODER_STATUS_OK;EndP:return ret;}int lencoder_maxnum_get(lencoder coder){#if defined(i386) || defined(_M_IX86) || defined(x86_64)return 65535;#elsereturn coder-maxnum;#endif};int lencoder_mpp_open(lencoder coder, lencoder_mpp_context *context){int ret LENCODER_STATUS_OK;#if defined(i386) || defined(_M_IX86) || defined(x86_64)#elseMPP_RET err;lencoder_mpp_context ctx;ctx (lencoder_mpp_context)malloc(sizeof(struct lencoder_mpp_context_t)); if(!ctx) { ret LENCODER_NO_SPACE_ERR; goto EndP; } memset(ctx, 0, sizeof(struct lencoder_mpp_context_t)); err encoder_mpp_create((ctx-decoder), MPP_CTX_DEC, MPP_VIDEO_CodingAVC); if(err ! MPP_OK) { ret LENCODER_MPP_CREATE_ERR; free(ctx); goto EndP; } err encoder_mpp_create((ctx-encoder), MPP_CTX_ENC, MPP_VIDEO_CodingHEVC); if(err ! MPP_OK) { ret LENCODER_MPP_CREATE_ERR; free(ctx); encoder_mpp_destroy((ctx-decoder)); goto EndP; } ret load_media_cfg(ctx-encoder); if(ret ! LENCODER_STATUS_OK) { goto EndP; } ctx-first 1; *context ctx; printf(context is %p, *context is %p\n, context, *context); ret LENCODER_STATUS_OK;EndP:#endifreturn ret;}// src_fmt 1 h264 dst_fmt 2 h265int lencoder_mpp_open_ext(lencoder coder, lencoder_mpp_context *context, int src_fmt, int dst_fmt){int ret LENCODER_STATUS_OK;#if defined(i386) || defined(_M_IX86) || defined(x86_64)#elseMPP_RET err;lencoder_mpp_context ctx;MppCodingType decode_type, encode_type;ctx (lencoder_mpp_context)malloc(sizeof(struct lencoder_mpp_context_t)); if(!ctx) { ret LENCODER_NO_SPACE_ERR; goto EndP; } memset(ctx, 0, sizeof(struct lencoder_mpp_context_t)); if(src_fmt 1) { decode_type MPP_VIDEO_CodingAVC; } else { decode_type MPP_VIDEO_CodingHEVC; } if(dst_fmt 1) { encode_type MPP_VIDEO_CodingAVC; } else { encode_type MPP_VIDEO_CodingHEVC; } err encoder_mpp_create((ctx-decoder), MPP_CTX_DEC, decode_type); if(err ! MPP_OK) { ret LENCODER_MPP_CREATE_ERR; free(ctx); goto EndP; } err encoder_mpp_create((ctx-encoder), MPP_CTX_ENC, encode_type); if(err ! MPP_OK) { ret LENCODER_MPP_CREATE_ERR; free(ctx); encoder_mpp_destroy((ctx-decoder)); goto EndP; } ret load_media_cfg(ctx-encoder); if(ret ! LENCODER_STATUS_OK) { goto EndP; } ctx-first 1; *context ctx; printf(context is %p, *context is %p\n, context, *context); ret LENCODER_STATUS_OK;EndP:#endifreturn ret;}int lencoder_mpp_get_frame(lencoder_mpp_context context, unsigned char **out, int *out_len){int ret LENCODER_STATUS_OK;#if defined(i386) || defined(_M_IX86) || defined(x86_64)#elseMPP_RET err MPP_OK;MppFrame frame NULL; err encoder_mpp_get_frame(context-decoder, frame); if(frame NULL) { ret LENCODER_MPP_GET_NULL; goto EndP; } if(context-first) { err encoder_mpp_cfg_setup(context-encoder, frame); if(err ! MPP_OK) { ret LENCODER_MPP_WRITE_ERR; encoder_mpp_destroy((context-encoder)); encoder_mpp_destroy((context-decoder)); goto EndP; } context-first 0; } err encoder_mpp_encode(context-encoder, frame, out, out_len); if(err ! MPP_OK) { ret LENCODER_MPP_WRITE_ERR; goto EndP; }EndP:if(frame) {mpp_frame_deinit(frame);}#endifreturn ret;}int lencoder_mpp_transcode(lencoder_mpp_context context, unsigned char *in, int in_len){int ret LENCODER_STATUS_OK;#if defined(i386) || defined(_M_IX86) || defined(x86_64)#elseMPP_RET err;err encoder_mpp_write_data(context-decoder, in, in_len); if(err ! MPP_OK) { if(err MPP_ERR_BUFFER_FULL) { ret LENCODER_MPP_WRITE_FULL; } else { ret LENCODER_MPP_WRITE_ERR; } }#endifreturn ret;}void lencoder_mpp_close(lencoder_mpp_context *context){#if defined(i386) || defined(_M_IX86) || defined(x86_64)#elseencoder_mpp_destroy((*context)-decoder);encoder_mpp_destroy((*context)-encoder);free(*context);#endif}//0 转码棒 1转码卡 2 CPU软解int lencoder_decoder_get(lencoder coder){#if defined(i386) || defined(_M_IX86) || defined(x86_64)return 2;#elsereturn vimicro_encoder_device_type(coder-vimirco);#endif}// fmt 3.SVAC2转H264int lencoder_open_ext(lencoder coder, lencoder_context *context, int fmt, unsigned char *pbuf, int buflen, int bit_rate, int fps, int gop){int ret LENCODER_STATUS_OK, idle_num;lencoder_context ctx;ctx (lencoder_context)malloc(sizeof(struct lencoder_context_t)); if(!ctx) { ret LENCODER_NO_SPACE_ERR; goto EndP; } memset(ctx, 0, sizeof(struct lencoder_context_t));#if defined(i386) || defined(_M_IX86) || defined(x86_64)switch(fmt) {case 3:ret soft_encoder_open(ctx-ctx, bit_rate, fps, gop, pbuf, buflen);if(ret ! SOFT_ENCODER_OK) {printf(“open soft encoder failed, %02x\n”, ret);ret LENCODER_OPEN_FAILED_DEVICE;goto EndP;}break;default:ret LENCODER_UNKNOWN_ENCODER_TYPE;}#else#endif*context ctx;EndP:if(ret ! LENCODER_STATUS_OK) {free(ctx);}return ret;}// fmt 1.H264转SVAC2 2.H265转SVAC2 3.SVAC2转H264int lencoder_open(lencoder coder, lencoder_context *context, int fmt, unsigned char *pbuf, int buflen){int ret LENCODER_STATUS_OK, idle_num;lencoder_context ctx;ctx (lencoder_context)malloc(sizeof(struct lencoder_context_t)); if(!ctx) { ret LENCODER_NO_SPACE_ERR; goto EndP; } memset(ctx, 0, sizeof(struct lencoder_context_t));#if defined(i386) || defined(_M_IX86) || defined(x86_64)switch(fmt) {case 3:ret soft_encoder_open(ctx-ctx, 512 * 1024, 25, 25, pbuf, buflen);if(ret ! SOFT_ENCODER_OK) {printf(“open soft encoder failed, %02x\n”, ret);ret LENCODER_OPEN_FAILED_DEVICE;goto EndP;}break;default:printf(“Unsuport fmt %d\n”, fmt);ret LENCODER_UNKNOWN_ENCODER_TYPE;}#elsevimicro_encoder_idle_get(coder-vimirco, idle_num);if (idle_num 1) {ret LENCODER_NO_IDLE_ERR;goto EndP;}ret vimicro_encoder_prefetch(coder-vimirco, idle_num, pbuf, buflen); if (ret) { ret LENCODER_PREFETCH_ENCODER_ERR; goto EndP; } switch(fmt) { case 1: //H264 ctx-usb vimicro_encoder_open(coder-vimirco, idle_num, USBDEC_VIDEO_H264); ctx-srcfmt USBDEC_VIDEO_H264; break; case 2: //H265 ctx-usb vimicro_encoder_open(coder-vimirco, idle_num, USBDEC_VIDEO_H265); ctx-srcfmt USBDEC_VIDEO_H265; break; default: printf(err video format:%d\n, fmt); ret LENCODER_UNKNOWN_ENCODER_TYPE; goto EndP; } if(ctx-usb NULL) { ret LENCODER_OPEN_FAILED_DEVICE; goto EndP; } ctx-frameout (svac_frame *)malloc(sizeof(svac_frame) * 1024); ctx-current_num idle_num; ctx-hasread -1;#endif*context ctx;EndP:if(ret ! LENCODER_STATUS_OK) {free(ctx);*context NULL;}return ret;}int lencoder_transcode(lencoder_context context, unsigned char *in, int in_len){int ret LENCODER_STATUS_OK, frame_type, i 0;#if defined(i386) || defined(_M_IX86) || defined(x86_64)ret soft_encoder_decode_svac(context-ctx, in, in_len);if(ret ! SOFT_ENCODER_OK) {printf(“soft_encoder_decode failed %02x\n”, ret);ret LENCODER_TRANSOCER_ERR;goto EndP;}#elseunsigned char c;c (in[2] 1 ? in[3] : in[4]); switch(context-srcfmt) { case USBDEC_VIDEO_H264: switch(c 0x1f) { case NAL_SLICE: frame_type 2; break; case NAL_SLICE_IDR: case NAL_SEI: case NAL_SPS: case NAL_PPS: frame_type 1; break; default: ret LENCODER_UNKNOWN_NALU_TYPE; goto EndP; } break; case USBDEC_VIDEO_H265: switch((c 0x7e) 1) { case TRAIL_R: frame_type 2; break; case BLA_W_LP: case BLA_W_RADL: case BLA_N_LP: case IDR_W_RADL: case IDR_N_LP: case VPS_NUT: case SPS_NUT: case PPS_NUT: case PREFIX_SEI_NUT: case SUFFIX_SEI_NUT: frame_type 1; break; default: ret LENCODER_UNKNOWN_NALU_TYPE; goto EndP; } break; default: break; } for(i 0; i context-frame_count; i ) { free(context-frameout[i].buf); context-frameout[i].buf NULL; } ret vimicro_encoder_transcode(context-usb, context-current_num, in, in_len, frame_type, context-frameout, (context-frame_count)); if(context-frame_count 0) { context-hasread 0; } else { context-hasread -1; } if(ret VMUSB_DEVICE_LOST) { ret LENCODER_LOST_DEVICE; goto EndP; }#endifret LENCODER_STATUS_OK;EndP:return ret;}void lencoder_close(lencoder coder, lencoder_context *context){lencoder_context ctx *context;#if defined(i386) || defined(_M_IX86) || defined(x86_64)soft_encoder_close(ctx-ctx);#elsevimicro_encoder_close(ctx-usb, ctx-current_num);if(ctx-frameout) {free(ctx-frameout);}#endifif(ctx) free(ctx);*context NULL;}void lencoder_destroy(lencoder *coder){lencoder tt *coder;#if defined(i386) || defined(_M_IX86) || defined(x86_64)soft_encoder_destroy(tt-s);#elsevimicro_encoder_destroy((tt-vimirco));tt-maxnum 0;#endiffree(tt);*coder NULL;}int lencoder_get_frame_ext(lencoder_context context, unsigned char **frame, unsigned int *frame_len, int *frame_type, int *iskey, int64_t *pts, int64_t *dts){int ret LENCODER_STATUS_OK;#if defined(i386) || defined(_M_IX86) || defined(x86_64)ret soft_encoder_get_h264(context-ctx, frame, (size_t *)frame_len, iskey, pts, dts);if(ret ! SOFT_ENCODER_OK) {//printf(“soft encoder get h264 failed %02x\n”, ret);ret LENCODER_CONTINUING;}else {ret LENCODER_STATUS_OK;}#else#endifreturn ret;}int lencoder_get_frame(lencoder_context context, unsigned char **frame, unsigned int *frame_len, int *frame_type){int ret LENCODER_STATUS_OK;#if defined(i386) || defined(_M_IX86) || defined(x86_64)int iskey;int64_t pts, dts;ret soft_encoder_get_h264(context-ctx, frame, (size_t *)frame_len, iskey, pts, dts);if(ret ! SOFT_ENCODER_OK) {//printf(“soft encoder get h264 failed %02x\n”, ret);ret LENCODER_CONTINUING;}else {ret LENCODER_STATUS_OK;}#elsesvac_frame *p;if(context-hasread -1) { return LENCODER_EMPTY_FRAME_TYPE; } //printf(has read before change is %d\n, context-hasread); p context-frameout[context-hasread]; *frame (unsigned char *)malloc(p-buf_len); if(*frame NULL) { return LENCODER_NO_SPACE_ERR; } //printf(frame is %p, p is %p, buflen is %d, count is %d, base is %p\n, *frame, p, p-buf_len, context-frame_count, context-frameout); memcpy(*frame, p-buf, p-buf_len); //printf(end-------------------\n); *frame_len p-buf_len; *frame_type p-frame_type; if(context-hasread (context-frame_count - 1)) { context-hasread ; } else { context-hasread -1; }#endifreturn ret;}
版权声明:本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!

北京网站大全如何维护建设网站

第一章:Open-AutoGLM怎么安装其他应用Open-AutoGLM 是一个基于 AutoGLM 架构的开源自动化工具平台,支持通过插件机制扩展功能以集成第三方应用。用户可以通过配置管理器加载外部应用模块,实现任务自动化、数据同步和跨平台协作等功能。环境准…

张小明 2026/1/17 21:19:15 网站建设

洪洞网站建设网站无法导入照片

设计模式与惯用法详解 1. 组合模式(Composite) 在实际使用命令模式时,我们常常需要将多个简单命令组合成一个更复杂的命令,或者记录和重放命令(脚本化)。组合模式可以优雅地实现这些需求。 树是计算机科学中广泛使用的数据结构,如文件系统的层次组织、集成开发环境(…

张小明 2026/1/17 21:19:18 网站建设

怎么免费推广自己网站富阳网站开发

在无数个深夜里,城市的路灯如同忠实的哨兵,默默照亮着归家的路。然而,一个长期存在的浪费现象却常常被我们忽略:在车流稀疏的后半夜,这些路灯依然以白天的全功率状态照耀着空旷的街道。这不仅消耗着巨大的电能&#xf…

张小明 2026/1/17 21:19:19 网站建设

设计好的网站推荐聊城手机网站建设多少钱

【15】MATLAB仿真 三维测距定位传感器最优布置问题,A优化指标,即最小化信息矩阵逆的迹。 三种不同约束求解。 有参考文档。 主要参考文档: 1. Optimal Sensor Placement for 3-D Time-of-Arrival Target Localization, in IEEE Transactions…

张小明 2026/1/17 21:19:22 网站建设

网站建设推广岗位轻量服务器wordpress

还在为直播时打字幕而焦头烂额吗?LocalVocal这款创新的OBS插件让实时字幕生成变得前所未有的简单。无论你是新手主播、教育工作者还是内容创作者,这款完全本地的语音转文字工具都能让你的视频制作效率倍增! 【免费下载链接】obs-localvocal O…

张小明 2026/1/17 21:19:21 网站建设

壹财富 网站开发网架公司赵娜

Java面试奇遇记:水货程序员谢飞机大战面试官,技术点全解析! 第一轮:Java基础与集合框架 面试官:谢飞机,先来个简单的。Java中的ArrayList和LinkedList有什么区别? 谢飞机:这个简单&a…

张小明 2026/1/17 21:19:21 网站建设