将java mjpeg流字节转换为图像

时间:2013-06-05 14:22:30

标签: java android mjpeg

我正在接收来自WiRC的mjpeg流。

WiRC文档描述了关于流的以下内容:

Camera image format      JPEG
Camera image resolution  CIF: 352 × 288

该文档描述了以下内容:

数据包规范

协议使用UDP数据包传输MJPEG流。 MJPEG流包括 独立的JPEG帧。 JPEG帧以多个数据包发送。片段大小由服务器应用程序确定。

数据包的前16个字节是标头。数据包标头有四个字段,包含网络字节顺序的32位字(big-endian)。

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

编辑:更改了代码并添加了控制台结果

3 个答案:

答案 0 :(得分:0)

JPEG图像通过UDP数据包分段,UDP数据包可能无序。

所以你必须看看标题:

  • 帧号:相同的号码 - 相同的帧
  • 偏移:在框架内订购
  • Last Packet标志:该数据包的帧编号是帧中的最后一个。

现在你必须弄清楚如何将它们组合在一起。我猜偏移将从每帧的0开始,所以应该很容易想出一些东西。

请记住构建一些超时机制,因为UDP不可靠。

例如:如果你的Frame x仍未完成且Frame x + 1已经完成,那就放弃它。或者你最终会得到一个充满不完整图像的记忆:)

---- ---- EDIT

您可能需要考虑使用ByteBuffer。它有非常方便的方法来处理byteorder和int / long从字节转换的任何内容。

答案 1 :(得分:0)

我发现了自己的错误。我用这种方式构建图像:

Bitmap bmp=BitmapFactory.decodeByteArray(bytes, 32, length);

应该在哪里:

Bitmap bmp=BitmapFactory.decodeByteArray(bytes, 16, length);

其余的都是正确的。

不过谢谢你们。

答案 2 :(得分:0)

为了更好地使用mjpeg流,您应该使用libjpeg库。 或者这个demp项目 http://www.anddev.org/resources/file/1484