2008-09-12 12:23:09 Faster JPEG encoding - files attached
Frank Van Hooft (CANADA)
Message: 62061
I'd been wanting to speed up JPEG encoding on the blackfin. Initially I'd been using FFMPEG, and it's fast thanks to the optimisations coded by the ADI folks. But FFMPEG caused me troubles due to its constant malloc'ing & free'ing of memory; over time I was getting Out Of Memory failures due to memory fragmentation. So I turned to the LIBJPEG library, which is much simpler, but slower due to not being optimised.
The bulk of the time in JPEG encoding is spent in the DCT algorithm. libjpeg ships with 3 different DCT implementations; float, accurate integer, fast integer, all coded in C. I recoded the fast integer routine, jfdctfst.c, into blackfin assembler. The new file, attached, is jfdctfst_bfin.S. The new function name is jfdctfst_bfin
Cycle counts (measured by me on a BF537) are:
Original jfdctfst.c function: 2507 cycles
New jfdctfst_bfin.S function: 1058 cycles
Also attached is a slightly edited Makefile containing a rule for building the .S file.
To try this new function, do the following:
1) Copy the two attached files into your libjpeg directory. The Makefile will overwrite the existing Makefile; you may want to make a copy of your original first.
2) Call the new function. I did it by editing the jfdctfst.c file so it calls the jfdctfst_bfin function instead. This might not be the most elegant, but it works. Add the following function prototype to the jfdctfst.c file:
void jfdctfst_bfin (DCTELEM *buf);
Then call the new assembler function at the beginning of the jpeg_fdct_ifast function:
jfdctfst_bfin (data);
return;
So now, when your libjpeg application calls the fast integer DCT routine, it's actually using the assembler version.
Some final notes. I'm not making any guarantees on this code. All I can say is, it works for me. I've tested it as best I can by feeding sample vectors through it, comparing the results to the original .c source, and it appears correct. JPEG images produced also appear correct. I'm sure it's not optimally fast - no doubt a smarter brain than mine can improve on this. But it's a big improvement over the C version - good enough for me. Enjoy.
Makefile
jfdctfst_bfin.S
QuoteReplyEditDelete
2008-09-12 15:24:41 Re: Faster JPEG encoding - files attached
Robin Getz (UNITED STATES)
Message: 62076
Frank:
Thanks. The person (Tom) who was looking at putting the optimized Blackfin code into libjpeg - is still planning on doing this - I think he was just stuck with a few things, and got bumped onto something else for a bit. Hopefully between what he has, and what you have done, we can get things that work, which are fast.
Thanks again.
-Robin
QuoteReplyEditDelete
2008-09-15 23:32:59 Re: Faster JPEG encoding - files attached
Sonic Zhang (CHINA)
Message: 62199
Recorded in patch tracker.
QuoteReplyEditDelete
2008-12-05 01:42:14 Re: Faster JPEG encoding - files attached
andy (UNITED STATES)
Message: 66375
I followed the instructions. Upon make I get the following error messages:
cc -c -o jfdctfst_bfin.o jfdctfst_bfin.S
jfdctfst_bfin.S: Assembler messages:
jfdctfst_bfin.S:157: Error: junk at end of line, first unrecognized character is `['
jfdctfst_bfin.S:167: Error: junk at end of line, first unrecognized character is `('
jfdctfst_bfin.S:169: Error: missing ']'
jfdctfst_bfin.S:169: Error: junk at end of line, first unrecognized character is `@'
jfdctfst_bfin.S:178: Error: no such instruction: `lsetup (.rowtop,.rowend)LC0=P1>>1'
jfdctfst_bfin.S:209: Error: junk at end of line, first unrecognized character is `['
jfdctfst_bfin.S:210: Error: junk at end of line, first unrecognized character is `['
jfdctfst_bfin.S:211: Error: junk at end of line, first unrecognized character is `('
jfdctfst_bfin.S:212: Error: junk at end of line, first unrecognized character is `['
jfdctfst_bfin.S:213: Error: junk at end of line, first unrecognized character is `('
jfdctfst_bfin.S:214: Error: bad expression
jfdctfst_bfin.S:214: Error: junk at end of line, first unrecognized character is `,'
jfdctfst_bfin.S:215: Error: junk at end of line, first unrecognized character is `('
jfdctfst_bfin.S:216: Error: junk at end of line, first unrecognized character is `['
jfdctfst_bfin.S:217: Error: bad expression
jfdctfst_bfin.S:217: Error: junk at end of line, first unrecognized character is `,'
jfdctfst_bfin.S:230: Error: bad expression
jfdctfst_bfin.S:230: Error: junk at end of line, first unrecognized character is `,'
jfdctfst_bfin.S:240: Error: junk at end of line, first unrecognized character is `['
jfdctfst_bfin.S:241: Error: junk at end of line, first unrecognized character is `['
jfdctfst_bfin.S:251: Error: junk at end of line, first unrecognized character is `('
jfdctfst_bfin.S:252: Error: no such instruction: `r4 >>>=8'
jfdctfst_bfin.S:254: Error: junk at end of line, first unrecognized character is `['
jfdctfst_bfin.S:255: Error: junk at end of line, first unrecognized character is `['
jfdctfst_bfin.S:266: Error: junk at end of line, first unrecognized character is `='
jfdctfst_bfin.S:277: Error: junk at end of line, first unrecognized character is `,'
jfdctfst_bfin.S:278: Error: bad expression
jfdctfst_bfin.S:278: Error: missing ')'
jfdctfst_bfin.S:278: Error: junk at end of line, first unrecognized character is `R'
jfdctfst_bfin.S:279: Error: no such instruction: `r6 >>>=8'
jfdctfst_bfin.S:280: Error: no such instruction: `r7 >>>=8'
jfdctfst_bfin.S:281: Error: junk at end of line, first unrecognized character is `('
jfdctfst_bfin.S:282: Error: no such instruction: `r0 <<=8'
jfdctfst_bfin.S:292: Error: bad expression
jfdctfst_bfin.S:292: Error: junk at end of line, first unrecognized character is `,'
jfdctfst_bfin.S:302: Error: junk at end of line, first unrecognized character is `['
jfdctfst_bfin.S:303: Error: junk at end of line, first unrecognized character is `['
jfdctfst_bfin.S:304: Error: junk at end of line, first unrecognized character is `['
jfdctfst_bfin.S:305: Error: invalid character '[' in mnemonic
jfdctfst_bfin.S:311: Error: no such instruction: `p0 +=32'
jfdctfst_bfin.S:323: Error: no such instruction: `lsetup (.coltop,.colend)LC0=P1>>1'
jfdctfst_bfin.S:340: Error: no such instruction: `p0 +=32'
jfdctfst_bfin.S:342: Error: junk at end of line, first unrecognized character is `('
jfdctfst_bfin.S:343: Error: junk at end of line, first unrecognized character is `('
jfdctfst_bfin.S:344: Error: junk at end of line, first unrecognized character is `('
jfdctfst_bfin.S:345: Error: junk at end of line, first unrecognized character is `('
jfdctfst_bfin.S:360: Error: junk at end of line, first unrecognized character is `['
jfdctfst_bfin.S:361: Error: junk at end of line, first unrecognized character is `['
jfdctfst_bfin.S:362: Error: junk at end of line, first unrecognized character is `['
jfdctfst_bfin.S:363: Error: junk at end of line, first unrecognized character is `['
jfdctfst_bfin.S:364: Error: junk at end of line, first unrecognized character is `['
jfdctfst_bfin.S:365: Error: bad expression
jfdctfst_bfin.S:365: Error: junk at end of line, first unrecognized character is `,'
jfdctfst_bfin.S:366: Error: junk at end of line, first unrecognized character is `['
jfdctfst_bfin.S:367: Error: junk at end of line, first unrecognized character is `['
jfdctfst_bfin.S:368: Error: bad expression
jfdctfst_bfin.S:368: Error: junk at end of line, first unrecognized character is `,'
jfdctfst_bfin.S:382: Error: bad expression
jfdctfst_bfin.S:382: Error: junk at end of line, first unrecognized character is `,'
jfdctfst_bfin.S:390: Error: junk at end of line, first unrecognized character is `('
jfdctfst_bfin.S:391: Error: junk at end of line, first unrecognized character is `='
jfdctfst_bfin.S:401: Error: junk at end of line, first unrecognized character is `('
jfdctfst_bfin.S:402: Error: no such instruction: `r4 >>>=8'
jfdctfst_bfin.S:403: Error: no such instruction: `r1 >>>=16'
jfdctfst_bfin.S:404: Error: junk at end of line, first unrecognized character is `,'
jfdctfst_bfin.S:405: Error: junk at end of line, first unrecognized character is `='
jfdctfst_bfin.S:406: Error: junk at end of line, first unrecognized character is `('
jfdctfst_bfin.S:407: Error: junk at end of line, first unrecognized character is `='
jfdctfst_bfin.S:408: Error: junk at end of line, first unrecognized character is `='
jfdctfst_bfin.S:420: Error: junk at end of line, first unrecognized character is `='
jfdctfst_bfin.S:430: Error: junk at end of line, first unrecognized character is `,'
jfdctfst_bfin.S:431: Error: bad expression
jfdctfst_bfin.S:431: Error: missing ')'
jfdctfst_bfin.S:431: Error: junk at end of line, first unrecognized character is `R'
jfdctfst_bfin.S:432: Error: no such instruction: `r6 >>>=8'
jfdctfst_bfin.S:433: Error: no such instruction: `r7 >>>=8'
jfdctfst_bfin.S:434: Error: junk at end of line, first unrecognized character is `('
jfdctfst_bfin.S:435: Error: no such instruction: `r0 <<=8'
jfdctfst_bfin.S:445: Error: bad expression
jfdctfst_bfin.S:445: Error: junk at end of line, first unrecognized character is `,'
jfdctfst_bfin.S:459: Error: junk at end of line, first unrecognized character is `('
jfdctfst_bfin.S:460: Error: junk at end of line, first unrecognized character is `='
jfdctfst_bfin.S:461: Error: junk at end of line, first unrecognized character is `('
jfdctfst_bfin.S:462: Error: junk at end of line, first unrecognized character is `='
jfdctfst_bfin.S:463: Error: junk at end of line, first unrecognized character is `('
jfdctfst_bfin.S:464: Error: junk at end of line, first unrecognized character is `='
jfdctfst_bfin.S:465: Error: junk at end of line, first unrecognized character is `('
jfdctfst_bfin.S:466: Error: junk at end of line, first unrecognized character is `['
jfdctfst_bfin.S:471: Error: junk at end of line, first unrecognized character is `('
jfdctfst_bfin.S:472: Error: no such instruction: `rts'
make: *** [jfdctfst_bfin.o] Error 1
How should I get it compile?
QuoteReplyEditDelete
2008-12-05 01:52:27 Re: Faster JPEG encoding - files attached
Yi Li (CHINA)
Message: 66376
Andy,
Please use blackfin toolchain to build (e.g, the bfin-uclinux-gcc).
-Yi
QuoteReplyEditDelete
2009-06-09 21:19:09 Re: Faster JPEG encoding - files attached
Frank Van Hooft (CANADA)
Message: 75417
I know this is an old thread, but presumably I'm not the only one needing a faster JPG encoder.
The clever folks over at Surveyor robots www.surveyor.com wrote a pretty good JPEG encoder. I took their code, added RGB support, and did a number of optimizations. The bottom line is that for my test image, libjpeg with the fast DCT takes around 260 ms. This new code takes 96 ms. It produces results visually identical (as far as I can see, and I've certainly looked) to libjpeg.
It's a real credit to the surveyor code that we were able to get it running so fast.
You can find the code in the surveyor forums. You might find it easier to pull it off my website here:
blog.frankvh.com/2009/06/09/blackfin-fast-jpeg-encoding/
simply because I also provide instructions on how to use it.
Hopefully this will benefit someone else.
QuoteReplyEditDelete
2009-06-09 21:29:39 Re: Faster JPEG encoding - files attached
Mike Frysinger (UNITED STATES)
Message: 75419
we've integrated optimized dct into the libjpeg in the trunk/2009R1 svn branches