Scientific Breakthrough Lets SnappyCam App Take 20 Full-Res Photos Per Second
techcrunch.com
techcrunch.com
That said, if their emphasis is on producing pictures with minimal time delta at highest resolution, algorithms used for still pictures are out of place. Video compression algorithms still use DCT and wavelets, but they do so only after they have reduced redundancies between series of pictures, a process that tends to work significantly better than anything you can get out of these lossy transformations when you want to preserve quality.
Of course, eliminating redundancy in a series of pictures might have tipped them off to the fact that the image sensor isn't actually producing fresh pictures at the rate they want.
1: as used in JPEG. The transformation itself is perfectly invertible, assuming infinite precision arithmetic.
Despite all of that, JPEG has now become computationally tractable. I remember the days where it took tens of seconds to encode a JPEG on a commodity machine. Now, with the help of SIMD, we can encode a high quality image in msec on a mobile device.
Fortunately you can choose the quantization matrix that determines the amount of loss. Even if you were to choose a unitary matrix, no human, not even superman with his laser eyes, can "detect" the quantization noise.
For SnappyCam, I chose to invest in JPEG a little more because it's a ubiquitous standard for still image compression.... and with the right hardware and algorithms, quite tractable.
I'll consider adding a JPEG "quality setting" so you can choose the amount of loss introduced... sounds like a great idea to me.
The idea behind SnappyCam was also to code each picture independently, and not rely on motion prediction or video codecs. If you try and pull a single frame from a HD video you might be disappointed: they compress the YUV dynamic range (studio swing) and it looks washed out, even if you land on an i-frame.
Lastly, as far as I can tell, the image sensor is yielding complete scans with each frame. I'd hazard a guess to say that any motion prediction or frame deltas might actually slow the whole chain down.
The only reason would be that you are pressed for memory or bandwidth, but certainly you have the resources to store one full frame and produce deltas, or just apply part of the JPEG chain, enough to remedy memory pressure. You can always encode it to an actual JPEG after the process.
And yes, pulling single frames from a completely encoded video isn't helpful, because they can get away with more compression. But there are very sophisticated algorithms for eliminating the redundancy between frames, which would have been my first avenue in attempting to do something like this.
I buffer as much as possible, while also encoding on any other cores that are available.
There's a reason why a "simple camera app" can total some 80 kLOC. :)
Have you attempted to do something like this? Because he not only has attempted, he's done it. Therefore I think you should stop talking down to him ("completely pointless", "it's just bizarre", "my first avenue"). It comes across as wanting to prove how smart you are instead of seeking to learn from someone who has done incredible work and—lucky for us—is bursting at the seams with enthusiasm to share it.
Oh and congratulations jpap on what's looking like the most successful and technically solidest HN launch in quite some time! I hope your hard work pays off.
With so many recent requests for AGIF, I'm absolutely going to add it to the app. (It's been on my list for a while, but lower priority than getting up a solid core product and the social sharing that is in development at the moment.)
I don't recommend the same path for everyone, but my ugrad at RMIT University, dual bachelors of EE and CS. I then went on to do a Ph.D at the University of Melbourne in EE. My dissertation was on mathematical optimization of wireless and wireline DSL. (Prof Jamie Evans is an awesome guy if you're on the lookout for an advisor!)
I've been in SFO for just over 5.5 years, and started SnappyLabs after winning the "greencard lottery".
SnappyCam, you might say, is the embodiment of both a very practical ugrad and somewhat applied but very theoretical pgrad.
Guy behind me said "Hey, this is pretty cool. Have you seen... oh, you're looking at it already."
The other SnappyCam purchaser I mentioned is an iOS/Android developer who is a sub-tenant in my office. We actually have a cheap, spare desk in this room at the moment if you wanted to visit and work for a while. Email me if you want to ask any questions.
Another fellow Australian and Melburnian.
Well done on the app John!
I first tried using the GPU, using old school GPGPU textures and OpenGL ES 2.0 shaders, but unfortunately the performance wasn't there for a variety of reasons given in [1].
SnappyCam has since been making extensive use of ARM NEON for the JPEG codec and a bunch of other image signal processing operations, like digital zoom. It's a great instruction set!
[1] http://www.snappylabs.com/blog/snappycam/2013/07/31/iphone-k...
It's like MMX / SSE of x86 world, a set of extra instructions to process many small integers in parallel in one instruction. Since image data are usually independent 3-byte pixels (or 3 planes of 1-byte subpixels, one per color channel), NEON is great for many image-processing tasks.
See e.g. https://en.wikipedia.org/wiki/ARM_architecture#Advanced_SIMD...
I think you definitely made the right choice though - it's interesting that the obvious delta-coding and motion compensation tricks to reduce bandwidth are rarely used for video acquisition apart from the most limited devices like phones, stills cameras and the GoPro. Everything that can afford to uses per-frame coding like ProRes, REDCODE, AVC-Intra, DNxHD, Cineform... being able to seek quickly is important!
In fact Canon's 1DC 4k camera uses (dun dun duhhhhh...) motion JPEG :)
It's not quite that simple. They have different strengths and weaknesses, so you can't say one is categorically better than the other. DCT has uniform frequency resolution, which sounds desirable but isn't once you start quantizing due to ringing, etc. See slide 25 or so of [1]. Wavelets overcome this problem by adapting the resolution in opposite ways at the extremes. This works fantastic for medium signal rates, but can have severe low passing at low rates. For low rate coding DCT with the bells and whistles (deblocking, etc) will typically win.
[1]: http://people.xiph.org/~tterribe/pubs/lca2012/auckland/intro...
Unless it takes a while to load - in which case I was just being uber impatient.
It might be yet another Chrome canvas bug. :-(
Try Safari and let me know if you can? :-)
The problem with Chrome 28.0.1500.x (.95 here) is troubling me. It seems a more recent problem that I'm convinced is another browser bug.
Thanks for the detailed version report, that's really going to help. :-)
Works with 28.0.1500.95, too.
However, looking at the console, I see occasional instances of Resource interpreted as <blah> but transferred as MIME type <foo>. Not a big deal, but maybe a pointer.
But not working on Chrome or FF :|
I do pretty much everything on OS X these days, but I did fire up a couple of VMs with Win XP, Win 7, and Win 8 to test.
I did my entire dev on Chrome, and apart from what appears to be a new canvas issue at present, I'm not having any major issues. (I'm looking into the canvas problem.)
I saw an issue also reported on here earlier today a few days ago. Sounds to me like a (new) canvas bug in Chrome.
There are unfortunately several workarounds for browser bugs in the HTML5 viewer. The AS3 Flash port was surprisingly very solid. I can't wait to share more info on that when it's time for another major release.
Cool app + site, congrats! Would love to use this to analyze my disc golf throws, and share with my fellow disc golfers.
Great work on the "living photo" idea -- that kind of adds this magical sort of feeling to it, which, I've gotta say, I felt.
I hope your hard work pays off. You've built something special here :)
I'm not actually planning on creating a new niche social network. I think, given the vastness of some of the ones that've emerged of late, it would be more fruitful to leverage the ones that exist today.
Can't wait for you to see it!
I'm still not convinced. :-)
I really think this could fill a space in between the perfect single shot and the realness of video.
You've put it very nicely--there's definitely some magic about a "silent moving picture".
It requires and sparks the imagination in the viewer, evoking emotion perhaps as easily as a carefully crafted cinematic short.
The work required to set up a basic social network around this would surely be insignificant when compared with what you've done to date! Yell out if you need help on the design side of things.
Keep up the good work!
Thanks for letting me know!
Good work on tech, please hire a UX specialist :-)
I did all of the graphics design myself, in the app and on the web. :-)
The infinite sign you see does require an explanation. I'll take your advice and think about how it can be done more simply.
It's basically telling you, the user, that the capture buffer has filled, and you're now dropping (some) shots.
Just some thoughts. If you have a buffer, and I'm gonna get fubarr'd if I hit the limit, you should probably show me the buffer (not just a warning that it's too late).
I generally can see the "end" of the circular buffer around the shutter button, so it doesn't seem to be an issue for me. Perhaps I tend to touch it on the lower-right instead of dead-center.
I made an effort to support lefties in the UI (see Advanced Settings), but the buffer doesn't spin the other way just yet. (To be honest, I've had to deprioritise that in favour of other features.)
Are you left handed?
[1] Yes, that's me jumping near the GG bridge. I'm quite good at it now, as you can imagine: http://a3.mzstatic.com/us/r1000/085/Purple/v4/c5/06/d5/c506d...
The red bar on the bottom woul probably be fine of you could make it like 70% transparent until it gets toward the end, the vacillate it between 0% and 50% so it looks like its flashing. Some visual indicator that I should be paying more attention to it.
I'm curious about the low-quality preview you get when scrolling through all the shots. Are you storing low-quality data separately or do you also have a fast, low-qual JPEG decoder? (Is the Huffman encoding between blocks independent?)
You've got a good eye: as part of the JPEG image compress, I also generate a low-resolution thumbnail that's embedded into each file as Exif metadata (along with geotagging, and other camera settings that define the shot, like exposure).
They are used as a "first-in" placeholder for an image.
The full image is then downsampled and decompressed simultaneously [1] exploiting the fact that the (Retina) screen resolution is often much lower than the full JPEG resolution.
As soon as you start zooming, the image is decompressed yet again at the full resolution and replaced in-place as quickly as possible so hopefully you won't see it. :-)
[1] As outlined in http://jpegclub.org/djpeg/ the technique relies on the fact that the top NxN DCT block of MxM coefficients, N < M, can be inverted to form a NxN pixel lower-resolution image of the original MxM block. When N is {1, 2, 4} a fast inverse DCT algorithm can be used with great success.
In fact, N == 1 is a trivial inversion and it might be tempting to use it as the low-resolution image instead of a thumbnail, but you still have to unpack all of the DCT coefficients to get to it, which can be expensive (Huffman).
Kudos to them, sounds like they deserve it.
I just hope Apple's engineers don't get pissed off by the press. SnappyCam is built on their hardware, which can do remarkable things.
Though we as app developers don't get access to a lot of their smarts, e.g. hardware JPEG codecs, I'm sure there's even more innovation in their work that often goes unacknowledged.
Aussie maths whiz supercharges net http://www.smh.com.au/articles/2007/11/05/1194117915862.html
Could be rolled out as part of the NBN pending Australia's election result.
It's been an awesome, surreal experience, very much reminiscent of 2007. Fun times, relived. :-)
However, you should be careful with this online ARM simulator. It simulates Cortex-A8 while iPhone 5 runs on Apple Swift, two generations ahead. It very likely has different instruction timings compared to Cortex-A8. I didn't have a chance to test Swift, but here is a list of what might be different, judging by Qualcomm Krait and ARM Cortex-A15, which are in the same generation:
- Instead of 2-cycle latency on Cortex-A8 simple ALU instructions might have 3-cycle latency on Krait (this is the case on Krait and Cortex-A15).
- Cortex-A8 can issue only 64-bit SIMD multiplication per cycle, Swift probably can do 128-bit VMUL.Ix each cycle (Krait does).
- Cortex-A8 can issue only one SIMD ALU instruction per cycle, Swift probably can do more (Cortex-A15 can issue 3 128-bit VADD/VAND/etc in 2 cycles).
- Cortex-A8 could issue one SIMD ALU + one SIMD LOAD/SHUFFLE per cycle, Swift could be less restrictive (and probably even can issue 3 NEON instructions per cycle, like Cortex-A15).
It's a lot of work to optimize the assembly code to each ARM variant, but glad to know that Swift will generally run the same code at the same or faster speeds as the Cortex-A8.
The 3-cycle latency on simple ALU instructions is a bummer, but fortunately I use them sparingly for computation as compared to NEON. (They're great for pointer arithmetic and computing image row strides.)
The multiple issue of an ALU + LOAD is awesome. That would definitely help some of my routines.
Criticism:
I use my thinkpad's pointer stick to move the mouse cursor. It's impossible to keep the cursor inside the "control strip" while moving it up and down and also looking away from the strip (and at the image). Too much accidental x motion is introduced.
It would be better for me if you were to enable the scroll wheel (which I can simulate on my pointer) as an alternative time control, or perhaps let me click on the control strip and then hold down mouse1 for as long as I want my y motion to control the position in time.
Love that you picked up on the expressions! It wasn't until I got the photos out of the app was I fascinated by the same thing. I really can't wait to enable this functionality for everyone soon. :-)
More elaborate mouse movements are possible, only in HTML5 full screen mode; required to "capture" the mouse (think a game).
The problem with that, too, is that instruction or a tutorial is required. (I'd try to make things as intuitive as possible, despite the failure in the other thread RE UX and the infinite shutter.)
What was happening is that I was trying to keep the mouse in the control strip, and it would go off the right side of the image.
Thanks a lot, Josh.
Edit: By the way, the fullscreen functionality isn't launching. But I do have a weird browser (conkeror on xulrunner 22.0).
In the app, you need to start with your finger near the thumbnail strip. (But can move it away for fine-grained scrubbing if you wish.)
It's no surprise that the learned behavior is transferring to the web viewer.
In SnappyCam, each photo is compressed to a separate JPEG file. There's no inter-frame compression, no motion vectors, etc. The same as mJPEG.
The main differences are:
* Each photo is stored in an individual file. This makes seeking through the living photo blindingly fast. (I guess you could do this with motion JPEG by utilizing an index.)
* Each photo also has full metadata. Try rotating the camera as you shoot. It will follow you. :-) Same goes for the geo-tagging: included are a bunch of timings that aren't normally included, so you can know the "precise" usec when you took the photo.
* Each photo has it's own thumbnail. That allows me to cheat a little bit in the photo viewer: you will see a flash from blurry to clear as you scroll around.
(There are more cheats in the viewer for decoding and downsampling at the same time before you zoom, to make the photo load faster as well. One of the handful of reasons why I rolled my own decoder as well.)
Several reasons:
* Video codecs are much more complex.
* Random access seek is a lot slower, unless you're using all I-frames. (That's now a codec option on iOS, but not when I started.)
* "Studio swing" reduces the dynamic range of the YCbCr components so the quality suffers.
* Each frame lacks their own thumbnail, unless you maintain an adjunct "thumbnail video"
* Each frame might(?) not be able to have attached separate metadata, like geotagging, sensor settings at time of capture, etc.
* Deleting one frame causes a "hole" and headache.
* Standards compliant JPEG means export is super easy.
* Anything above full HD video is difficult to deal with in 3rd party software.
Edit: A new algorithm counts as science, but the TechCrunch article really gave no justification for the claim.
If you like signal processing, fixed point arithmetic, SIMD cores, and assembly, then this is for you. :-)
That's a cool feat and is a little damning for Accelerate.framework, although the way techcrunch writes it I expected a new kind of fast cosine transform.
The actual DCT algorithm created and used in the app is different to the typical AAN (Arai, Agui, Nakajima) DCT algorithm that's used in JPEG codecs, at least all the ones I've seen.
It's all about doing as little work as possible to achieve the end result. That's why there's so much asm implementation, with carefully chosen NEON instructions for each step.
Think of it as a cross-layer optimization between algorithm and implementation... done by hand. :-)
While SnappyCam has been the most difficult, complex, piece of software I've written since I started coding in my early teens, it's also been one of the most satisfying technically.
I'd love to disclose the many, many optimizations baked in, but as this is a commercial app I must keep much of it as a trade secret.
I will say though that a lot of precomputation was involved, both for the encoder and decoder. Jumped at the chance to avoid computation, memory reads, etc., as much as possible. :-)
Well done on realising something that seems obvious in retrospect, but most people still miss.
G'day from across the ditch John and I'm glad to see things are going well! (from John D. in Sydney)
[1] http://www.rmit.edu.au/browse/Current%20students%2FAdmin%20e...
The Australian Communications Theory Workshop was such a long time ago--what great memories. :-)
What are you up to these days?
Will definitely look you up when I'm down next. Trying to drop by more consistently during the summer these days. I spent five weeks in Melbourne last Jan and loved every minute of warmth. :)
Here's a more interesting link directly from the app developers: http://www.snappylabs.com/blog/snappycam/2013/07/31/iphone-k...
> extended some of that research to create a new algorithm
> 10,000 lines of hand-tuned assembly code
> optimized out pipeline bubbles using a cycle counter tool
Color me impressed. It sounds like they really pulled out all the stops.
There's no reason he couldn't do the same on Android and see similar gains. It would just be a lot of work..
[42] http://research.microsoft.com/en-us/um/redmond/projects/blin...
The code for the codec is written in mixed C and assembly, so it can be "easily" ported to Android by making use the JNI.
While the R&D for the fast JPEG codec took about a year to perfect, the iOS app took just about the same time to get polished (including the NodeJS backend work, the HTML5 website and embeddable widgets in AngularJS).
Writing the rest of the app would take a few months of full time work, and it's not yet clear if that might pay off at this stage.
We'll see... and glad to hear there's interest! :D
https://android.googlesource.com/platform/packages/apps/Came...
I would buy that in a heartbeat.
Unrelated, how quickly can you alter exposure settings? Can you get 30 pictures per second with three interleaved exposure brackets? (i.e. burst of 10 HDR photos / second) That would be very, very, very, very cool.
I did consider getting into other aspects of iPhoneography, like HDR, etc. The trouble with HDR in particular is that there's no API access to direct the sensor into each of the bracketing modes.
In the case of HDR, it might be more fruitful to attempt some kind of image signal processing, similar to "Clarity" on Camera+.
I looked into that for a while, and I figured that Camera+ might be using some version of the Contrast Limited Adaptive Histogram Equalization (CLAHE) algorithm. In any case, what they've done is really neat from a DSP perspective. :D
There's also a cool technology allows you to save near the same jpeg with much, much smaller file size.
https://play.google.com/store/apps/details?id=com.spritefish...
The claimed speed is 30 fps, the moar RAM the better I think.
That's one of the reasons I spent a lot of time to make sure SnappyCam could compress these images, thumbnails and Exif metadata included, at a ridiculous speed.
Android on the other hand, has more open and better hardware, e.g. larger full-res camera, much larger RAM, faster external storage or even OTG, more CPU/GPU cores. In theory if SnappyCam is full ported to Android you can make it faster than 8M pixels @ 20fps
I think the main advantage of the androids will be the fact that high end devices have generally more RAM than iOS counterparts. So even if the codec cannot be pushed as far as on the iOS the bigger possible buffers can help.
On SnappyCam, I had to arbitrarily limit the size of the buffer to a fraction of the system memory because there's no way to know "how much" RAM can be allocated to avoid the dreaded memory warnings until you hit one; and then it's a three strike's out policy: you get two and the third kills the app.
The first two are "soft" warnings, but I suspect have a lower threshold than the "hard" one that sends SIGKILL.
In setting the limit arbitrarily, I unfortunately have no choice but to select it rather conservatively: it might otherwise be (a lot?) higher.
... but they must have an awesome JPEG encoder. I'd assume 41Mpx stills would need to be compressed in no more than 1 second for a reasonable UX. That there is a 41+Mpx/sec encoder.
I've also noticed they are using higher quality chroma sampling (4:2:2) so their encoder is actually doing a lot more work than say SnappyCam.
But I bet they're not doing it in software, either.
Couldn't you get significant FPS increases (given that you still had free space/memory available)?
One core is dedicated to host the capture/buffer, the other will encode shots in the background.
When you see the big circle percent animation, both cores are dedicated to compression to clear the encoder queue so you can take back to back living photos quickly.
This is one of the main reasons I keep coming back to HN. A story gets posted about some cool new tech, and the creator is in the comments answering questions. Simply awesome.
To be honest, I don't often post here because I'm busy working, but am enjoying the discussion on a baby I've nursed for two years now. :-) Thanks for your post!
That's how I would do it. But apparently they already do this :)
Try it on an iPhone 5 with "infinite shutter" disabled and you will see the dropped frames in the filenames once you import them to your machine from iTunes App File Sharing (or over SSH if you're jailbroken).
It's been a hard slog working 7 day weeks for just over two years now. Feels great to receive some kind of recognition for the work.
(Hmm, after writing that, I somehow feel it sounds like it should have a reference to my rural, folksy, respected job that clearly makes me qualified to discuss such things. Unlike those Amazon reviews I'm refering to though, I mean every word.)
I played with price. Until now, most of my sales were word of mouth, and the $1.99 price hindered "growth".
It's been an interesting game. Many people whom I demo the app to in person love it, then when they reach into their pocket to download it, realize it's a paid app, they place their phone back into the pocket.
Still have lessons to learn in sales and marketing... but am enjoying the schooling.
For me $0.99 just breaks that psychological barrier into 'who cares if it sucks'.
I gotta say though, after playing with snappycam it's definitely worth it. I bet being cheaper will end up with easily more than twice the sales
I found that having it at $1.99 most definitely improved sales after it had been at $0.99 for about a week; after another week, it started to degrade again.
You're spot on in saying that $0.99 is a good price to get "disconnected" users who might experiment. If they like the app, they might make the personal recommendation to their "connections" where price is less sensitive.
After a while, that social proof and networking effect wears off and it's time to reset the price down to the "discovery amount" of $0.99.
To be honest, I'd love to flip SnappyCam over to freemium; but I feel that can't happen until the social sharing is bolted in and the app has a chance to sell itself organically.
See my post in another thread here on the same topic.
Except... I also get annoyed sorting through those pictures afterwards. It would be interesting if with some post-processing it could sort through the pictures some for me, identifying distinct pictures, or filtering out ones that are clearly bad (mostly too blurry), or if fancier maybe doing eye or smile detection. I want to capture the moment a person looks up, before they think about the camera.
Another cool case would be taking photos of movement. If I can track the movement with the camera the picture can come out surprisingly well. But tracking movement is hard. If I had several seconds of pictures, over the course of that time probably I'd track the movement well enough for a few of the photos to come out.
Are you up for an old fashioned DUEL to see which app can shoot the most "native camera quality" 8MP images per second in 60 seconds without crashing?
On an iPhone 5 with all apps closed, SnappyCam manages to save only about eight 8MP per second over 10 seconds on average and loses the other 12 per second. And these are not 8MP images at least as far as comparing resolution against the native camera app or Fast Camera. All of this technical discussion sounds great but is anyone actually testing this like I am? Just download a stopwatch app with hundredths of seconds and burst for 10 seconds. You'll see. Then shoot something with a LOT of detail at 8MP in both SnappyCam and Fast Camera.
Fast Camera is capable of 10-12 native quality 8MP images per second (more than SnappyCam) We throttle it back on purpose.
And what's with camera-shutter.caf John? ;)
Michael Zaletel Founder, i4software Fast Camera, Vizzywig, Video Filters
As discussed over e-mail, I've created an in depth report showing that SnappyCam indeed takes full quality 8 Mpx shots on the iPhone 5.
With the amazing discussion and interest here on HN, I thought to share it with the community here as well:
http://www.snappylabs.com/blog/snappycam/2013/08/03/snappyca...
I'm off the grid on a hiking vacation for the next 2.5 weeks, back in late August and look forward to the discussion then.
jpap
On the first launch, if I quickly press the Setting button (bottom-right) it starts the flip animation and still shows the handwritten overlay explaining where to tap for manual focus and all whatnot. After the animation is complete, the overlay is still shown, so it looks like a mess. And it's also not obvious how to get the overlay back, because I haven't seen what it actually said.
Congrats on the TC cover and a very nice app. Get rich! :)
(edit) A nitpick - "Warm-up", not "Warmup"
(edit) Report Usage = On. Seriously? Who on Earth in their sane mind would actually want this, except for you? Next thing you tell me is that you have some "app analytics" library linked in and it's always on. Please don't be evil.
(edit) The same goes for "Send Crash Reports = Always". It should be "Ask". Respect your users and they will help.
1. Looks like a race condition for the settings button tap. Does it happen if you wait a second before pressing the settings button?
2. You can re-enable the tutorial (overlay) screens from the bottom of the settings menu.
3. On the usage/reports, I hear you. I won't give you bullshit on "standard industry practices" here, but I will say that I had to hack a well-known closed-source library to give you that opt-out from usage reporting. I really do value your privacy. (I've already requested the library developer fix it, and will try and write a blog post on how other developers can provide a kill switch, too.)
4. The default is there because many people don't like to configure apps, they just use them as-is. In that light, the default configuration is the one I felt was best for general use.
Just tried the actual functionality and it gives the machine gun sound effect, showing a counter going up to 50-60, then I release the button, the blue stripe around the button shrinks back, it adds a photo to the bottom-left area, but when I tap it, there are just 3 frames. What am I missing? Is it adaptively trimming bad frames (I am shooting in a low light conditions)?
(edit) Just tried again and this time after I release the shot button, it showed a big circle overlay with the "JPEG" in the middle that counted up to 100% and the resulting photo had the right amount frames. It didn't do that on the first try. It's either a bug ... or you are missing a helpful hint that explains what's going on :)
1. The receding circle is the capture buffer being processed. When you're tapping on the thumbnail, SnappyCam sees the start of the living photo being available and shows it. It does not, unfortunately, refresh the thumbnail list as more shots complete processing.
This is a (feature) bug and I'll work to address it.
2. The circle with percent progress is what I call "turbo rewind", where the camera is shut down so that all CPU cores can be applied to compression so that you can take back-to-back living photos quickly.
You can select the buffer "threshold" for when this kicks in under the advanced settings: look for Turbo Rewind.
Kudos, I just bought the app!
I'd just like to add that in addition to handcrafted code, choosing the right algorithm and always trying to "do less work" (less cycles, less data IO, better use of registers) makes a big difference.
Some feedback, the default exposure settings showed my room as pitch black (I have it very dim now), the native iphone5 camera adjusted automatically. I was able to snap a shot by pointing to the light. Personally I prefer not to crank the gain on the sensor.
Interesting on the native camera adjustment. SnappyCam will use the "low light boost" high ISO capabilities of the camera. I'll have a play around with it.
Otherwise, does the continuous flash help you much?
Enabling that automatically is an interesting problem in itself: I'd have to estimate the light level based on the camera preview... or perhaps from the preview metadata.
Will think about how that might be done. Thanks for the thought. :-)
Bought this!
A good start is actually the ARM processor; since it's a RISC instruction set, it's quite simple.
I've done lots of assembly in my ugrad days, even writing a Motorola HC11 micro-controller emulator, but ARM would be a much better choice right now.
I found the "Tonic: Whirlwind Tour of Assembly" [1] site invaluable to get me started for SnappyCam, as it covers a lot of the ARM ISA.
For iOS-related assembly, I'd recommend [2].
And for a taste of ARM NEON SIMD, have a look at [3]. The one thing that "clicked" for me on SIMD is that you should look at each register "lane" as trying to unroll a loop. I initially dived in thinking I'd just make a sequential algorithm parallel, which is often too difficult to arrange.
[1] http://www.coranac.com/tonc/text/asm.htm [2] http://www.shervinemami.info/armAssembly.html [3] http://hilbert-space.de/?p=22
1. What is the difference in quality between using this and the video capture mode? I.e. if what I really want is a high quality video, would this get me a better result than the built in programs?
2. Seeing as how you've done all this work (and how Android apps can be compiled from C) how difficult is it to port this to Android so that the rest of us can get in on it?
3. Is it just me, or can anyone else not change the settings / look at the other demos on the samples page?
2. It's a lot of work, hinted at in another thread here on HN. The entire "app" build on top of the JPEG codec needs to be built from scratch; new artwork is required, etc.
3. I just tried it from another machine and works for me.
My backend API is being hammered at the moment, which is awesome, but it doesn't appear to be overloaded. (Gotta love NodeJS!)
Will look into it...
Does it mean that S4's hardware is faster than iPhone 5 given they're using similar algorithms, and if you'd make the same app for Android it could get even better results?
If SnappyCam can do it on hardware that is older than the S4, then I can't see why technically Samsung can't lift their game.
And judging by how quickly they've been chasing Apple, and sometimes stepping ahead, I wouldn't be surprised to see a bit of leap-frogging for some time to come.
Let's see what the 5S/C brings in a few months! I'm excited.
I had similar thoughts myself, and forms a part of what I have in mind for the next major SnappyCam release (a taste is what you see on SnappyCam.com today). My thoughts are perhaps more web-focussed that what you describe, but the thought is really encouraging!
Instead of doing full resolution at 20 fps, can you do a smaller resolution at, say, 160 fps?
If the next generation iPhone processor is faster (a safe bet), do you think your software would allow at least 24 fps, and you could use the iPhone to shoot a 10+ megapixel movie?
Shouldn't Apple have hired you already?
I'm not performing any true miracles here: I'm just making best use of the hardware resources available, with some clever software tricks and algorithms.
The iPhone 5 actually supports 60 pictures/sec capture, for example, but Apple has decided for whatever reason, to disable it on iOS 6. If the iPhone 5 ran on iOS 5 (surprise?!) then it would likely run at 60 pictures/sec.
On iOS 7 that all changes: so you'll soon be able to capture at 60 pictures/sec, which is rad.
The rollerblader shown on the TC article was shot at Sunday Streets in the SF Mission District on my iPhone 4S at 60 pictures/sec. The photo quality is somewhat degraded for the web, but it still looks awesome full screen (from the SnappyCam website; the TC embed is in a restricted iframe and can't go full-screen).
I know a couple of great engineers that work at Apple, but haven't spoken with them for one or more years. Sounds like a cool place to work, but so can be working for yourself.
It's been a hard slog--I quit my last full-time job in March 2011--but I'd love to see SnappyCam through and bring to life another startup idea I have in mind. (Some of the YC partners have already seen me pitch it; SnappyCam has been a rather good distraction of late.)
I wonder how long before we start to see Kinect-like infrared cameras mounted on phones to make the depth problem easier to solve. That would be cool!
[1]: http://prodesigntools.com/photoshop-cs7-image-deblurring.htm...
This reminds me of research into superresolution, an area that's "super interesting" :-) as well.
The guys who started Occipital (360 Panorama), I believe, tried to dabble in that with ClearCam many years ago... but I honestly don't know much about it. Anyone from Occipital here on HN?
I was kinda hoping I could also turn the speed down to multiple seconds per photo, since it talks about doing time-lapse shots. One of my major uses for my phone's camera is selfies for art reference, currently done with Genius - which annoyingly won't do repeated shots at anything less than 10 seconds. Being able to take one shot every 1-3 seconds would be pretty damn cool for me.
You can reduce the capture rate in the app settings, down to 1 photo per {1, 5, 10, 30, ... } seconds.
Move the slider toward the turtle under "Camera Lens".
jpap
Also, some people were saying that webapp wasn't working for them on some chrome versions. As for me - I've got the 28.0.1500.95 - the culprit was Disconnect extension, which when disabled, allowed the whole application to behave as expected.
How does the encoder performance compare to libjpeg-turbo? That also has some SIMD work for NEON.
I haven't had a chance to do a side-by-side comparison as yet, but I suspect the SnappyCam encoder is faster for many reasons, including choice of algorithm and the way they use two multiplies (low, high) at times, and their image row-by-row nature with function call overhead in favour of code maintainability.
It seems I enthusiastically chose a larger buffer size that appears to be having some issues on some devices that have a lot of memory pressure.
If you reboot your phone, as awful as that sounds, it will likely fix the issue.
EDIT: I've just submitted an update to Apple that uses a more conservative buffer size.
This aspect is hard to get right: I once used an adaptive buffer size that heeded to memory warnings, but that meant that the buffer filled to lower levels than a conservatively sized buffer.
If only iOS had an opt-in for an *alloc returning 0 instead of these warnings, or at least notifying us of how much space left before we're SIGKILL'ed.
I recently read an article here on HN that briefly touched on memory management under iOS and especially the problem of apps getting killed, maybe it is interesting for you: http://sealedabstract.com/rants/why-mobile-web-apps-are-slow... (scroll down to "How much memory is available on iOS?")
Would love to see some real world comparison examples. Drop me a line when you've got something, would love to check it out. :)
I'd guess that DSLRs use a combination of hardware acceleration on the "tricky" bits (like DCT) with firmware to control the compute hardware.
Huffman is a particularly difficult beast, as it can't be parallelized. The JPEG bitstream is inherently serial, though there has been some proposals to improve that.
If you run a SnappyCam JPEG that you pluck from iTunes File Sharing through djpeg (from libJpeg) you will notice that each of the YCbCr planes are not interleaved.
I once experimented with a parallel JPEG encoder, encoding the Y, Cb, and Cr planes in parallel but the threading overhead was more than just queuing up each JPEG encode separately in a multithread queue.
Bonus points if you notice another marker in the JPEG. That's intended for parallel JPEG decoding but hasn't yet been implemented in SnappyCam as yet. (The existing decoder is fast enough for 8Mpx shots.)
On top of that, you'll have the 'firmware', which is where projects such as Magic Lantern/CHDK make things fun.
Some reading on the Canon gear:
http://cpn.canon-europe.com/content/education/infobank/captu...
It was my understanding that German mobile numbers are written locally starting with 01? [1]
e.g. in Australia, my mobile number would be 040x-xxx-xxx. The international version is +61 40x-xxx-xxx. When you select Australia, it will show 04.
(OK, I now see how this could be confusing; my apologies.)
[1] http://en.wikipedia.org/wiki/Telephone_numbers_in_Germany#No...
(Internally I add the international prefix. As you can imagine it took a while to find all of the local prefixes and create number masks!)
I haven't personally tried it, but would love for it to match the code quality of hand-cranked assembly... writing it is tedious, error prone, but you do get control over when you preload the cache, the stack, and you can do really cool things with the CPP and macros to "manually inline" things. :-)
And who doesn't like writing a good 'ol fashioned jump table?!
Out of curiosity and a bit unrelated, I've been craving for real raw capture on the iPhone (before bayer interpolation, white balance, noise removal). Is it possible?
If you have a look at the data sheets, for example [1], you'll see YCbCr or RGB output formats being listed.
I guess it would make sense for as much signal processing to be done as early in the chain in the interests of lowering power consumption. (Less data to transfer over a serial bus into more circuitry, at the very least.)
[1] http://www.ovt.com/products/sensor.php?id=134
(Sony also make the sensors for Apple, apparently.)
I'm not usually one to post publicly either, but with practice I'm finding it comes more naturally.
I do hope you dive in---the devil's details in image signal processing is really interesting.
They really like to hide those iPhone apps! ;-)
It will be nice to play with the interactive living photos full-screen, though iOS 7 makes iPhone apps look amazing on the iPads in any case.
Perhaps one day! :D It was a tonne of work that I'd love for fellow engineers to take a look at. I learned a massive amount from reading the likes of libTurboJpeg and other OSS implementations; though none of them are using the same DCT as the one I developed for SnappyCam. (They weren't a good fit for the ARM NEON ISA.)
I suspect Clarity on Camera+ is some form of Contrast Limited Adaptive Histogram Equalization (CLAHE).
CLAHE came about from digital image cleanup of medical scans for human analysis.
I'd love to revisit it. It really works wonders. I've played with the CLAHE implementation in Fiji/ImageJ and while it can produce really good results, it does require some tuning.
I really admire the Camera+ guys for creating an auto tuning algorithm that is quite similar. (I'm unsure if they're using CLAHE or a variation.)
Any good skating sites I might want to contact?
I've read ARM's source code and found they they too use the AAN algorithm for the DCT. (They provide a tonne of code for other multimedia related stuff too.)
I learned a lot from their code, even though my implementation is completely different and original.
I would also dare to say that my asm source is maintainable. I had a very hard time understanding their code as it wasn't very well documented or laid out... but nevertheless a valuable learning tool.
Could you take the 'trimmed' section and create a looping GIF from that? (Can I do that already?)
great app man, thanks
Unless you roll your own viewer, many devs suggest using an embedded UIWebView to animate it.
Otherwise it kinda gets treated as pass-through for most of iOS. The Messages app apparently animates them nicely, and for some is a real motivation to include the feature. (So they can send animated GIFs to their friends.)
Glad you like the app! :D
The whole "living image" sounds nice. If it was possible to create a format, say "AJPEG", out of it, it would be awesome.
Futhermore, what happens if you point this at a device that can affect each pixel on the phone's image sensor 20 times a second? Is all the information preserved? If so, this is an interesting hardware hack. If not, this is an interesting shell game. But I don't see how it's a scientific breakthrough.
(It sure is good for sales when TechCrunch prints your press release verbatim, though!)