网站接入服务单位,网站全屏轮播代码 js,电子商务网站建设与课程设计,株洲seo主管整体方案参考上一篇博文 https://blog.csdn.net/qq_31764341/article/details/134810566 本篇博文主要介绍基于RK3588进行硬解码 还是之前的套路#xff0c;我不生产代码#xff0c;我只是代码的搬运工#xff0c;今天我们搬运瑞芯微的官方代码#xff0c;并记录下来整个调…整体方案参考上一篇博文 https://blog.csdn.net/qq_31764341/article/details/134810566 本篇博文主要介绍基于RK3588进行硬解码 还是之前的套路我不生产代码我只是代码的搬运工今天我们搬运瑞芯微的官方代码并记录下来整个调试历程。两篇文章下来我们3588上面的流肯定能出来 代码贴的特别详细。。。 希望不要取关 谢谢 然后后面再出一个 硬件解码的ffmpeg 编译以及opencv拉流示例代码
mpp库文件
rk3588 编码有自己的demo 这个demo一般存在于下面的这坨东西里
4. you can get demo about mpp applied to linux and android.Liunx : https://github.com/WainDing/mpp_linux_cpphttps://github.com/MUZLATAN/ffmpeg_rtsp_mppAndroid : https://github.com/c-xh/RKMediaCodecDemo
5. offical github: https://github.com/rockchip-linux/mppdevelop github: https://github.com/HermanChen/mppdevelop gitee : https://gitee.com/hermanchen82/mpp
6. Commit message format should base on https://keepachangelog.com/en/1.0.0/More document can be found at http://opensource.rock-chips.com/wiki_Mpp一般我们把这个链接的东西down下来然后传到板子上在mpp路径下执行 make make install https://github.com/rockchip-linux/mpp 就能够在test路径下面拿到测试的app程序了大概是这样的
xxxorangepi5plus:~/xxx/mpp-develop/test$ ls
CMakeFiles mpi_dec_mt_test mpi_dec_test mpi_rc2_test mpp_info_test.c vpu_api_test
cmake_install.cmake mpi_dec_mt_test.c mpi_dec_test.c mpi_rc2_test.c mpp_parse_cfg.c vpu_api_test.c
CMakeLists.txt mpi_dec_multi_test mpi_enc_mt_test mpi_rc.cfg mpp_parse_cfg.h
dec.yuv mpi_dec_multi_test.c mpi_enc_mt_test.cpp mpp_event_trigger.c output.h264
gastest.o mpi_dec_nt_test mpi_enc_test mpp_event_trigger.h output.yuv
Makefile mpi_dec_nt_test.c mpi_enc_test.c mpp_info_test README.md
编码
这篇先说264编码为了蹭一口流量卷拆开两篇文章说 编码 encode ,这个路径下的encode的两个都是编码例程一个多线程一个单线程对应的程序文件也在同路径下面
自己的工程使用他的编解码
如果是要把他的文件放在其他路径下面用CmakeLists.txt需要按照下面的写就可以了
cmake_minimum_required(VERSION 3.5)
project(rtspserver)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
# -g 开启调试
set(CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS} -DSOCKLEN_Tsocklen_t -g )#find_package(OpenCV 4.8.0 REQUIRED)
#find_package(OpenSSL REQUIRED)# MPP
set(MPP_PATH /home/orangepi/XXX/mpp-develop/inc)
set(MPP_LIBS /home/orangepi/XXX/mpp-develop/mpp/librockchip_mpp.so)
include_directories(${MPP_PATH})# OSAL
set(OSAL_PATH /home/orangepi/XXX/mpp-develop/osal/inc/ /home/orangepi/XXX/mpp-develop/utils)
set(OSAL_LIBS /home/orangepi/XXX/mpp-develop/osal/libosal.a /home/orangepi/XXX/mpp-develop/utils/libutils.a)
include_directories(${OSAL_PATH})# RGA RGA库 放到同文件夹下面的/3rdparty/rga/RK3588 这个地方
set(RGA_PATH ${CMAKE_SOURCE_DIR}/3rdparty/rga/RK3588)
set(RGA_LIB ${RGA_PATH}/lib/Linux/aarch64/librga.so)
include_directories(${RGA_PATH}/include)# 写你的main.cpp 文件 rtsp是生成的二进制可执行文件名
add_executable(rtsp
example/rtsp_server.cpp
)
# 这里一定要把库链接进来
target_link_libraries(rtsp ${MPP_LIBS} ${OSAL_LIBS} ${OpenCV_LIBS} ${RGA_LIB} OpenSSL::SSL OpenSSL::Crypto )Encoder程序拆解
他支持三种方式这个地方要看他的官方文档支持路径一般是Rk3588-linux-v002\linux\docs\Linux\Multimedia\Rockchip_Developer_Guide_MPP_CN.pdf(如果有人需要Rk3588-linux-v002下面的东西。。。 可以私聊我 售价30或者在其他地方找一找) 他是说我们使用编码器/解码器的三种方式第二章从接口角度介绍第三章从应用角度介绍前两种方式使用MppPacket 与 MppFrame这对结构第三种高级模式是使用MppTask。前两种一种是无脑往里塞一种是告诉分配空间大小和格式往里塞第三种是自己定义task 只研究了linux demo里面的最简单的方式带mt的那个是多线程也没研究多线。主打的一个先能用
mpi_enc_test.c
粗解析一下 后面贴我整理后的底层 这里推荐一个方法可以快速的开发在他的Cmakelist.txt 的C/Cpp 编译flags 里面加-g然后重新生成再配合我前面的有一篇vscode远程debug 配置直接可以逐行运行然后确定他最后运行的配置。
main
先看main
RK_S32 ret MPP_NOK;
// MpiEncTestArgs 初始化 判断是否开多线程
MpiEncTestArgs* cmd mpi_enc_test_cmd_get();// parse the cmd option 使用argc argv解析给cmd赋值
ret mpi_enc_test_cmd_update_by_args(cmd, argc, argv);
if (ret)goto DONE;//
mpi_enc_test_cmd_show_opt(cmd);// 打印 解析到的输入参数信息ret enc_test_multi(cmd, argv[0]);// 按照输入参数执行enc_test_multi
重点就是下面这句创建了线程然后就是判断frame是否全部处理完或者键盘输入回车二者有一个就开始中断线程。 ret pthread_create(ctxs[i].thd, NULL, enc_test, ctxs[i]);他这里很多参数都是配置用于计时的自己用可以适当删减。
enc_test
mpp_buffer_get 是获取参数的他的例程配置了很多有的就没有任何变化拿了一个原始数据然后再给配置上目的应该是为了给演示操作。这个自己看需求应该可以删一部分不过我没试。 下面是核心语句
ret test_ctx_init(info);// ctx 初始化
// 拿到内部Buffer group的类型
ret mpp_buffer_group_get_internal(p-buf_grp, MPP_BUFFER_TYPE_DRM);
// 拿取Buffer 到 p-frm_buf指针
ret mpp_buffer_get(p-buf_grp, p-frm_buf, p-frame_size p-header_size);
ret mpp_buffer_get(p-buf_grp, p-pkt_buf, p-frame_size);
ret mpp_buffer_get(p-buf_grp, p-md_info, p-mdinfo_size);ret mpp_create(p-ctx, p-mpi);// 创建mpp实例
p-mpi-control(p-ctx, MPP_SET_OUTPUT_TIMEOUT, timeout);// 设置超时时间
mpp_init(p-ctx, MPP_CTX_ENC, p-type);//mpp初始化
mpp_enc_cfg_init(p-cfg);// 编码器初始化
p-mpi-control(p-ctx, MPP_ENC_GET_CFG, p-cfg);
test_mpp_enc_cfg_setup(info);// 大批量初始化参数
ret test_mpp_run(info);// 处理一帧
test_mpp_run
这个函数就是完整的处理一帧数据 这玩意总体上干的事情就是 你通过buf 填充一帧数据给frame然后调用put语句把frame送入编码器再通过get 语句拿到 while (!p-pkt_eos)// 判断这个packet是否放入结束
// 下面这句 是把fp_input的数据读到初始化的buf里面buf是在前面初始化的时候从mpp里面拿过来的地址使用这个拿的指针mpp_buffer_get_ptr当指针用就行ret read_image(buf, p-fp_input, p-width, p-height,p-hor_stride, p-ver_stride, p-fmt);
// 另一个判断是要去从相机里面拿数据使用的是v4l2的库拿的 没认真看
ret mpp_frame_init(frame);
// 初始化 设定frame格式 也就是编码输入
mpp_frame_set_width(frame, p-width);
mpp_frame_set_height(frame, p-height);
mpp_frame_set_hor_stride(frame, p-hor_stride);
mpp_frame_set_ver_stride(frame, p-ver_stride);
mpp_frame_set_fmt(frame, p-fmt);
mpp_frame_set_eos(frame, p-frm_eos);
mpp_frame_set_buffer(frame, p-frm_buf);
// 初始化 packet 也就是编码结果的格式
meta mpp_frame_get_meta(frame);
mpp_packet_init_with_buffer(packet, p-pkt_buf);
/* NOTE: It is important to clear output packet length!! */
mpp_packet_set_length(packet, 0);
mpp_meta_set_packet(meta, KEY_OUTPUT_PACKET, packet);
mpp_meta_set_buffer(meta, KEY_MOTION_INFO, p-md_info);
// 中间是可选项 osd userdata roi啥的
// 扔进去一帧图像
ret mpi-encode_put_frame(ctx, frame);
// 拿回来一个packet 一次不一定能拿完 没拿完再do循环里 拿完就跳出来了
ret mpi-encode_get_packet(ctx, packet);
// 把结果写入文件
fwrite(ptr, 1, len, p-fp_output);我的底层
使用PostAframe 操作一帧 encoder.cpp,我这里是能用的…
#include encoder.h
#include opencv2/opencv.hpp
//#include videoThread.h
// #include liveMedia.hh
// #include GroupsockHelper.hh
// #include BasicUsageEnvironment.hh
// #include H264VideoRTPSource.hh
#include unistd.h
/* 创建有名管道写数据 */
#include sys/types.h
#include sys/stat.h
#include fcntl.h
#include stdio.h
// #include QDebug
// 用于初始化。
MPP_RET test_ctx_init(MpiEncMultiCtxInfo *info)
{MpiEncTestData *p info-ctx;MPP_RET ret MPP_OK;// get paramter from cmdp-width 1280;p-height 720;p-hor_stride (MPP_ALIGN(p-width, 16)*3);p-ver_stride (MPP_ALIGN(p-height, 16));p-fmt MPP_FMT_RGB888;p-type MPP_VIDEO_CodingAVC;p-bps 0;p-bps_min 0;p-bps_max 0;p-rc_mode MPP_ENC_RC_MODE_VBR;p-frame_num 1;p-gop_mode 0;p-gop_len 5;p-vi_len 0;p-fps_in_flex 0;p-fps_in_den 0;p-fps_in_num 0;p-fps_out_flex 0;p-fps_out_den 0;p-fps_out_num 0;p-scene_mode 0;p-mdinfo_size (MPP_VIDEO_CodingHEVC p-type) ?(MPP_ALIGN(p-hor_stride, 32) 5) *(MPP_ALIGN(p-ver_stride, 32) 5) * 16 :(MPP_ALIGN(p-hor_stride, 64) 6) *(MPP_ALIGN(p-ver_stride, 16) 4) * 16;// p-fp_input fopen(/home/orangepi/code/mpp-develop/test/dog_bike_car_448x448.bgr, rb);// if (NULL p-fp_input) {// mpp_err(failed to open input file %s\n, /home/orangepi/code/mpp-develop/test/dog_bike_car_448x448.bgr);// mpp_err(create default yuv image for test\n);// }// }// } 有个指针没有初始化 是数据输入指针 p-fp_input// 测试 264 输出p-fp_output fopen(./1.h264, wb);if (NULL p-fp_output) {mpp_err(failed to open output file %s\n, p-fp_output);ret MPP_ERR_OPEN_FILE;}// }// update resource parameterswitch (p-fmt MPP_FRAME_FMT_MASK) {case MPP_FMT_YUV420SP:case MPP_FMT_YUV420P: {p-frame_size MPP_ALIGN(p-hor_stride, 64) * MPP_ALIGN(p-ver_stride, 64) * 3 / 2;} break;case MPP_FMT_YUV422_YUYV :case MPP_FMT_YUV422_YVYU :case MPP_FMT_YUV422_UYVY :case MPP_FMT_YUV422_VYUY :case MPP_FMT_YUV422P :case MPP_FMT_YUV422SP : {p-frame_size MPP_ALIGN(p-hor_stride, 64) * MPP_ALIGN(p-ver_stride, 64) * 2;} break;case MPP_FMT_RGB444 :case MPP_FMT_BGR444 :case MPP_FMT_RGB555 :case MPP_FMT_BGR555 :case MPP_FMT_RGB565 :case MPP_FMT_BGR565 :case MPP_FMT_RGB888 :case MPP_FMT_BGR888 :case MPP_FMT_RGB101010 :case MPP_FMT_BGR101010 :case MPP_FMT_ARGB8888 :case MPP_FMT_ABGR8888 :case MPP_FMT_BGRA8888 :case MPP_FMT_RGBA8888 : {p-frame_size MPP_ALIGN(p-hor_stride, 64) * MPP_ALIGN(p-ver_stride, 64);} break;default: {p-frame_size MPP_ALIGN(p-hor_stride, 64) * MPP_ALIGN(p-ver_stride, 64) * 4;} break;}if (MPP_FRAME_FMT_IS_FBC(p-fmt)) {if ((p-fmt MPP_FRAME_FBC_MASK) MPP_FRAME_FBC_AFBC_V1)p-header_size MPP_ALIGN(MPP_ALIGN(p-width, 16) * MPP_ALIGN(p-height, 16) / 16, SZ_4K);elsep-header_size MPP_ALIGN(p-width, 16) * MPP_ALIGN(p-height, 16) / 16;} else {p-header_size 0;}return ret;
}MPP_RET test_mpp_enc_cfg_setup(MpiEncMultiCtxInfo *info)
{MpiEncTestData *p info-ctx;MppApi *mpi p-mpi;MppCtx ctx p-ctx;MppEncCfg cfg p-cfg;RK_U32 quiet 0;MPP_RET ret;RK_U32 rotation;RK_U32 mirroring;RK_U32 flip;RK_U32 gop_mode p-gop_mode;MppEncRefCfg ref NULL;/* setup default parameter */if (p-fps_in_den 0)p-fps_in_den 1;if (p-fps_in_num 0)p-fps_in_num 15;if (p-fps_out_den 0)p-fps_out_den 1;if (p-fps_out_num 0)p-fps_out_num 15;if (!p-bps)p-bps p-width * p-height / 8 * (p-fps_out_num / p-fps_out_den);mpp_enc_cfg_set_s32(cfg, tune:scene_mode, p-scene_mode);mpp_enc_cfg_set_s32(cfg, prep:width, p-width);mpp_enc_cfg_set_s32(cfg, prep:height, p-height);mpp_enc_cfg_set_s32(cfg, prep:hor_stride, p-hor_stride);mpp_enc_cfg_set_s32(cfg, prep:ver_stride, p-ver_stride);mpp_enc_cfg_set_s32(cfg, prep:format, p-fmt);mpp_enc_cfg_set_s32(cfg, rc:mode, p-rc_mode);/* fix input / output frame rate */mpp_enc_cfg_set_s32(cfg, rc:fps_in_flex, p-fps_in_flex);mpp_enc_cfg_set_s32(cfg, rc:fps_in_num, p-fps_in_num);mpp_enc_cfg_set_s32(cfg, rc:fps_in_denorm, p-fps_in_den);mpp_enc_cfg_set_s32(cfg, rc:fps_out_flex, p-fps_out_flex);mpp_enc_cfg_set_s32(cfg, rc:fps_out_num, p-fps_out_num);mpp_enc_cfg_set_s32(cfg, rc:fps_out_denorm, p-fps_out_den);/* drop frame or not when bitrate overflow */mpp_enc_cfg_set_u32(cfg, rc:drop_mode, MPP_ENC_RC_DROP_FRM_DISABLED);mpp_enc_cfg_set_u32(cfg, rc:drop_thd, 20); /* 20% of max bps */mpp_enc_cfg_set_u32(cfg, rc:drop_gap, 1); /* Do not continuous drop frame *//* setup bitrate for different rc_mode */mpp_enc_cfg_set_s32(cfg, rc:bps_target, p-bps);switch (p-rc_mode) {case MPP_ENC_RC_MODE_FIXQP : {/* do not setup bitrate on FIXQP mode */} break;case MPP_ENC_RC_MODE_CBR : {/* CBR mode has narrow bound */mpp_enc_cfg_set_s32(cfg, rc:bps_max, p-bps_max ? p-bps_max : p-bps * 17 / 16);mpp_enc_cfg_set_s32(cfg, rc:bps_min, p-bps_min ? p-bps_min : p-bps * 15 / 16);} break;case MPP_ENC_RC_MODE_VBR :case MPP_ENC_RC_MODE_AVBR : {/* VBR mode has wide bound */mpp_enc_cfg_set_s32(cfg, rc:bps_max, p-bps_max ? p-bps_max : p-bps * 17 / 16);mpp_enc_cfg_set_s32(cfg, rc:bps_min, p-bps_min ? p-bps_min : p-bps * 1 / 16);} break;default : {/* default use CBR mode */mpp_enc_cfg_set_s32(cfg, rc:bps_max, p-bps_max ? p-bps_max : p-bps * 17 / 16);mpp_enc_cfg_set_s32(cfg, rc:bps_min, p-bps_min ? p-bps_min : p-bps * 15 / 16);} break;}/* setup qp for different codec and rc_mode */switch (p-type) {case MPP_VIDEO_CodingAVC :case MPP_VIDEO_CodingHEVC : {switch (p-rc_mode) {case MPP_ENC_RC_MODE_FIXQP : {RK_S32 fix_qp 0;mpp_enc_cfg_set_s32(cfg, rc:qp_init, fix_qp);mpp_enc_cfg_set_s32(cfg, rc:qp_max, fix_qp);mpp_enc_cfg_set_s32(cfg, rc:qp_min, fix_qp);mpp_enc_cfg_set_s32(cfg, rc:qp_max_i, fix_qp);mpp_enc_cfg_set_s32(cfg, rc:qp_min_i, fix_qp);mpp_enc_cfg_set_s32(cfg, rc:qp_ip, 0);mpp_enc_cfg_set_s32(cfg, rc:fqp_min_i, fix_qp);mpp_enc_cfg_set_s32(cfg, rc:fqp_max_i, fix_qp);mpp_enc_cfg_set_s32(cfg, rc:fqp_min_p, fix_qp);mpp_enc_cfg_set_s32(cfg, rc:fqp_max_p, fix_qp);} break;case MPP_ENC_RC_MODE_CBR :case MPP_ENC_RC_MODE_VBR :case MPP_ENC_RC_MODE_AVBR : {mpp_enc_cfg_set_s32(cfg, rc:qp_init, -1);mpp_enc_cfg_set_s32(cfg, rc:qp_max, 51);mpp_enc_cfg_set_s32(cfg, rc:qp_min, 10);mpp_enc_cfg_set_s32(cfg, rc:qp_max_i, 51);mpp_enc_cfg_set_s32(cfg, rc:qp_min_i, 10);mpp_enc_cfg_set_s32(cfg, rc:qp_ip, 2);mpp_enc_cfg_set_s32(cfg, rc:fqp_min_i, 10);mpp_enc_cfg_set_s32(cfg, rc:fqp_max_i, 51);mpp_enc_cfg_set_s32(cfg, rc:fqp_min_p, 10);mpp_enc_cfg_set_s32(cfg, rc:fqp_max_p, 51);} break;default : {mpp_err_f(unsupport encoder rc mode %d\n, p-rc_mode);} break;}} break;case MPP_VIDEO_CodingVP8 : {/* vp8 only setup base qp range */mpp_enc_cfg_set_s32(cfg, rc:qp_init, 40);mpp_enc_cfg_set_s32(cfg, rc:qp_max, 127);mpp_enc_cfg_set_s32(cfg, rc:qp_min, 0);mpp_enc_cfg_set_s32(cfg, rc:qp_max_i,127);mpp_enc_cfg_set_s32(cfg, rc:qp_min_i, 0);mpp_enc_cfg_set_s32(cfg, rc:qp_ip, 6);} break;case MPP_VIDEO_CodingMJPEG : {/* jpeg use special codec config to control qtable */mpp_enc_cfg_set_s32(cfg, jpeg:q_factor, 80);mpp_enc_cfg_set_s32(cfg, jpeg:qf_max, 99);mpp_enc_cfg_set_s32(cfg, jpeg:qf_min, 1);} break;default : {} break;}/* setup codec */mpp_enc_cfg_set_s32(cfg, codec:type, p-type);switch (p-type) {case MPP_VIDEO_CodingAVC : {RK_U32 constraint_set;/** H.264 profile_idc parameter* 66 - Baseline profile* 77 - Main profile* 100 - High profile*/mpp_enc_cfg_set_s32(cfg, h264:profile, 100);/** H.264 level_idc parameter* 10 / 11 / 12 / 13 - qcif15fps / cif7.5fps / cif15fps / cif30fps* 20 / 21 / 22 - cif30fps / half-D125fps / D112.5fps* 30 / 31 / 32 - D125fps / 720p30fps / 720p60fps* 40 / 41 / 42 - 1080p30fps / 1080p30fps / 1080p60fps* 50 / 51 / 52 - 4K30fps*/mpp_enc_cfg_set_s32(cfg, h264:level, 40);mpp_enc_cfg_set_s32(cfg, h264:cabac_en, 1);mpp_enc_cfg_set_s32(cfg, h264:cabac_idc, 0);mpp_enc_cfg_set_s32(cfg, h264:trans8x8, 1);mpp_env_get_u32(constraint_set, constraint_set, 0);if (constraint_set 0x3f0000)mpp_enc_cfg_set_s32(cfg, h264:constraint_set, constraint_set);} break;case MPP_VIDEO_CodingHEVC :case MPP_VIDEO_CodingMJPEG :case MPP_VIDEO_CodingVP8 : {} break;default : {mpp_err_f(unsupport encoder coding type %d\n, p-type);} break;}p-split_mode 0;p-split_arg 0;p-split_out 0;mpp_env_get_u32(split_mode, p-split_mode, MPP_ENC_SPLIT_NONE);mpp_env_get_u32(split_arg, p-split_arg, 0);mpp_env_get_u32(split_out, p-split_out, 0);if (p-split_mode) {mpp_log_q(quiet, %p split mode %d arg %d out %d\n, ctx,p-split_mode, p-split_arg, p-split_out);mpp_enc_cfg_set_s32(cfg, split:mode, p-split_mode);mpp_enc_cfg_set_s32(cfg, split:arg, p-split_arg);mpp_enc_cfg_set_s32(cfg, split:out, p-split_out);}mpp_env_get_u32(mirroring, mirroring, 0);mpp_env_get_u32(rotation, rotation, 0);mpp_env_get_u32(flip, flip, 0);mpp_enc_cfg_set_s32(cfg, prep:mirroring, mirroring);mpp_enc_cfg_set_s32(cfg, prep:rotation, rotation);mpp_enc_cfg_set_s32(cfg, prep:flip, flip);// config gop_len and ref cfgmpp_enc_cfg_set_s32(cfg, rc:gop, p-gop_len ? p-gop_len : p-fps_out_num * 2);mpp_env_get_u32(gop_mode, gop_mode, gop_mode);if (gop_mode) {mpp_enc_ref_cfg_init(ref);if (p-gop_mode 4)mpi_enc_gen_ref_cfg(ref, gop_mode);elsempi_enc_gen_smart_gop_ref_cfg(ref, p-gop_len, p-vi_len);mpp_enc_cfg_set_ptr(cfg, rc:ref_cfg, ref);}ret mpi-control(ctx, MPP_ENC_SET_CFG, cfg);if (ret) {mpp_err(mpi control enc set cfg failed ret %d\n, ret);goto RET;}if (ref)mpp_enc_ref_cfg_deinit(ref);/* optional */{RK_U32 sei_mode;mpp_env_get_u32(sei_mode, sei_mode, MPP_ENC_SEI_MODE_ONE_FRAME);p-sei_mode (MppEncSeiMode)sei_mode;ret mpi-control(ctx, MPP_ENC_SET_SEI_CFG, p-sei_mode);if (ret) {mpp_err(mpi control enc set sei cfg failed ret %d\n, ret);goto RET;}}if (p-type MPP_VIDEO_CodingAVC || p-type MPP_VIDEO_CodingHEVC) {p-header_mode MPP_ENC_HEADER_MODE_EACH_IDR;ret mpi-control(ctx, MPP_ENC_SET_HEADER_MODE, p-header_mode);if (ret) {mpp_err(mpi control enc set header mode failed ret %d\n, ret);goto RET;}}/* setup test mode by env */mpp_env_get_u32(osd_enable, p-osd_enable, 0);mpp_env_get_u32(osd_mode, p-osd_mode, MPP_ENC_OSD_PLT_TYPE_DEFAULT);mpp_env_get_u32(roi_enable, p-roi_enable, 0);mpp_env_get_u32(user_data_enable, p-user_data_enable, 0);if (p-roi_enable) {mpp_enc_roi_init(p-roi_ctx, p-width, p-height, p-type, 4);mpp_assert(p-roi_ctx);}RET:return ret;
}
MPP_RET test_ctx_deinit(MpiEncTestData *p)
{if (p) {
// if (p-cam_ctx) {
// camera_source_deinit(p-cam_ctx);
// p-cam_ctx NULL;
// }if (p-fp_input) {fclose(p-fp_input);p-fp_input NULL;}if (p-fp_output) {fclose(p-fp_output);p-fp_output NULL;}if (p-fp_verify) {fclose(p-fp_verify);p-fp_verify NULL;}}return MPP_OK;
}
// using namespace std;
// int isOpen false;
// const char * fifo_name /home/orangepi/code/live/testProgs/pipe.264;
// int pipe_fd;
// int mpp_packet_write_to_fifo(void *ptr, size_t len)
// {
// int ret 0;
// if(!isOpen)
// {
// qDebug()start open the fifo file\n;
// pipe_fd open(fifo_name, O_WRONLY); //阻塞至读端打开
// if(pipe_fd ! -1)
// {
// qDebug()(open fifo success\n);
// // qDebug()(thread mpp_packet_write_to_fifo, pipe_fd %d\n, pipe_fd);
// isOpen true;
// //return pipe_fd;
// }
// else
// {
// qDebug()(pipe file open error %s\n, strerror(errno));
// return -1;
// // pthread_exit(NULL);
// }
// }
// ret write(pipe_fd, ptr, len);
// if(ret ! len)
// {
// printf(Write fifo Err\n);
// return -1;
// }
// return 0;
// }
MPP_RET test_mpp_run(MpiEncMultiCtxInfo *info,cv::Mat pic,char* fs,int length)
{// MpiEncTestArgs *cmd info-cmd;MpiEncTestData *p info-ctx;MppApi *mpi p-mpi;MppCtx ctx p-ctx;RK_U32 quiet 0;RK_S32 chn info-chn;RK_U32 cap_num 0;DataCrc checkcrc;MPP_RET ret MPP_OK;p-frame_count 0;// 初始化 crc校验数据结构memset(checkcrc, 0, sizeof(checkcrc));checkcrc.sum mpp_malloc(RK_ULONG, 512);// 一次完整的调用 包括帧初始化 de初始化 还有填充 获取while (!p-pkt_eos) {MppMeta meta NULL;MppFrame frame NULL;MppPacket packet NULL;void *buf mpp_buffer_get_ptr(p-frm_buf);RK_S32 cam_frm_idx -1;MppBuffer cam_buf NULL;RK_U32 eoi 1;// 数据实际输入int width pic.rows;int height pic.cols;int totalBytes width * height * 3; // 3个通道BGR每个通道占一个字节memcpy(buf, pic.data, totalBytes);// if (p-fp_input) {// 测试图像 2 // int width 1920;// int height 1080;// // 创建一个空白图像全黑// cv::Mat colorBar cv::Mat::zeros(height, width, CV_8UC3);// // 设置彩条的宽度// int barWidth width / 8; // 8个彩条你可以根据需要调整// // 生成彩条// for (int i 0; i 8; i) {// // 计算彩条的起始和结束位置// int startX i * barWidth;// int endX (i 1) * barWidth;// // 设置彩条颜色BGR格式// cv::Vec3b color;// if (i % 2 0) {// color cv::Vec3b(255, 0, 0); // 蓝色// } else {// color cv::Vec3b(0, 255, 0); // 绿色// }// // 在图像上画出彩条// colorBar(cv::Rect(startX, 0, barWidth, height)) color;// }// int totalBytes width * height * 3; // 3个通道BGR每个通道占一个字节// memcpy(buf, colorBar.data, totalBytes);// 测试图像// ret read_image((RK_U8*)buf, p-fp_input, p-width, p-height,// p-hor_stride, p-ver_stride, p-fmt);// buf 存储图片数据 ,fp_input 应该是一个文件的fp 明天再开if (ret MPP_NOK ) {p-frm_eos 1;// 判定是否满足结束标志 满足则加一个eos帧if (p-frame_num 0 || p-frame_count p-frame_num) {clearerr(p-fp_input);rewind(p-fp_input);p-frm_eos 0;mpp_log_q(quiet, chn %d loop times %d\n, chn, p-loop_times);continue;}mpp_log_q(quiet, chn %d found last frame. feof %d\n, chn, feof(p-fp_input));} else if (ret MPP_ERR_VALUE)goto RET;// } ret mpp_frame_init(frame);if (ret) {mpp_err_f(mpp_frame_init failed\n);goto RET;}mpp_frame_set_width(frame, p-width);mpp_frame_set_height(frame, p-height);mpp_frame_set_hor_stride(frame, p-hor_stride);mpp_frame_set_ver_stride(frame, p-ver_stride);mpp_frame_set_fmt(frame, p-fmt);mpp_frame_set_eos(frame, p-frm_eos);// 使用我的分配内存的frm_buf指针 填充Frame mpp_frame_set_buffer(frame, p-frm_buf);meta mpp_frame_get_meta(frame);mpp_packet_init_with_buffer(packet, p-pkt_buf);/* NOTE: It is important to clear output packet length!! */mpp_packet_set_length(packet, 0);mpp_meta_set_packet(meta, KEY_OUTPUT_PACKET, packet);mpp_meta_set_buffer(meta, KEY_MOTION_INFO, p-md_info);// if (p-osd_enable || p-user_data_enable || p-roi_enable) {// if (p-user_data_enable) {// MppEncUserData user_data;// char *str this is user data\n;// if ((p-frame_count 10) 0) {// user_data.pdata str;// user_data.len strlen(str) 1;// mpp_meta_set_ptr(meta, KEY_USER_DATA, user_data);// }// static RK_U8 uuid_debug_info[16] {// 0x57, 0x68, 0x97, 0x80, 0xe7, 0x0c, 0x4b, 0x65,// 0xa9, 0x06, 0xae, 0x29, 0x94, 0x11, 0xcd, 0x9a// };// MppEncUserDataSet data_group;// MppEncUserDataFull datas[2];// char *str1 this is user data 1\n;// char *str2 this is user data 2\n;// data_group.count 2;// datas[0].len strlen(str1) 1;// datas[0].pdata str1;// datas[0].uuid uuid_debug_info;// datas[1].len strlen(str2) 1;// datas[1].pdata str2;// datas[1].uuid uuid_debug_info;// data_group.datas datas;// mpp_meta_set_ptr(meta, KEY_USER_DATAS, data_group);// }// if (p-osd_enable) {// /* gen and cfg osd plt */// mpi_enc_gen_osd_plt(p-osd_plt, p-frame_count);// p-osd_plt_cfg.change MPP_ENC_OSD_PLT_CFG_CHANGE_ALL;// p-osd_plt_cfg.type MPP_ENC_OSD_PLT_TYPE_USERDEF;// p-osd_plt_cfg.plt p-osd_plt;// ret mpi-control(ctx, MPP_ENC_SET_OSD_PLT_CFG, p-osd_plt_cfg);// if (ret) {// mpp_err(mpi control enc set osd plt failed ret %d\n, ret);// goto RET;// }// /* gen and cfg osd plt */// mpi_enc_gen_osd_data(p-osd_data, p-buf_grp, p-width,// p-height, p-frame_count);// mpp_meta_set_ptr(meta, KEY_OSD_DATA, (void*)p-osd_data);// }// if (p-roi_enable) {// RoiRegionCfg *region p-roi_region;// /* calculated in pixels */// region-x MPP_ALIGN(p-width / 8, 16);// region-y MPP_ALIGN(p-height / 8, 16);// region-w 128;// region-h 256;// region-force_intra 0;// region-qp_mode 1;// region-qp_val 24;// mpp_enc_roi_add_region(p-roi_ctx, region);// region-x MPP_ALIGN(p-width / 2, 16);// region-y MPP_ALIGN(p-height / 4, 16);// region-w 256;// region-h 128;// region-force_intra 1;// region-qp_mode 1;// region-qp_val 10;// mpp_enc_roi_add_region(p-roi_ctx, region);// /* send roi info by metadata */// mpp_enc_roi_setup_meta(p-roi_ctx, meta);// }// }if (!p-first_frm)p-first_frm mpp_time();/** NOTE: in non-block mode the frame can be resent.* The default input timeout mode is block.** User should release the input frame to meet the requirements of* resource creator must be the resource destroyer.*/ret mpi-encode_put_frame(ctx, frame);if (ret) {mpp_err(chn %d encode put frame failed\n, chn);mpp_frame_deinit(frame);goto RET;}mpp_frame_deinit(frame);do {ret mpi-encode_get_packet(ctx, packet);if (ret) {mpp_err(chn %d encode get packet failed\n, chn);goto RET;}mpp_assert(packet);if (packet) {// write packet to file herevoid *ptr mpp_packet_get_pos(packet);size_t len mpp_packet_get_length(packet);char log_buf[256];RK_S32 log_size sizeof(log_buf) - 1;RK_S32 log_len 0;if (!p-first_pkt)p-first_pkt mpp_time();p-pkt_eos mpp_packet_get_eos(packet);if (p-fp_output){// fwrite(ptr, 1, len, p-fp_output);fs (char*)malloc(len*sizeof(char));memcpy(fs, ptr, len);length len;// fs (char*)cpy;//pipe close
// if(mpp_packet_write_to_fifo(cpy, len) 0)//阻塞
// {
// // goto RET;
// printf( mpp_packet_write_to_fifo err \n);
// }// timeval ref;// gettimeofday(ref, NULL);// fs-postFrame((char*)cpy,len,ref);}if (p-fp_verify !p-pkt_eos) {calc_data_crc((RK_U8 *)ptr, (RK_U32)len, checkcrc);mpp_log(p-frame_count%d, len%d\n, p-frame_count, len);write_data_crc(p-fp_verify, checkcrc);}log_len snprintf(log_buf log_len, log_size - log_len,encoded frame %-4d, p-frame_count);/* for low delay partition encoding */if (mpp_packet_is_partition(packet)) {eoi mpp_packet_is_eoi(packet);log_len snprintf(log_buf log_len, log_size - log_len, pkt %d, p-frm_pkt_cnt);p-frm_pkt_cnt (eoi) ? (0) : (p-frm_pkt_cnt 1);}log_len snprintf(log_buf log_len, log_size - log_len, size %-7zu, len);if (mpp_packet_has_meta(packet)) {meta mpp_packet_get_meta(packet);RK_S32 temporal_id 0;RK_S32 lt_idx -1;RK_S32 avg_qp -1;if (MPP_OK mpp_meta_get_s32(meta, KEY_TEMPORAL_ID, temporal_id))log_len snprintf(log_buf log_len, log_size - log_len, tid %d, temporal_id);if (MPP_OK mpp_meta_get_s32(meta, KEY_LONG_REF_IDX, lt_idx))log_len snprintf(log_buf log_len, log_size - log_len, lt %d, lt_idx);if (MPP_OK mpp_meta_get_s32(meta, KEY_ENC_AVERAGE_QP, avg_qp))log_len snprintf(log_buf log_len, log_size - log_len, qp %d, avg_qp);}// mpp_log_q(quiet, chn %d %s\n, chn, log_buf);mpp_packet_deinit(packet);// fps_calc_inc(p-fps_out_num);p-stream_size len;p-frame_count eoi;if (p-pkt_eos) {mpp_log_q(quiet, chn %d found last packet\n, chn);mpp_assert(p-frm_eos);}}} while (!eoi);if (p-frame_num 0 p-frame_count p-frame_num)break;if (p-frm_eos p-pkt_eos)break;}
RET:MPP_FREE(checkcrc.sum);return ret;
}encoder::encoder()
{}int encoder::init(char * fs,int size)
{ memset(this-info,0,sizeof(MpiEncMultiCtxInfo));MpiEncTestData *p info-ctx;MpiEncMultiCtxRet *enc_ret info-ret;MppApi *mpi p-mpi;MppCtx ctx p-ctx;MppPollType timeout MPP_POLL_BLOCK;MPP_RET ret MPP_OK;RK_S64 t_s 0;RK_S64 t_e 0;RK_U32 quiet ;ret test_ctx_init(info);if (ret) {mpp_err_f(test data init failed ret %d\n, ret);goto MPP_TEST_OUT;}ret mpp_buffer_group_get_internal(p-buf_grp, MPP_BUFFER_TYPE_DRM);if (ret) {mpp_err_f(failed to get mpp buffer group ret %d\n, ret);goto MPP_TEST_OUT;}ret mpp_buffer_get(p-buf_grp, p-frm_buf, p-frame_size p-header_size);if (ret) {mpp_err_f(failed to get buffer for input frame ret %d\n, ret);goto MPP_TEST_OUT;}ret mpp_buffer_get(p-buf_grp, p-pkt_buf, p-frame_size);if (ret) {mpp_err_f(failed to get buffer for output packet ret %d\n, ret);goto MPP_TEST_OUT;}ret mpp_buffer_get(p-buf_grp, p-md_info, p-mdinfo_size);if (ret) {mpp_err_f(failed to get buffer for motion info output packet ret %d\n, ret);goto MPP_TEST_OUT;}// encoder demoret mpp_create(p-ctx, p-mpi);if (ret) {mpp_err(mpp_create failed ret %d\n, ret);goto MPP_TEST_OUT;}mpp_log_q(quiet, %p encoder test start w %d h %d type %d\n,p-ctx, p-width, p-height, p-type);ret p-mpi-control(p-ctx, MPP_SET_OUTPUT_TIMEOUT, timeout);if (MPP_OK ! ret) {mpp_err(mpi control set output timeout %d ret %d\n, timeout, ret);goto MPP_TEST_OUT;}ret mpp_init(p-ctx, MPP_CTX_ENC, p-type);if (ret) {mpp_err(mpp_init failed ret %d\n, ret);goto MPP_TEST_OUT;}ret mpp_enc_cfg_init(p-cfg);if (ret) {mpp_err_f(mpp_enc_cfg_init failed ret %d\n, ret);goto MPP_TEST_OUT;}ret p-mpi-control(p-ctx, MPP_ENC_GET_CFG, p-cfg);if (ret) {mpp_err_f(get enc cfg failed ret %d\n, ret);goto MPP_TEST_OUT;}ret test_mpp_enc_cfg_setup(info);if (ret) {mpp_err_f(test mpp setup failed ret %d\n, ret);goto MPP_TEST_OUT;}p-pkt_eos 0;// prepare a frame headif (p-type MPP_VIDEO_CodingAVC || p-type MPP_VIDEO_CodingHEVC) {MppPacket packet NULL;/** Can use packet with normal malloc buffer as input not pkt_buf.* Please refer to vpu_api_legacy.cpp for normal buffer case.* Using pkt_buf buffer here is just for simplifing demo.*/mpp_packet_init_with_buffer(packet, p-pkt_buf);/* NOTE: It is important to clear output packet length!! */mpp_packet_set_length(packet, 0);ret p-mpi-control(p-ctx, MPP_ENC_GET_HDR_SYNC, packet);if (ret) {mpp_err(mpi control enc get extra info failed\n);// goto RET;} else {/* get and write sps/pps for H.264 */void *ptr mpp_packet_get_pos(packet);size_t len mpp_packet_get_length(packet);if (p-fp_output)fs (char*)malloc(len*sizeof(char));memcpy(fs, ptr, len);size len;// fwrite(ptr, 1, len, p-fp_output);}mpp_packet_deinit(packet);return 1;}MPP_TEST_OUT:if (p-ctx) {mpp_destroy(p-ctx);p-ctx NULL;}if (p-cfg) {mpp_enc_cfg_deinit(p-cfg);p-cfg NULL;}if (p-frm_buf) {mpp_buffer_put(p-frm_buf);p-frm_buf NULL;}if (p-pkt_buf) {mpp_buffer_put(p-pkt_buf);p-pkt_buf NULL;}if (p-md_info) {mpp_buffer_put(p-md_info);p-md_info NULL;}if (p-osd_data.buf) {mpp_buffer_put(p-osd_data.buf);p-osd_data.buf NULL;}if (p-buf_grp) {mpp_buffer_group_put(p-buf_grp);p-buf_grp NULL;}if (p-roi_ctx) {mpp_enc_roi_deinit(p-roi_ctx);p-roi_ctx NULL;}test_ctx_deinit(p);return 0;
}
MPP_RET encoder::postAframe(cv::Mat pic,char* fs,int length ){MPP_RET ret MPP_NOK;MpiEncTestData *p info-ctx;ret test_mpp_run(info,pic,fs,length);POST_OUT:return ret;}
int encoder::deinit(MPP_RET ret MPP_OK){MpiEncTestData *p info-ctx;if (ret) {mpp_err_f(test mpp run failed ret %d\n, ret);goto POST_OUT;}ret p-mpi-reset(p-ctx);if (ret) {mpp_err(mpi-reset failed\n);goto POST_OUT;}POST_OUT:// return ret;
if (p-ctx) {mpp_destroy(p-ctx);p-ctx NULL;}if (p-cfg) {mpp_enc_cfg_deinit(p-cfg);p-cfg NULL;}if (p-frm_buf) {mpp_buffer_put(p-frm_buf);p-frm_buf NULL;}if (p-pkt_buf) {mpp_buffer_put(p-pkt_buf);p-pkt_buf NULL;}if (p-md_info) {mpp_buffer_put(p-md_info);p-md_info NULL;}if (p-osd_data.buf) {mpp_buffer_put(p-osd_data.buf);p-osd_data.buf NULL;}if (p-buf_grp) {mpp_buffer_group_put(p-buf_grp);p-buf_grp NULL;}if (p-roi_ctx) {mpp_enc_roi_deinit(p-roi_ctx);p-roi_ctx NULL;}test_ctx_deinit(p);return 0;}
encoder::~encoder(){}
.h文件
#ifndef ENCODER_H
#define ENCODER_H#include string.h
#include rk_mpi.h#include mpp_env.h
#include mpp_mem.h
#include mpp_time.h
#include mpp_debug.h
#include mpp_common.h#include utils.h
#include mpi_enc_utils.h
//#include camera_source.h
#include mpp_enc_roi_utils.h
#include mpp_rc_api.h
#include opencv2/opencv.hpp
// #include H264_V4l2DeviceSource.htypedef struct {// base flow contextMppCtx ctx;MppApi *mpi;RK_S32 chn;// global flow control flagRK_U32 frm_eos;RK_U32 pkt_eos;RK_U32 frm_pkt_cnt;RK_S32 frame_num;RK_S32 frame_count;RK_U64 stream_size;/* end of encoding flag when set quit the loop */volatile RK_U32 loop_end;// src and dstFILE *fp_input;FILE *fp_output;FILE *fp_verify;/* encoder config set */MppEncCfg cfg;MppEncPrepCfg prep_cfg;MppEncRcCfg rc_cfg;MppEncCodecCfg codec_cfg;MppEncSliceSplit split_cfg;MppEncOSDPltCfg osd_plt_cfg;MppEncOSDPlt osd_plt;MppEncOSDData osd_data;RoiRegionCfg roi_region;MppEncROICfg roi_cfg;// input / outputMppBufferGroup buf_grp;MppBuffer frm_buf;MppBuffer pkt_buf;MppBuffer md_info;MppEncSeiMode sei_mode;MppEncHeaderMode header_mode;// paramter for resource mallocRK_U32 width;RK_U32 height;RK_U32 hor_stride;RK_U32 ver_stride;MppFrameFormat fmt;MppCodingType type;RK_S32 loop_times;
// CamSource *cam_ctx;MppEncRoiCtx roi_ctx;// resourcessize_t header_size;size_t frame_size;size_t mdinfo_size;/* NOTE: packet buffer may overflow */size_t packet_size;RK_U32 osd_enable;RK_U32 osd_mode;RK_U32 split_mode;RK_U32 split_arg;RK_U32 split_out;RK_U32 user_data_enable;RK_U32 roi_enable;// rate control runtime parameterRK_S32 fps_in_flex;RK_S32 fps_in_den;RK_S32 fps_in_num;RK_S32 fps_out_flex;RK_S32 fps_out_den;RK_S32 fps_out_num;RK_S32 bps;RK_S32 bps_max;RK_S32 bps_min;RK_S32 rc_mode;RK_S32 gop_mode;RK_S32 gop_len;RK_S32 vi_len;RK_S32 scene_mode;RK_S64 first_frm;RK_S64 first_pkt;
} MpiEncTestData;/* For each instance thread return value */
typedef struct {float frame_rate;RK_U64 bit_rate;RK_S64 elapsed_time;RK_S32 frame_count;RK_S64 stream_size;RK_S64 delay;
} MpiEncMultiCtxRet;typedef struct {MpiEncTestArgs *cmd; // pointer to global command line infoconst char *name;RK_S32 chn;pthread_t thd; // thread for for each instanceMpiEncTestData ctx; // context of encoderMpiEncMultiCtxRet ret; // return of encoder
} MpiEncMultiCtxInfo;
class encoder
{
public:encoder();~encoder();int init(char * fs,int size);int deinit(MPP_RET ret );MPP_RET postAframe(cv::Mat pic,char* fs,int length );// void run();// void defaultInit();
private:MpiEncMultiCtxInfo *info new MpiEncMultiCtxInfo ;};#endif // VIDEOTHREAD_H
main.cpp
#include encoder.h
#include decoder.h
#include iostream
#include opencv2/opencv.hpp
#include opencv2/core/core.hpp
#include opencv2/highgui/highgui.hpp
#include fstream
#include sstream
void writeCharPointerToFile(const char* data, std::size_t size, const std::string filename) {// 打开文件std::ofstream file(filename, std::ios::binary);// 检查文件是否成功打开if (!file.is_open()) {std::cerr 无法打开文件: filename std::endl;return;}// 写入数据file.write(data, size);// 关闭文件file.close();
}
using namespace std;
using namespace cv;
int main(){std::string filename output.txt;int width 1280;int height 720;// 创建一个空白图像全黑cv::Mat colorBar cv::Mat::zeros(height, width, CV_8UC3);// 设置彩条的宽度int barWidth width / 8; // 8个彩条你可以根据需要调整// 生成彩条for (int i 0; i 8; i) {// 计算彩条的起始和结束位置int startX i * barWidth;int endX (i 1) * barWidth;// 设置彩条颜色BGR格式cv::Vec3b color;if (i % 2 0) {color cv::Vec3b(255, 0, 0); // 蓝色} else {color cv::Vec3b(0, 255, 0); // 绿色}// 在图像上画出彩条colorBar(cv::Rect(startX, 0, barWidth, height)) color;}int totalBytes width * height * 3; // 3个通道BGR每个通道占一个字节// memcpy(buf, colorBar.data, totalBytes);imwrite(1.jpg,colorBar);encoder e;decoder d;char* frame;int len;e.init(frame,len);d.init();for(int i 0 ;i1000;i){e.postAframe(colorBar,frame,len);usleep(30*1000);writeCharPointerToFile(frame, len, filename);d.poststream(frame,len);}e.deinit(MPP_OK);return 0;
}调试建议
一个是前面说的 -g,debug 看配置再有就是上一篇编码gop设小一点,如果是实时流的话 然后就是看你输出的东西对不对劲了这个我推荐一个软件HxD hex editor 看二进制可以在他的读入文件那里用一个jpg图像或者用opencv保存一个bgr的彩条图像然后直接使用图像编码模式编码出来一个264文件测试逐帧保存结果。看和他的结果是否一样如果完全一致就对了不一致的话需要找找原因。 文章转载自: http://www.morning.mfltz.cn.gov.cn.mfltz.cn http://www.morning.bqnhh.cn.gov.cn.bqnhh.cn http://www.morning.mkrqh.cn.gov.cn.mkrqh.cn http://www.morning.zrpys.cn.gov.cn.zrpys.cn http://www.morning.ykmkz.cn.gov.cn.ykmkz.cn http://www.morning.fmdvbsa.cn.gov.cn.fmdvbsa.cn http://www.morning.hfnbr.cn.gov.cn.hfnbr.cn http://www.morning.ggjlm.cn.gov.cn.ggjlm.cn http://www.morning.trhrk.cn.gov.cn.trhrk.cn http://www.morning.mlntx.cn.gov.cn.mlntx.cn http://www.morning.fsjcn.cn.gov.cn.fsjcn.cn http://www.morning.mnslh.cn.gov.cn.mnslh.cn http://www.morning.hbxnb.cn.gov.cn.hbxnb.cn http://www.morning.ylqb8.cn.gov.cn.ylqb8.cn http://www.morning.qnqt.cn.gov.cn.qnqt.cn http://www.morning.dlurfdo.cn.gov.cn.dlurfdo.cn http://www.morning.hwpcm.cn.gov.cn.hwpcm.cn http://www.morning.xfcjs.cn.gov.cn.xfcjs.cn http://www.morning.mtrfz.cn.gov.cn.mtrfz.cn http://www.morning.xzkgp.cn.gov.cn.xzkgp.cn http://www.morning.mgbcf.cn.gov.cn.mgbcf.cn http://www.morning.gbjxj.cn.gov.cn.gbjxj.cn http://www.morning.pbsqr.cn.gov.cn.pbsqr.cn http://www.morning.sqfrg.cn.gov.cn.sqfrg.cn http://www.morning.hxwhyjh.com.gov.cn.hxwhyjh.com http://www.morning.xkjqg.cn.gov.cn.xkjqg.cn http://www.morning.gqtw.cn.gov.cn.gqtw.cn http://www.morning.pdkht.cn.gov.cn.pdkht.cn http://www.morning.cjmmt.cn.gov.cn.cjmmt.cn http://www.morning.clkjn.cn.gov.cn.clkjn.cn http://www.morning.zwsgl.cn.gov.cn.zwsgl.cn http://www.morning.nqwkn.cn.gov.cn.nqwkn.cn http://www.morning.wjhdn.cn.gov.cn.wjhdn.cn http://www.morning.nhzxd.cn.gov.cn.nhzxd.cn http://www.morning.fwlch.cn.gov.cn.fwlch.cn http://www.morning.xxrwp.cn.gov.cn.xxrwp.cn http://www.morning.ycwym.cn.gov.cn.ycwym.cn http://www.morning.xkpjl.cn.gov.cn.xkpjl.cn http://www.morning.nhpmn.cn.gov.cn.nhpmn.cn http://www.morning.mqtzd.cn.gov.cn.mqtzd.cn http://www.morning.jybj.cn.gov.cn.jybj.cn http://www.morning.cgntj.cn.gov.cn.cgntj.cn http://www.morning.yqkxr.cn.gov.cn.yqkxr.cn http://www.morning.tgts.cn.gov.cn.tgts.cn http://www.morning.pqrhb.cn.gov.cn.pqrhb.cn http://www.morning.rbbgh.cn.gov.cn.rbbgh.cn http://www.morning.dkcpt.cn.gov.cn.dkcpt.cn http://www.morning.c7624.cn.gov.cn.c7624.cn http://www.morning.ltpmy.cn.gov.cn.ltpmy.cn http://www.morning.lxwjx.cn.gov.cn.lxwjx.cn http://www.morning.kycwt.cn.gov.cn.kycwt.cn http://www.morning.lynkz.cn.gov.cn.lynkz.cn http://www.morning.nhrkc.cn.gov.cn.nhrkc.cn http://www.morning.wyjpt.cn.gov.cn.wyjpt.cn http://www.morning.chmcq.cn.gov.cn.chmcq.cn http://www.morning.phzrq.cn.gov.cn.phzrq.cn http://www.morning.jbfzx.cn.gov.cn.jbfzx.cn http://www.morning.qiyelm.com.gov.cn.qiyelm.com http://www.morning.hhfwj.cn.gov.cn.hhfwj.cn http://www.morning.rhmk.cn.gov.cn.rhmk.cn http://www.morning.ltrz.cn.gov.cn.ltrz.cn http://www.morning.lpmjr.cn.gov.cn.lpmjr.cn http://www.morning.mfmbn.cn.gov.cn.mfmbn.cn http://www.morning.lqynj.cn.gov.cn.lqynj.cn http://www.morning.bssjz.cn.gov.cn.bssjz.cn http://www.morning.hnkkm.cn.gov.cn.hnkkm.cn http://www.morning.qgmwt.cn.gov.cn.qgmwt.cn http://www.morning.nzkkh.cn.gov.cn.nzkkh.cn http://www.morning.rpdmj.cn.gov.cn.rpdmj.cn http://www.morning.kehejia.com.gov.cn.kehejia.com http://www.morning.fbmrz.cn.gov.cn.fbmrz.cn http://www.morning.thmlt.cn.gov.cn.thmlt.cn http://www.morning.lkbyq.cn.gov.cn.lkbyq.cn http://www.morning.tgfsr.cn.gov.cn.tgfsr.cn http://www.morning.nkddq.cn.gov.cn.nkddq.cn http://www.morning.jrhmh.cn.gov.cn.jrhmh.cn http://www.morning.kbfzp.cn.gov.cn.kbfzp.cn http://www.morning.jqmmf.cn.gov.cn.jqmmf.cn http://www.morning.ztcxx.com.gov.cn.ztcxx.com http://www.morning.gyrdn.cn.gov.cn.gyrdn.cn