views:

205

answers:

1

I've actually curious about this for the iPhone. I am getting an MJPEG stream from a server and trying to render it natively on the iphone (without the use of safari class). Reasons for this is because the safari class while CAN render MJPEG natively, does not do so at the framerate I would like.

So I tried drawing it natively, but I've come up with performance issues, namely a syncing issue between what I'm getting from the server and what I am able to draw onto the screen of the phone. (There should be a little lag, but the drift gets really bad, which is what I want to avoid).

So I have a connection set up to my server and I do get the JPEGS. It's just data I insert into a NSMutableArray buffer

      CFMutableDataRef _t_data_ref = (CFMutableDataRef)[_buffer_array objectAtIndex:0];


  //CGDataProviderRef imgDataProvider = CGDataProviderCreateWithCFData (_cf_buffer_data);
  CGDataProviderRef imgDataProvider = CGDataProviderCreateWithCFData(_t_data_ref);
  CGImageRef image = CGImageCreateWithJPEGDataProvider(imgDataProvider, NULL, true, kCGRenderingIntentDefault);
  CGImageRef imgRef = image;

  CGContextDrawImage(context, CGRectMake(0, 17, 380, 285), imgRef);

  CGImageRelease(image);
  CGDataProviderRelease(imgDataProvider);

please note this is the gist of my code, but it should summarize what I am trying to accomplish with regards to drawing. Also in order to get the framerate in sync, I had to detach a separate thread that sleeps X seconds and calls [self setNeedsDisplay].

 NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; // Top-level pool

 while(1)
 {

  //[NSThread sleepForTimeInterval:TIMER_REFRESH_VALUE];
  //sleep(unsigned int );
  usleep(MICRO_REFRESH_VALUE);


  if ([_buffer_array count] > 10)
  {
   //NSLog(@"stuff %d", [_buffer_array count]);
   //[self setNeedsDisplay];
   [self performSelectorOnMainThread:@selector(setNeedsDisplay) withObject:nil waitUntilDone:NO];
  }

 }

    [pool release];  // Release the objects in the pool.

My buffer of jpeg data actually fills up quite quick, but I can't seem to actually consume what i'm getting at the same rate, actually much slower. Are there any documents that can describe what kind of performance tuning I can do to make it go faster when rendering the JPEG to the screen? Or am I kind of stuck here?

Thanks!

A: 

It may help to call CGImageCreateWithJPEGDataProvider in a separate thread, assuming CGImage does not delay the actual decoding until the image is drawn. One thread for networking, another for decoding, and the UI thread for drawing.

performSelectorOnMainThread is less efficient than an NSTimer running on the main thread. Instead of checking the array count directly, set an atomic flag that you can check in the timer.

drawnonward