我有一台IP摄像机,可以在UDP / RTP中传输JPEG压缩数据。我使用Boost Asio来接收数据。我知道我已正确收到数据,因为我使用Wireshark检查了每个数据包的头信息。
#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 Mat中并显示它将显示垃圾值。我也试过
cv::Mat img = cv::imdecode(frame, CV_LOAD_IMAGE_COLOR);
但它也没有用。我查看了本网站上可以找到的所有可能的解决方案,但它们都没有为我工作。有没有我可以用来将这个缓冲区传递给它的一个函数并检索JPEG帧的库?另外,为了解码帧,我是否应该在缓冲区中包含头字节?如果是哪个标题? JPEG标题,RTP标题或两者兼而有之?
我非常感谢任何有用的解决方案或建议。
答案 0 :(得分:0)
JPEG over RTP标头称为主标头,长度仅为8个字节。因此,应该创建JFIF标头,以便能够解码JPEG压缩数据。可以使用“RFC 2435”格式完成JFIF标头创建。一切都在那里解释了。创建JFIF标头后,应将其添加到压缩数据之前,然后传递给uncompressedFrame = cv :: imdecode(compressedImage,1)或任何其他JPEG解码器以检索未压缩的帧。如果你遇到这样的问题,请通过(davar.daei@gmail.com)告诉我。我将非常乐意提供帮助。