流式JPEG,检测JPEG的结尾

时间:2010-03-05 02:32:48

标签: iphone objective-c nsstream nsinputstream

我创建了一个java服务器,它截取屏幕截图,调整大小,然后通过TCP / IP将它们发送到我的iPhone应用程序。然后,应用程序使用NSInputStream收集传入的图像数据,使用字节缓冲区创建NSMutableData实例,然后创建要在iPhone上显示的UIImage对象。 Screenshare,基本上。我目前收集图像数据的iPhone代码如下:

- (void)stream:(NSStream *)theStream handleEvent:(NSStreamEvent)streamEvent{


if(streamEvent == NSStreamEventHasBytesAvailable && [iStream hasBytesAvailable]){
        uint8_t buffer[1024];

    while([iStream hasBytesAvailable]){
        NSLog(@"New Data");

        int len = [iStream read:buffer maxLength:sizeof(buffer)];

        [imgdata appendBytes:buffer length:len];
        fullen=fullen+len;

        /*Here is where the problem lies.  What should be in this
         if statement in order to make it test the last byte of
         the incoming buffer, to tell if it is the End of Image marker
         for the end of incoming JPEG file?
         */
        if(buffer[len]=='FFD9'){
        UIImage *img = [[UIImage alloc] initWithData:imgdata];
        NSLog(@"NUMBER OF BYTES: %u", len);

        image.image = img;
        }
    }

}
}

我的问题,如代码内注释所示,是在何时停止在NSMutableData对象中收集数据,并使用该数据创建UIImage。在传入的字节中查找JPEG文件结束标记 - 图像结束(EOI)标记(FFD9)似乎是有意义的,因为图像将在发送时准备好显示。我该如何测试呢?我要么缺少关于数据存储方式的信息,要么关于JPEG文件中的标记,但是我们将非常感谢您对此进行测试的任何帮助!

詹姆斯

1 个答案:

答案 0 :(得分:3)

你显然不想关闭流,因为这会扼杀性能。

由于您控制客户端服务器连接,因此在发送图像数据之前,请向下发送图像中的字节数。更好的是,发送图像中的字节数,图像数据和最后一个容易识别的序列号,这样您就可以快速验证数据是否已实际到达。

比实际检查文件结束标记更容易,更有效。当然,你也可以在收到字节数之后检查一下。很容易。

当然,除了不寻常的情况之外,所有这些对于屏幕共享风格目的来说都是非常低效的。在大多数情况下,只有一小部分要镜像的屏幕实际上随每帧而变化。如果你尝试每帧都发送整个屏幕,你会很快就会使你的连接饱和,而且客户端会非常迟钝而且没有反应。

鉴于这是一个非常成熟的市场,有大量的解决方案和相当多的开源位,您可以从中获得满足您需求的解决方案(例如,参见VNC)。