Open Bug 531802 Opened 15 years ago Updated 2 years ago

APNG frame delay does not work correctly if < 11 ms

Categories

(Core :: Graphics: ImageLib, defect)

x86
Windows XP
defect

Tracking

()

People

(Reporter: crynsos, Unassigned)

References

(Blocks 1 open bug)

Details

Attachments

(1 file)

User-Agent:       Mozilla/5.0 (Windows; U; Windows NT 5.1; de; rv:1.9.1.5) Gecko/20091102 Firefox/3.5.5
Build Identifier: Mozilla/5.0 (Windows; U; Windows NT 5.1; de; rv:1.9.1.5) Gecko/20091102 Firefox/3.5.5

Firefox ignores APNGs (created with the "APNG Edit" Add-On) with a delay between frames that is less or equal to 10 ms, 11 ms + frame delays work correctly.
The same file is shown correctly in Opera 9.64 and XnView 1.96.2.

Reproducible: Always

Steps to Reproduce:
Compare http://h.imagehost.org/0010/GAU-19.png (1 ms delay, 2 - 10 produce the same speed) with http://h.imagehost.org/0819/GAU-19.png (11 ms delay)

Actual Results:  
The frame switching speed is reduced extremely when changing from 11 ms frame delay to 1 - 10 ms frame delay.

