当前位置:网站首页>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 to apply for company email when registering in company email format?
- Third party payment function test point [Hangzhou multi tester _ Wang Sir] [Hangzhou multi tester]
- Use of cocospods
- Leetcode relaxation question - day of the week
- 流媒体技术优化
- Convolution和Batch normalization的融合
- 程序分析与优化 - 9 附录 XLA的缓冲区指派
- Returns the root node of the largest binary search subtree in a binary tree
- VIM interval deletion note
猜你喜欢

JDBC練習案例

Connexion à distance de la tarte aux framboises en mode visionneur VNC

In February 2022, the ranking list of domestic databases: oceanbase regained its popularity with "three consecutive increases", and gaussdb is expected to achieve the largest increase this month
![[Verilog tutorial]](/img/15/d5e188a15e22fa44f1756fc492099d.jpg)
[Verilog tutorial]

Mapper agent development

非路由组件之头部组件和底部组件书写

Load balancing cluster (LBC)

Implementation of VGA protocol based on FPGA

How to set automatic reply for mailbox and enterprise mailbox?

Explain in detail the process of realizing Chinese text classification by CNN
随机推荐
JDBC Exercise case
容器运行时分析
Create an interactive experience of popular games, and learn about the real-time voice of paileyun unity
Request and response
ArrayList analysis 2: pits in ITR, listiterator, and sublist
C MVC creates a view to get rid of the influence of layout
Explain in detail the process of realizing Chinese text classification by CNN
开发知识点
Why can't the start method be called repeatedly? But the run method can?
Intranet penetration | teach you how to conduct intranet penetration hand in hand
RTP 接发ps流工具改进(二)
Agnosticism and practice makes perfect
Solution: exceptiole 'xxxxx QRTZ_ Locks' doesn't exist and MySQL's my CNF file append lower_ case_ table_ Error message after names startup
RuntimeError: no valid convolution algorithms available in CuDNN
Speech recognition Series 1: speech recognition overview
JDBC練習案例
Interface switching based on pyqt5 toolbar button -2
95 pages of smart education solutions 2022
Returns the size of the largest binary search subtree in a binary tree
[proteus simulation] 51 MCU +lcd12864 push box game