当前位置:网站首页>Improvement of RTP receiving and sending PS stream tool (II)
Improvement of RTP receiving and sending PS stream tool (II)
2022-07-02 23:50:00 【qianbo_ insist】
RTP ps
Last time I wrote RTP Tool send RTP package , This time it improves sending and receiving , Can really receive and send images , This revision , bring RTP Send receive and PS flow RTP Sending and receiving have been successful . The delay is in 300 Millisecond or so . The code address is in the last article .
Here's how to receive , This use udp Asynchronous reception , Send to the parsing thread to decode the display , Use callback function to communicate with the main interface . It also contains storage h264 Code for , Every time 500 frame , These will be configured later , It is not perfect yet .
The main improvement of reception is the use of asynchronous reception , Synchronous reception remains , Later, a switch will be made to turn on and off , Sending and receiving are not well configured on the interface , It used to be RTP Package send and receive , This time it is PS Packet sending and receiving of streams . Readers need to change the code themselves for the time being .
UDPserver
This time, I used boost Of asio, Consider using it alone later c++20, and asio coordination .
#pragma once
#include <cstdlib>
#include <iostream>
#include <memory>
#include <unordered_map>
#include <boost/asio.hpp>
#include <boost/asio/spawn.hpp>
#include "c_rtp.h"
#include "c_thread.h"
using namespace boost;
using boost::asio::ip::udp;
typedef void(*rtp_callback_data)(void* puser, void* pkt,int len, int w, int h, uint32_t ssrc);
typedef void(*rtp_callback_log)(void* puser, const char* log,...);
#define DEFINE_EC \ boost::system::error_code ec;
class IO_Thread;
class c_udpserver:public c_thread
{
//asio::strand<asio::io_context::executor_type> v_strand;
asio::io_context v_context;
asio::ip::udp::socket v_socket;
//ssrc rtpcontext
std::unordered_map<uint32_t, s_rtp_context*> v_ctxs;
s_rtp_context * getctx(uint32_t ssrc)
{
auto it = v_ctxs.find(ssrc);
if (it != v_ctxs.end())
return it->second;
else
{
s_rtp_context *sc = new s_rtp_context();
v_ctxs[ssrc] = sc;
return sc;
}
}
void data_call(s_rtp_context *ctx);
int live_rtp_unpack_h264(s_rtp_context *ctx, uint8_t *data, int inlen);
int live_rtp_unpack_ps(s_rtp_context *ctx,
uint8_t *data,
int inlen, uint32_t ssrc
);
public:
c_udpserver(short port):
//v_strand(io_context.get_executor()),
v_socket(v_context)
{
udp::endpoint ep(udp::v4(), port);
v_socket.open(ep.protocol());
v_socket.set_option(boost::asio::ip::udp::socket::reuse_address(true));
boost::asio::socket_base::receive_buffer_size recv_option(2*1024*1024);
v_socket.set_option(recv_option);
v_socket.bind(ep);
}
~c_udpserver()
{
//v_context_maps.clear();
}
void Run();
//to flv server
void do_receive_rtp_head();
void do_receive();
void set_callback(void *puser, rtp_callback_data cb, rtp_callback_log cblog)
{
v_callback_data = cb;
v_callback_log = cblog;
v_user = puser;
}
void do_send(std::size_t length);
void do_judge_spspps(s_rtp_context *ctx);
private:
udp::endpoint sender_endpoint_;
enum {
max_length = 1500};
char data_[max_length] = {
0};
public:
rtp_callback_data v_callback_data = NULL;
rtp_callback_log v_callback_log = NULL;
void* v_user = NULL;
public:
void Stop();
// Send information to the thread
void postmessage(uint32_t ssrc, int number);
void postmessage_2interface(char* strFmt, ...);
void postmessage_2show(void* pkt,int payload);
};
As the code shows , Communication with the interface mainly depends on two callback functions
rtp_callback_data v_callback_data = NULL;
rtp_callback_log v_callback_log = NULL;
among v_user It is the main interface , Represented by empty type .
Exhibition
In order not to use more libraries , Use it first GDI Show , It also contains SDL Show , Readers can modify .
class c_drawrgb24
{
public:
c_drawrgb24(void);
~c_drawrgb24(void);
protected:
void CreateDoubleBuffer(HDC hdc1, int cxClient1 ,int cyClient1,HDC hdc2,int cxClient2,int cyClient2);
public:
void Draw2(HWND hWnd,HWND hWnd2, unsigned char * buffer, int SrcW, int SrcH);
void DrawSDL(HWND hWnd, unsigned char * buffer, int SrcW, int SrcH);
//void DrawPInP(HWND hWnd
public:
// Image reversal
void SetVertial();
private:
LPBITMAPINFO m_lpBmpInfo;
bool m_bInit;
HBITMAP _hBm1;
HDC _hdc_buffer1;
HBITMAP _hBm2;
HDC _hdc_buffer2;
SDLDraw _sdldraw;
};
#ifdef _WIN32
#include <SDKDDKVer.h>
#endif
#include "c_drawrgb24.h"
c_drawrgb24::c_drawrgb24(void):
m_bInit(false),
m_lpBmpInfo(NULL),
_hBm1(NULL),
_hdc_buffer1(NULL),
_hBm2(NULL),
_hdc_buffer2(NULL)
{
}
c_drawrgb24::~c_drawrgb24(void)
{
if(m_lpBmpInfo)
delete m_lpBmpInfo;
}
void c_drawrgb24::SetVertial()
{
if(m_lpBmpInfo!=NULL)
m_lpBmpInfo->bmiHeader.biHeight = 0-m_lpBmpInfo->bmiHeader.biHeight;
}
void c_drawrgb24::CreateDoubleBuffer(HDC hdc1, int cxClient1 ,int cyClient1,HDC hdc2,int cxClient2,int cyClient2)
{
// Create a virtual bitmap
if(hdc1!=NULL)
{
_hBm1 = CreateCompatibleBitmap(hdc1,cxClient1,cyClient1);
// Create and hdc Compatible devices
_hdc_buffer1 = CreateCompatibleDC(hdc1);
SelectObject(_hdc_buffer1,_hBm1);
}
if(hdc2!=NULL)
{
_hBm2 = CreateCompatibleBitmap(hdc2,cxClient2,cyClient2);
// Create and hdc Compatible devices
_hdc_buffer1 = CreateCompatibleDC(hdc2);
SelectObject(_hdc_buffer2,_hBm2);
}
}
void c_drawrgb24::Draw2(HWND hWnd, HWND hWnd2,unsigned char * buffer, int SrcW, int SrcH)
{
HDC hDCDst1 = NULL;
HDC hDCDst2 = NULL;
RECT destRect1;
RECT destRect2;
if(hWnd!=NULL)
{
hDCDst1 = GetDC(hWnd);
GetClientRect(hWnd,&destRect1);
}
if(hWnd2!=NULL)
{
hDCDst2 = GetDC(hWnd2);
GetClientRect(hWnd2,&destRect2);
}
if(!m_bInit)
{
m_bInit = true;
m_lpBmpInfo=new BITMAPINFO;
m_lpBmpInfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
m_lpBmpInfo->bmiHeader.biWidth = SrcW;
m_lpBmpInfo->bmiHeader.biHeight= -SrcH;
m_lpBmpInfo->bmiHeader.biPlanes= 1;
m_lpBmpInfo->bmiHeader.biBitCount = 24;
m_lpBmpInfo->bmiHeader.biCompression = 0;
m_lpBmpInfo->bmiHeader.biSizeImage = 0;
m_lpBmpInfo->bmiHeader.biXPelsPerMeter = 0;
m_lpBmpInfo->bmiHeader.biYPelsPerMeter = 0;
m_lpBmpInfo->bmiHeader.biClrUsed=0;
m_lpBmpInfo->bmiHeader.biClrImportant = 0;
//CDC * dc = CDC::FromHandle(hDCDst);
//m_pMemDC = new CMemDC(*dc,DestRect);
}
if(hDCDst1!=NULL)
{
int DstWidth = destRect1.right-destRect1.left;
int DstHeight = destRect1.bottom- destRect1.top;
SetStretchBltMode(hDCDst1,STRETCH_HALFTONE);
::StretchDIBits(
//m_pMemDC->GetDC().GetSafeHdc(),
hDCDst1,
0, 0, DstWidth, DstHeight,
0, 0, SrcW, SrcH,
buffer, m_lpBmpInfo, DIB_RGB_COLORS, SRCCOPY );
ReleaseDC(hWnd,hDCDst1);
}
if(hDCDst2!=NULL)
{
int DstWidth = destRect2.right-destRect2.left;
int DstHeight = destRect2.bottom- destRect2.top;
SetStretchBltMode(hDCDst2,STRETCH_HALFTONE);
::StretchDIBits(
//m_pMemDC->GetDC().GetSafeHdc(),
hDCDst2,
0, 0, DstWidth, DstHeight,
0, 0, SrcW, SrcH,
buffer, m_lpBmpInfo, DIB_RGB_COLORS, SRCCOPY );
ReleaseDC(hWnd2,hDCDst2);
}
}
void c_drawrgb24::DrawSDL(HWND hWnd, unsigned char * buffer, int SrcW, int SrcH)
{
_sdldraw.draw_init(hWnd, SrcW, SrcH);
_sdldraw.draw(buffer, SrcW, SrcH);
}
The new code has been submitted , Readers can find the open source address in my first article .
边栏推荐
- How much do you know about synchronized?
- JDBC教程
- Solution: exceptiole 'xxxxx QRTZ_ Locks' doesn't exist and MySQL's my CNF file append lower_ case_ table_ Error message after names startup
- Detailed explanation of 'viewpager' in compose | developer said · dtalk
- sourcetree 详细
- PR FAQ, what about PR preview video card?
- RuntimeError: no valid convolution algorithms available in CuDNN
- 实用系列丨免费可商用视频素材库
- Where is the win11 automatic shutdown setting? Two methods of setting automatic shutdown in win11
- Yolox enhanced feature extraction network panet analysis
猜你喜欢
Solution: exceptiole 'xxxxx QRTZ_ Locks' doesn't exist and MySQL's my CNF file append lower_ case_ table_ Error message after names startup
非路由组件之头部组件和底部组件书写
Connexion à distance de la tarte aux framboises en mode visionneur VNC
95 pages of smart education solutions 2022
Go project operation method
JDBC教程
(stinger) use pystinger Socks4 to go online and not go out of the network host
How much do you know about synchronized?
67页新型智慧城市整体规划建设方案(附下载)
采用VNC Viewer方式远程连接树莓派
随机推荐
Fusion de la conversion et de la normalisation des lots
2022 latest and complete interview questions for software testing
Remote connection of raspberry pie by VNC viewer
Interpretation of new plug-ins | how to enhance authentication capability with forward auth
Create an interactive experience of popular games, and learn about the real-time voice of paileyun unity
Data set - fault diagnosis: various data and data description of bearings of Western Reserve University
程序分析与优化 - 9 附录 XLA的缓冲区指派
Golang common settings - modify background
Happy Lantern Festival, how many of these technical lantern riddles can you guess correctly?
Maybe you read a fake Tianlong eight
Returns the maximum distance between two nodes of a binary tree
SharedPreferences save list < bean > to local and solve com google. gson. internal. Linkedtreemap cannot be cast to exception
Solution: exceptiole 'xxxxx QRTZ_ Locks' doesn't exist and MySQL's my CNF file append lower_ case_ table_ Error message after names startup
Program analysis and Optimization - 9 appendix XLA buffer assignment
富滇银行完成数字化升级|OceanBase数据库助力布局分布式架构中台
【OJ】两个数组的交集(set、哈希映射 ...)
JDBC practice cases
CADD course learning (4) -- obtaining proteins without crystal structure (Swiss model)
Where is the win11 automatic shutdown setting? Two methods of setting automatic shutdown in win11
C# MVC创建一个视图摆脱布局的影响