Expected Results:  
Faster frame switching (equivalent / higher to the second image's frame switching)

Tested in safe mode, same result. (possibility of Add-Ons slowing down Firefox)
Version: unspecified → 3.5 Branch
Component: File Handling → ImageLib
Product: Firefox → Core
QA Contact: file.handling → imagelib
Version: 3.5 Branch → 1.9.1 Branch
This is definitely the case, but is on purpose. Not sure if it's something we should fix, though. Dolske, any thoughts?
Status: UNCONFIRMED → NEW
Ever confirmed: true
Version: 1.9.1 Branch → Trunk
Well, its not a high priority thing anyways since similar results can be created just as well with 11 ms delay or a bit more, but since it seemed unusual I thought I'd report it.
Dunno, I don't thing APNG Edit itself is doing any limiting.

IIRC, GIFs have historically has frame delays < 10ms clamped to 10ms, so this might have just been trying to mimic that. You'd have to ask vlad or Andrew Smith why APNGs do this.

Does seem like a bug that a < 10ms frame delay is playing slower than a 11ms frame delay, though.
(In reply to comment #3)
> Does seem like a bug that a < 10ms frame delay is playing slower
> than a 11ms frame delay, though.

The spec says, "If the [delay] is 0 the decoder should render the next
frame as quickly as possible, though viewers may impose a reasonable
lower bound."  That might be slower than 11ms, if 0 displays the entire
frame but 11ms abandons the frame after 11ms.  I think the spec means
to say that delays of 1-10 are exact but the implementation might be interpreting any of those to be the same as 0 ("as quickly as possible").
Assignee: nobody → glennrp+bmo
Status: NEW → ASSIGNED
I think the behavior comes from this code in src/modules/libpr0n/src:

    // Uh oh, the frame we want to show is currently being decoded (partial)
    // Wait a bit and try again
    mAnim->timer->SetDelay(100);

If it takes 10ms to decode the frame, then if the requested delay is 11ms that
will be the actual delay.  But for requested delays 1-10ms the actual
delay will be 101-110ms.

You could try a build with a smaller SetDelay parameter, e.g., (10) or even (1).  The framing rate would still slow down but not so obviously.

With (10) the actual delays would be 11-20, and with (1) they would all be about 11ms, which seems like a reasonable behavior.
I tried changing SetDelay(100) to SetDelay(1) but it seems to make no difference.
How are we supposed to distinguish between an 11ms delay and a 1ms delay on a typical 75Hz monitor?  In either case the framing rate exceeds the capability of the monitor (13.3ms).  Would it be useful to have a maximum framing rate in about:config, and make some use of that information in the animation decoder?  i.e., SetDelay(13) instead of SetDelay(100) when the monitor has a 75Hz refresh rate, and maybe skip frames when the framing rate is too high.
Blocks: 495609
The problem in comment 7 sounds very much related to the stuff roc is working on for compositor (bug 374980). Specifically, the part about not just blasting paints as they're needed, but batching to dispatch at a reasonable frequency.

I'd almost guess you'd want animations to be driven by a single timer heartbeat, and paint based on computing what frame should be visible at time t. Maybe with some fancyness to slow the heartbeat to a lower rate when there are no active animations or are animating slowly.

But I'm not a gfx hacker, so this could all be crazytalk. :)
One thing a browser could do is look at dispose_op in the fcTL chunk.  If it is not DISPOSE_OP_NONE then the frame can be skipped without decoding or displaying the fdAT chunk data, if the animation is running behind schedule.  If it is DISPLOSE_OP_NONE, though, subsequent frames depend on it and it has to be decoded.

In an animation with a constant 1msec framing rate, you'd want to skip all but 1 out of each 13 frames to drive a 75Hz display.

Counterintuitively, this would mean that DISPOSE_OP_PREVIOUS is the preferable dispose_op, not DISPOSE_OP_NONE which seems simpler.
From https://wiki.mozilla.org/APNG_Specification

"The `delay_num` and `delay_den` parameters together specify a fraction indicating the time to display the current frame, in seconds. If the denominator is 0, it is to be treated as if it were 100 (that is, `delay_num` then specifies 1/100ths of a second). If the the value of the numerator is 0 the decoder should render the next frame as quickly as possible, though viewers may impose a reasonable lower bound.

Frame timings should be independent of the time required for decoding and display of each frame, so that animations will run at the same rate regardless of the performance of the decoder implementation."

I think there might be some confusion between perceived frame rate (eg. monitor, human eye, etc.) and actual drawing frame rate.  If we interepret specification literally it provides both "as quickly as possible" (0ms?) and 1/32767th's of a second.  Also, "frame timings should be independent of decoder".  Frame timings are the time the frame IS displayed, NOT the time between drawing frames.

0ms is extremely useful where parts of the image are updated between perceived frames.  The major advantage is APNG file size.

For example:

Start with a background image 1000x1000 pixels.
Add random pixels at a rate of 1ms.
For simplicity, assume 20ms (50 fps) visible frame rate.
That means we draw 20 pixels per visible frame.

It's far more efficient to have the single 1000x1000 background frame (uncompressed ~1MB) then apply 20 random single pixel frames (~60 bytes each) at 0ms (1200 bytes) with a 20ms delay frame (empty).  In contrast, if we were to animate full frames every 20ms then the data requirement is INSANE (~50MB second).

Using this rationale it's imperative that 0ms ("as quickly as possible") be supported and I believe this was the intention of the APNG spec. I'd rather animate the 20 pixels above at 0ms then add a delay frame with no data or a sync frame (a little like MPEG).  By doing this, we could update pieces of an image between sync frames without blowing out the APNG file sizes.  (Note: Conceivably the APNG spec could be extended further to provide MPEG style animation and keep file sizes down.  References to Alpha blending imply it).

The above example is something we've hit in practice.  This 11ms bug is causing us a headache, however, the concept of frames has been very easy to program and overall we like the APNG spec.  By removing the 11ms limitation in FF we could do some very interesting animations/videos that would easily compete Flash video.  We'd rather be using an open APNG format than something proprietary!
I've written a patch for bug 71829 that will help fix this issue. There will still be a minimum delay of 10 ms, but at least Firefox will use 10 ms as a minimum delay instead of changing delays of 10 ms and below to 100 ms.

I'm not sure if it's feasible to use delays of 0 ms to make updates to different parts of an APNG. I could write a patch that will cause Firefox to honor all delays, and someone could build a version of Firefox to see if it works for that purpose.
The test case for this bug has disappeared.

The bug assignee didn't login in Bugzilla in the last 7 months.
:aosmond, could you have a look please?
For more information, please visit auto_nag documentation.

Assignee: glennrp+bmo → nobody
Status: ASSIGNED → NEW
Flags: needinfo?(aosmond)
Severity: normal → S3
Flags: needinfo?(aosmond)
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: