-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathreceiver.cpp
125 lines (111 loc) · 3.6 KB
/
receiver.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
//#pragma once
#include "receiver.h"
#include <QtDebug>
//#include <QAtomicInteger>
const bool RESIZE = false;
VideoChat::VideoChat(std::string ip1):
porta(port1),
portb(port2),
init(1),
ep1(boost::asio::ip::address::from_string(ip1), port3),
// ep2(ip::address::from_string(ip1), port4),
recvSocket(ioc, boost::asio::ip::udp::endpoint(boost::asio::ip::udp::v4(), port1)),
sendSocket(ioc, boost::asio::ip::udp::endpoint(boost::asio::ip::udp::v4(), port2)),
receive_cnt(0),
error_cnt(0)
{
memset(recv_data, 0, sizeof(recv_data));
}
void VideoChat::send() { // port2 -> 1
// print("sender start");
int ack = 1;
while(true) {
sendSocket.send_to(boost::asio::buffer(&ack, sizeof(ack)), ep1); // 给发送端点确认信息
}
}
cv::Mat VideoChat::recv() {
// print("receiver start");
receive_cnt++;
if(init) {
qDebug() << "receiver init...";
init = 0;
cv::Mat frame;
cv::VideoCapture cap;
int deviceID = 0;
int apiID = cv::CAP_ANY;
cap.open(deviceID, apiID);
if (!cap.isOpened()) { std::cerr << "ERROR! Unable to open camera\n"; }
frame = cv::Mat::zeros(cap.get(cv::CAP_PROP_FRAME_HEIGHT), cap.get(cv::CAP_PROP_FRAME_WIDTH), CV_8UC3);
cap.release();
if(RESIZE)
resize(frame, frame2, cv::Size(), 0.25, 0.25);
else {
resize(frame, frame2, cv::Size(), 1, 1);
}
qDebug() << "receiver init end";
}
receive_init_end.store(true);
cv::Mat tmp_frame = frame2;
int shrinksize = (frame2.dataend - frame2.datastart);
if(RESIZE)
recvSocket.receive_from(boost::asio::buffer((char*)frame2.data, shrinksize), ep2);
else {
// bool frame_complete = true;
int shrinksize_seg = shrinksize / 16;
// 使得每帧图像的起始位置相同
int ack = 0;
recvSocket.receive_from(boost::asio::buffer(&ack, sizeof(ack)), ep2);
qDebug() << "should be 314..." << ack;
while(ack != 31415926) {
recvSocket.receive_from(boost::asio::buffer(&ack, sizeof(ack)), ep2);
}
// if(!ack) { qDebug() << "not complete frame"; return; }
char buf[65000];
for(int i = 0; i < 16; ++i) {
memset(&buf, 0, sizeof(buf));
recvSocket.receive_from(boost::asio::buffer(buf), ep2);
int index = -1;
memcpy(&index, buf, sizeof(int));
if(index != i) {
qDebug() << "wrong at " << i << endl;
// memset((char*)(frame2.data), 0, shrinksize); // 接受错误时黑屏
// frame_complete = false;
error_cnt++;
double rer = receive_error_rate();
if(rer > 0.1) rate_ok.store(false);
else rate_ok.store(true);
qDebug() << rer;
// memset((char*)(frame2.data), 0, shrinksize); // 接受错误时黑屏
// return tmp_frame;
// frame2 = tmp_frame; // 接受错误时保持原帧
cvtColor(frame2, frame2, CV_BGR2RGB);
return frame2;
// break;
}
memcpy((char*)(frame2.data + i * shrinksize_seg ),buf + 4, shrinksize_seg);
}
}
return frame2;
// text
// while(1) {
// recvSocket.receive_from(buffer(recv_data), ep2);
// print("recv from sender: ");
// print(recv_data);
// }
}
void VideoChat::start() {
// print("okok");
}
cv::Mat VideoChat::get_frame() {
return recv();
// this->recv();
// return this->frame2;
}
double VideoChat::receive_error_rate() {
if(receive_cnt < 100) return 1;
double ans = double(error_cnt) / double(receive_cnt);
error_cnt = 0;
receive_cnt = 0;
return ans;
}
//extern VideoChat demo;