我正在从WiRC接收mjpeg流。
WiRC文档对流进行了以下描述:
Camera image format JPEG
Camera image resolution CIF: 352 × 288
该文档描述了以下内容:
包规格
该协议使用UDP数据包传输MJPEG流。 MJPEG流包括
独立的JPEG帧。 JPEG帧以几个数据包发送。片段大小由服务器应用程序确定。
数据包的前16个字节是标头。数据包头有四个字段,其中包含按网络字节顺序(big-endian)排列的32位字。
name offset width description
version 0 32 bit protocol version and flags
frame num 4 32 bit bit index of the JPEG frame in the stream
offset 8 32 bit offset of the packet data in the JPEG frame
length 12 32 bit number of data bytes in the packet beyond the header
版本栏位
标志在版本字段的高16位,低16位中编码
包含版本号(在解释时注意主机字节顺序
版本字段)。
name bits description
reserved flag bits 31..17 these bits shall be ignored
last packet flag 16 if set this is the last packet of a JPEG frame
version information 15..0 Protocol version, expected value is 0x5503
我正在使用以下代码将流解码为图像:
int offset = ((int)(bytes[8] & 255) << 24) |
((int)(bytes[9] & 255) << 16) |
((int)(bytes[10] & 255) << 8) |
((int)(bytes[11] & 255));
int length = ((bytes[12] & 255) << 24) |
((bytes[13] & 255) << 16) |
((bytes[14] & 255) << 8) |
((bytes[15] & 255));
long frame = ((bytes[4] & 255) << 24) |
((bytes[5] & 255) << 16) |
((bytes[6] & 255) << 8) |
((bytes[7] & 255));
System.out.printf("Version: 0x%02X 0x%02X", bytes[2], bytes[3]);
Boolean last = (bytes[1] & 1) == 1 ? true : false;
System.out.println(" Offset: "+offset+" Length: "+length);
System.out.println("Lastpacket: "+last + " framenum: "+frame);
System.out.println();
Bitmap bmp=BitmapFactory.decodeByteArray(bytes,32,length);
但是,这总是返回一条消息,指出BitmapFactory失败
有什么想法或建议吗?
我在控制台上收到以下响应:
UDP received stuff
Version: 0x5503 Offset: 0 Length: 7584
Lastpacket: true framenum: 223
编辑:更改代码并添加控制台结果
最佳答案
JPEG图像通过UDP数据包分段,并且UDP数据包可能会乱序。
因此,您必须查看标题:
框架编号:相同编号-相同框架
胶印:内框订购
Last Packet标志:此数据包的帧号是该帧中的最后一个。
现在,您必须弄清楚如何将它们组合在一起。我想每帧的偏移量将从0开始,因此想出一些东西应该很容易。
记住要建立一些超时机制,因为UDP不可靠。
例如:如果帧x仍未完成且帧x + 1已完成,则将其沟渠。否则您最终将拥有不完整图像的记忆:)
- - 编辑 - -
您可能要考虑使用ByteBuffer。它具有非常方便的方法来处理字节序和int / long,无论从字节转换为多少。