我有一台IP摄像机,它在UDP/RTP中传输JPEG压缩数据。我使用Boost Asio来接收数据。我知道我已经收到了正确的数据,因为我使用Wireshark检查了每个数据包的标题信息。将从IP摄像机接收到的JPEG数据流解码为C++中的RGB图像
#include <boost/asio.hpp>
#define MAX_BYTES 1500
using boost::asio::ip::udp;
int main(){
boost::asio::io_service io_service;
udp::socket socket(io_service , udp::endpoint(udp::v4(),50242));
char data[MAX_BYTES];
size_t bytes_received = 0;
while(true){
bytes_received = socket.receive(boost::asio::buffer(data,MAX_BYTES));
}
}
我接收的总的1452个字节的每个分组,其中前20个字节是RTP报头(12个字节),接着JPEG报头(8个字节)。剩余的1432个字节包含有效载荷。假设每个帧由145个数据包组成(frm_pckts = 145)。排序报文后我将它们存储在缓冲器中用于单个帧如下:
unsigned char* buffer = (unsigned char*) malloc(frm_pckts * 1432 * sizeof(unsigned char);
memcpy(&buffer[packet_index*1432] , &data[20], 1432);
如果我这个缓冲器复制到一个OpenCV的垫,并显示它会显示无用值。我也试过
cv::Mat img = cv::imdecode(frame, CV_LOAD_IMAGE_COLOR);
但它也没有工作。我看到了所有可能的解决方案,我可以在这个网站上找到,但没有人为我工作。有没有可用于将此缓冲区传递给其中一个函数并检索JPEG帧的库?另外,为了解码帧,我还应该在缓冲区中包含头字节?如果是,哪个头? JPEG标头,RTP标头还是两者?
我非常感谢任何有用的解决方案或建议。
您究竟如何整理数据包?这可能是你问题的根源。 –
你必须在传递给'cv :: imdecode()'的缓冲区中包含JPEG头文件。它必须能够知道图像的格式,所以它需要标题。作为您正确接收图像的第一个测试,将其保存到文件并尝试使用任何JPEG查看器打开该文件。作为另一个测试,我建议使用'cv :: imdecode()'来创建一个小程序,用它解码JPEG文件,以查看您是否正确使用API。 – zett42
感谢您的回复。我不认为排序有任何问题,因为我根据从RTP头获得的时间戳和序列号对数据包进行排序。 –