views:

672

answers:

3

Greetings. I'm building a video player in ActionScript 3, that's supposed to be targeted on performance. It has to play large h264 videos via RTMP, with the least possible processor load.

There's not much control on the actual video playback part, but my approach is to try and not kill the processor with the chrome and other additional parts of the player. I've ditched the FLVPlayback and all components and build my own player from scratch, using Video, NetConnection and NetStream, but the NetStream class does not have an update event.

Therefor, in order to update the progress bar and elapsed time textfield, I must create a regular event of my own, that reads from the NetStream.time property and calculates the progress of the video.

As far as I've figured out, I have two ways I can do that: by creating a Timer class instance or by adding a listener for the EnterFrame event. I'm looking for the best way to update regularly (each couple hundreds ms), with the least impact on the processor load. Which of the two is likely to be a better option?

There's also a third solution, but it seems like a long shot to me: create a separate animation, a basic tween, that plays independent of the video and only syncs on various video events. That would remove the regular update altogether, but only as far as I can see in the code. The animation still updates itself while playing, obviously, but I'm guessing that would be handled on a lower level than a timer. Sure, there will be extra code in order to keep the animation of the progress bar and the actual video playback in sync, but at least I won't have a timer going off 30 times per second.

Which is the best way to eat up the least processor resources?

+1  A: 

if this is just about redrawing one bar and updating a textfield, your considerations are a bit over the edge ... i like it, when people care about performance, but you see, the cost of decoding an h264 video frame makes your task completely unsignificant, performance wise ... personally, i'd go with a Timer, every second ... this largely suffices ... the position will not change faster than that (or are you showing msecs?) ... and if you have a big file, than the progress bar will not move much faster, than 1 pixel every 10 seconds ... so that is fine ... but you could as well do it on enterframe ... to save a little performance, you may check if a redraw/update is neccessary at all before carrying it out, so no unneccessary rendering is performed ... but really, this is FAR from being a bottle neck ...

little note: flash.utils::setInterval is more performant (although admittedly not such a clean solution as Timer), since it bypasses the need of a TimerEvent instantiation (and instantiation is always rather expensive), and the overhead of event dispatching ... yet, in this case, there will be no measurable improvement ...

back2dos
+2  A: 

Asking which approach is the most efficient is the wrong way to begin. Instead, ask yourself which approach is conceptually appropriate for what you want to do.

Since you're updating part of your app's visuals, it would probably be wise to start with the fact that Flash updates the screen on a fixed schedule - once per frames - and it issues events before and afterwards. If performance didn't matter, the most correct approach would be to update the visual in an ENTER_FRAME handler - ensuring that you don't run your update code more than once per frame (wasting cycles on updates that will not be drawn to the screen) or less (possibly degrading the visual results). So start with that.

Since using a frame handler is the correct approach if performance didn't matter, the next question is, does using a frame handler affect performance? The best way to answer that is to profile your app, but I'd bet my house the answer will be no. Flash will be redrawing your video anyway, and unless your progress bar has fifteen filters on it, it's hard to imagine that it have any measurable effect. Also, even if you decided to call your updated every Nth frame, instead of every frame, unless everything you'd be updating is outside of the dirty rectangle, it will be redrawn every frame anyway, regardless of whether you've moved it or not. So the "savings" in performance would amount to little more than a function call and a variable assignment each frame. Such savings would be invisible compared to simplifying the graphics in the progress bar itself (and thus lowering the cost of redrawing it), if squeezing out more performance was necessary.

All this is a long-winded way of saying, use the Frame handler unless you can find a measurable reason not to. (You won't. ;) If in doubt, after you're finished, try removing the event listener and see if it makes any difference in performance, and if it does, tackle the problem then.

fenomas
A: 

Compared to the cost of decoding h264 video streams, I don't think that the overhead added by the FLVPlayer component would be so significant.

By the way avoid the 3rd solution, because you can't really know the play time. On older machines the decoding will cause the video to hung or lag.

kajyr
Obviously, resync operations would be applied. Which, of course, complicates things.
evilpenguin