当前位置: 首页> 健康> 美食 > 最近北京病毒感染是什么情况啊_论坛seo教程_凡科建站app_舆情分析网站

最近北京病毒感染是什么情况啊_论坛seo教程_凡科建站app_舆情分析网站

时间:2025/7/29 21:40:39来源:https://blog.csdn.net/iamqianrenzhan/article/details/144003424 浏览次数:0次
最近北京病毒感染是什么情况啊_论坛seo教程_凡科建站app_舆情分析网站

目标:

将opencv处理后的图像,直接进行rtsp推流。

测试推流

推流本地文件

.\gst-launch-1.0.exe filesrc location=D:\\5.mp4 ! decodebin ! videoconvert ! x264enc ! rtspclientsink location=rtsp://127.0.0.1:8554/live

播放推流内容

.\gst-launch-1.0.exe rtspsrc location=rtsp://127.0.0.1:8554/live ! rtph264depay ! h264parse ! avdec_h264 ! autovideosink

推流实现方案

方案1:使用gstreamer进行推流

//使用代码进行opencv推流
#include <gst/gst.h>
#include <gst/app/gstappsrc.h>
#include <opencv2/opencv.hpp>#define RTSP_SERVER_URL "rtsp://127.0.0.1:8554/live"
#define CAPTURE_WIDTH 640
#define CAPTURE_HEIGHT 480
#define CAPTURE_FPS 30
#define FRAME_INTERVAL_MS (1000 / CAPTURE_FPS)int main(int argc, char* argv[]) 
{//GStreamergst_init(&argc, &argv);std::cout << "3e" << std::endl;// GStreamerGstElement* pipeline = gst_pipeline_new("rtsp-pipeline");GstElement* appsrc = gst_element_factory_make("appsrc", "app-source");GstElement* videoconvert = gst_element_factory_make("videoconvert", "convert");GstElement* x264enc = gst_element_factory_make("x264enc", "encoder");GstElement* rtph264pay = gst_element_factory_make("rtph264pay", "payloader");GstElement* rtspclientsink = gst_element_factory_make("rtspclientsink", "sink");//appsrcg_object_set(G_OBJECT(appsrc), "is-live", TRUE, NULL);g_object_set(G_OBJECT(appsrc), "format", GST_FORMAT_TIME, NULL);g_object_set(G_OBJECT(appsrc), "caps", gst_caps_new_simple("video/x-raw","format", G_TYPE_STRING, "BGR","width", G_TYPE_INT, CAPTURE_WIDTH,"height", G_TYPE_INT, CAPTURE_HEIGHT,"framerate", GST_TYPE_FRACTION, CAPTURE_FPS, 1,NULL), NULL);//gst_bin_add_many(GST_BIN(pipeline), appsrc, videoconvert, x264enc, rtph264pay, rtspclientsink, NULL);// gst_element_link_many(appsrc, videoconvert, x264enc, rtph264pay, rtspclientsink, NULL);//rtspclientsink g_object_set(G_OBJECT(rtspclientsink), "location", RTSP_SERVER_URL, NULL);//gst_element_set_state(pipeline, GST_STATE_PLAYING);//cv::VideoCapture cap(0);if (!cap.isOpened()) {std::cerr << "Error: Unable to open camera." << std::endl;return -1;}//while (true){cv::Mat frame;cap >> frame;if (frame.empty()) {std::cerr << "Warning: Empty frame." << std::endl;continue;}//打印精确到ms的时间std::chrono::system_clock::time_point now = std::chrono::system_clock::now();auto t = std::chrono::system_clock::to_time_t(now);auto tp = std::chrono::system_clock::from_time_t(t);auto ms = std::chrono::duration_cast<std::chrono::milliseconds>(now - tp).count();auto in_time_t = std::chrono::system_clock::to_time_t(now);std::cout << std::put_time(std::localtime(&in_time_t), "%Y-%m-%d %X") << "." << ms << std::endl;//GstBuffer* buffer = gst_buffer_new_allocate(NULL, frame.total() * frame.elemSize(), NULL);GstMapInfo map;gst_buffer_map(buffer, &map, GST_MAP_WRITE);memcpy(map.data, frame.data, frame.total() * frame.elemSize());gst_buffer_unmap(buffer, &map);GstFlowReturn ret;g_signal_emit_by_name(appsrc, "push-buffer", buffer, &ret);gst_buffer_unref(buffer);//g_usleep(FRAME_INTERVAL_MS * 1000);}//gst_element_set_state(pipeline, GST_STATE_NULL);gst_object_unref(pipeline);return 0;
}

方案2:使用ffmpeg推流

#include "rtspencoder.h"
#include <QCoreApplication>
#include <QDebug>RTSPEncoder::RTSPEncoder(const char* rtspUrl, int outputWidth, int outputHeight, QObject* parent): QThread(parent), m_rtspUrl(rtspUrl), m_outputWidth(outputWidth), m_outputHeight(outputHeight)
{}RTSPEncoder::~RTSPEncoder()
{cleanup();
}int RTSPEncoder::initialize()
{avformat_network_init();// Initialize output contextm_outFormatCtx = nullptr;avformat_alloc_output_context2(&m_outFormatCtx, nullptr, "rtsp", m_rtspUrl.c_str());if (!m_outFormatCtx) {std::cerr << "Error: Failed to allocate output context\n";return -1;}// Find encoder for H264m_codec = (AVCodec*)avcodec_find_encoder(AV_CODEC_ID_H264);if (!m_codec) {std::cerr << "Error: Failed to find H264 encoder\n";return -1;}// Add video stream to output contextm_outStream = avformat_new_stream(m_outFormatCtx, m_codec);if (!m_outStream) {std::cerr << "Error: Failed to create new stream\n";return -1;}// Initialize codec context for the encoderm_codecCtx = avcodec_alloc_context3(m_codec);if (!m_codecCtx) {std::cerr << "Error: Failed to allocate codec context\n";return -1;}m_codecCtx->codec_id = AV_CODEC_ID_H264;m_codecCtx->codec_type = AVMEDIA_TYPE_VIDEO;m_codecCtx->pix_fmt = AV_PIX_FMT_YUV420P;m_codecCtx->width = m_outputWidth;m_codecCtx->height = m_outputHeight;m_codecCtx->time_base = { 1, 25 }; // assuming 25fpsm_codecCtx->bit_rate = 700000;m_codecCtx->gop_size = 10;m_codecCtx->max_b_frames = 0;m_codecCtx->flags = AV_CODEC_FLAG_GLOBAL_HEADER | AV_CODEC_FLAG_LOW_DELAY;// Set codec optionsAVDictionary* codecOptions = nullptr;av_dict_set(&codecOptions, "preset", "ultrafast", 0);av_dict_set(&codecOptions, "tune", "zerolatency", 0);// Open the encoder codecOptions 设置到m_codecCtxif (avcodec_open2(m_codecCtx, m_codec, &codecOptions) < 0) {std::cerr << "Error: Failed to open encoder\n";return -1;}// Copy codec parameters to output streamavcodec_parameters_from_context(m_outStream->codecpar, m_codecCtx);// Write stream headeravformat_write_header(m_outFormatCtx, nullptr);m_frame.create(m_outputHeight, m_outputWidth, CV_8UC3);m_frame.setTo(0);m_frameCount = 0;m_avFrame = av_frame_alloc();return 0;
}void RTSPEncoder::encodeFrameAndSend()
{while (1){//阻塞,等待AddFrame{std::unique_lock<std::mutex> lock(mtx);while (!m_isReady) {m_cv.wait(lock);}m_isReady = false;// Convert OpenCV Mat to AVFramecv::cvtColor(m_frame, m_im420, cv::COLOR_RGB2YUV_I420);m_avFrame->data[0] = m_im420.data;m_avFrame->data[1] = m_avFrame->data[0] + m_codecCtx->width * m_codecCtx->height;m_avFrame->data[2] = m_avFrame->data[1] + m_codecCtx->width * m_codecCtx->height / 4;m_avFrame->linesize[0] = m_codecCtx->width;m_avFrame->linesize[1] = m_codecCtx->width / 2;m_avFrame->linesize[2] = m_codecCtx->width / 2;m_avFrame->width = m_codecCtx->width;m_avFrame->height = m_codecCtx->height;m_avFrame->format = AV_PIX_FMT_YUV420P;//m_frameCount += 30;m_avFrame->pts = m_frameCount++;auto ret = avcodec_send_frame(m_codecCtx, m_avFrame);if (ret < 0){std::cerr << "Error: Failed to send frame for encoding\n";return;}AVPacket pkt;av_init_packet(&pkt);while (ret >= 0){ret = avcodec_receive_packet(m_codecCtx, &pkt);if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF){break;}else if (ret < 0){std::cout << "Error: Failed to receive encoded packet\n";continue;}pkt.stream_index = m_outStream->index;av_packet_rescale_ts(&pkt, m_codecCtx->time_base, m_outStream->time_base);ret = av_interleaved_write_frame(m_outFormatCtx, &pkt);av_packet_unref(&pkt);if (ret < 0){std::cout << "Error: Failed to write packet to output stream\n";continue;}}}}
}void RTSPEncoder::AddFrame(cv::Mat& imGBR, int nFrame)
{if (imGBR.cols != m_outputWidth || imGBR.rows != m_outputHeight)return;//阻塞等待encodeFrameAndSend{std::lock_guard<std::mutex> lock(mtx);memcpy(m_frame.data, imGBR.data, imGBR.cols * imGBR.rows * 3);m_frameCount = nFrame;m_isReady = true;}m_cv.notify_one();}void RTSPEncoder::cleanup()
{// Write trailerav_write_trailer(m_outFormatCtx);// Cleanupif(m_codecCtx)avcodec_free_context(&m_codecCtx);if(m_avFrame)av_frame_free(&m_avFrame);if(m_outFormatCtx)avformat_free_context(m_outFormatCtx);
}

方案3:使用opencv的gstream后端进行推流

使用这种方式,实现简单,但在测试时会有一定的延迟。

void push()
{int codec = cv::VideoWriter::fourcc('H', 'E', 'V', 'C');m_writer.open(push_str, codec, fps, cv::Size(width, height));cv::Mat tmp;while (true){{std::unique_lock<std::mutex> lk(proc2push_mtx);proc2push_cv.wait(lk);tmp = img_push.clone();}if (!m_writer.isOpened()){int codec = cv::VideoWriter::fourcc('H', 'E', 'V', 'C');m_writer.open(push_str, codec, fps, cv::Size(width, height));}m_writer.write(tmp);}
}

其他测试代码

int main1()  
{  //std::cout << cv::getBuildInformation() << std::endl;  //gst-launch-1.0 //usb//gst-launch-1.0 v4l2src device=/dev/video0 ! image/jpeg,width=1920,height=1080,framerate=30/1 ! jpegdec ! videoconvert ! xvimagesink//gst-launch-1.0 v4l2src device=/dev/video0 ! image/jpeg,format=MJPG,width=1280,height=720,framerate=30/1 ! nvv4l2decoder mjpeg=1 ! nvvidconv ! autovideosink//cv::VideoCapture capture(0);  //not ok blur//"v4l2src device=/dev/video0 ! image/jpeg,width=1920,height=1080,framerate=30/1 ! jpegdec ! videoconvert ! appsink"std::string pipeline = "v4l2src device=/dev/video0 ! image/jpeg,width=1920,height=1080,framerate=30/1 ! nvv4l2decoder mjpeg=1 ! nvvidconv ! appsink";cv::VideoCapture capture(pipeline,cv::CAP_GSTREAMER);  //ok//rtsp//gst-launch-1.0 rtspsrc location='rtsp://admin:admin@192.168.1.108/cam/realmonitor?channel=1&subtype=0' latency=100 ! rtph264depay ! h264parse ! omxh264dec ! nvvidconv ! video/x-raw, width=1920, height=1080, format=BGRx ! videoconvert ! xvimagesink//gst-launch-1.0 rtspsrc location='rtsp://admin:admin@192.168.1.108/cam/realmonitor?channel=1&subtype=0' latency=100 ! videoconvert ! xvimagesink//cv::VideoCapture capture("rtsp://admin:admin@192.168.1.108/cam/realmonitor?channel=1&subtype=0",cv::CAP_FFMPEG); //not gstreamer 2s delay//std::string pipeline = "rtspsrc location='rtsp://admin:admin@192.168.1.108/cam/realmonitor?channel=1&subtype=0' latency=100 ! rtph264depay ! h264parse ! omxh264dec ! nvvidconv ! video/x-raw, width=1920, height=1080, format=BGRx !videoconvert ! appsink";//std::string pipeline = "rtsp://admin:admin@192.168.1.108/cam/realmonitor?channel=1&subtype=0";//cv::VideoCapture capture(pipeline, cv::CAP_GSTREAMER);//std::string pipeline = "rtspsrc location=rtsp://admin:admin@192.168.1.108/cam/realmonitor?channel=1&subtype=0 ! decodebin ! videoconvert ! appsink max-buffers=1 drop=true";// cv::VideoCapture capture;// if(capture.open("rtsp://admin:admin@192.168.1.108/cam/realmonitor?channel=1&subtype=0"))  //, cv::CAP_GSTREAMER// {//     std::cout << "open video Failed !" << std::endl;  //     return -1;  // }if (!capture.isOpened()) {  std::cout << "Read video Failed !" << std::endl;  return -1;  }  // cv::VideoWriter m_writer;// int codec = cv::VideoWriter::fourcc('H', '2', '6', '4');// double fps = 25.0;// int width = 1920;// int height = 1080;  //nvv4l2h264enc// m_writer.open("appsrc ! videoconvert ! x264enc ! flvmux ! rtmpsink location=rtmp://192.168.18.218:1935/live", codec, fps, cv::Size(width, height));  //client// if (!m_writer.isOpened())// {//     std::cout << "Error: VideoWriter is not opened!" << std::endl;//     return -1;// }cv::Mat frame;  cv::namedWindow("video test");  int frame_num = capture.get(cv::CAP_PROP_FRAME_COUNT);  std::cout << "total frame number is: " << frame_num << std::endl;  //for (int i = 0; i < frame_num - 1; ++i)  while(1){  capture >> frame;  //m_writer.write(frame);//capture.read(frame); 第二种方式  imshow("video test", frame);  if (cv::waitKey(30) == 'q')  {  break;  }  }  cv::destroyWindow("video test");  capture.release();  return 0;  
}  
 gst-launch-1.0 -v filesrc location=D:/1.mp4 ! decodebin ! x264enc ! rtph264pay ! udpsink host=127.0.0.1 port=8554gst-launch-1.0 -v rtspsrc location=rtsp://127.0.0.1:10054/live/Fs4FsmKSR ! rtph264depay !  h264parse ! avdec_h264 ! videoconvert ! video/x-raw, width=3840, height=2100, format=BGRx ! videoconvert !  ximagesink sync=falsegst-launch-1.0 -v videotestsrc ! video/x-raw, format=BGRx ! autovideosinkgst-launch-1.0 -v rtspsrc location=rtsp://127.0.0.1:10054/live/Fs4FsmKSR ! rtph264depay !  h264parse ! avdec_h264 ! videoconvert ! video/2.mp4, format=BGRx ! videoconvert !  ximagesink sync=falsegst-launch-1.0 -v rtspsrc location=rtsp://127.0.0.1:10054/live/Fs4FsmKSR ! decodebin ! videoconvert ! autovideosinkgst-launch-1.0 -v appsrc ! videoconvert ! video/x-raw,format=I420 ! nvvidconv ! video/x-raw(memory:NVMM),format=I420 ! nvv4l2h264enc insert-sps-pps=1 ! video/x-h264,stream-format=byte-stream ! rtspclientsink location=rtsp://localhost:8554/mystreamgst-launch-1.0 -v appsrc name=mysource is-live=true block=true format=GST_FORMAT_TIME \! videoconvert \! video/x-raw,format=NV12 \! nvv4l2h264enc \! video/x-h264,stream-format=byte-stream \! h264parse \! rtspclientsink location=rtsp://localhost:8554/mystream
关键字:最近北京病毒感染是什么情况啊_论坛seo教程_凡科建站app_舆情分析网站

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

责任编辑: